├── .gitignore
├── .kokoro
├── common.cfg
├── continuous.cfg
├── deploy-build-test.sh
├── periodic.cfg
├── presubmit.cfg
└── trampoline.sh
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SPEECH-TRANSLATION.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ ├── assets
│ │ ├── speech-recording-16khz.b64
│ │ ├── speech-recording-16khz.wav
│ │ ├── speech-recording-24khz.b64
│ │ └── speech-recording-24khz.wav
│ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── solutions
│ │ └── flexenv
│ │ └── common
│ │ ├── Base64EncodingHelperAndroidTest.java
│ │ └── SpeechTranslationHelperAndroidTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── google
│ │ └── cloud
│ │ └── solutions
│ │ └── flexenv
│ │ ├── FirebaseLogger.java
│ │ ├── PlayActivity.java
│ │ └── common
│ │ ├── Base64EncodingHelper.java
│ │ ├── BaseMessage.java
│ │ ├── GcsDownloadHelper.java
│ │ ├── LogEntry.java
│ │ ├── RecordingHelper.java
│ │ ├── SpeechMessage.java
│ │ ├── SpeechTranslationException.java
│ │ ├── SpeechTranslationHelper.java
│ │ ├── TextMessage.java
│ │ └── Translation.java
│ └── res
│ ├── drawable
│ ├── ic_baseline_mic_24px.xml
│ ├── ic_baseline_mic_none_24px.xml
│ ├── mic_button_selector.xml
│ └── side_nav_bar.xml
│ ├── layout
│ ├── activity_play.xml
│ ├── app_bar_play.xml
│ ├── content_play.xml
│ └── nav_header_play.xml
│ ├── menu
│ └── activity_play_drawer.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── speech_translation.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── nexus5.png
├── settings.gradle
└── speech-translation-device.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 | build/
16 |
17 | # Gradle cache
18 | .gradle/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Mobile Tools for Java (J2ME)
33 | .mtj.tmp/
34 |
35 | # Package Files
36 | *.jar
37 | !gradle/wrapper/gradle-wrapper.jar
38 | *.war
39 | *.ear
40 |
41 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
42 | hs_err_pid*
43 |
44 | # IDEA/Android Studio project files, because
45 | # the project can be imported from settings.gradle
46 | *.iml
47 | .idea/*
48 | !.idea/copyright
49 | !.idea/codeStyles/codeStyleConfig.xml
50 |
51 | # Keystore files
52 | *.jks
53 |
54 | # External native build folder
55 | .externalNativeBuild
56 |
57 | # Google services configuration file
58 | google-services.json
59 |
60 | # Attributes of the parent folder on macOS
61 | .DS_Store
62 |
63 | # Eclipse project files
64 | .classpath
65 | .project
66 |
67 | # Sandbox stuff
68 | _sandbox
69 | # Android Studio captures folder
70 | captures/
71 |
--------------------------------------------------------------------------------
/.kokoro/common.cfg:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google LLC.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # Format: //devtools/kokoro/config/proto/build.proto
16 |
17 | # Download trampoline resources.
18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
19 |
20 | # Download project resources from Cloud Storage.
21 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/firebase-android-client"
22 |
23 | # Download project resources for Cloud Function
24 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/nodejs-docs-samples"
25 |
26 | # Configure the docker image for kokoro-trampoline.
27 | env_vars: {
28 | key: "TRAMPOLINE_IMAGE"
29 | value: "gcr.io/cloud-devrel-kokoro-resources/java"
30 | }
31 |
32 |
33 | # Use the trampoline script to run in docker.
34 | build_file: "firebase-android-client/.kokoro/trampoline.sh"
35 |
36 | action {
37 | define_artifacts {
38 | regex: "**/*sponge_log*"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/.kokoro/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google LLC.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # Format: //devtools/kokoro/config/proto/build.proto
16 |
17 | # Tell trampoline which tests to run.
18 | env_vars: {
19 | key: "TRAMPOLINE_BUILD_FILE"
20 | value: "github/firebase-android-client/.kokoro/deploy-build-test.sh"
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/.kokoro/deploy-build-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # Fail on any error.
17 | set -e
18 |
19 | # Save starting directory. The script needs it later.
20 | cwd=$(pwd)
21 |
22 | echo "Setting up Android environment…"
23 | cd ${cwd}
24 | if [ ! -d ${HOME}/android-sdk ]; then
25 | mkdir -p ${HOME}/android-sdk
26 | pushd "${HOME}/android-sdk"
27 | wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
28 | unzip sdk-tools-linux-4333796.zip
29 | popd
30 | fi
31 |
32 | export ANDROID_HOME="${HOME}/android-sdk"
33 | export adb_command="$ANDROID_HOME"'/platform-tools/adb'
34 | # Install Android SDK, tools, and build tools API 29, system image, and emulator
35 | echo "y" | ${ANDROID_HOME}/tools/bin/sdkmanager \
36 | "platforms;android-29" "tools" "platform-tools" "build-tools;29.0.3" \
37 | "system-images;android-29;google_apis;x86_64" "emulator"
38 |
39 | export PATH=${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools:${PATH}
40 |
41 | echo "Use the headless emulator build..."
42 | cp "$ANDROID_HOME"'/emulator/qemu/linux-x86_64/qemu-system-x86_64-headless' \
43 | "$ANDROID_HOME"'/emulator/qemu/linux-x86_64/qemu-system-x86_64'
44 |
45 | echo "Move to the tools/bin directory…"
46 | cd ${ANDROID_HOME}/tools/bin
47 | echo "no" | ./avdmanager create avd -n test -k "system-images;android-29;google_apis;x86_64"
48 | echo ""
49 | echo "Start the emulator…"
50 | cd ${ANDROID_HOME}/emulator
51 | emulator -avd test -no-audio -no-window -screen no-touch &
52 | $adb_command wait-for-device
53 |
54 | echo "Setting up speech translation microservice…"
55 |
56 | git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git github/nodejs-docs-samples
57 | export QT_DEBUG_PLUGINS=1
58 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secrets-key.json
59 | export GCLOUD_PROJECT=nodejs-docs-samples-tests
60 | export GCF_REGION=us-central1
61 | export NODE_ENV=development
62 | export FUNCTIONS_TOPIC=integration-tests-instance
63 | export FUNCTIONS_BUCKET=$GCLOUD_PROJECT
64 | gcloud auth activate-service-account --key-file "$GOOGLE_APPLICATION_CREDENTIALS"
65 | gcloud config set project $GCLOUD_PROJECT
66 | cd ./github/nodejs-docs-samples/functions/speech-to-speech/functions
67 | env
68 | gcloud components update
69 | gcloud --version
70 | gcloud functions deploy speechTranslate --runtime nodejs10 --trigger-http \
71 | --update-env-vars ^:^OUTPUT_BUCKET=playchat-c5cc70f6-61ed-4640-91be-996721838560:SUPPORTED_LANGUAGE_CODES=en,es,fr
72 |
73 | echo "Move to the root directory of the repo…"
74 | cd ${cwd}/github/firebase-android-client
75 |
76 | # Copy the Google services configuration file and test values
77 | cp ${KOKORO_GFILE_DIR}/google-services.json app/google-services.json
78 | cp ${KOKORO_GFILE_DIR}/speech_translation_test.xml app/src/main/res/values/speech_translation.xml
79 |
80 | echo "Run tests and build APK file…"
81 | $adb_command logcat --clear
82 | $adb_command logcat v long > logcat_sponge_log &
83 | ./gradlew clean check build connectedAndroidTest
84 | $adb_command logcat --clear
85 |
86 | echo "Delete the Cloud Function…"
87 | gcloud functions delete speechTranslate
88 |
--------------------------------------------------------------------------------
/.kokoro/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google LLC.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # Format: //devtools/kokoro/config/proto/build.proto
16 |
17 | # Tell trampoline which tests to run.
18 | env_vars: {
19 | key: "TRAMPOLINE_BUILD_FILE"
20 | value: "github/firebase-android-client/.kokoro/deploy-build-test.sh"
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/.kokoro/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google LLC.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # Format: //devtools/kokoro/config/proto/build.proto
16 |
17 | # Tell trampoline which tests to run.
18 | env_vars: {
19 | key: "TRAMPOLINE_BUILD_FILE"
20 | value: "github/firebase-android-client/.kokoro/deploy-build-test.sh"
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/.kokoro/trampoline.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py"
17 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Want to contribute? Great! First, read this page (including the small print at the end).
2 |
3 | ### Before you contribute
4 | Before we can use your code, you must sign the
5 | [Google Individual Contributor License Agreement]
6 | (https://cla.developers.google.com/about/google-individual)
7 | (CLA), which you can do online. The CLA is necessary mainly because you own the
8 | copyright to your changes, even after your contribution becomes part of our
9 | codebase, so we need your permission to use and distribute your code. We also
10 | need to be sure of various other things—for instance that you'll tell us if you
11 | know that your code infringes on other people's patents. You don't have to sign
12 | the CLA until after you've submitted your code for review and a member has
13 | approved it, but you must do it before we can put your code into our codebase.
14 | Before you start working on a larger contribution, you should get in touch with
15 | us first through the issue tracker with your idea so that we can help out and
16 | possibly guide you. Coordinating up front makes it much easier to avoid
17 | frustration later on.
18 |
19 | ### Code reviews
20 | All submissions, including submissions by project members, require review. We
21 | use Github pull requests for this purpose.
22 |
23 | ### The small print
24 | Contributions made by corporations are covered by a different agreement than
25 | the one above, the
26 | [Software Grant and Corporate Contributor License Agreement]
27 | (https://cla.developers.google.com/about/google-corporate).
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5 | 1. Definitions.
6 | "License" shall mean the terms and conditions for use, reproduction,
7 | and distribution as defined by Sections 1 through 9 of this document.
8 | "Licensor" shall mean the copyright owner or entity authorized by
9 | the copyright owner that is granting the License.
10 | "Legal Entity" shall mean the union of the acting entity and all
11 | other entities that control, are controlled by, or are under common
12 | control with that entity. For the purposes of this definition,
13 | "control" means (i) the power, direct or indirect, to cause the
14 | direction or management of such entity, whether by contract or
15 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
16 | outstanding shares, or (iii) beneficial ownership of such entity.
17 | "You" (or "Your") shall mean an individual or Legal Entity
18 | exercising permissions granted by this License.
19 | "Source" form shall mean the preferred form for making modifications,
20 | including but not limited to software source code, documentation
21 | source, and configuration files.
22 | "Object" form shall mean any form resulting from mechanical
23 | transformation or translation of a Source form, including but
24 | not limited to compiled object code, generated documentation,
25 | and conversions to other media types.
26 | "Work" shall mean the work of authorship, whether in Source or
27 | Object form, made available under the License, as indicated by a
28 | copyright notice that is included in or attached to the work
29 | (an example is provided in the Appendix below).
30 | "Derivative Works" shall mean any work, whether in Source or Object
31 | form, that is based on (or derived from) the Work and for which the
32 | editorial revisions, annotations, elaborations, or other modifications
33 | represent, as a whole, an original work of authorship. For the purposes
34 | of this License, Derivative Works shall not include works that remain
35 | separable from, or merely link (or bind by name) to the interfaces of,
36 | the Work and Derivative Works thereof.
37 | "Contribution" shall mean any work of authorship, including
38 | the original version of the Work and any modifications or additions
39 | to that Work or Derivative Works thereof, that is intentionally
40 | submitted to Licensor for inclusion in the Work by the copyright owner
41 | or by an individual or Legal Entity authorized to submit on behalf of
42 | the copyright owner. For the purposes of this definition, "submitted"
43 | means any form of electronic, verbal, or written communication sent
44 | to the Licensor or its representatives, including but not limited to
45 | communication on electronic mailing lists, source code control systems,
46 | and issue tracking systems that are managed by, or on behalf of, the
47 | Licensor for the purpose of discussing and improving the Work, but
48 | excluding communication that is conspicuously marked or otherwise
49 | designated in writing by the copyright owner as "Not a Contribution."
50 | "Contributor" shall mean Licensor and any individual or Legal Entity
51 | on behalf of whom a Contribution has been received by Licensor and
52 | subsequently incorporated within the Work.
53 | 2. Grant of Copyright License. Subject to the terms and conditions of
54 | this License, each Contributor hereby grants to You a perpetual,
55 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
56 | copyright license to reproduce, prepare Derivative Works of,
57 | publicly display, publicly perform, sublicense, and distribute the
58 | Work and such Derivative Works in Source or Object form.
59 | 3. Grant of Patent License. Subject to the terms and conditions of
60 | this License, each Contributor hereby grants to You a perpetual,
61 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
62 | (except as stated in this section) patent license to make, have made,
63 | use, offer to sell, sell, import, and otherwise transfer the Work,
64 | where such license applies only to those patent claims licensable
65 | by such Contributor that are necessarily infringed by their
66 | Contribution(s) alone or by combination of their Contribution(s)
67 | with the Work to which such Contribution(s) was submitted. If You
68 | institute patent litigation against any entity (including a
69 | cross-claim or counterclaim in a lawsuit) alleging that the Work
70 | or a Contribution incorporated within the Work constitutes direct
71 | or contributory patent infringement, then any patent licenses
72 | granted to You under this License for that Work shall terminate
73 | as of the date such litigation is filed.
74 | 4. Redistribution. You may reproduce and distribute copies of the
75 | Work or Derivative Works thereof in any medium, with or without
76 | modifications, and in Source or Object form, provided that You
77 | meet the following conditions:
78 | (a) You must give any other recipients of the Work or
79 | Derivative Works a copy of this License; and
80 | (b) You must cause any modified files to carry prominent notices
81 | stating that You changed the files; and
82 | (c) You must retain, in the Source form of any Derivative Works
83 | that You distribute, all copyright, patent, trademark, and
84 | attribution notices from the Source form of the Work,
85 | excluding those notices that do not pertain to any part of
86 | the Derivative Works; and
87 | (d) If the Work includes a "NOTICE" text file as part of its
88 | distribution, then any Derivative Works that You distribute must
89 | include a readable copy of the attribution notices contained
90 | within such NOTICE file, excluding those notices that do not
91 | pertain to any part of the Derivative Works, in at least one
92 | of the following places: within a NOTICE text file distributed
93 | as part of the Derivative Works; within the Source form or
94 | documentation, if provided along with the Derivative Works; or,
95 | within a display generated by the Derivative Works, if and
96 | wherever such third-party notices normally appear. The contents
97 | of the NOTICE file are for informational purposes only and
98 | do not modify the License. You may add Your own attribution
99 | notices within Derivative Works that You distribute, alongside
100 | or as an addendum to the NOTICE text from the Work, provided
101 | that such additional attribution notices cannot be construed
102 | as modifying the License.
103 | You may add Your own copyright statement to Your modifications and
104 | may provide additional or different license terms and conditions
105 | for use, reproduction, or distribution of Your modifications, or
106 | for any such Derivative Works as a whole, provided Your use,
107 | reproduction, and distribution of the Work otherwise complies with
108 | the conditions stated in this License.
109 | 5. Submission of Contributions. Unless You explicitly state otherwise,
110 | any Contribution intentionally submitted for inclusion in the Work
111 | by You to the Licensor shall be under the terms and conditions of
112 | this License, without any additional terms or conditions.
113 | Notwithstanding the above, nothing herein shall supersede or modify
114 | the terms of any separate license agreement you may have executed
115 | with Licensor regarding such Contributions.
116 | 6. Trademarks. This License does not grant permission to use the trade
117 | names, trademarks, service marks, or product names of the Licensor,
118 | except as required for reasonable and customary use in describing the
119 | origin of the Work and reproducing the content of the NOTICE file.
120 | 7. Disclaimer of Warranty. Unless required by applicable law or
121 | agreed to in writing, Licensor provides the Work (and each
122 | Contributor provides its Contributions) on an "AS IS" BASIS,
123 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
124 | implied, including, without limitation, any warranties or conditions
125 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
126 | PARTICULAR PURPOSE. You are solely responsible for determining the
127 | appropriateness of using or redistributing the Work and assume any
128 | risks associated with Your exercise of permissions under this License.
129 | 8. Limitation of Liability. In no event and under no legal theory,
130 | whether in tort (including negligence), contract, or otherwise,
131 | unless required by applicable law (such as deliberate and grossly
132 | negligent acts) or agreed to in writing, shall any Contributor be
133 | liable to You for damages, including any direct, indirect, special,
134 | incidental, or consequential damages of any character arising as a
135 | result of this License or out of the use or inability to use the
136 | Work (including but not limited to damages for loss of goodwill,
137 | work stoppage, computer failure or malfunction, or any and all
138 | other commercial damages or losses), even if such Contributor
139 | has been advised of the possibility of such damages.
140 | 9. Accepting Warranty or Additional Liability. While redistributing
141 | the Work or Derivative Works thereof, You may choose to offer,
142 | and charge a fee for, acceptance of support, warranty, indemnity,
143 | or other liability obligations and/or rights consistent with this
144 | License. However, in accepting such obligations, You may act only
145 | on Your own behalf and on Your sole responsibility, not on behalf
146 | of any other Contributor, and only if You agree to indemnify,
147 | defend, and hold each Contributor harmless for any liability
148 | incurred by, or claims asserted against, such Contributor by reason
149 | of your accepting any such warranty or additional liability.
150 | END OF TERMS AND CONDITIONS
151 | APPENDIX: How to apply the Apache License to your work.
152 | To apply the Apache License to your work, attach the following
153 | boilerplate notice, with the fields enclosed by brackets "{}"
154 | replaced with your own identifying information. (Don't include
155 | the brackets!) The text should be enclosed in the appropriate
156 | comment syntax for the file format. We also recommend that a
157 | file or class name and description of purpose be included on the
158 | same "printed page" as the copyright notice for easier
159 | identification within third-party archives.
160 | Copyright {yyyy} {name of copyright owner}
161 | Licensed under the Apache License, Version 2.0 (the "License");
162 | you may not use this file except in compliance with the License.
163 | You may obtain a copy of the License at
164 | http://www.apache.org/licenses/LICENSE-2.0
165 | Unless required by applicable law or agreed to in writing, software
166 | distributed under the License is distributed on an "AS IS" BASIS,
167 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
168 | See the License for the specific language governing permissions and
169 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | This project is no longer actively developed or maintained.
4 |
5 | For new work on this check out [this sample](https://github.com/firebase/quickstart-android).
6 |
7 | # Build a mobile app using Firebase and App Engine flexible environment
8 |
9 | 
10 |
11 | This repository contains the Android client sample code for the [Build a Mobile
12 | App Using Firebase and App Engine Flexible
13 | Environment](https://cloud.google.com/solutions/mobile/mobile-firebase-app-engine-flexible)
14 | solution. You can find the sample code for the backend in the
15 | [firebase-appengine-backend](../../../firebase-appengine-backend)
16 | repository.
17 |
18 | ## Build requirements
19 |
20 | - Sign up for [Firebase](https://firebase.google.com/) and create a new project
21 | in the [Firebase console](https://console.firebase.google.com/).
22 | - Deploy your backend according to the instructions in the
23 | [firebase-appengine-backend](../../../firebase-appengine-backend)
24 | repository.
25 |
26 | > **Note**: Firebase is a Google product, independent from Google Cloud
27 | > Platform.
28 |
29 | Build and test environment:
30 |
31 | - Android Studio 4.0.1 from the stable channel.
32 | - Android 8.1 (API Level 27) emulator.
33 |
34 | ## Configuration
35 |
36 | 1. Sign in to the [Firebase console](https://console.firebase.google.com) and
37 | select your backend project.
38 | 1. In the **Develop** section, select **Authentication**.
39 | 1. In the **Authentication** page, select **Sign-in Method**.
40 | 1. Select and enable the **Google** sign-in provider.
41 | 1. [Get your development environment SHA-1
42 | fingerprints](https://developers.google.com/android/guides/client-auth).
43 | 1. Provide the following information in your Firebase project settings:
44 | - **App nickname**: PlayChat
45 | - **Package name**: com.google.cloud.solutions.flexenv
46 | - **SHA certificate fingerprints**: Your development environment SHA-1
47 | fingerprints from the previous step.
48 | 1. Download the `google-services.json` file to the root directory of the `app`
49 | module in your Android project.
50 |
51 | ## Launch and test
52 |
53 | 1. Start your emulator and run the app.
54 | 1. Sign in with a Google account.
55 | 1. Select a channel from top-left menu and enter messages.
56 |
57 | The following screenshot shows messages displayed in the app:
58 |
59 | 
60 |
61 | This sample supports speech messages that are automatically translated to the
62 | device language. For more information, see [Enable speech translation with
63 | Machine Learning technologies on Google Cloud Platform](SPEECH-TRANSLATION.md).
64 |
65 | ## License
66 |
67 | Copyright 2018 Google LLC. All Rights Reserved.
68 |
69 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
70 | this file except in compliance with the License. You may obtain a copy of the
71 | License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
72 | applicable law or agreed to in writing, software distributed under the License
73 | is distributed on an "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
74 | KIND, either express or implied. See the License for the specific language
75 | governing permissions and limitations under the License.
76 |
77 | This is not an official Google product.
78 |
--------------------------------------------------------------------------------
/SPEECH-TRANSLATION.md:
--------------------------------------------------------------------------------
1 | # Enable speech translation with Machine Learning technologies on Google Cloud Platform
2 |
3 | The PlayChat sample supports speech messages that are automatically translated
4 | to different languages by a microservice on Google Cloud Platform (GCP).
5 |
6 | The microservice is implemented as a [Google Cloud Function][1] that uses the
7 | [Speech-to-Text][2], [Translation][3], and [Text-to-Speech][4] APIs to process
8 | the audio messages. The translated messages are stored in a bucket on [Google
9 | Cloud Storage][5] where the PlayChat app can retrieve them. The microservice is
10 | available in the [Speech-to-Speech Translation Sample][6].
11 |
12 | The following screenshot shows the PlayChat sample with a message translated to
13 | French.
14 |
15 | 
16 |
17 | ## Configuring speech translation
18 |
19 | 1. Configure the PlayChat sample following the instructions on the
20 | [README](README.md) file.
21 | 1. Deploy the [Speech-to-Speech Translation Sample][6] to your GCP project.
22 | 1. Update the value of the `speechToSpeechEndpoint` field in the
23 | [speech_translation.xml][7] file with the URL of the function deployed in the
24 | previous step.
25 | 1. Make sure that your user account has read permissions to the bucket where the
26 | microservice stores the translated audio messages. For more information, see
27 | [Setting bucket permissions][8] in the Google Cloud Storage documentation.
28 |
29 | ## Launch and test
30 |
31 | 1. Start your emulator and run the app.
32 | 1. Sign in with a Google account.
33 | 1. Tap the microphone icon and record a short voice message in the language of
34 | your device. The microservice supports English, Spanish, and French by
35 | default. However, you can configure other languages.
36 | 1. Change the default language on your device settings. The PlayChat app
37 | displays the message on the new language.
38 | 1. Tap the translated message to listen to it in the language of the device.
39 |
40 | ## License
41 |
42 | Copyright 2018 Google LLC. All Rights Reserved.
43 |
44 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
45 | this file except in compliance with the License. You may obtain a copy of the
46 | License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
47 | applicable law or agreed to in writing, software distributed under the License
48 | is distributed on an "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
49 | KIND, either express or implied. See the License for the specific language
50 | governing permissions and limitations under the License.
51 |
52 | This is not an official Google product.
53 |
54 | [1]: https://cloud.google.com/functions/
55 | [2]: https://cloud.google.com/speech-to-text/
56 | [3]: https://cloud.google.com/translate/
57 | [4]: https://cloud.google.com/text-to-speech/
58 | [5]: https://cloud.google.com/storage/
59 | [6]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/functions/speech-to-speech
60 | [7]: https://github.com/GoogleCloudPlatform/firebase-android-client/blob/master/app/src/main/res/values/speech_translation.xml
61 | [8]: https://cloud.google.com/storage/docs/cloud-console#_bucketpermission
62 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'com.google.gms.google-services'
3 |
4 | android {
5 | compileSdkVersion 29
6 | buildToolsVersion "29.0.3"
7 |
8 | defaultConfig {
9 | applicationId "com.google.cloud.solutions.flexenv"
10 | minSdkVersion 24
11 | targetSdkVersion 29
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(include: ['*.jar'], dir: 'libs')
32 | implementation 'androidx.appcompat:appcompat:1.2.0'
33 | implementation 'com.google.android.material:material:1.1.0'
34 | implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
35 | testImplementation 'junit:junit:4.12'
36 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
37 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
38 |
39 | implementation 'com.google.android.gms:play-services-base:17.4.0'
40 | implementation 'com.google.android.gms:play-services-auth:18.1.0'
41 | implementation 'com.google.firebase:firebase-auth:19.4.0'
42 | implementation 'com.google.firebase:firebase-database:19.4.0'
43 | implementation 'com.google.firebase:firebase-storage:19.2.0'
44 | implementation 'com.fasterxml.jackson.core:jackson-core:2.11.2'
45 | implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.2'
46 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.2'
47 | implementation "androidx.constraintlayout:constraintlayout:2.0.0"
48 | implementation 'org.chromium.net:cronet-embedded:76.3809.111'
49 | androidTestImplementation 'androidx.test:rules:1.3.0'
50 |
51 | androidTestImplementation 'com.android.support:support-annotations:28.0.0'
52 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
53 | androidTestImplementation 'androidx.test:runner:1.1.1'
54 | androidTestImplementation 'androidx.test:rules:1.1.1'
55 | }
56 |
57 | apply plugin: 'com.google.gms.google-services'
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/assets/speech-recording-16khz.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleCloudPlatform/firebase-android-client/9e801a6314640a8375df56fee956a296bf5f20b7/app/src/androidTest/assets/speech-recording-16khz.wav
--------------------------------------------------------------------------------
/app/src/androidTest/assets/speech-recording-24khz.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleCloudPlatform/firebase-android-client/9e801a6314640a8375df56fee956a296bf5f20b7/app/src/androidTest/assets/speech-recording-24khz.wav
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/google/cloud/solutions/flexenv/common/Base64EncodingHelperAndroidTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Google LLC.
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package com.google.cloud.solutions.flexenv.common;
17 |
18 | import android.content.Context;
19 |
20 | import org.junit.Assert;
21 | import org.junit.Test;
22 |
23 | import java.io.BufferedReader;
24 | import java.io.File;
25 | import java.io.FileOutputStream;
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.InputStreamReader;
29 | import java.io.OutputStream;
30 |
31 | import androidx.test.filters.SmallTest;
32 | import androidx.test.platform.app.InstrumentationRegistry;
33 |
34 | @SmallTest
35 | public class Base64EncodingHelperAndroidTest {
36 |
37 | @Test
38 | public void base64Encode_16Khz_Success() throws IOException {
39 | String expectedFilePath = "assets/speech-recording-16khz.b64";
40 | InputStream expectedInputStream = this.getClass().getClassLoader().getResourceAsStream(expectedFilePath);
41 | InputStreamReader expectedInputStreamReader = new InputStreamReader(expectedInputStream);
42 | BufferedReader expectedBufferedReader = new BufferedReader(expectedInputStreamReader);
43 | StringBuilder expected = new StringBuilder();
44 |
45 | String line;
46 | while((line = expectedBufferedReader.readLine()) != null) {
47 | expected.append(line);
48 | }
49 |
50 | String actualFilePath = "assets/speech-recording-16khz.wav";
51 | InputStream actualInputStream = this.getClass().getClassLoader().getResourceAsStream(actualFilePath);
52 |
53 | Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
54 | File actualFile = new File(context.getCacheDir(), "speech-recording-16khz.wav");
55 | OutputStream output = new FileOutputStream(actualFile);
56 | byte[] buffer = new byte[1024];
57 | int read;
58 | while ((read = actualInputStream.read(buffer)) != -1) {
59 | output.write(buffer, 0, read);
60 | }
61 | output.flush();
62 | output.close();
63 | actualInputStream.close();
64 |
65 | String actual = Base64EncodingHelper.encode(actualFile);
66 |
67 | Assert.assertEquals(expected.toString(), actual);
68 | }
69 |
70 | @Test
71 | public void base64Encode_24Khz_Success() throws IOException {
72 | String expectedFilePath = "assets/speech-recording-24khz.b64";
73 | InputStream expectedInputStream = this.getClass().getClassLoader().getResourceAsStream(expectedFilePath);
74 | InputStreamReader expectedInputStreamReader = new InputStreamReader(expectedInputStream);
75 | BufferedReader expectedBufferedReader = new BufferedReader(expectedInputStreamReader);
76 | StringBuilder expected = new StringBuilder();
77 |
78 | String line;
79 | while((line = expectedBufferedReader.readLine()) != null) {
80 | expected.append(line);
81 | }
82 |
83 | String actualFilePath = "assets/speech-recording-24khz.wav";
84 | InputStream actualInputStream = this.getClass().getClassLoader().getResourceAsStream(actualFilePath);
85 |
86 | Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
87 | File actualFile = new File(context.getCacheDir(), "speech-recording-24khz.wav");
88 | OutputStream output = new FileOutputStream(actualFile);
89 | byte[] buffer = new byte[1024];
90 | int read;
91 | while ((read = actualInputStream.read(buffer)) != -1) {
92 | output.write(buffer, 0, read);
93 | }
94 | output.flush();
95 | output.close();
96 | actualInputStream.close();
97 |
98 | String actual = Base64EncodingHelper.encode(actualFile);
99 |
100 | Assert.assertEquals(expected.toString(), actual);
101 | }
102 |
103 | @Test
104 | public void base64Encode_Fail() throws IOException {
105 | String expectedFilePath = "assets/speech-recording-24khz.b64";
106 | InputStream expectedInputStream = this.getClass().getClassLoader().getResourceAsStream(expectedFilePath);
107 | InputStreamReader expectedInputStreamReader = new InputStreamReader(expectedInputStream);
108 | BufferedReader expectedBufferedReader = new BufferedReader(expectedInputStreamReader);
109 | StringBuilder expected = new StringBuilder();
110 |
111 | String line;
112 | while((line = expectedBufferedReader.readLine()) != null) {
113 | expected.append(line);
114 | }
115 |
116 | String actualFilePath = "assets/speech-recording-16khz.wav";
117 | InputStream actualInputStream = this.getClass().getClassLoader().getResourceAsStream(actualFilePath);
118 |
119 | Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
120 | File actualFile = new File(context.getCacheDir(), "speech-recording-16khz.wav");
121 | OutputStream output = new FileOutputStream(actualFile);
122 | byte[] buffer = new byte[1024];
123 | int read;
124 | while ((read = actualInputStream.read(buffer)) != -1) {
125 | output.write(buffer, 0, read);
126 | }
127 | output.flush();
128 | output.close();
129 | actualInputStream.close();
130 |
131 | String actual = Base64EncodingHelper.encode(actualFile);
132 |
133 | Assert.assertNotEquals(expected.toString(), actual);
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/google/cloud/solutions/flexenv/common/SpeechTranslationHelperAndroidTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Google LLC.
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package com.google.cloud.solutions.flexenv.common;
17 |
18 | import android.content.Context;
19 | import android.util.Log;
20 |
21 | import org.chromium.net.CronetEngine;
22 | import org.json.JSONException;
23 | import org.json.JSONObject;
24 | import org.junit.Assert;
25 | import org.junit.Before;
26 | import org.junit.Test;
27 |
28 | import java.io.BufferedReader;
29 | import java.io.IOException;
30 | import java.io.InputStream;
31 | import java.io.InputStreamReader;
32 |
33 | import androidx.test.filters.LargeTest;
34 | import androidx.test.platform.app.InstrumentationRegistry;
35 |
36 | import static org.junit.Assert.assertTrue;
37 |
38 | @LargeTest
39 | public class SpeechTranslationHelperAndroidTest {
40 | private static final String TAG = "SpeechTranslationHelperAndroidTest";
41 | private static String base64EncodedAudioMessage;
42 | private static Context context;
43 | private static CronetEngine cronetEngine;
44 |
45 | @Before
46 | public void readSpeechRecording16khzb64File() throws IOException {
47 | String file = "assets/speech-recording-16khz.b64";
48 | InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);
49 | InputStreamReader inputStreamReader = new InputStreamReader(in);
50 | BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
51 |
52 | StringBuilder stringBuilder = new StringBuilder();
53 |
54 | String line;
55 | while((line = bufferedReader.readLine()) != null) {
56 | stringBuilder.append(line);
57 | }
58 | base64EncodedAudioMessage = stringBuilder.toString();
59 |
60 | context = InstrumentationRegistry.getInstrumentation().getTargetContext();
61 |
62 | CronetEngine.Builder myBuilder = new CronetEngine.Builder(context);
63 | cronetEngine = myBuilder.build();
64 | }
65 |
66 | @Test
67 | public void translateAudioMessage_Success() throws InterruptedException {
68 | final Object waiter = new Object();
69 |
70 | synchronized (waiter) {
71 | SpeechTranslationHelper.getInstance()
72 | .translateAudioMessage(context, cronetEngine, base64EncodedAudioMessage,
73 | 16000, new SpeechTranslationHelper.SpeechTranslationListener() {
74 | @Override
75 | public void onTranslationSucceeded(String responseBody) {
76 | try {
77 | Log.i(TAG, responseBody);
78 | JSONObject response = new JSONObject(responseBody);
79 | assertTrue(response.has("transcription"));
80 | } catch (JSONException e) {
81 | Log.i(TAG, e.getMessage());
82 | Assert.fail();
83 | } finally {
84 | synchronized (waiter) {
85 | waiter.notify();
86 | }
87 | }
88 | }
89 |
90 | @Override
91 | public void onTranslationFailed(Exception e) {
92 | Log.i(TAG, e.getMessage());
93 | Assert.fail();
94 | synchronized (waiter) {
95 | waiter.notify();
96 | }
97 | }
98 | });
99 |
100 | synchronized (waiter) {
101 | waiter.wait();
102 | }
103 | }
104 | }
105 |
106 | @Test
107 | public void translateAudioMessage_Wrong_SampleRate() throws InterruptedException {
108 | final Object waiter = new Object();
109 |
110 | synchronized (waiter) {
111 | SpeechTranslationHelper.getInstance()
112 | .translateAudioMessage(context, cronetEngine, base64EncodedAudioMessage,
113 | 24000, new SpeechTranslationHelper.SpeechTranslationListener() {
114 | @Override
115 | public void onTranslationSucceeded(String responseBody) {
116 | Log.i(TAG, responseBody);
117 | Assert.fail();
118 | }
119 |
120 | @Override
121 | public void onTranslationFailed(Exception e) {
122 | Log.i(TAG, e.getMessage());
123 | Assert.assertTrue(e.getMessage().contains("INVALID_ARGUMENT: sample_rate_hertz"));
124 | synchronized (waiter) {
125 | waiter.notify();
126 | }
127 | }
128 | });
129 |
130 | synchronized (waiter) {
131 | waiter.wait();
132 | }
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/google/cloud/solutions/flexenv/FirebaseLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright 2016 Google LLC.
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | */
15 |
16 | package com.google.cloud.solutions.flexenv;
17 |
18 | // [START firebase_logger]
19 |
20 | import com.google.cloud.solutions.flexenv.common.LogEntry;
21 | import com.google.firebase.database.DatabaseReference;
22 | import com.google.firebase.database.FirebaseDatabase;
23 |
24 | /*
25 | * FirebaseLogger pushes user event logs to a specified path.
26 | * A backend servlet instance listens to
27 | * the same key and keeps track of event logs.
28 | */
29 | class FirebaseLogger {
30 | private final DatabaseReference logRef;
31 |
32 | FirebaseLogger(String path) {
33 | logRef = FirebaseDatabase.getInstance().getReference().child(path);
34 | }
35 |
36 | public void log(String tag, String message) {
37 | LogEntry entry = new LogEntry(tag, message);
38 | logRef.push().setValue(entry);
39 | }
40 |
41 | }
42 | // [END firebase_logger]
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/google/cloud/solutions/flexenv/PlayActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Google LLC.
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package com.google.cloud.solutions.flexenv;
17 |
18 | import android.content.Intent;
19 | import android.media.MediaPlayer;
20 | import android.net.Uri;
21 | import android.os.Bundle;
22 | import android.util.Log;
23 | import android.view.KeyEvent;
24 | import android.view.Menu;
25 | import android.view.MenuItem;
26 | import android.view.View;
27 | import android.widget.AdapterView;
28 | import android.widget.Button;
29 | import android.widget.EditText;
30 | import android.widget.ImageButton;
31 | import android.widget.ListView;
32 | import android.widget.SimpleAdapter;
33 | import android.widget.TextView;
34 | import android.widget.Toast;
35 |
36 | import androidx.annotation.NonNull;
37 | import androidx.appcompat.app.ActionBarDrawerToggle;
38 | import androidx.appcompat.app.AppCompatActivity;
39 | import androidx.appcompat.widget.Toolbar;
40 | import androidx.core.view.GravityCompat;
41 | import androidx.drawerlayout.widget.DrawerLayout;
42 |
43 | import com.google.android.gms.auth.api.signin.GoogleSignIn;
44 | import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
45 | import com.google.android.gms.auth.api.signin.GoogleSignInClient;
46 | import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
47 | import com.google.android.gms.common.SignInButton;
48 | import com.google.android.gms.tasks.OnCompleteListener;
49 | import com.google.android.gms.tasks.Task;
50 | import com.google.android.material.navigation.NavigationView;
51 | import com.google.cloud.solutions.flexenv.common.Base64EncodingHelper;
52 | import com.google.cloud.solutions.flexenv.common.BaseMessage;
53 | import com.google.cloud.solutions.flexenv.common.GcsDownloadHelper;
54 | import com.google.cloud.solutions.flexenv.common.RecordingHelper;
55 | import com.google.cloud.solutions.flexenv.common.SpeechMessage;
56 | import com.google.cloud.solutions.flexenv.common.SpeechTranslationHelper;
57 | import com.google.cloud.solutions.flexenv.common.TextMessage;
58 | import com.google.cloud.solutions.flexenv.common.Translation;
59 | import com.google.firebase.auth.AuthCredential;
60 | import com.google.firebase.auth.FirebaseAuth;
61 | import com.google.firebase.auth.FirebaseUser;
62 | import com.google.firebase.auth.GoogleAuthProvider;
63 | import com.google.firebase.database.ChildEventListener;
64 | import com.google.firebase.database.DataSnapshot;
65 | import com.google.firebase.database.DatabaseError;
66 | import com.google.firebase.database.DatabaseReference;
67 | import com.google.firebase.database.FirebaseDatabase;
68 | import com.google.firebase.database.ValueEventListener;
69 |
70 | import org.chromium.net.CronetEngine;
71 | import org.json.JSONException;
72 | import org.json.JSONObject;
73 |
74 | import java.io.File;
75 | import java.io.IOException;
76 | import java.text.SimpleDateFormat;
77 | import java.util.ArrayList;
78 | import java.util.Arrays;
79 | import java.util.Date;
80 | import java.util.HashMap;
81 | import java.util.List;
82 | import java.util.Locale;
83 | import java.util.Map;
84 |
85 | /*
86 | * Main activity to select a channel and exchange messages with other users
87 | * The app expects users to authenticate with Google ID. It also sends user
88 | * activity logs to a servlet instance through Firebase.
89 | */
90 | public class PlayActivity
91 | extends AppCompatActivity
92 | implements NavigationView.OnNavigationItemSelectedListener,
93 | AdapterView.OnItemClickListener,
94 | View.OnKeyListener,
95 | View.OnClickListener {
96 |
97 | // Firebase keys commonly used with backend servlet instances
98 | private static final String IBX = "inbox";
99 | private static final String CHS = "channels";
100 | private static final String REQLOG = "requestLogger";
101 |
102 | private static final int RC_SIGN_IN = 9001;
103 |
104 | private static final String TAG = "PlayActivity";
105 | private static final String CURRENT_CHANNEL_KEY = "CURRENT_CHANNEL_KEY";
106 | private static final String INBOX_KEY = "INBOX_KEY";
107 | private static final String FIREBASE_LOGGER_PATH_KEY = "FIREBASE_LOGGER_PATH_KEY";
108 | private static FirebaseLogger fbLog;
109 |
110 | private GoogleSignInClient mGoogleSignInClient;
111 | private String firebaseLoggerPath;
112 | private String inbox;
113 | private String currentChannel;
114 | private ChildEventListener channelListener;
115 | private SimpleDateFormat fmt;
116 | private CronetEngine cronetEngine;
117 |
118 | private Menu channelMenu;
119 | private TextView channelLabel;
120 | private List