summaryrefslogtreecommitdiff
path: root/java/com/android/voicemail
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/voicemail')
-rw-r--r--java/com/android/voicemail/AndroidManifest.xml53
-rw-r--r--java/com/android/voicemail/VoicemailClient.java34
-rw-r--r--java/com/android/voicemail/VoicemailPowerCycleReceiver.java38
-rw-r--r--java/com/android/voicemail/VoicemailSecretCodeReceiver.java36
-rw-r--r--java/com/android/voicemail/impl/ActivationTask.java3
-rw-r--r--java/com/android/voicemail/impl/AndroidManifest.xml25
-rw-r--r--java/com/android/voicemail/impl/DeviceProvisionedJobService.java33
-rw-r--r--java/com/android/voicemail/impl/OmtpConstants.java37
-rw-r--r--java/com/android/voicemail/impl/OmtpReceiver.java105
-rw-r--r--java/com/android/voicemail/impl/OmtpService.java52
-rw-r--r--java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java56
-rw-r--r--java/com/android/voicemail/impl/PackageReplacedReceiver.java43
-rw-r--r--java/com/android/voicemail/impl/SubscriptionInfoHelper.java70
-rw-r--r--java/com/android/voicemail/impl/TelephonyManagerStub.java40
-rw-r--r--java/com/android/voicemail/impl/TelephonyVvmConfigManager.java2
-rw-r--r--java/com/android/voicemail/impl/VoicemailBootReceiver.java31
-rw-r--r--java/com/android/voicemail/impl/VoicemailClientImpl.java38
-rw-r--r--java/com/android/voicemail/impl/VoicemailClientReceiver.java6
-rw-r--r--java/com/android/voicemail/impl/VoicemailModule.java3
-rw-r--r--java/com/android/voicemail/impl/VoicemailStatus.java3
-rw-r--r--java/com/android/voicemail/impl/VoicemailTranscriptionServiceGrpc.java390
-rw-r--r--java/com/android/voicemail/impl/VvmPackageInstallReceiver.java80
-rw-r--r--java/com/android/voicemail/impl/VvmPhoneStateListener.java5
-rw-r--r--java/com/android/voicemail/impl/configui/AndroidManifest.xml25
-rw-r--r--java/com/android/voicemail/impl/configui/ConfigOverrideFragment.java178
-rw-r--r--java/com/android/voicemail/impl/configui/VoicemailSecretCodeActivity.java58
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-af/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-am/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ar/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-az/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-b+sr+Latn/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-be/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-bg/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-bn/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-bs/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ca/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-cs/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-da/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-de/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-el/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-en-rAU/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-en-rGB/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-en-rIN/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-es-rUS/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-es/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-et/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-eu/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-fa/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-fi/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-fr-rCA/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-fr/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-gl/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-gu/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-hi/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-hr/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-hu/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-hy/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-in/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-is/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-it/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-iw/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ja/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ka/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-kk/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-km/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-kn/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ko/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ky/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-lo/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-lt/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-lv/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-mk/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ml/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-mn/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-mr/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ms/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-my/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-nb/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ne/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-nl/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-no/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-pa/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-pl/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-pt-rBR/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-pt-rPT/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-pt/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ro/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ru/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-si/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-sk/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-sl/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-sq/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-sr/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-sv/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-sw/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ta/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-te/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-th/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-tl/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-tr/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-uk/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-ur/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-uz/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-vi/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-zh-rCN/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-zh-rHK/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-zh-rTW/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values-zu/strings.xml19
-rw-r--r--java/com/android/voicemail/impl/configui/res/values/strings.xml21
-rw-r--r--java/com/android/voicemail/impl/configui/res/xml/vvm_config_override.xml76
-rw-r--r--java/com/android/voicemail/impl/fetch/VoicemailFetchedCallback.java18
-rw-r--r--java/com/android/voicemail/impl/imap/ImapHelper.java19
-rw-r--r--java/com/android/voicemail/impl/mail/MailTransport.java5
-rw-r--r--java/com/android/voicemail/impl/mail/Message.java4
-rw-r--r--java/com/android/voicemail/impl/mail/internet/MimeHeader.java1
-rw-r--r--java/com/android/voicemail/impl/mail/internet/MimeMessage.java24
-rw-r--r--java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java2
-rw-r--r--java/com/android/voicemail/impl/proguard.flags4
-rw-r--r--java/com/android/voicemail/impl/protocol/OmtpProtocol.java2
-rw-r--r--java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java2
-rw-r--r--java/com/android/voicemail/impl/res/values-af/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-am/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ar/strings.xml4
-rw-r--r--java/com/android/voicemail/impl/res/values-az/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-b+sr+Latn/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-be/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-bg/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-bn/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-bs/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ca/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-cs/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-da/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-de/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-el/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-en-rAU/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-en-rGB/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-en-rIN/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-es-rUS/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-es/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-et/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-eu/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-fa/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-fi/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-fr-rCA/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-fr/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-gl/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-gu/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-hi/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-hr/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-hu/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-hy/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-in/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-is/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-it/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-iw/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ja/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ka/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-kk/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-km/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-kn/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ko/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ky/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-lo/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-lt/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-lv/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-mk/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ml/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-mn/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-mr/strings.xml4
-rw-r--r--java/com/android/voicemail/impl/res/values-ms/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-my/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-nb/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ne/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-nl/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-no/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-pa/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-pl/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-pt-rBR/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-pt-rPT/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-pt/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ro/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ru/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-si/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-sk/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-sl/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-sq/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-sr/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-sv/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-sw/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ta/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-te/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-th/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-tl/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-tr/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-uk/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-ur/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-uz/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-vi/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-zh-rCN/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-zh-rHK/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-zh-rTW/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values-zu/strings.xml2
-rw-r--r--java/com/android/voicemail/impl/res/values/strings.xml9
-rw-r--r--java/com/android/voicemail/impl/scheduling/TaskExecutor.java10
-rw-r--r--java/com/android/voicemail/impl/scheduling/TaskSchedulerJobService.java4
-rw-r--r--java/com/android/voicemail/impl/scheduling/TaskSchedulerService.java400
-rw-r--r--java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java18
-rw-r--r--java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java1
-rw-r--r--java/com/android/voicemail/impl/sms/OmtpMessageReceiver.java7
-rw-r--r--java/com/android/voicemail/impl/sms/OmtpMessageSender.java6
-rw-r--r--java/com/android/voicemail/impl/sync/OmtpVvmSyncReceiver.java2
-rw-r--r--java/com/android/voicemail/impl/sync/OmtpVvmSyncService.java131
-rw-r--r--java/com/android/voicemail/impl/sync/SyncOneTask.java7
-rw-r--r--java/com/android/voicemail/impl/sync/SyncTask.java9
-rw-r--r--java/com/android/voicemail/impl/sync/UploadTask.java6
-rw-r--r--java/com/android/voicemail/impl/sync/VoicemailsQueryHelper.java11
-rw-r--r--java/com/android/voicemail/impl/sync/VvmAccountManager.java61
-rw-r--r--java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java2
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java85
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java90
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionDbHelper.java137
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionService.java223
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionTask.java225
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionTaskAsync.java123
-rw-r--r--java/com/android/voicemail/impl/transcribe/TranscriptionTaskSync.java69
-rw-r--r--java/com/android/voicemail/impl/transcribe/VoicemailCompat.java59
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/GetTranscriptResponseAsync.java102
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClient.java61
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClientFactory.java196
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponse.java53
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseAsync.java53
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseSync.java43
-rw-r--r--java/com/android/voicemail/impl/transcribe/grpc/voicemail_transcription.proto133
-rw-r--r--java/com/android/voicemail/permissions.xml21
-rw-r--r--java/com/android/voicemail/stub/StubVoicemailClient.java21
235 files changed, 4614 insertions, 1112 deletions
diff --git a/java/com/android/voicemail/AndroidManifest.xml b/java/com/android/voicemail/AndroidManifest.xml
new file mode 100644
index 000000000..817cf1b55
--- /dev/null
+++ b/java/com/android/voicemail/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<!--
+ ~ Copyright (C) 2017 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.voicemail">
+
+ <uses-sdk
+ android:minSdkVersion="23"
+ android:targetSdkVersion="26"/>
+
+ <!-- Applications using this module should merge these permissions using android_manifest_merge -->
+
+ <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"/>
+ <uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+ <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.SEND_SMS"/>
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+
+ <application>
+ <receiver
+ android:name=".VoicemailSecretCodeReceiver"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.SECRET_CODE" />
+ <data android:scheme="android_secret_code" />
+ </intent-filter>
+ </receiver>
+
+ <receiver android:name="com.android.voicemail.VoicemailPowerCycleReceiver"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="android.intent.action.ACTION_SHUTDOWN" />
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
diff --git a/java/com/android/voicemail/VoicemailClient.java b/java/com/android/voicemail/VoicemailClient.java
index 97b824b27..d52a67a8e 100644
--- a/java/com/android/voicemail/VoicemailClient.java
+++ b/java/com/android/voicemail/VoicemailClient.java
@@ -18,7 +18,10 @@ package com.android.voicemail;
import android.content.Context;
import android.content.Intent;
+import android.os.PersistableBundle;
import android.provider.VoicemailContract.Voicemails;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
@@ -52,6 +55,18 @@ public interface VoicemailClient {
"com.android.voicemail.VoicemailClient.ACTION_SHOW_LEGACY_VOICEMAIL";
/**
+ * Boolean extra send with {@link #ACTION_SHOW_LEGACY_VOICEMAIL}, indicating that the notification
+ * is sent by legacy mode and should not be suppressed even when VVM is activated
+ */
+ String EXTRA_IS_LEGACY_MODE = "is_legacy_mode";
+
+ /**
+ * Secret code to launch the voicemail config activity intended for OEMs and Carriers. {@code
+ * *#*#VVMCONFIG#*#*}
+ */
+ String VOICEMAIL_SECRET_CODE = "886266344";
+
+ /**
* Whether the visual voicemail service is enabled for the {@code phoneAccountHandle}. "Enable"
* means the user "wants" to have this service on, and does not mean the service is actually
* functional(For example, the service is blocked on the carrier side. The service will be
@@ -122,4 +137,23 @@ public interface VoicemailClient {
* provisioning. Being "activated" means all setup are completed, and VVM is expected to work.
*/
boolean isActivated(Context context, PhoneAccountHandle phoneAccountHandle);
+
+ /**
+ * Called when {@link #VOICEMAIL_SECRET_CODE} is dialed. {@code context} will be a broadcast
+ * receiver context.
+ */
+ @MainThread
+ void showConfigUi(@NonNull Context context);
+
+ @NonNull
+ PersistableBundle getConfig(
+ @NonNull Context context, @Nullable PhoneAccountHandle phoneAccountHandle);
+
+ @MainThread
+ void onBoot(@NonNull Context context);
+
+ @MainThread
+ void onShutdown(@NonNull Context context);
+
+ void onTosAccepted(Context context);
}
diff --git a/java/com/android/voicemail/VoicemailPowerCycleReceiver.java b/java/com/android/voicemail/VoicemailPowerCycleReceiver.java
new file mode 100644
index 000000000..e9362b42d
--- /dev/null
+++ b/java/com/android/voicemail/VoicemailPowerCycleReceiver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.voicemail;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import com.android.dialer.common.Assert;
+
+/** Receives {@link Intent#ACTION_BOOT_COMPLETED} and {@link Intent#ACTION_SHUTDOWN} */
+public class VoicemailPowerCycleReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ VoicemailClient voicemailClient = VoicemailComponent.get(context).getVoicemailClient();
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ voicemailClient.onBoot(context);
+ } else if (Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
+ voicemailClient.onShutdown(context);
+ } else {
+ throw Assert.createAssertionFailException("unexpected action: " + intent.getAction());
+ }
+ }
+}
diff --git a/java/com/android/voicemail/VoicemailSecretCodeReceiver.java b/java/com/android/voicemail/VoicemailSecretCodeReceiver.java
new file mode 100644
index 000000000..6d142410c
--- /dev/null
+++ b/java/com/android/voicemail/VoicemailSecretCodeReceiver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.voicemail;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import com.android.dialer.common.LogUtil;
+
+/** Receives android.provider.Telephony.SECRET_CODE */
+public class VoicemailSecretCodeReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String host = intent.getData().getHost();
+ if (!VoicemailClient.VOICEMAIL_SECRET_CODE.equals(host)) {
+ return;
+ }
+ LogUtil.i("VoicemailSecretCodeReceiver.onReceive", "secret code received");
+ VoicemailComponent.get(context).getVoicemailClient().showConfigUi(context);
+ }
+}
diff --git a/java/com/android/voicemail/impl/ActivationTask.java b/java/com/android/voicemail/impl/ActivationTask.java
index 6e27b5015..320ea2aaa 100644
--- a/java/com/android/voicemail/impl/ActivationTask.java
+++ b/java/com/android/voicemail/impl/ActivationTask.java
@@ -36,7 +36,6 @@ import com.android.voicemail.impl.scheduling.RetryPolicy;
import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
import com.android.voicemail.impl.sms.StatusMessage;
import com.android.voicemail.impl.sms.StatusSmsFetcher;
-import com.android.voicemail.impl.sync.OmtpVvmSyncService;
import com.android.voicemail.impl.sync.SyncTask;
import com.android.voicemail.impl.sync.VvmAccountManager;
import com.android.voicemail.impl.utils.LoggerUtils;
@@ -258,7 +257,7 @@ public class ActivationTask extends BaseTask {
VoicemailStatus.edit(context, phoneAccountHandle),
OmtpEvents.CONFIG_REQUEST_STATUS_SUCCESS);
clearLegacyVoicemailNotification(context, phoneAccountHandle);
- SyncTask.start(context, phoneAccountHandle, OmtpVvmSyncService.SYNC_FULL_SYNC);
+ SyncTask.start(context, phoneAccountHandle);
}
/** Sends a broadcast to the dialer UI to clear legacy voicemail notifications if any. */
diff --git a/java/com/android/voicemail/impl/AndroidManifest.xml b/java/com/android/voicemail/impl/AndroidManifest.xml
index 95e6e8212..4cad2247c 100644
--- a/java/com/android/voicemail/impl/AndroidManifest.xml
+++ b/java/com/android/voicemail/impl/AndroidManifest.xml
@@ -15,15 +15,10 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.voicemailomtp">
+ package="com.android.voicemail.impl">
<application
- android:allowBackup="false"
- android:supportsRtl="true"
- android:usesCleartextTraffic="true"
- android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true">
-
+ android:supportsRtl="true">
<!-- Causes the "Voicemail" item under "Calls" setting to be hidden. The voicemail module will
be handling the settings. Has no effect before OC where dialer cannot provide voicemail
settings-->
@@ -97,6 +92,16 @@
android:exported="false"/>
<service
+ android:name="com.android.voicemail.impl.transcribe.TranscriptionService"
+ android:permission="android.permission.BIND_JOB_SERVICE"
+ android:exported="false"/>
+
+ <service
+ android:name="com.android.voicemail.impl.transcribe.TranscriptionBackfillService"
+ android:permission="android.permission.BIND_JOB_SERVICE"
+ android:exported="false"/>
+
+ <service
android:name="com.android.voicemail.impl.OmtpService"
android:permission="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"
android:exported="true"
@@ -112,10 +117,10 @@
android:windowSoftInputMode="stateVisible|adjustResize">
</activity>
- <receiver android:name="com.android.voicemail.impl.VoicemailBootReceiver"
- android:exported="false">
+ <receiver android:name="com.android.voicemail.impl.PackageReplacedReceiver"
+ android:exported="false">
<intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
diff --git a/java/com/android/voicemail/impl/DeviceProvisionedJobService.java b/java/com/android/voicemail/impl/DeviceProvisionedJobService.java
index a0b999d23..20993d051 100644
--- a/java/com/android/voicemail/impl/DeviceProvisionedJobService.java
+++ b/java/com/android/voicemail/impl/DeviceProvisionedJobService.java
@@ -29,6 +29,7 @@ import android.content.Intent;
import android.os.Build.VERSION_CODES;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.support.annotation.VisibleForTesting;
import android.telecom.PhoneAccountHandle;
import com.android.dialer.constants.ScheduledJobIds;
@@ -39,29 +40,25 @@ import com.android.dialer.constants.ScheduledJobIds;
@TargetApi(VERSION_CODES.O)
public class DeviceProvisionedJobService extends JobService {
- private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "EXTRA_PHONE_ACCOUNT_HANDLE";
+ @VisibleForTesting static final String EXTRA_PHONE_ACCOUNT_HANDLE = "EXTRA_PHONE_ACCOUNT_HANDLE";
/** Queue the phone account to be reactivated after the setup wizard has completed. */
public static void activateAfterProvisioned(
Context context, PhoneAccountHandle phoneAccountHandle) {
- JobInfo jobInfo =
- new JobInfo.Builder(
- ScheduledJobIds.VVM_DEVICE_PROVISIONED_JOB,
- new ComponentName(context, DeviceProvisionedJobService.class))
- .addTriggerContentUri(
- new TriggerContentUri(Global.getUriFor(Global.DEVICE_PROVISIONED), 0))
- // VVM activation must be run as soon as possible to avoid voicemail loss
- .setTriggerContentMaxDelay(0)
- .build();
-
Intent intent = new Intent();
intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
- context.getSystemService(JobScheduler.class).enqueue(jobInfo, new JobWorkItem(intent));
+ context
+ .getSystemService(JobScheduler.class)
+ .enqueue(createJobInfo(context), new JobWorkItem(intent));
}
@Override
public boolean onStartJob(JobParameters params) {
- Assert.isTrue(isDeviceProvisioned());
+ if (!isDeviceProvisioned()) {
+ VvmLog.i("DeviceProvisionedJobService.onStartJob", "device not provisioned, rescheduling");
+ getSystemService(JobScheduler.class).schedule(createJobInfo(this));
+ return false; // job not running in background
+ }
VvmLog.i("DeviceProvisionedJobService.onStartJob", "device provisioned");
for (JobWorkItem item = params.dequeueWork(); item != null; item = params.dequeueWork()) {
PhoneAccountHandle phoneAccountHandle =
@@ -82,4 +79,14 @@ public class DeviceProvisionedJobService extends JobService {
private boolean isDeviceProvisioned() {
return Settings.Global.getInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) == 1;
}
+
+ private static JobInfo createJobInfo(Context context) {
+ return new JobInfo.Builder(
+ ScheduledJobIds.VVM_DEVICE_PROVISIONED_JOB,
+ new ComponentName(context, DeviceProvisionedJobService.class))
+ .addTriggerContentUri(new TriggerContentUri(Global.getUriFor(Global.DEVICE_PROVISIONED), 0))
+ // VVM activation must be run as soon as possible to avoid voicemail loss
+ .setTriggerContentMaxDelay(0)
+ .build();
+ }
}
diff --git a/java/com/android/voicemail/impl/OmtpConstants.java b/java/com/android/voicemail/impl/OmtpConstants.java
index 599d0d5f0..97da2a8e3 100644
--- a/java/com/android/voicemail/impl/OmtpConstants.java
+++ b/java/com/android/voicemail/impl/OmtpConstants.java
@@ -234,6 +234,39 @@ public class OmtpConstants {
public static final int CHANGE_PIN_INVALID_CHARACTER = 5;
public static final int CHANGE_PIN_SYSTEM_ERROR = 6;
- /** Indicates the client is Google visual voicemail version 1.0. */
- public static final String CLIENT_TYPE_GOOGLE_10 = "google.vvm.10";
+ public static String getClientType() {
+ String manufacturer =
+ truncate(
+ android.os.Build.MANUFACTURER
+ .replace('=', '_')
+ .replace(';', '_')
+ .replace('.', '_')
+ .replace(' ', '_'),
+ 12);
+
+ String version =
+ truncate(
+ android.os.Build.VERSION
+ .RELEASE
+ .replace('=', '_')
+ .replace(';', '_')
+ .replace('.', '_')
+ .replace(' ', '_'),
+ 8);
+
+ String model =
+ truncate(
+ android.os.Build.MODEL
+ .replace('=', '_')
+ .replace(';', '_')
+ .replace('.', '_')
+ .replace(' ', '_'),
+ 28 - manufacturer.length() - version.length());
+
+ return String.format("%s.%s.%s", manufacturer, model, version);
+ }
+
+ private static final String truncate(String string, int length) {
+ return string.substring(0, Math.min(length, string.length()));
+ }
}
diff --git a/java/com/android/voicemail/impl/OmtpReceiver.java b/java/com/android/voicemail/impl/OmtpReceiver.java
deleted file mode 100644
index 9baf95415..000000000
--- a/java/com/android/voicemail/impl/OmtpReceiver.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.voicemail.impl;
-
-import android.annotation.TargetApi;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build.VERSION_CODES;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.VisualVoicemailSms;
-import com.android.dialer.common.Assert;
-import com.android.dialer.logging.DialerImpression;
-import com.android.dialer.logging.Logger;
-import com.android.voicemail.VoicemailComponent;
-import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
-import com.android.voicemail.impl.sync.VvmAccountManager;
-
-/** Listens to com.android.phone.vvm.ACTION_TEMP_VISUAL_VOICEMAIL_SERVICE_EVENT */
-@TargetApi(VERSION_CODES.O)
-public class OmtpReceiver extends BroadcastReceiver {
-
- private static final String TAG = "VvmOmtpReceiver";
-
- public static final String ACTION_SMS_RECEIVED = "com.android.vociemailomtp.sms.sms_received";
-
- public static final String EXTRA_VOICEMAIL_SMS = "extra_voicemail_sms";
-
- private static final String EXTRA_WHAT = "what";
-
- private static final int MSG_ON_CELL_SERVICE_CONNECTED = 1;
-
- private static final int MSG_ON_SMS_RECEIVED = 2;
-
- private static final int MSG_ON_SIM_REMOVED = 3;
-
- private static final int MSG_TASK_STOPPED = 5;
-
- private static final String DATA_PHONE_ACCOUNT_HANDLE = "data_phone_account_handle";
-
- private static final String DATA_SMS = "data_sms";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- // ACTION_VISUAL_VOICEMAIL_SERVICE_EVENT is not a protected broadcast pre-O.
- if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
- VvmLog.e(TAG, "ACTION_VISUAL_VOICEMAIL_SERVICE_EVENT received when module is disabled");
- return;
- }
-
- int what = intent.getIntExtra(EXTRA_WHAT, -1);
- PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(DATA_PHONE_ACCOUNT_HANDLE);
- OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(context, phoneAccountHandle);
- if (!config.isValid()) {
- VvmLog.i(TAG, "VVM not supported on " + phoneAccountHandle);
- return;
- }
- if (!VisualVoicemailSettingsUtil.isEnabled(context, phoneAccountHandle)
- && !config.isLegacyModeEnabled()) {
- VvmLog.i(TAG, "VVM is disabled");
- return;
- }
- switch (what) {
- case MSG_ON_CELL_SERVICE_CONNECTED:
- VvmLog.i(TAG, "onCellServiceConnected");
- Logger.get(context).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
- ActivationTask.start(context, phoneAccountHandle, null);
- break;
- case MSG_ON_SMS_RECEIVED:
- VvmLog.i(TAG, "onSmsReceived");
- Logger.get(context).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
- VisualVoicemailSms sms = intent.getParcelableExtra(DATA_SMS);
- Intent receivedIntent = new Intent(ACTION_SMS_RECEIVED);
- receivedIntent.setPackage(context.getPackageName());
- receivedIntent.putExtra(EXTRA_VOICEMAIL_SMS, sms);
- context.sendBroadcast(receivedIntent);
- break;
- case MSG_ON_SIM_REMOVED:
- VvmLog.i(TAG, "onSimRemoved");
- Logger.get(context).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
- VvmAccountManager.removeAccount(context, phoneAccountHandle);
- break;
- case MSG_TASK_STOPPED:
- VvmLog.i(TAG, "onStopped");
- Logger.get(context).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
- break;
- default:
- throw Assert.createIllegalStateFailException("unexpected what: " + what);
- }
- }
-}
diff --git a/java/com/android/voicemail/impl/OmtpService.java b/java/com/android/voicemail/impl/OmtpService.java
index b82cc5f68..4db1aeb7e 100644
--- a/java/com/android/voicemail/impl/OmtpService.java
+++ b/java/com/android/voicemail/impl/OmtpService.java
@@ -17,9 +17,13 @@
package com.android.voicemail.impl;
import android.annotation.TargetApi;
+import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION_CODES;
import android.os.UserManager;
+import android.preference.PreferenceManager;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
import android.telecom.PhoneAccountHandle;
import android.telephony.VisualVoicemailService;
import android.telephony.VisualVoicemailSms;
@@ -40,6 +44,8 @@ public class OmtpService extends VisualVoicemailService {
public static final String EXTRA_VOICEMAIL_SMS = "extra_voicemail_sms";
+ private static final String IS_SHUTTING_DOWN = "com.android.voicemail.impl.is_shutting_down";
+
@Override
public void onCellServiceConnected(
VisualVoicemailTask task, final PhoneAccountHandle phoneAccountHandle) {
@@ -50,7 +56,7 @@ public class OmtpService extends VisualVoicemailService {
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
VvmLog.i(TAG, "onCellServiceConnected: user locked");
task.finish();
return;
@@ -75,7 +81,7 @@ public class OmtpService extends VisualVoicemailService {
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
LegacyModeSmsHandler.handle(this, sms);
return;
}
@@ -105,12 +111,18 @@ public class OmtpService extends VisualVoicemailService {
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
VvmLog.i(TAG, "onSimRemoved: user locked");
task.finish();
return;
}
+ if (isShuttingDown(this)) {
+ VvmLog.i(TAG, "onSimRemoved: system shutting down, ignoring");
+ task.finish();
+ return;
+ }
+
Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
VvmAccountManager.removeAccount(this, phoneAccountHandle);
task.finish();
@@ -124,7 +136,7 @@ public class OmtpService extends VisualVoicemailService {
task.finish();
return;
}
- if (!isUserUnlocked()) {
+ if (!isUserUnlocked(this)) {
VvmLog.i(TAG, "onStopped: user locked");
task.finish();
return;
@@ -132,6 +144,22 @@ public class OmtpService extends VisualVoicemailService {
Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
}
+ @MainThread
+ static void onBoot(@NonNull Context context) {
+ VvmLog.i(TAG, "onBoot");
+ Assert.isTrue(isUserUnlocked(context));
+ Assert.isMainThread();
+ setShuttingDown(context, false);
+ }
+
+ @MainThread
+ static void onShutdown(@NonNull Context context) {
+ VvmLog.i(TAG, "onShutdown");
+ Assert.isTrue(isUserUnlocked(context));
+ Assert.isMainThread();
+ setShuttingDown(context, true);
+ }
+
private boolean isModuleEnabled() {
return VoicemailComponent.get(this).getVoicemailClient().isVoicemailModuleEnabled();
}
@@ -150,8 +178,20 @@ public class OmtpService extends VisualVoicemailService {
return true;
}
- private boolean isUserUnlocked() {
- UserManager userManager = getSystemService(UserManager.class);
+ private static boolean isUserUnlocked(@NonNull Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
return userManager.isUserUnlocked();
}
+
+ private static void setShuttingDown(Context context, boolean value) {
+ PreferenceManager.getDefaultSharedPreferences(context)
+ .edit()
+ .putBoolean(IS_SHUTTING_DOWN, value)
+ .apply();
+ }
+
+ private static boolean isShuttingDown(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean(IS_SHUTTING_DOWN, false);
+ }
}
diff --git a/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java b/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java
index 4a9e43370..700e1cbca 100644
--- a/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java
+++ b/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java
@@ -15,9 +15,11 @@
*/
package com.android.voicemail.impl;
+import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.NonNull;
@@ -30,6 +32,7 @@ import android.telephony.VisualVoicemailSmsFilterSettings;
import android.text.TextUtils;
import android.util.ArraySet;
import com.android.dialer.common.Assert;
+import com.android.voicemail.impl.configui.ConfigOverrideFragment;
import com.android.voicemail.impl.protocol.VisualVoicemailProtocol;
import com.android.voicemail.impl.protocol.VisualVoicemailProtocolFactory;
import com.android.voicemail.impl.sms.StatusMessage;
@@ -48,27 +51,28 @@ import java.util.Set;
*
* <p>The current hidden configs are: {@link #getSslPort()} {@link #getDisabledCapabilities()}
*/
+@TargetApi(VERSION_CODES.O)
public class OmtpVvmCarrierConfigHelper {
private static final String TAG = "OmtpVvmCarrierCfgHlpr";
- static final String KEY_VVM_TYPE_STRING = CarrierConfigManager.KEY_VVM_TYPE_STRING;
- static final String KEY_VVM_DESTINATION_NUMBER_STRING =
+ public static final String KEY_VVM_TYPE_STRING = CarrierConfigManager.KEY_VVM_TYPE_STRING;
+ public static final String KEY_VVM_DESTINATION_NUMBER_STRING =
CarrierConfigManager.KEY_VVM_DESTINATION_NUMBER_STRING;
- static final String KEY_VVM_PORT_NUMBER_INT = CarrierConfigManager.KEY_VVM_PORT_NUMBER_INT;
- static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING =
+ public static final String KEY_VVM_PORT_NUMBER_INT = CarrierConfigManager.KEY_VVM_PORT_NUMBER_INT;
+ public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING =
CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING;
- static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY =
+ public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY =
"carrier_vvm_package_name_string_array";
- static final String KEY_VVM_PREFETCH_BOOL = CarrierConfigManager.KEY_VVM_PREFETCH_BOOL;
- static final String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL =
+ public static final String KEY_VVM_PREFETCH_BOOL = CarrierConfigManager.KEY_VVM_PREFETCH_BOOL;
+ public static final String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL =
CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL;
/** @see #getSslPort() */
- static final String KEY_VVM_SSL_PORT_NUMBER_INT = "vvm_ssl_port_number_int";
+ public static final String KEY_VVM_SSL_PORT_NUMBER_INT = "vvm_ssl_port_number_int";
/** @see #isLegacyModeEnabled() */
- static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL = "vvm_legacy_mode_enabled_bool";
+ public static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL = "vvm_legacy_mode_enabled_bool";
/**
* Ban a capability reported by the server from being used. The array of string should be a subset
@@ -76,10 +80,10 @@ public class OmtpVvmCarrierConfigHelper {
*
* @see #getDisabledCapabilities()
*/
- static final String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY =
+ public static final String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY =
"vvm_disabled_capabilities_string_array";
- static final String KEY_VVM_CLIENT_PREFIX_STRING = "vvm_client_prefix_string";
+ public static final String KEY_VVM_CLIENT_PREFIX_STRING = "vvm_client_prefix_string";
private final Context mContext;
private final PersistableBundle mCarrierConfig;
@@ -87,6 +91,8 @@ public class OmtpVvmCarrierConfigHelper {
private final VisualVoicemailProtocol mProtocol;
private final PersistableBundle mTelephonyConfig;
+ @Nullable private final PersistableBundle mOverrideConfig;
+
private PhoneAccountHandle mPhoneAccountHandle;
public OmtpVvmCarrierConfigHelper(Context context, @Nullable PhoneAccountHandle handle) {
@@ -100,6 +106,7 @@ public class OmtpVvmCarrierConfigHelper {
VvmLog.e(TAG, "PhoneAccountHandle is invalid");
mCarrierConfig = null;
mTelephonyConfig = null;
+ mOverrideConfig = null;
mVvmType = null;
mProtocol = null;
return;
@@ -111,6 +118,13 @@ public class OmtpVvmCarrierConfigHelper {
mVvmType = getVvmType();
mProtocol = VisualVoicemailProtocolFactory.create(mContext.getResources(), mVvmType);
+
+ if (ConfigOverrideFragment.isOverridden(context)) {
+ mOverrideConfig = ConfigOverrideFragment.getConfig(context);
+ VvmLog.w(TAG, "Config override is activated: " + mOverrideConfig);
+ } else {
+ mOverrideConfig = null;
+ }
}
@VisibleForTesting
@@ -119,10 +133,23 @@ public class OmtpVvmCarrierConfigHelper {
mContext = context;
mCarrierConfig = carrierConfig;
mTelephonyConfig = telephonyConfig;
+ mOverrideConfig = null;
mVvmType = getVvmType();
mProtocol = VisualVoicemailProtocolFactory.create(mContext.getResources(), mVvmType);
}
+ public PersistableBundle getConfig() {
+ PersistableBundle result = new PersistableBundle();
+ if (mTelephonyConfig != null) {
+ result.putAll(mTelephonyConfig);
+ }
+ if (mCarrierConfig != null) {
+ result.putAll(mCarrierConfig);
+ }
+
+ return result;
+ }
+
public Context getContext() {
return mContext;
}
@@ -426,6 +453,13 @@ public class OmtpVvmCarrierConfigHelper {
@Nullable
private Object getValue(String key, Object defaultValue) {
Object result;
+ if (mOverrideConfig != null) {
+ result = mOverrideConfig.get(key);
+ if (result != null) {
+ return result;
+ }
+ }
+
if (mCarrierConfig != null) {
result = mCarrierConfig.get(key);
if (result != null) {
diff --git a/java/com/android/voicemail/impl/PackageReplacedReceiver.java b/java/com/android/voicemail/impl/PackageReplacedReceiver.java
new file mode 100644
index 000000000..6a7ca4a7b
--- /dev/null
+++ b/java/com/android/voicemail/impl/PackageReplacedReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.voicemail.impl;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import com.android.voicemail.VoicemailComponent;
+
+/** Receives MY_PACKAGE_REPLACED to trigger VVM activation. */
+public class PackageReplacedReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ VvmLog.i("PackageReplacedReceiver.onReceive", "package replaced, starting activation");
+
+ if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
+ VvmLog.e("PackageReplacedReceiver.onReceive", "module disabled");
+ return;
+ }
+
+ for (PhoneAccountHandle phoneAccountHandle :
+ context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()) {
+ ActivationTask.start(context, phoneAccountHandle, null);
+ }
+ }
+}
diff --git a/java/com/android/voicemail/impl/SubscriptionInfoHelper.java b/java/com/android/voicemail/impl/SubscriptionInfoHelper.java
deleted file mode 100644
index d8a8423eb..000000000
--- a/java/com/android/voicemail/impl/SubscriptionInfoHelper.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Copyright (C) 2014 The Android Open Source Project
- *
- * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * <p>http://www.apache.org/licenses/LICENSE-2.0
- *
- * <p>Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.voicemail.impl;
-
-import android.app.ActionBar;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.text.TextUtils;
-
-/**
- * Helper for manipulating intents or components with subscription-related information.
- *
- * <p>In settings, subscription ids and labels are passed along to indicate that settings are being
- * changed for particular subscriptions. This helper provides functions for helping extract this
- * info and perform common operations using this info.
- */
-public class SubscriptionInfoHelper {
- public static final int NO_SUB_ID = -1;
-
- // Extra on intent containing the id of a subscription.
- public static final String SUB_ID_EXTRA =
- "com.android.voicemailomtp.settings.SubscriptionInfoHelper.SubscriptionId";
- // Extra on intent containing the label of a subscription.
- private static final String SUB_LABEL_EXTRA =
- "com.android.voicemailomtp.settings.SubscriptionInfoHelper.SubscriptionLabel";
-
- private static Context mContext;
-
- private static int mSubId = NO_SUB_ID;
- private static String mSubLabel;
-
- /** Instantiates the helper, by extracting the subscription id and label from the intent. */
- public SubscriptionInfoHelper(Context context, Intent intent) {
- mContext = context;
- mSubId = intent.getIntExtra(SUB_ID_EXTRA, NO_SUB_ID);
- mSubLabel = intent.getStringExtra(SUB_LABEL_EXTRA);
- }
-
- /**
- * Sets the action bar title to the string specified by the given resource id, formatting it with
- * the subscription label. This assumes the resource string is formattable with a string-type
- * specifier.
- *
- * <p>If the subscription label does not exists, leave the existing title.
- */
- public void setActionBarTitle(ActionBar actionBar, Resources res, int resId) {
- if (actionBar == null || TextUtils.isEmpty(mSubLabel)) {
- return;
- }
-
- String title = String.format(res.getString(resId), mSubLabel);
- actionBar.setTitle(title);
- }
-
- public int getSubId() {
- return mSubId;
- }
-}
diff --git a/java/com/android/voicemail/impl/TelephonyManagerStub.java b/java/com/android/voicemail/impl/TelephonyManagerStub.java
deleted file mode 100644
index 4762e9023..000000000
--- a/java/com/android/voicemail/impl/TelephonyManagerStub.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.voicemail.impl;
-
-import android.annotation.TargetApi;
-import android.os.Build.VERSION_CODES;
-
-/**
- * Temporary stub for public APIs that should be added into telephony manager.
- *
- * <p>TODO(b/32637799) remove this.
- */
-@TargetApi(VERSION_CODES.O)
-public class TelephonyManagerStub {
-
- public static void showVoicemailNotification(int voicemailCount) {}
-
- /**
- * Dismisses the message waiting (voicemail) indicator.
- *
- * @param subId the subscription id we should dismiss the notification for.
- */
- public static void clearMwiIndicator(int subId) {}
-
- public static void setShouldCheckVisualVoicemailConfigurationForMwi(int subId, boolean enabled) {}
-}
diff --git a/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java b/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java
index b4def2fc3..046113c26 100644
--- a/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java
+++ b/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java
@@ -21,7 +21,7 @@ import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.ArrayMap;
-import com.android.dialer.common.ConfigProviderBindings;
+import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.voicemail.impl.utils.XmlUtils;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/java/com/android/voicemail/impl/VoicemailBootReceiver.java b/java/com/android/voicemail/impl/VoicemailBootReceiver.java
deleted file mode 100644
index 0a3e61a01..000000000
--- a/java/com/android/voicemail/impl/VoicemailBootReceiver.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * <p>http://www.apache.org/licenses/LICENSE-2.0
- *
- * <p>Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.voicemail.impl;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import com.android.voicemail.VoicemailComponent;
-
-/** Receives {@link Intent#ACTION_BOOT_COMPLETED} for the voicemail module. */
-public class VoicemailBootReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
- return;
- }
- StatusCheckJobService.schedule(context);
- }
-}
diff --git a/java/com/android/voicemail/impl/VoicemailClientImpl.java b/java/com/android/voicemail/impl/VoicemailClientImpl.java
index 83c0523bf..9bb14f2dc 100644
--- a/java/com/android/voicemail/impl/VoicemailClientImpl.java
+++ b/java/com/android/voicemail/impl/VoicemailClientImpl.java
@@ -17,21 +17,26 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION_CODES;
+import android.os.PersistableBundle;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.os.BuildCompat;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
import com.android.dialer.common.Assert;
-import com.android.dialer.common.ConfigProviderBindings;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.voicemail.VisualVoicemailTypeExtensions;
import com.android.voicemail.VoicemailClient;
+import com.android.voicemail.impl.configui.VoicemailSecretCodeActivity;
import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
import com.android.voicemail.impl.settings.VoicemailChangePinActivity;
import com.android.voicemail.impl.settings.VoicemailSettingsFragment;
import com.android.voicemail.impl.sync.VvmAccountManager;
+import com.android.voicemail.impl.transcribe.TranscriptionBackfillService;
import java.util.List;
import javax.inject.Inject;
@@ -126,6 +131,31 @@ public class VoicemailClientImpl implements VoicemailClient {
return VvmAccountManager.isAccountActivated(context, phoneAccountHandle);
}
+ @Override
+ public void showConfigUi(@NonNull Context context) {
+ Intent intent = new Intent(context, VoicemailSecretCodeActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+
+ @Override
+ public PersistableBundle getConfig(Context context, PhoneAccountHandle phoneAccountHandle) {
+ return new OmtpVvmCarrierConfigHelper(context, phoneAccountHandle).getConfig();
+ }
+
+ @Override
+ @MainThread
+ public void onBoot(@NonNull Context context) {
+ OmtpService.onBoot(context);
+ StatusCheckJobService.schedule(context);
+ }
+
+ @Override
+ @MainThread
+ public void onShutdown(@NonNull Context context) {
+ OmtpService.onShutdown(context);
+ }
+
@TargetApi(VERSION_CODES.O)
@Override
public void appendOmtpVoicemailSelectionClause(
@@ -201,4 +231,10 @@ public class VoicemailClientImpl implements VoicemailClient {
where.append(")");
}
}
+
+ @Override
+ public void onTosAccepted(Context context) {
+ LogUtil.i("VoicemailClientImpl.onTosAccepted", "try backfilling voicemail transcriptions");
+ TranscriptionBackfillService.scheduleTask(context);
+ }
}
diff --git a/java/com/android/voicemail/impl/VoicemailClientReceiver.java b/java/com/android/voicemail/impl/VoicemailClientReceiver.java
index 49a55a41b..688636e6c 100644
--- a/java/com/android/voicemail/impl/VoicemailClientReceiver.java
+++ b/java/com/android/voicemail/impl/VoicemailClientReceiver.java
@@ -23,6 +23,7 @@ import android.telecom.PhoneAccountHandle;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.voicemail.VoicemailClient;
+import com.android.voicemail.VoicemailComponent;
import com.android.voicemail.impl.sync.UploadTask;
import com.android.voicemail.impl.sync.VvmAccountManager;
@@ -31,6 +32,11 @@ public class VoicemailClientReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
+ if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
+ LogUtil.i(
+ "VoicemailClientReceiver.onReceive", "module disabled, ignoring " + intent.getAction());
+ return;
+ }
switch (intent.getAction()) {
case VoicemailClient.ACTION_UPLOAD:
doUpload(context);
diff --git a/java/com/android/voicemail/impl/VoicemailModule.java b/java/com/android/voicemail/impl/VoicemailModule.java
index 5a4e739f5..e689e47d2 100644
--- a/java/com/android/voicemail/impl/VoicemailModule.java
+++ b/java/com/android/voicemail/impl/VoicemailModule.java
@@ -18,6 +18,7 @@ package com.android.voicemail.impl;
import android.content.Context;
import android.support.v4.os.BuildCompat;
+import com.android.dialer.inject.ApplicationContext;
import com.android.voicemail.VoicemailClient;
import com.android.voicemail.VoicemailPermissionHelper;
import com.android.voicemail.stub.StubVoicemailClient;
@@ -31,7 +32,7 @@ public final class VoicemailModule {
@Provides
@Singleton
- static VoicemailClient provideVoicemailClient(Context context) {
+ static VoicemailClient provideVoicemailClient(@ApplicationContext Context context) {
if (!BuildCompat.isAtLeastO()) {
VvmLog.i("VoicemailModule.provideVoicemailClient", "SDK below O");
return new StubVoicemailClient();
diff --git a/java/com/android/voicemail/impl/VoicemailStatus.java b/java/com/android/voicemail/impl/VoicemailStatus.java
index ec1ab4e70..5553cf5e0 100644
--- a/java/com/android/voicemail/impl/VoicemailStatus.java
+++ b/java/com/android/voicemail/impl/VoicemailStatus.java
@@ -24,6 +24,7 @@ import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccountHandle;
+import com.android.dialer.strictmode.DialerStrictMode;
public class VoicemailStatus {
@@ -99,7 +100,7 @@ public class VoicemailStatus {
ContentResolver contentResolver = mContext.getContentResolver();
Uri statusUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
try {
- contentResolver.insert(statusUri, mValues);
+ DialerStrictMode.bypass(() -> contentResolver.insert(statusUri, mValues));
} catch (IllegalArgumentException iae) {
VvmLog.e(TAG, "apply :: failed to insert content resolver ", iae);
mValues.clear();
diff --git a/java/com/android/voicemail/impl/VoicemailTranscriptionServiceGrpc.java b/java/com/android/voicemail/impl/VoicemailTranscriptionServiceGrpc.java
new file mode 100644
index 000000000..8fcbf3b97
--- /dev/null
+++ b/java/com/android/voicemail/impl/VoicemailTranscriptionServiceGrpc.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.google.internal.communications.voicemailtranscription.v1;
+
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+
+/**
+ * <pre>
+ * RPC service for transcribing voicemails.
+ * </pre>
+ */
+@javax.annotation.Generated(
+ value = "by gRPC proto compiler (version 1.0.3)",
+ comments = "Source: voicemail_transcription.proto")
+public class VoicemailTranscriptionServiceGrpc {
+
+ private VoicemailTranscriptionServiceGrpc() {}
+
+ public static final String SERVICE_NAME = "google.internal.communications.voicemailtranscription.v1.VoicemailTranscriptionService";
+
+ // Static method descriptors that strictly reflect the proto.
+ @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+ public static final io.grpc.MethodDescriptor<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest,
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse> METHOD_TRANSCRIBE_VOICEMAIL =
+ io.grpc.MethodDescriptor.create(
+ io.grpc.MethodDescriptor.MethodType.UNARY,
+ generateFullMethodName(
+ "google.internal.communications.voicemailtranscription.v1.VoicemailTranscriptionService", "TranscribeVoicemail"),
+ io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest.getDefaultInstance()),
+ io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse.getDefaultInstance()));
+ @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+ public static final io.grpc.MethodDescriptor<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest,
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse> METHOD_TRANSCRIBE_VOICEMAIL_ASYNC =
+ io.grpc.MethodDescriptor.create(
+ io.grpc.MethodDescriptor.MethodType.UNARY,
+ generateFullMethodName(
+ "google.internal.communications.voicemailtranscription.v1.VoicemailTranscriptionService", "TranscribeVoicemailAsync"),
+ io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest.getDefaultInstance()),
+ io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse.getDefaultInstance()));
+ @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+ public static final io.grpc.MethodDescriptor<com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest,
+ com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse> METHOD_GET_TRANSCRIPT =
+ io.grpc.MethodDescriptor.create(
+ io.grpc.MethodDescriptor.MethodType.UNARY,
+ generateFullMethodName(
+ "google.internal.communications.voicemailtranscription.v1.VoicemailTranscriptionService", "GetTranscript"),
+ io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest.getDefaultInstance()),
+ io.grpc.protobuf.lite.ProtoLiteUtils.marshaller(com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse.getDefaultInstance()));
+
+ /**
+ * Creates a new async stub that supports all call types for the service
+ */
+ public static VoicemailTranscriptionServiceStub newStub(io.grpc.Channel channel) {
+ return new VoicemailTranscriptionServiceStub(channel);
+ }
+
+ /**
+ * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+ */
+ public static VoicemailTranscriptionServiceBlockingStub newBlockingStub(
+ io.grpc.Channel channel) {
+ return new VoicemailTranscriptionServiceBlockingStub(channel);
+ }
+
+ /**
+ * Creates a new ListenableFuture-style stub that supports unary and streaming output calls on the service
+ */
+ public static VoicemailTranscriptionServiceFutureStub newFutureStub(
+ io.grpc.Channel channel) {
+ return new VoicemailTranscriptionServiceFutureStub(channel);
+ }
+
+ /**
+ * <pre>
+ * RPC service for transcribing voicemails.
+ * </pre>
+ */
+ public static abstract class VoicemailTranscriptionServiceImplBase implements io.grpc.BindableService {
+
+ /**
+ * <pre>
+ * Returns a transcript of the given voicemail.
+ * </pre>
+ */
+ public void transcribeVoicemail(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest request,
+ io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_TRANSCRIBE_VOICEMAIL, responseObserver);
+ }
+
+ /**
+ * <pre>
+ * Schedules a transcription of the given voicemail. The transcript can be
+ * retrieved using the returned ID.
+ * </pre>
+ */
+ public void transcribeVoicemailAsync(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest request,
+ io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_TRANSCRIBE_VOICEMAIL_ASYNC, responseObserver);
+ }
+
+ /**
+ * <pre>
+ * Returns the transcript corresponding to the given ID, which was returned
+ * by TranscribeVoicemailAsync.
+ * </pre>
+ */
+ public void getTranscript(com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest request,
+ io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_GET_TRANSCRIPT, responseObserver);
+ }
+
+ @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
+ return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+ .addMethod(
+ METHOD_TRANSCRIBE_VOICEMAIL,
+ asyncUnaryCall(
+ new MethodHandlers<
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest,
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse>(
+ this, METHODID_TRANSCRIBE_VOICEMAIL)))
+ .addMethod(
+ METHOD_TRANSCRIBE_VOICEMAIL_ASYNC,
+ asyncUnaryCall(
+ new MethodHandlers<
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest,
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse>(
+ this, METHODID_TRANSCRIBE_VOICEMAIL_ASYNC)))
+ .addMethod(
+ METHOD_GET_TRANSCRIPT,
+ asyncUnaryCall(
+ new MethodHandlers<
+ com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest,
+ com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse>(
+ this, METHODID_GET_TRANSCRIPT)))
+ .build();
+ }
+ }
+
+ /**
+ * <pre>
+ * RPC service for transcribing voicemails.
+ * </pre>
+ */
+ public static final class VoicemailTranscriptionServiceStub extends io.grpc.stub.AbstractStub<VoicemailTranscriptionServiceStub> {
+ private VoicemailTranscriptionServiceStub(io.grpc.Channel channel) {
+ super(channel);
+ }
+
+ private VoicemailTranscriptionServiceStub(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ super(channel, callOptions);
+ }
+
+ @java.lang.Override
+ protected VoicemailTranscriptionServiceStub build(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ return new VoicemailTranscriptionServiceStub(channel, callOptions);
+ }
+
+ /**
+ * <pre>
+ * Returns a transcript of the given voicemail.
+ * </pre>
+ */
+ public void transcribeVoicemail(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest request,
+ io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse> responseObserver) {
+ asyncUnaryCall(
+ getChannel().newCall(METHOD_TRANSCRIBE_VOICEMAIL, getCallOptions()), request, responseObserver);
+ }
+
+ /**
+ * <pre>
+ * Schedules a transcription of the given voicemail. The transcript can be
+ * retrieved using the returned ID.
+ * </pre>
+ */
+ public void transcribeVoicemailAsync(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest request,
+ io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse> responseObserver) {
+ asyncUnaryCall(
+ getChannel().newCall(METHOD_TRANSCRIBE_VOICEMAIL_ASYNC, getCallOptions()), request, responseObserver);
+ }
+
+ /**
+ * <pre>
+ * Returns the transcript corresponding to the given ID, which was returned
+ * by TranscribeVoicemailAsync.
+ * </pre>
+ */
+ public void getTranscript(com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest request,
+ io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse> responseObserver) {
+ asyncUnaryCall(
+ getChannel().newCall(METHOD_GET_TRANSCRIPT, getCallOptions()), request, responseObserver);
+ }
+ }
+
+ /**
+ * <pre>
+ * RPC service for transcribing voicemails.
+ * </pre>
+ */
+ public static final class VoicemailTranscriptionServiceBlockingStub extends io.grpc.stub.AbstractStub<VoicemailTranscriptionServiceBlockingStub> {
+ private VoicemailTranscriptionServiceBlockingStub(io.grpc.Channel channel) {
+ super(channel);
+ }
+
+ private VoicemailTranscriptionServiceBlockingStub(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ super(channel, callOptions);
+ }
+
+ @java.lang.Override
+ protected VoicemailTranscriptionServiceBlockingStub build(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ return new VoicemailTranscriptionServiceBlockingStub(channel, callOptions);
+ }
+
+ /**
+ * <pre>
+ * Returns a transcript of the given voicemail.
+ * </pre>
+ */
+ public com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse transcribeVoicemail(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest request) {
+ return blockingUnaryCall(
+ getChannel(), METHOD_TRANSCRIBE_VOICEMAIL, getCallOptions(), request);
+ }
+
+ /**
+ * <pre>
+ * Schedules a transcription of the given voicemail. The transcript can be
+ * retrieved using the returned ID.
+ * </pre>
+ */
+ public com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse transcribeVoicemailAsync(com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest request) {
+ return blockingUnaryCall(
+ getChannel(), METHOD_TRANSCRIBE_VOICEMAIL_ASYNC, getCallOptions(), request);
+ }
+
+ /**
+ * <pre>
+ * Returns the transcript corresponding to the given ID, which was returned
+ * by TranscribeVoicemailAsync.
+ * </pre>
+ */
+ public com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse getTranscript(com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest request) {
+ return blockingUnaryCall(
+ getChannel(), METHOD_GET_TRANSCRIPT, getCallOptions(), request);
+ }
+ }
+
+ /**
+ * <pre>
+ * RPC service for transcribing voicemails.
+ * </pre>
+ */
+ public static final class VoicemailTranscriptionServiceFutureStub extends io.grpc.stub.AbstractStub<VoicemailTranscriptionServiceFutureStub> {
+ private VoicemailTranscriptionServiceFutureStub(io.grpc.Channel channel) {
+ super(channel);
+ }
+
+ private VoicemailTranscriptionServiceFutureStub(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ super(channel, callOptions);
+ }
+
+ @java.lang.Override
+ protected VoicemailTranscriptionServiceFutureStub build(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ return new VoicemailTranscriptionServiceFutureStub(channel, callOptions);
+ }
+
+ /**
+ * <pre>
+ * Returns a transcript of the given voicemail.
+ * </pre>
+ */
+ public com.google.common.util.concurrent.ListenableFuture<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse> transcribeVoicemail(
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest request) {
+ return futureUnaryCall(
+ getChannel().newCall(METHOD_TRANSCRIBE_VOICEMAIL, getCallOptions()), request);
+ }
+
+ /**
+ * <pre>
+ * Schedules a transcription of the given voicemail. The transcript can be
+ * retrieved using the returned ID.
+ * </pre>
+ */
+ public com.google.common.util.concurrent.ListenableFuture<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse> transcribeVoicemailAsync(
+ com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest request) {
+ return futureUnaryCall(
+ getChannel().newCall(METHOD_TRANSCRIBE_VOICEMAIL_ASYNC, getCallOptions()), request);
+ }
+
+ /**
+ * <pre>
+ * Returns the transcript corresponding to the given ID, which was returned
+ * by TranscribeVoicemailAsync.
+ * </pre>
+ */
+ public com.google.common.util.concurrent.ListenableFuture<com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse> getTranscript(
+ com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest request) {
+ return futureUnaryCall(
+ getChannel().newCall(METHOD_GET_TRANSCRIPT, getCallOptions()), request);
+ }
+ }
+
+ private static final int METHODID_TRANSCRIBE_VOICEMAIL = 0;
+ private static final int METHODID_TRANSCRIBE_VOICEMAIL_ASYNC = 1;
+ private static final int METHODID_GET_TRANSCRIPT = 2;
+
+ private static class MethodHandlers<Req, Resp> implements
+ io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+ io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+ io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+ io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+ private final VoicemailTranscriptionServiceImplBase serviceImpl;
+ private final int methodId;
+
+ public MethodHandlers(VoicemailTranscriptionServiceImplBase serviceImpl, int methodId) {
+ this.serviceImpl = serviceImpl;
+ this.methodId = methodId;
+ }
+
+ @java.lang.Override
+ @java.lang.SuppressWarnings("unchecked")
+ public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+ switch (methodId) {
+ case METHODID_TRANSCRIBE_VOICEMAIL:
+ serviceImpl.transcribeVoicemail((com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest) request,
+ (io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse>) responseObserver);
+ break;
+ case METHODID_TRANSCRIBE_VOICEMAIL_ASYNC:
+ serviceImpl.transcribeVoicemailAsync((com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest) request,
+ (io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse>) responseObserver);
+ break;
+ case METHODID_GET_TRANSCRIPT:
+ serviceImpl.getTranscript((com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest) request,
+ (io.grpc.stub.StreamObserver<com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse>) responseObserver);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @java.lang.Override
+ @java.lang.SuppressWarnings("unchecked")
+ public io.grpc.stub.StreamObserver<Req> invoke(
+ io.grpc.stub.StreamObserver<Resp> responseObserver) {
+ switch (methodId) {
+ default:
+ throw new AssertionError();
+ }
+ }
+ }
+
+ public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+ return new io.grpc.ServiceDescriptor(SERVICE_NAME,
+ METHOD_TRANSCRIBE_VOICEMAIL,
+ METHOD_TRANSCRIBE_VOICEMAIL_ASYNC,
+ METHOD_GET_TRANSCRIPT);
+ }
+
+}
diff --git a/java/com/android/voicemail/impl/VvmPackageInstallReceiver.java b/java/com/android/voicemail/impl/VvmPackageInstallReceiver.java
deleted file mode 100644
index 1e2de6070..000000000
--- a/java/com/android/voicemail/impl/VvmPackageInstallReceiver.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.voicemail.impl;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import com.android.voicemail.VoicemailComponent;
-import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
-
-/**
- * When a new package is installed, check if it matches any of the vvm carrier apps of the currently
- * enabled dialer VVM sources. The dialer VVM client will be disabled upon carrier VVM app
- * installation, unless it was explicitly enabled by the user.
- */
-public class VvmPackageInstallReceiver extends BroadcastReceiver {
-
- private static final String TAG = "VvmPkgInstallReceiver";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
- return;
- }
-
- if (intent.getData() == null) {
- return;
- }
-
- String packageName = intent.getData().getSchemeSpecificPart();
- if (packageName == null) {
- return;
- }
-
- // This get called every time an app is installed and will be noisy. Don't log until the app
- // is identified as a carrier VVM app.
- for (PhoneAccountHandle phoneAccount :
- context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()) {
- OmtpVvmCarrierConfigHelper carrierConfigHelper =
- new OmtpVvmCarrierConfigHelper(context, phoneAccount);
- if (!carrierConfigHelper.isValid()) {
- continue;
- }
- if (carrierConfigHelper.getCarrierVvmPackageNames() == null) {
- continue;
- }
- if (!carrierConfigHelper.getCarrierVvmPackageNames().contains(packageName)) {
- continue;
- }
-
- VvmLog.i(TAG, "Carrier app installed");
- if (VisualVoicemailSettingsUtil.isEnabledUserSet(context, phoneAccount)) {
- // Skip the check if this voicemail source's setting is overridden by the user.
- VvmLog.i(TAG, "VVM enabled by user, not disabling");
- continue;
- }
-
- // Force deactivate the client. The user can re-enable it in the settings.
- // There is no need to update the settings for deactivation. At this point, if the
- // default value is used it should be false because a carrier package is present.
- VvmLog.i(TAG, "Carrier VVM package installed, disabling system VVM client");
- VisualVoicemailSettingsUtil.setEnabled(context, phoneAccount, false);
- }
- }
-}
diff --git a/java/com/android/voicemail/impl/VvmPhoneStateListener.java b/java/com/android/voicemail/impl/VvmPhoneStateListener.java
index 48b72042c..00c1358ab 100644
--- a/java/com/android/voicemail/impl/VvmPhoneStateListener.java
+++ b/java/com/android/voicemail/impl/VvmPhoneStateListener.java
@@ -19,7 +19,6 @@ import android.content.Context;
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
-import com.android.voicemail.impl.sync.OmtpVvmSyncService;
import com.android.voicemail.impl.sync.SyncTask;
import com.android.voicemail.impl.sync.VoicemailStatusQueryHelper;
import com.android.voicemail.impl.sync.VvmAccountManager;
@@ -37,7 +36,7 @@ public class VvmPhoneStateListener extends PhoneStateListener {
private int mPreviousState = -1;
public VvmPhoneStateListener(Context context, PhoneAccountHandle accountHandle) {
- // TODO: b/32637799 too much trouble to call super constructor through reflection,
+ // TODO(twyen): b/32637799 too much trouble to call super constructor through reflection,
// just use non-phoneAccountHandle version for now.
super();
mContext = context;
@@ -82,7 +81,7 @@ public class VvmPhoneStateListener extends PhoneStateListener {
VvmLog.v(TAG, "Signal returned: requesting resync for " + mPhoneAccount);
// If the source is already registered, run a full sync in case something was missed
// while signal was down.
- SyncTask.start(mContext, mPhoneAccount, OmtpVvmSyncService.SYNC_FULL_SYNC);
+ SyncTask.start(mContext, mPhoneAccount);
} else {
VvmLog.v(TAG, "Signal returned: reattempting activation for " + mPhoneAccount);
// Otherwise initiate an activation because this means that an OMTP source was
diff --git a/java/com/android/voicemail/impl/configui/AndroidManifest.xml b/java/com/android/voicemail/impl/configui/AndroidManifest.xml
new file mode 100644
index 000000000..95796f978
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.voicemail.impl.configui">
+
+ <application>
+ <activity android:name="com.android.voicemail.impl.configui.VoicemailSecretCodeActivity"
+ android:exported="false">
+ </activity>
+ </application>
+</manifest>
diff --git a/java/com/android/voicemail/impl/configui/ConfigOverrideFragment.java b/java/com/android/voicemail/impl/configui/ConfigOverrideFragment.java
new file mode 100644
index 000000000..1624ce579
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/ConfigOverrideFragment.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.voicemail.impl.configui;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.strictmode.DialerStrictMode;
+import com.android.voicemail.VoicemailComponent;
+
+/**
+ * Fragment to edit the override values for the {@link import
+ * com.android.voicemail.impl.OmtpVvmCarrierConfigHelper}
+ */
+public class ConfigOverrideFragment extends PreferenceFragment
+ implements OnPreferenceChangeListener {
+
+ /**
+ * Any preference with key that starts with this prefix will be written to the dialer carrier
+ * config.
+ */
+ @VisibleForTesting static final String CONFIG_OVERRIDE_KEY_PREFIX = "vvm_config_override_key_";
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ PreferenceManager.setDefaultValues(getActivity(), R.xml.vvm_config_override, false);
+ addPreferencesFromResource(R.xml.vvm_config_override);
+
+ // add listener so the value of a EditTextPreference will be updated to the summary.
+ for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
+ Preference preference = getPreferenceScreen().getPreference(i);
+ preference.setOnPreferenceChangeListener(this);
+ updatePreference(preference);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ Assert.isMainThread();
+ ThreadUtil.postOnUiThread(() -> updatePreference(preference));
+ return true;
+ }
+
+ private void updatePreference(Preference preference) {
+ if (preference instanceof EditTextPreference) {
+ EditTextPreference editTextPreference = (EditTextPreference) preference;
+ editTextPreference.setSummary(editTextPreference.getText());
+ }
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ if (TextUtils.equals(
+ preference.getKey(), getString(R.string.vvm_config_override_load_current_key))) {
+ loadCurrentConfig();
+ }
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+
+ /**
+ * Loads the config for the currently carrier into the override values, from the dialer or the
+ * carrier config app. This is a "reset" button to load the defaults.
+ */
+ private void loadCurrentConfig() {
+ Context context = getActivity();
+ PhoneAccountHandle phoneAccountHandle =
+ context
+ .getSystemService(TelecomManager.class)
+ .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_VOICEMAIL);
+
+ PersistableBundle config =
+ VoicemailComponent.get(context).getVoicemailClient().getConfig(context, phoneAccountHandle);
+
+ for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
+ Preference preference = getPreferenceScreen().getPreference(i);
+ String key = preference.getKey();
+ if (!key.startsWith(CONFIG_OVERRIDE_KEY_PREFIX)) {
+ continue;
+ }
+
+ String configKey = key.substring(CONFIG_OVERRIDE_KEY_PREFIX.length());
+
+ if (configKey.endsWith("bool")) {
+ ((SwitchPreference) preference).setChecked(config.getBoolean(configKey));
+ } else if (configKey.endsWith("int")) {
+ ((EditTextPreference) preference).setText(String.valueOf(config.getInt(configKey)));
+ } else if (configKey.endsWith("string")) {
+ ((EditTextPreference) preference).setText(config.getString(configKey));
+ } else if (configKey.endsWith("string_array")) {
+ ((EditTextPreference) preference).setText(toCsv(config.getStringArray(configKey)));
+ } else {
+ throw Assert.createAssertionFailException("unknown type for key " + configKey);
+ }
+ updatePreference(preference);
+ }
+ }
+
+ public static boolean isOverridden(Context context) {
+ return DialerStrictMode.bypass(
+ () ->
+ PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean(context.getString(R.string.vvm_config_override_enabled_key), false));
+ }
+
+ public static PersistableBundle getConfig(Context context) {
+ Assert.checkState(isOverridden(context));
+ PersistableBundle result = new PersistableBundle();
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+ for (String key : preferences.getAll().keySet()) {
+ if (!key.startsWith(CONFIG_OVERRIDE_KEY_PREFIX)) {
+ continue;
+ }
+ String configKey = key.substring(CONFIG_OVERRIDE_KEY_PREFIX.length());
+ if (configKey.endsWith("bool")) {
+ result.putBoolean(configKey, preferences.getBoolean(key, false));
+ } else if (configKey.endsWith("int")) {
+ result.putInt(configKey, Integer.valueOf(preferences.getString(key, null)));
+ } else if (configKey.endsWith("string")) {
+ result.putString(configKey, preferences.getString(key, null));
+ } else if (configKey.endsWith("string_array")) {
+ result.putStringArray(configKey, fromCsv(preferences.getString(key, null)));
+ } else {
+ throw Assert.createAssertionFailException("unknown type for key " + configKey);
+ }
+ }
+ return result;
+ }
+
+ private static String toCsv(String[] array) {
+ if (array == null) {
+ return "";
+ }
+ StringBuilder result = new StringBuilder();
+ for (String element : array) {
+ if (result.length() != 0) {
+ result.append(",");
+ }
+ result.append(element);
+ }
+ return result.toString();
+ };
+
+ private static String[] fromCsv(String csv) {
+ return csv.split(",");
+ }
+}
diff --git a/java/com/android/voicemail/impl/configui/VoicemailSecretCodeActivity.java b/java/com/android/voicemail/impl/configui/VoicemailSecretCodeActivity.java
new file mode 100644
index 000000000..beeb9564d
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/VoicemailSecretCodeActivity.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.voicemail.impl.configui;
+
+import android.content.Intent;
+import android.preference.PreferenceActivity;
+import android.provider.VoicemailContract;
+import java.util.List;
+
+/** Activity launched by simulator->voicemail, provides debug features. */
+@SuppressWarnings("FragmentInjection") // not exported
+public class VoicemailSecretCodeActivity extends PreferenceActivity {
+
+ private Header syncHeader;
+
+ @Override
+ public void onBuildHeaders(List<Header> target) {
+ super.onBuildHeaders(target);
+ syncHeader = new Header();
+ syncHeader.title = "Sync";
+ target.add(syncHeader);
+
+ Header configOverride = new Header();
+ configOverride.fragment = ConfigOverrideFragment.class.getName();
+ configOverride.title = "VVM config override";
+ target.add(configOverride);
+ }
+
+ @Override
+ public void onHeaderClick(Header header, int position) {
+ if (header == syncHeader) {
+ Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL);
+ intent.setPackage(getPackageName());
+ sendBroadcast(intent);
+ return;
+ }
+ super.onHeaderClick(header, position);
+ }
+
+ @Override
+ protected boolean isValidFragment(String fragmentName) {
+ return true;
+ }
+}
diff --git a/java/com/android/voicemail/impl/configui/res/values-af/strings.xml b/java/com/android/voicemail/impl/configui/res/values-af/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-af/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-am/strings.xml b/java/com/android/voicemail/impl/configui/res/values-am/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-am/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ar/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ar/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ar/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-az/strings.xml b/java/com/android/voicemail/impl/configui/res/values-az/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-az/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-b+sr+Latn/strings.xml b/java/com/android/voicemail/impl/configui/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-be/strings.xml b/java/com/android/voicemail/impl/configui/res/values-be/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-be/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-bg/strings.xml b/java/com/android/voicemail/impl/configui/res/values-bg/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-bg/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-bn/strings.xml b/java/com/android/voicemail/impl/configui/res/values-bn/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-bn/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-bs/strings.xml b/java/com/android/voicemail/impl/configui/res/values-bs/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-bs/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ca/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ca/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ca/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-cs/strings.xml b/java/com/android/voicemail/impl/configui/res/values-cs/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-cs/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-da/strings.xml b/java/com/android/voicemail/impl/configui/res/values-da/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-da/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-de/strings.xml b/java/com/android/voicemail/impl/configui/res/values-de/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-de/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-el/strings.xml b/java/com/android/voicemail/impl/configui/res/values-el/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-el/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-en-rAU/strings.xml b/java/com/android/voicemail/impl/configui/res/values-en-rAU/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-en-rAU/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-en-rGB/strings.xml b/java/com/android/voicemail/impl/configui/res/values-en-rGB/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-en-rGB/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-en-rIN/strings.xml b/java/com/android/voicemail/impl/configui/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-en-rIN/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-es-rUS/strings.xml b/java/com/android/voicemail/impl/configui/res/values-es-rUS/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-es-rUS/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-es/strings.xml b/java/com/android/voicemail/impl/configui/res/values-es/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-es/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-et/strings.xml b/java/com/android/voicemail/impl/configui/res/values-et/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-et/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-eu/strings.xml b/java/com/android/voicemail/impl/configui/res/values-eu/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-eu/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-fa/strings.xml b/java/com/android/voicemail/impl/configui/res/values-fa/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-fa/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-fi/strings.xml b/java/com/android/voicemail/impl/configui/res/values-fi/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-fi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-fr-rCA/strings.xml b/java/com/android/voicemail/impl/configui/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-fr-rCA/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-fr/strings.xml b/java/com/android/voicemail/impl/configui/res/values-fr/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-fr/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-gl/strings.xml b/java/com/android/voicemail/impl/configui/res/values-gl/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-gl/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-gu/strings.xml b/java/com/android/voicemail/impl/configui/res/values-gu/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-gu/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-hi/strings.xml b/java/com/android/voicemail/impl/configui/res/values-hi/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-hi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-hr/strings.xml b/java/com/android/voicemail/impl/configui/res/values-hr/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-hr/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-hu/strings.xml b/java/com/android/voicemail/impl/configui/res/values-hu/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-hu/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-hy/strings.xml b/java/com/android/voicemail/impl/configui/res/values-hy/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-hy/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-in/strings.xml b/java/com/android/voicemail/impl/configui/res/values-in/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-in/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-is/strings.xml b/java/com/android/voicemail/impl/configui/res/values-is/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-is/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-it/strings.xml b/java/com/android/voicemail/impl/configui/res/values-it/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-it/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-iw/strings.xml b/java/com/android/voicemail/impl/configui/res/values-iw/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-iw/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ja/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ja/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ja/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ka/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ka/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ka/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-kk/strings.xml b/java/com/android/voicemail/impl/configui/res/values-kk/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-kk/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-km/strings.xml b/java/com/android/voicemail/impl/configui/res/values-km/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-km/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-kn/strings.xml b/java/com/android/voicemail/impl/configui/res/values-kn/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-kn/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ko/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ko/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ko/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ky/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ky/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ky/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-lo/strings.xml b/java/com/android/voicemail/impl/configui/res/values-lo/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-lo/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-lt/strings.xml b/java/com/android/voicemail/impl/configui/res/values-lt/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-lt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-lv/strings.xml b/java/com/android/voicemail/impl/configui/res/values-lv/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-lv/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-mk/strings.xml b/java/com/android/voicemail/impl/configui/res/values-mk/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-mk/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ml/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ml/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ml/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-mn/strings.xml b/java/com/android/voicemail/impl/configui/res/values-mn/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-mn/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-mr/strings.xml b/java/com/android/voicemail/impl/configui/res/values-mr/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-mr/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ms/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ms/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ms/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-my/strings.xml b/java/com/android/voicemail/impl/configui/res/values-my/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-my/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-nb/strings.xml b/java/com/android/voicemail/impl/configui/res/values-nb/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-nb/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ne/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ne/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ne/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-nl/strings.xml b/java/com/android/voicemail/impl/configui/res/values-nl/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-nl/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-no/strings.xml b/java/com/android/voicemail/impl/configui/res/values-no/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-no/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-pa/strings.xml b/java/com/android/voicemail/impl/configui/res/values-pa/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-pa/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-pl/strings.xml b/java/com/android/voicemail/impl/configui/res/values-pl/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-pl/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-pt-rBR/strings.xml b/java/com/android/voicemail/impl/configui/res/values-pt-rBR/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-pt-rBR/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-pt-rPT/strings.xml b/java/com/android/voicemail/impl/configui/res/values-pt-rPT/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-pt-rPT/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-pt/strings.xml b/java/com/android/voicemail/impl/configui/res/values-pt/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ro/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ro/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ro/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ru/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ru/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ru/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-si/strings.xml b/java/com/android/voicemail/impl/configui/res/values-si/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-si/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-sk/strings.xml b/java/com/android/voicemail/impl/configui/res/values-sk/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-sk/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-sl/strings.xml b/java/com/android/voicemail/impl/configui/res/values-sl/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-sl/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-sq/strings.xml b/java/com/android/voicemail/impl/configui/res/values-sq/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-sq/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-sr/strings.xml b/java/com/android/voicemail/impl/configui/res/values-sr/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-sr/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-sv/strings.xml b/java/com/android/voicemail/impl/configui/res/values-sv/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-sv/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-sw/strings.xml b/java/com/android/voicemail/impl/configui/res/values-sw/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-sw/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ta/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ta/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ta/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-te/strings.xml b/java/com/android/voicemail/impl/configui/res/values-te/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-te/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-th/strings.xml b/java/com/android/voicemail/impl/configui/res/values-th/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-th/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-tl/strings.xml b/java/com/android/voicemail/impl/configui/res/values-tl/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-tl/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-tr/strings.xml b/java/com/android/voicemail/impl/configui/res/values-tr/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-tr/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-uk/strings.xml b/java/com/android/voicemail/impl/configui/res/values-uk/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-uk/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-ur/strings.xml b/java/com/android/voicemail/impl/configui/res/values-ur/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-ur/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-uz/strings.xml b/java/com/android/voicemail/impl/configui/res/values-uz/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-uz/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-vi/strings.xml b/java/com/android/voicemail/impl/configui/res/values-vi/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-vi/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-zh-rCN/strings.xml b/java/com/android/voicemail/impl/configui/res/values-zh-rCN/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-zh-rCN/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-zh-rHK/strings.xml b/java/com/android/voicemail/impl/configui/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-zh-rHK/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-zh-rTW/strings.xml b/java/com/android/voicemail/impl/configui/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-zh-rTW/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values-zu/strings.xml b/java/com/android/voicemail/impl/configui/res/values-zu/strings.xml
new file mode 100644
index 000000000..826efd3cd
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values-zu/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/values/strings.xml b/java/com/android/voicemail/impl/configui/res/values/strings.xml
new file mode 100644
index 000000000..fea76be02
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="vvm_config_override_load_current_key" translatable="false">vvm_config_override_load_current</string>
+ <string name="vvm_config_override_enabled_key" translatable="false">vvm_config_override_enabled</string>
+
+</resources>
diff --git a/java/com/android/voicemail/impl/configui/res/xml/vvm_config_override.xml b/java/com/android/voicemail/impl/configui/res/xml/vvm_config_override.xml
new file mode 100644
index 000000000..c4a23c789
--- /dev/null
+++ b/java/com/android/voicemail/impl/configui/res/xml/vvm_config_override.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <Preference
+ android:key="@string/vvm_config_override_load_current_key"
+ android:title="Load current"/>
+
+ <SwitchPreference
+ android:key="@string/vvm_config_override_enabled_key"
+ android:title="Override enabled"
+ android:defaultValue="false"/>
+
+ <!-- Keys should be a key in CarrierConfigManager prefixed with "vvm_config_override_key_" -->
+ <EditTextPreference
+ android:key="vvm_config_override_key_vvm_type_string"
+ android:title="type"
+ android:defaultValue="vvm_type_omtp"
+ />
+
+ <EditTextPreference
+ android:key="vvm_config_override_key_vvm_destination_number_string"
+ android:title="destination number"
+ />
+
+ <EditTextPreference
+ android:key="vvm_config_override_key_vvm_port_number_int"
+ android:title="destination port"
+ />
+ <EditTextPreference
+ android:key="vvm_config_override_key_carrier_vvm_package_name_string_array"
+ android:title="vvm package name (CSV)"
+ />
+
+ <SwitchPreference
+ android:key="vvm_config_override_key_vvm_prefetch_bool"
+ android:title="prefetch"
+ android:defaultValue="true"/>
+
+ <SwitchPreference
+ android:key="vvm_config_override_key_vvm_cellular_data_required_bool"
+ android:title="cellular data required"
+ android:defaultValue="false"/>
+ <EditTextPreference
+ android:key="vvm_config_override_key_vvm_ssl_port_number_int"
+ android:title="SSL port"
+ />
+
+ <SwitchPreference
+ android:key="vvm_config_override_key_vvm_legacy_mode_enabled_bool"
+ android:title="legacy mode"
+ android:defaultValue="false"/>
+
+ <EditTextPreference
+ android:key="vvm_config_override_key_vvm_disabled_capabilities_string_array"
+ android:title="disabled capabilities (CSV)"
+ />
+
+ <EditTextPreference
+ android:key="vvm_config_override_key_vvm_client_prefix_string"
+ android:title="client prefix"
+ />
+</PreferenceScreen> \ No newline at end of file
diff --git a/java/com/android/voicemail/impl/fetch/VoicemailFetchedCallback.java b/java/com/android/voicemail/impl/fetch/VoicemailFetchedCallback.java
index f386fce0e..3e825407b 100644
--- a/java/com/android/voicemail/impl/fetch/VoicemailFetchedCallback.java
+++ b/java/com/android/voicemail/impl/fetch/VoicemailFetchedCallback.java
@@ -23,9 +23,12 @@ import android.provider.VoicemailContract.Voicemails;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.voicemail.impl.R;
import com.android.voicemail.impl.VvmLog;
import com.android.voicemail.impl.imap.VoicemailPayload;
+import com.android.voicemail.impl.transcribe.TranscriptionService;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
@@ -56,6 +59,7 @@ public class VoicemailFetchedCallback {
* @param voicemailPayload The object containing the content data for the voicemail
*/
public void setVoicemailContent(@Nullable VoicemailPayload voicemailPayload) {
+ Assert.isWorkerThread();
if (voicemailPayload == null) {
VvmLog.i(TAG, "Payload not found, message has unsupported format");
ContentValues values = new ContentValues();
@@ -90,13 +94,23 @@ public class VoicemailFetchedCallback {
ContentValues values = new ContentValues();
values.put(Voicemails.MIME_TYPE, voicemailPayload.getMimeType());
values.put(Voicemails.HAS_CONTENT, true);
- updateVoicemail(values);
+ if (updateVoicemail(values)) {
+ ThreadUtil.postOnUiThread(
+ () -> {
+ if (!TranscriptionService.scheduleNewVoicemailTranscriptionJob(mContext, mUri, true)) {
+ VvmLog.w(TAG, String.format("Failed to schedule transcription for %s", mUri));
+ }
+ });
+ }
}
- private void updateVoicemail(ContentValues values) {
+ private boolean updateVoicemail(ContentValues values) {
int updatedCount = mContentResolver.update(mUri, values, null, null);
if (updatedCount != 1) {
VvmLog.e(TAG, "Updating voicemail should have updated 1 row, was: " + updatedCount);
+ return false;
+ } else {
+ return true;
}
}
}
diff --git a/java/com/android/voicemail/impl/imap/ImapHelper.java b/java/com/android/voicemail/impl/imap/ImapHelper.java
index f1bc8b221..94abe9bad 100644
--- a/java/com/android/voicemail/impl/imap/ImapHelper.java
+++ b/java/com/android/voicemail/impl/imap/ImapHelper.java
@@ -251,13 +251,18 @@ public class ImapHelper implements Closeable {
long time = messageDetails.getSentDate().getTime();
String number = getNumber(messageDetails.getFrom());
boolean isRead = Arrays.asList(messageDetails.getFlags()).contains(Flag.SEEN);
- return Voicemail.createForInsertion(time, number)
- .setPhoneAccount(mPhoneAccount)
- .setSourcePackage(mContext.getPackageName())
- .setSourceData(messageDetails.getUid())
- .setIsRead(isRead)
- .setTranscription(listener.getVoicemailTranscription())
- .build();
+ Long duration = messageDetails.getDuration();
+ Voicemail.Builder builder =
+ Voicemail.createForInsertion(time, number)
+ .setPhoneAccount(mPhoneAccount)
+ .setSourcePackage(mContext.getPackageName())
+ .setSourceData(messageDetails.getUid())
+ .setIsRead(isRead)
+ .setTranscription(listener.getVoicemailTranscription());
+ if (duration != null) {
+ builder.setDuration(duration);
+ }
+ return builder.build();
}
/**
diff --git a/java/com/android/voicemail/impl/mail/MailTransport.java b/java/com/android/voicemail/impl/mail/MailTransport.java
index 3df36d544..c35e41450 100644
--- a/java/com/android/voicemail/impl/mail/MailTransport.java
+++ b/java/com/android/voicemail/impl/mail/MailTransport.java
@@ -17,7 +17,9 @@ package com.android.voicemail.impl.mail;
import android.content.Context;
import android.net.Network;
+import android.net.TrafficStats;
import android.support.annotation.VisibleForTesting;
+import com.android.dialer.constants.TrafficStatsTags;
import com.android.voicemail.impl.OmtpEvents;
import com.android.voicemail.impl.imap.ImapHelper;
import com.android.voicemail.impl.mail.store.ImapStore;
@@ -188,10 +190,13 @@ public class MailTransport {
try {
LogUtils.v(TAG, "createSocket: network specified");
+ TrafficStats.setThreadStatsTag(TrafficStatsTags.VISUAL_VOICEMAIL_TAG);
return mNetwork.getSocketFactory().createSocket();
} catch (IOException ioe) {
LogUtils.d(TAG, ioe.toString());
throw new MessagingException(MessagingException.IOERROR, ioe.toString());
+ } finally {
+ TrafficStats.clearThreadStatsTag();
}
}
diff --git a/java/com/android/voicemail/impl/mail/Message.java b/java/com/android/voicemail/impl/mail/Message.java
index aea5d3ead..ca65d3d73 100644
--- a/java/com/android/voicemail/impl/mail/Message.java
+++ b/java/com/android/voicemail/impl/mail/Message.java
@@ -15,6 +15,7 @@
*/
package com.android.voicemail.impl.mail;
+import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import java.util.Date;
import java.util.HashSet;
@@ -64,6 +65,9 @@ public abstract class Message implements Part, Body {
public abstract void setSentDate(Date sentDate) throws MessagingException;
+ @Nullable
+ public abstract Long getDuration() throws MessagingException;
+
public abstract Address[] getRecipients(String type) throws MessagingException;
public abstract void setRecipients(String type, Address[] addresses) throws MessagingException;
diff --git a/java/com/android/voicemail/impl/mail/internet/MimeHeader.java b/java/com/android/voicemail/impl/mail/internet/MimeHeader.java
index d41cdb3e4..8f0817650 100644
--- a/java/com/android/voicemail/impl/mail/internet/MimeHeader.java
+++ b/java/com/android/voicemail/impl/mail/internet/MimeHeader.java
@@ -36,6 +36,7 @@ public class MimeHeader {
public static final String HEADER_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
public static final String HEADER_CONTENT_ID = "Content-ID";
+ public static final String HEADER_CONTENT_DURATION = "Content-Duration";
/** Fields that should be omitted when writing the header using writeTo() */
private static final String[] WRITE_OMIT_FIELDS = {
diff --git a/java/com/android/voicemail/impl/mail/internet/MimeMessage.java b/java/com/android/voicemail/impl/mail/internet/MimeMessage.java
index 589720660..39378a092 100644
--- a/java/com/android/voicemail/impl/mail/internet/MimeMessage.java
+++ b/java/com/android/voicemail/impl/mail/internet/MimeMessage.java
@@ -15,7 +15,9 @@
*/
package com.android.voicemail.impl.mail.internet;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
+import com.android.voicemail.impl.VvmLog;
import com.android.voicemail.impl.mail.Address;
import com.android.voicemail.impl.mail.Body;
import com.android.voicemail.impl.mail.BodyPart;
@@ -197,6 +199,28 @@ public class MimeMessage extends Message {
}
@Override
+ @Nullable
+ public Long getDuration() {
+ String durationHeader = null;
+ try {
+ durationHeader = getFirstHeader(MimeHeader.HEADER_CONTENT_DURATION);
+ } catch (MessagingException e) {
+ VvmLog.e("MimeMessage.getDuration", "cannot retrieve header: ", e);
+ return null;
+ }
+ if (durationHeader == null) {
+ VvmLog.w("MimeMessage.getDuration", "message missing Content-Duration header");
+ return null;
+ }
+ try {
+ return Long.valueOf(durationHeader);
+ } catch (NumberFormatException e) {
+ VvmLog.w("MimeMessage.getDuration", "cannot parse duration " + durationHeader);
+ return null;
+ }
+ }
+
+ @Override
public String getContentType() throws MessagingException {
final String contentType = getFirstHeader(MimeHeader.HEADER_CONTENT_TYPE);
if (contentType == null) {
diff --git a/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java b/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java
index 88ec0ed90..fd56952d7 100644
--- a/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java
+++ b/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java
@@ -27,7 +27,7 @@ public final class ImapConstants {
public static final String FETCH_FIELD_BODY_PEEK_SANE =
String.format(Locale.US, "BODY.PEEK[]<0.%d>", ImapStore.FETCH_BODY_SANE_SUGGESTED_SIZE);
public static final String FETCH_FIELD_HEADERS =
- "BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc message-id)]";
+ "BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc message-id content-duration)]";
public static final String ALERT = "ALERT";
public static final String APPEND = "APPEND";
diff --git a/java/com/android/voicemail/impl/proguard.flags b/java/com/android/voicemail/impl/proguard.flags
new file mode 100644
index 000000000..9379df322
--- /dev/null
+++ b/java/com/android/voicemail/impl/proguard.flags
@@ -0,0 +1,4 @@
+-assumenosideeffects class com.android.voicemail.impl.VvmLog {
+ public static void v(...);
+ public static void d(...);
+}
diff --git a/java/com/android/voicemail/impl/protocol/OmtpProtocol.java b/java/com/android/voicemail/impl/protocol/OmtpProtocol.java
index 27aab8a7c..971edcf4f 100644
--- a/java/com/android/voicemail/impl/protocol/OmtpProtocol.java
+++ b/java/com/android/voicemail/impl/protocol/OmtpProtocol.java
@@ -35,7 +35,7 @@ public class OmtpProtocol extends VisualVoicemailProtocol {
phoneAccountHandle,
applicationPort,
destinationNumber,
- OmtpConstants.CLIENT_TYPE_GOOGLE_10,
+ OmtpConstants.getClientType(),
OmtpConstants.PROTOCOL_VERSION1_1,
null /*clientPrefix*/);
}
diff --git a/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java b/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java
index 1cdbbfbca..d9a06494e 100644
--- a/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java
+++ b/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java
@@ -31,7 +31,7 @@ import android.text.Html;
import android.text.Spanned;
import android.text.style.URLSpan;
import android.util.ArrayMap;
-import com.android.dialer.common.ConfigProviderBindings;
+import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.voicemail.impl.ActivationTask;
import com.android.voicemail.impl.Assert;
import com.android.voicemail.impl.OmtpEvents;
diff --git a/java/com/android/voicemail/impl/res/values-af/strings.xml b/java/com/android/voicemail/impl/res/values-af/strings.xml
index 2e829c9b9..0ed54fa8c 100644
--- a/java/com/android/voicemail/impl/res/values-af/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-af/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Verander PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visuele stemboodskap moet geaktiveer wees om PIN te verander"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuele stemboodskap is nog nie geaktiveer nie, probeer asseblief later weer"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Ou PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nuwe PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Wag asseblief."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Die nuwe PIN is te kort."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Die nuwe PIN is te lank."</string>
diff --git a/java/com/android/voicemail/impl/res/values-am/strings.xml b/java/com/android/voicemail/impl/res/values-am/strings.xml
index 183f7b76e..39b21b478 100644
--- a/java/com/android/voicemail/impl/res/values-am/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-am/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"ፒን ይቀይሩ"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ፒን ለመቀየር የእይታ የድምጽ መልዕክት መንቃት አለበት"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"የእይታ የድምጽ መልዕክት ገና ገቢር አልሆነም፣ እባክዎ ቆይተው እንደገና ይሞክሩ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"የቀድሞ ፒን"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"አዲስ ፒን"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"እባክዎ ይጠብቁ።"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"አዲሱ ፒን በጣም አጭር ነው።"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"አዲሱ ፒን በጣም ረጅም ነው።"</string>
diff --git a/java/com/android/voicemail/impl/res/values-ar/strings.xml b/java/com/android/voicemail/impl/res/values-ar/strings.xml
index 8b75b6e5b..4cdba4dfc 100644
--- a/java/com/android/voicemail/impl/res/values-ar/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ar/strings.xml
@@ -25,9 +25,7 @@
<string name="voicemail_set_pin_preference_title" msgid="1034691230818233684">"تعيين رقم التعريف الشخصي"</string>
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"تغيير رقم التعريف الشخصي"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ينبغي تشغيل البريد الصوتي المرئي لتغيير رقم التعريف الشخصي"</string>
- <string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"لم يتم تنشيط البريد الصوتي المرئي بعد، الرجاء المحاولة مرة أخرى لاحقًا"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"رقم التعريف الشخصي القديم"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"رقم التعريف الشخصي الجديد"</string>
+ <string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"لم يتم تنشيط البريد الصوتي المرئي بعد، يُرجى المحاولة مرة أخرى لاحقًا"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"يُرجى الانتظار."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"رقم التعريف الشخصي الجديد قصير جدًا."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"رقم التعريف الشخصي الجديد طويل جدًا."</string>
diff --git a/java/com/android/voicemail/impl/res/values-az/strings.xml b/java/com/android/voicemail/impl/res/values-az/strings.xml
index 978365055..f24573075 100644
--- a/java/com/android/voicemail/impl/res/values-az/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-az/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN-i dəyişin"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN-i dəyişmək üçün görünən səsli e-poçt aktiv olmalıdır"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Görünən səsli e-poçt hələ aktiv edilməyib, daha sonra yenidən cəhd edin"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Köhnə PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Yeni PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Gözləyin."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Yeni PIN çox qısadır."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Yeni PIN çox uzundur."</string>
diff --git a/java/com/android/voicemail/impl/res/values-b+sr+Latn/strings.xml b/java/com/android/voicemail/impl/res/values-b+sr+Latn/strings.xml
index f7c7a62dc..7c12c9e64 100644
--- a/java/com/android/voicemail/impl/res/values-b+sr+Latn/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-b+sr+Latn/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Promenite PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Morate da omogućite vizuelnu govornu poštu da biste promenili PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizuelna govorna pošta još uvek nije aktivirana, probajte ponovo kasnije"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Stari PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Novi PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Sačekajte."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Novi PIN je prekratak."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Novi PIN je predugačak."</string>
diff --git a/java/com/android/voicemail/impl/res/values-be/strings.xml b/java/com/android/voicemail/impl/res/values-be/strings.xml
index 6f4d1250d..c88f8ab98 100644
--- a/java/com/android/voicemail/impl/res/values-be/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-be/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Змяніць PIN-код"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Трэба ўключыць візуальную галасавую пошту, каб змяніць PIN-код"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Візуальная галасавая пошта пакуль не актываваная. Паўтарыце спробу пазней"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Стары PIN-код"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Новы PIN-код"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Пачакайце."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Новы PIN-код занадта кароткі."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Новы PIN-код занадта доўгі."</string>
diff --git a/java/com/android/voicemail/impl/res/values-bg/strings.xml b/java/com/android/voicemail/impl/res/values-bg/strings.xml
index 553c8f3ed..380efe23a 100644
--- a/java/com/android/voicemail/impl/res/values-bg/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-bg/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Промяна на ПИН кода"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"За промяна на ПИН кода трябва да бъде активирана визуалната гласова поща"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Визуалната гласова поща още не е активирана. Моля, опитайте отново по-късно"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Стар ПИН"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Нов ПИН"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Моля, изчакайте."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Новият ПИН е твърде къс."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Новият ПИН е твърде дълъг."</string>
diff --git a/java/com/android/voicemail/impl/res/values-bn/strings.xml b/java/com/android/voicemail/impl/res/values-bn/strings.xml
index 362240ae6..011a74ec1 100644
--- a/java/com/android/voicemail/impl/res/values-bn/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-bn/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"পিন পরিবর্তন করুন"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"পিন পরিবর্তন করতে ভিজ্যুয়াল ভয়েসমেল অবশ্যই সক্ষম করতে হবে"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ভিজ্যুয়াল ভয়েসমেল এখনও সক্রিয় করা হয়নি, অনুগ্রহ করে পরে আবার চেষ্টা করুন"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"পুরোনো PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"নতুন PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"অনুগ্রহ করে অপেক্ষা করুন৷"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"নতুন PIN খুবই ছোট৷"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"নতুন PIN খুবই বড়৷"</string>
diff --git a/java/com/android/voicemail/impl/res/values-bs/strings.xml b/java/com/android/voicemail/impl/res/values-bs/strings.xml
index f897a61e5..0a26706a5 100644
--- a/java/com/android/voicemail/impl/res/values-bs/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-bs/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Promijenite PIN kôd"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Vizuelna govorna pošta mora biti omogućena za promjenu PIN kôda"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizuelna govorna pošta još uvijek nije aktivirana, pokušajte ponovo kasnije"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Stari PIN kod"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Novi PIN kod"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Pričekajte."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Novi PIN kod je prekratak."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Novi PIN kod je predug."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ca/strings.xml b/java/com/android/voicemail/impl/res/values-ca/strings.xml
index 51e19fb45..5c36ea716 100644
--- a/java/com/android/voicemail/impl/res/values-ca/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ca/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Canvia el PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"La bústia de veu visual ha d\'estar activada per poder canviar el PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"La bústia de veu visual encara no està activada. Torna-ho a provar més tard."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN antic"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN nou"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Espera."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"El PIN nou és massa curt."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"El PIN nou és massa llarg."</string>
diff --git a/java/com/android/voicemail/impl/res/values-cs/strings.xml b/java/com/android/voicemail/impl/res/values-cs/strings.xml
index 38ef3fe5f..ddef49171 100644
--- a/java/com/android/voicemail/impl/res/values-cs/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-cs/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Změnit kód PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Pokud chcete kód PIN změnit, musíte mít zapnutou vizuální hlasovou schránku"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizuální hlasová schránka zatím není aktivovaná, zkuste to prosím znovu později"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Starý kód PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nový kód PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Čekejte prosím."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Nový kód PIN je příliš krátký."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Nový kód PIN je příliš dlouhý."</string>
diff --git a/java/com/android/voicemail/impl/res/values-da/strings.xml b/java/com/android/voicemail/impl/res/values-da/strings.xml
index 7e471171d..64e658852 100644
--- a/java/com/android/voicemail/impl/res/values-da/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-da/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Skift pinkode"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visuel telefonsvarer skal være aktiveret, for at du kan skifte pinkode"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuel telefonsvarer er ikke aktiveret endnu. Prøv igen senere"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Nuværende pinkode"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Ny pinkode"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Vent et øjeblik."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Den nye pinkode er for kort."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Den nye pinkode er for lang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-de/strings.xml b/java/com/android/voicemail/impl/res/values-de/strings.xml
index 35b86f2c7..9b162759c 100644
--- a/java/com/android/voicemail/impl/res/values-de/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-de/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN ändern"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Die visuelle Mailbox muss aktiviert sein, um die PIN zu ändern"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Die visuelle Mailbox wurde noch nicht aktiviert, bitte versuche es später noch einmal"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Alte PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Neue PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Bitte warten."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Die neue PIN ist zu kurz."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Die neue PIN ist zu lang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-el/strings.xml b/java/com/android/voicemail/impl/res/values-el/strings.xml
index 11711bb4a..b197b1c21 100644
--- a/java/com/android/voicemail/impl/res/values-el/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-el/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Αλλαγή κωδικού PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Για αλλαγή του PIN, ενεργοποιήστε τον οπτικό αυτόματο τηλεφωνητή"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Ο οπτικός αυτόματος τηλεφωνητής δεν έχει ενεργοποιηθεί ακόμα. Δοκιμάστε ξανά αργότερα."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Παλιός αριθμός PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Νέος αριθμός PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Περιμένετε."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Το νέο PIN είναι πολύ μικρό."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Το νέο PIN είναι πολύ μεγάλo."</string>
diff --git a/java/com/android/voicemail/impl/res/values-en-rAU/strings.xml b/java/com/android/voicemail/impl/res/values-en-rAU/strings.xml
index be29e4736..f49f9ff12 100644
--- a/java/com/android/voicemail/impl/res/values-en-rAU/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-en-rAU/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Change PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visual voicemail must be enabled to change PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visual voicemail is not activated yet. Please try again later"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Old PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"New PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Please wait."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"The new PIN is too short."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"The new PIN is too long."</string>
diff --git a/java/com/android/voicemail/impl/res/values-en-rGB/strings.xml b/java/com/android/voicemail/impl/res/values-en-rGB/strings.xml
index be29e4736..f49f9ff12 100644
--- a/java/com/android/voicemail/impl/res/values-en-rGB/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-en-rGB/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Change PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visual voicemail must be enabled to change PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visual voicemail is not activated yet. Please try again later"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Old PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"New PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Please wait."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"The new PIN is too short."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"The new PIN is too long."</string>
diff --git a/java/com/android/voicemail/impl/res/values-en-rIN/strings.xml b/java/com/android/voicemail/impl/res/values-en-rIN/strings.xml
index be29e4736..f49f9ff12 100644
--- a/java/com/android/voicemail/impl/res/values-en-rIN/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-en-rIN/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Change PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visual voicemail must be enabled to change PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visual voicemail is not activated yet. Please try again later"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Old PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"New PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Please wait."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"The new PIN is too short."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"The new PIN is too long."</string>
diff --git a/java/com/android/voicemail/impl/res/values-es-rUS/strings.xml b/java/com/android/voicemail/impl/res/values-es-rUS/strings.xml
index e958ecf9e..f5aeeb9f3 100644
--- a/java/com/android/voicemail/impl/res/values-es-rUS/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-es-rUS/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Cambiar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"El buzón de voz visual se debe activar para cambiar el PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"El buzón de voz visual aún no está activado. Vuelve a intentarlo más tarde."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN anterior"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN nuevo"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Espera."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"El PIN nuevo es demasiado corto."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"El PIN nuevo es demasiado largo."</string>
diff --git a/java/com/android/voicemail/impl/res/values-es/strings.xml b/java/com/android/voicemail/impl/res/values-es/strings.xml
index b965ca0c5..3dc171396 100644
--- a/java/com/android/voicemail/impl/res/values-es/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-es/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Cambiar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Para poder cambiar el PIN, el buzón de voz visual debe estar habilitado"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"El buzón de voz visual aún no está activado; inténtalo de nuevo más tarde"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN antiguo"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN nuevo"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Espera..."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"El PIN nuevo es muy corto."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"El PIN nuevo es muy largo."</string>
diff --git a/java/com/android/voicemail/impl/res/values-et/strings.xml b/java/com/android/voicemail/impl/res/values-et/strings.xml
index 28042ec10..e964dcd00 100644
--- a/java/com/android/voicemail/impl/res/values-et/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-et/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN-koodi muutmine"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN-koodi muutmiseks peab olema lubatud visuaalne kõnepost"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuaalne kõnepost pole veel aktiveeritud, proovige hiljem uuesti"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Vana PIN-kood"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Uus PIN-kood"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Oodake."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Uus PIN-kood on liiga lühike."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Uus PIN-kood on liiga pikk."</string>
diff --git a/java/com/android/voicemail/impl/res/values-eu/strings.xml b/java/com/android/voicemail/impl/res/values-eu/strings.xml
index ff2f34c0a..398ff2382 100644
--- a/java/com/android/voicemail/impl/res/values-eu/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-eu/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Aldatu PIN kodea"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Ikusizko erantzungailuak gaituta egon behar du PIN kodea aldatu ahal izateko"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Oraindik ez dago aktibatuta ikusizko erantzungailua. Saiatu berriro geroago."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN zaharra"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN berria"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Itxaron, mesedez."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Laburregia da PIN kode berria."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Luzeegia da PIN kode berria."</string>
diff --git a/java/com/android/voicemail/impl/res/values-fa/strings.xml b/java/com/android/voicemail/impl/res/values-fa/strings.xml
index bba6541ee..c57da2662 100644
--- a/java/com/android/voicemail/impl/res/values-fa/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-fa/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"تغییر پین"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"برای تغییر پین، پست صوتی تصویری باید فعال شود"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"پست صوتی تصویری هنوز فعال نشده است، لطفاً بعداً دوباره امتحان کنید"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"پین قدیمی"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"پین جدید"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"لطفاً منتظر بمانید."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"پین جدید خیلی کوتاه است."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"پین جدید خیلی طولانی است."</string>
diff --git a/java/com/android/voicemail/impl/res/values-fi/strings.xml b/java/com/android/voicemail/impl/res/values-fi/strings.xml
index 6886effbf..bb1d2d0ce 100644
--- a/java/com/android/voicemail/impl/res/values-fi/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-fi/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Vaihda PIN-koodi"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Ota visuaalinen puhelinvastaaja käyttöön, jotta voit vaihtaa PIN-koodin."</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuaalista puhelinvastaajaa ei ole vielä aktivoitu. Yritä myöhemmin uudelleen."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Vanha PIN-koodi"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Uusi PIN-koodi"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Odota."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Uusi PIN-koodi on liian lyhyt."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Uusi PIN-koodi on liian pitkä."</string>
diff --git a/java/com/android/voicemail/impl/res/values-fr-rCA/strings.xml b/java/com/android/voicemail/impl/res/values-fr-rCA/strings.xml
index 3e485e0a3..92b7df6dd 100644
--- a/java/com/android/voicemail/impl/res/values-fr-rCA/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-fr-rCA/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Modifier le NIP"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"La messagerie vocale visuelle doit être activée pour que vous puissiez modifier votre NIP"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"La messagerie vocale visuelle n\'a pas encore été activée. Veuillez réessayer plus tard"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Ancien NIP"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nouveau NIP"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Veuillez patienter."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Le nouveau NIP est trop court."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Le nouveau NIP est trop long."</string>
diff --git a/java/com/android/voicemail/impl/res/values-fr/strings.xml b/java/com/android/voicemail/impl/res/values-fr/strings.xml
index e540f6085..771c32436 100644
--- a/java/com/android/voicemail/impl/res/values-fr/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-fr/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Modifier le code secret"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Pour que vous puissiez modifier le code secret, la messagerie vocale visuelle doit être activée"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"La messagerie vocale visuelle n\'est pas encore activée. Veuillez réessayer plus tard"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Ancien code"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nouveau code"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Veuillez patienter."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Le nouveau code est trop court."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Le nouveau code est trop long."</string>
diff --git a/java/com/android/voicemail/impl/res/values-gl/strings.xml b/java/com/android/voicemail/impl/res/values-gl/strings.xml
index b059879bc..22f401fef 100644
--- a/java/com/android/voicemail/impl/res/values-gl/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-gl/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Cambiar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Para poder cambiar o PIN, o correo de voz visual ten que estar activado"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"O correo de voz visual aínda non está activado. Téntao de novo máis tarde"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN antigo"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN novo"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Agarda."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"O novo PIN é demasiado curto."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"O novo PIN é demasiado longo."</string>
diff --git a/java/com/android/voicemail/impl/res/values-gu/strings.xml b/java/com/android/voicemail/impl/res/values-gu/strings.xml
index 3ec3c5d1a..107fd4762 100644
--- a/java/com/android/voicemail/impl/res/values-gu/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-gu/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN બદલો"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN બદલવા માટે વિઝ્યુઅલ વૉઇસમેઇલ સક્ષમ હોય તે આવશ્યક છે"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"વિઝ્યુઅલ વૉઇસમેઇલ હજુ સુધી સક્રિય નથી, કૃપા કરીને પછીથી ફરી પ્રયાસ કરો"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"જૂનો PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"નવો PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"કૃપા કરીને રાહ જુઓ."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"નવો PIN ખૂબ ટૂંકો છે."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"નવો PIN ખૂબ લાંબો છે."</string>
diff --git a/java/com/android/voicemail/impl/res/values-hi/strings.xml b/java/com/android/voicemail/impl/res/values-hi/strings.xml
index 545fffd4d..88613708b 100644
--- a/java/com/android/voicemail/impl/res/values-hi/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-hi/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"पिन बदलें"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"पिन बदलने के लिए विज़ुअल वॉइसमेल ज़रूर सक्षम होना चाहिए"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"विज़ुअल वॉइसमेल को अभी तक सक्रिय नहीं किया गया है, कृपया बाद में फिर से कोशिश करें"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"पुराना पिन"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"नया पिन"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"कृपया प्रतीक्षा करें."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"नया पिन बहुत छोटा है."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"नया पिन बहुत बड़ा है."</string>
diff --git a/java/com/android/voicemail/impl/res/values-hr/strings.xml b/java/com/android/voicemail/impl/res/values-hr/strings.xml
index 9d5d60636..ee1bf1f57 100644
--- a/java/com/android/voicemail/impl/res/values-hr/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-hr/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Promjena PIN-a"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Za promjenu PIN-a potrebno je omogućiti vizualnu govornu poštu"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizualna govorna pošta još nije aktivirana, pokušajte ponovno kasnije"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Stari PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Novi PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Pričekajte."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Novi PIN je prekratak."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Novi PIN je predugačak."</string>
diff --git a/java/com/android/voicemail/impl/res/values-hu/strings.xml b/java/com/android/voicemail/impl/res/values-hu/strings.xml
index 982ba995a..d761d40cd 100644
--- a/java/com/android/voicemail/impl/res/values-hu/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-hu/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN-kód módosítása"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"A PIN-kód módosításához engedélyezni kell a vizuális hangpostát."</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"A vizuális hangposta még nincs aktiválva. Engedélyezze később."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Régi PIN-kód"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Új PIN-kód"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Kérjük, várjon."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Az új PIN-kód túl rövid."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Az új PIN-kód túl hosszú."</string>
diff --git a/java/com/android/voicemail/impl/res/values-hy/strings.xml b/java/com/android/voicemail/impl/res/values-hy/strings.xml
index 00a132ddd..008aeeeb6 100644
--- a/java/com/android/voicemail/impl/res/values-hy/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-hy/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Փոխեք PIN կոդը"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN կոդը փոխելու համար տեսողական ձայնային փոստը պետք է միացված լինի"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Տեսողական ձայնային փոստը դեռ ակտիվացված չէ: Փորձեք ավելի ուշ:"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Հին PIN կոդ"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Նոր PIN կոդ"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Սպասեք:"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Նոր PIN կոդը չափազանց կարճ է:"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Նոր PIN կոդը չափազանց երկար է:"</string>
diff --git a/java/com/android/voicemail/impl/res/values-in/strings.xml b/java/com/android/voicemail/impl/res/values-in/strings.xml
index 7523fc9e8..cda3a1a50 100644
--- a/java/com/android/voicemail/impl/res/values-in/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-in/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Ubah PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Pesan suara visual harus diaktifkan untuk mengubah PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Pesan suara visual belum diaktifkan, coba lagi nanti"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN lama"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN Baru"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Mohon tunggu."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"PIN baru terlalu pendek."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"PIN baru terlalu panjang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-is/strings.xml b/java/com/android/voicemail/impl/res/values-is/strings.xml
index b2e616b0e..44ef9e068 100644
--- a/java/com/android/voicemail/impl/res/values-is/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-is/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Breyta PIN-númeri"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Kveikt þarf að vera á myndrænu talhólfi til að breyta PIN-númeri"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Ekki er búið að virkja myndrænt talhólf. Reyndu aftur síðar"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Gamla PIN-númerið"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nýtt PIN-númer"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Augnablik."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Nýja PIN-númerið er of stutt."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Nýja PIN-númerið er of langt."</string>
diff --git a/java/com/android/voicemail/impl/res/values-it/strings.xml b/java/com/android/voicemail/impl/res/values-it/strings.xml
index f4fea84fb..afbbbc234 100644
--- a/java/com/android/voicemail/impl/res/values-it/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-it/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Cambia PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"La lettura delle segreteria deve essere attivata per cambiare il PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Lettura della segreteria non attivata. Riprova più tardi"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN attuale"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nuovo PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Attendi."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Il nuovo PIN è troppo corto."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Il nuovo PIN è troppo lungo."</string>
diff --git a/java/com/android/voicemail/impl/res/values-iw/strings.xml b/java/com/android/voicemail/impl/res/values-iw/strings.xml
index e48e35ded..acc2e6c50 100644
--- a/java/com/android/voicemail/impl/res/values-iw/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-iw/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"שינוי קוד הגישה"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"צריך להפעיל את הדואר הקולי הוויזואלי כדי לשנות את קוד הגישה"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"הדואר הקולי הוויזואלי לא הופעל עדיין. נסה שוב מאוחר יותר"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"קוד הגישה הישן"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"קוד הגישה החדש"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"נא להמתין."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"קוד הגישה החדש קצר מדי."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"קוד הגישה החדש ארוך מדי."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ja/strings.xml b/java/com/android/voicemail/impl/res/values-ja/strings.xml
index cd825d2e1..f0d6a9b5a 100644
--- a/java/com/android/voicemail/impl/res/values-ja/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ja/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN の変更"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN を変更するには、ビジュアル ボイスメールを有効にする必要があります"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ビジュアル ボイスメールがまだ有効になっていません。しばらくしてからもう一度お試しください"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"古い PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"新しい PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"お待ちください。"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"新しい PIN が短すぎます。"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"新しい PIN が長すぎます。"</string>
diff --git a/java/com/android/voicemail/impl/res/values-ka/strings.xml b/java/com/android/voicemail/impl/res/values-ka/strings.xml
index 12a677a62..84c13b10f 100644
--- a/java/com/android/voicemail/impl/res/values-ka/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ka/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN-კოდის შეცვლა"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN-კოდის შესაცვლელად ჩართული უნდა იყოს ვიზუალური ხმოვანი ფოსტა"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ვიზუალური ხმოვანი ფოსტა ჯერ გააქტიურებული არ არის. გთხოვთ, სცადოთ ხელახლა."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"ძველი PIN-კოდი"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"ახალი PIN-კოდი"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"გთხოვთ, დაელოდოთ."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"ახალი PIN-კოდი ძალიან მოკლეა."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"ახალი PIN-კოდი ძალიან გრძელია."</string>
diff --git a/java/com/android/voicemail/impl/res/values-kk/strings.xml b/java/com/android/voicemail/impl/res/values-kk/strings.xml
index 08c7cce30..c2afc8e46 100644
--- a/java/com/android/voicemail/impl/res/values-kk/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-kk/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN кодын өзгерту"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN кодын өзгерту үшін визуалды дауыс хабарын қосу қажет"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Визуалды дауыс хабары әлі қосылмаған. Кейінірек қайталап көріңіз"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Ескі PIN коды"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Жаңа PIN коды"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Күте тұрыңыз."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Жаңа PIN коды тым қысқа."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Жаңа PIN коды тым ұзын."</string>
diff --git a/java/com/android/voicemail/impl/res/values-km/strings.xml b/java/com/android/voicemail/impl/res/values-km/strings.xml
index ea3d6ff47..55a225367 100644
--- a/java/com/android/voicemail/impl/res/values-km/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-km/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"ផ្លាស់ប្ដូរ​កូដ PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"សារ​​ជា​សំឡេង​ដែល​មើល​ឃើញ​ត្រូវតែ​បើកដំណើរការ ដើម្បី​ផ្លាស់ប្ដូរ PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"សារ​ជាសំឡេង​ដែល​មើល​ឃើញ​មិនទាន់​​ត្រូវ​បាន​ធ្វើ​ឲ្យ​សកម្ម​នៅ​ឡើយ​ទេ សូម​ព្យាយាម​ម្ដង​ទៀត​នៅ​ពេល​ក្រោយ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"កូដ PIN ចាស់"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"កូដ PIN ថ្មី"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"សូមរង់ចាំ។"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"កូដ PIN ថ្មី​ ខ្លី​ពេក។"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"កូដ PIN ថ្មី​ វែង​ពេក។"</string>
diff --git a/java/com/android/voicemail/impl/res/values-kn/strings.xml b/java/com/android/voicemail/impl/res/values-kn/strings.xml
index 48e14f57b..695c8d455 100644
--- a/java/com/android/voicemail/impl/res/values-kn/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-kn/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"ಪಿನ್‌ ಬದಲಾಯಿಸಿ"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ಪಿನ್ ಬದಲಾಯಿಸಲು ದೃಶ್ಯ ಧ್ವನಿಮೇಲ್ ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ದೃಶ್ಯ ಧ್ವನಿಮೇಲ್ ಇನ್ನೂ ಸಕ್ರಿಯವಾಗಿಲ್ಲ, ದಯವಿಟ್ಟು ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"ಹಳೆಯ ಪಿನ್"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"ಹೊಸ ಪಿನ್‌"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"ದಯವಿಟ್ಟು ನಿರೀಕ್ಷಿಸಿ."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"ಹೊಸ ಪಿನ್ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"ಹೊಸ ಪಿನ್ ತುಂಬಾ ಉದ್ದವಾಗಿದೆ."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ko/strings.xml b/java/com/android/voicemail/impl/res/values-ko/strings.xml
index 1138a5b0f..7f1d8b03f 100644
--- a/java/com/android/voicemail/impl/res/values-ko/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ko/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN 변경"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN을 변경하려면 시각적 음성사서함이 사용 설정되어 있어야 합니다."</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"시각적 음성사서함이 아직 활성 상태가 아닙니다. 나중에 다시 시도해 주세요."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"이전 PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"새 PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"기다려 주세요."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"새 PIN이 너무 짧습니다."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"새 PIN이 너무 깁니다."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ky/strings.xml b/java/com/android/voicemail/impl/res/values-ky/strings.xml
index b54d2b4d9..736a56ac6 100644
--- a/java/com/android/voicemail/impl/res/values-ky/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ky/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN кодду өзгөртүү"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN кодду өзгөртүү үчүн визуладык үн почтасын иштетүү керек"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Визуалдык үн почтаңыз күйгүзүлгөн жок. Кайра аракет кылыңыз."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Эски PIN код"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Жаңы PIN код"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Күтө туруңуз."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Жаңы PIN код өтө эле кыска."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Жаңы PIN код өтө эле узун."</string>
diff --git a/java/com/android/voicemail/impl/res/values-lo/strings.xml b/java/com/android/voicemail/impl/res/values-lo/strings.xml
index 2052059b4..fb0313361 100644
--- a/java/com/android/voicemail/impl/res/values-lo/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-lo/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"​ປ່ຽນ​ລະຫັດ PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ຈະຕ້ອງເປີດໃຊ້ຂໍ້ຄວາມສຽງສະເໝືອນເພື່ອປ່ຽນ PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ຍັງບໍໄດ້ເປີດໃຊ້ຂໍ້ຄວາມສຽງສະເໝືອນເທື່ອ, ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"ລະຫັດ PIN ເກົ່າ"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"ລະຫັດ PIN ໃໝ່"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"ກະລຸນາລໍຖ້າ."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"ລະຫັດ PIN ໃໝ່ສັ້ນເກີນໄປ."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"ລະຫັດ PIN ໃໝ່ຍາວເກີນໄປ."</string>
diff --git a/java/com/android/voicemail/impl/res/values-lt/strings.xml b/java/com/android/voicemail/impl/res/values-lt/strings.xml
index 4d7d378b9..c9891abf4 100644
--- a/java/com/android/voicemail/impl/res/values-lt/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-lt/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN kodo keitimas"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Vaizdinis balso paštas turi būti įgalintas, kad būtų galima pakeisti PIN kodą"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vaizdinis balso paštas dar nesuaktyvintas, vėliau bandykite dar kartą"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Senas PIN kodas"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Naujas PIN kodas"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Palaukite."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Naujas PIN kodas per trumpas."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Naujas PIN kodas per ilgas."</string>
diff --git a/java/com/android/voicemail/impl/res/values-lv/strings.xml b/java/com/android/voicemail/impl/res/values-lv/strings.xml
index 776f1029a..7a26aa043 100644
--- a/java/com/android/voicemail/impl/res/values-lv/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-lv/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN mainīšana"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Lai varētu mainīt PIN, ir jābūt iespējotam vizuālajam balss pastam."</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizuālais balss pasts vēl nav aktivizēts. Lūdzu, vēlāk mēģiniet vēlreiz."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Iepriekšējais PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Jaunais PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Lūdzu, uzgaidiet!"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Jaunais PIN ir pārāk īss."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Jaunais PIN ir pārāk garš."</string>
diff --git a/java/com/android/voicemail/impl/res/values-mk/strings.xml b/java/com/android/voicemail/impl/res/values-mk/strings.xml
index 52ec73d7c..2ef8faeb5 100644
--- a/java/com/android/voicemail/impl/res/values-mk/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-mk/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Променете PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"За променување на PIN-кодот, мора да се овозможи визуелна говорна пошта"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Визуелната говорна пошта сѐ уште не е активна. Обидете се повторно подоцна"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Стар PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Нов PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Почекајте."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Новиот PIN е премногу кус."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Новиот PIN е премногу долг."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ml/strings.xml b/java/com/android/voicemail/impl/res/values-ml/strings.xml
index baece4692..ac0ad23c1 100644
--- a/java/com/android/voicemail/impl/res/values-ml/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ml/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"പിൻ മാറ്റുക"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"പിൻ മാറ്റുന്നതിന് വിഷ്വൽ വോയ്‌സ്‌മെയിൽ പ്രവർത്തനക്ഷമമാക്കേണ്ടതുണ്ട്"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"വിഷ്വൽ വോയ്‌സ്‌മെയിൽ ഇതുവരെ സജീവമാക്കിയിട്ടില്ല, പിന്നീട് വീണ്ടും ശ്രമിച്ചുനോക്കൂ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"പഴയ പിൻ"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"പുതിയ പിൻ"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"കാത്തിരിക്കുക."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"പുതിയ പിൻ വളരെ ചെറുതാണ്."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"പുതിയ പിൻ വളരെ ദൈർഘ്യമേറിയതാണ്."</string>
diff --git a/java/com/android/voicemail/impl/res/values-mn/strings.xml b/java/com/android/voicemail/impl/res/values-mn/strings.xml
index 58c31344a..96e0e42b4 100644
--- a/java/com/android/voicemail/impl/res/values-mn/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-mn/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN өөрчлөх"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Харагдах дуут шуудан PIN-г өөрчлөх боломжтой байх ёстой"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Харагдах дуут шуудан хараахан идэвхжээгүй байна, дараа дахин оролдоно уу"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Хуучин PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Шинэ PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Түр хүлээнэ үү."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Шинэ PIN хэт богино байна."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Шинэ PIN хэт урт байна."</string>
diff --git a/java/com/android/voicemail/impl/res/values-mr/strings.xml b/java/com/android/voicemail/impl/res/values-mr/strings.xml
index 17a7f7a47..85b5270e5 100644
--- a/java/com/android/voicemail/impl/res/values-mr/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-mr/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"पिन बदला"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"पिन बदलण्‍यासाठी व्हिज्युअल व्हॉइसमेल सक्षम करणे आवश्‍यक आहे"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"व्हिज्युअल व्हॉइसमेल अद्याप सक्रिय केले नाही, कृपया नंतर पुन्हा प्रयत्न करा"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"जुना पिन"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"नवीन पिन"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"कृपया प्रतीक्षा करा."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"नवीन पिन खूप लहान आहे."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"नवीन पिन खूप दीर्घ आहे."</string>
@@ -46,6 +44,6 @@
<string name="change_pin_enter_new_pin_hint" msgid="1289662932759932217">"पिन <xliff:g id="MIN">%1$d</xliff:g>-<xliff:g id="MAX">%2$d</xliff:g> अंकी असणे आवश्‍यक आहे."</string>
<string name="change_pin_confirm_pin_header" msgid="7282604363655862136">"आपल्या पिनची पुष्टी करा"</string>
<string name="change_pin_confirm_pins_dont_match" msgid="8626742552205369433">"पिन जुळत नाहीत"</string>
- <string name="change_pin_succeeded" msgid="6869403202124894671">"व्हॉइसमेल पिन अद्यतनित केला"</string>
+ <string name="change_pin_succeeded" msgid="6869403202124894671">"व्हॉइसमेल पिन अपडेट केला"</string>
<string name="change_pin_system_error" msgid="5762853042379833829">"पिन सेट करण्यात अक्षम"</string>
</resources>
diff --git a/java/com/android/voicemail/impl/res/values-ms/strings.xml b/java/com/android/voicemail/impl/res/values-ms/strings.xml
index b58445126..c44ba38a8 100644
--- a/java/com/android/voicemail/impl/res/values-ms/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ms/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Tukar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Mel suara visual mesti didayakan untuk menukar PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Mel suara visual belum diaktifkan. Sila cuba sebentar lagi"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN Lama"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN Baharu"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Sila tunggu."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"PIN baharu terlalu pendek."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"PIN baharu terlalu panjang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-my/strings.xml b/java/com/android/voicemail/impl/res/values-my/strings.xml
index b29c8521f..d9ef363e3 100644
--- a/java/com/android/voicemail/impl/res/values-my/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-my/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"ပင်နံပါတ် ပြောင်းပါ"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ပင်နံပါတ်ပြောင်းရန် စာသားမှတ်တမ်းပါ အသံမေးလ်ကို ဖွင့်ထားရပါမည်"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"စာသားမှတ်တမ်းပါ အသံမေးလ်ကို မဖွင့်ရသေးပါ၊ နောက်မှ ထပ်ဖွင့်ကြည့်ပါ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"ပင်နံပါတ်အဟောင်း"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"ပင်နံပါတ်အသစ်"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"ခဏစောင့်ပါ။"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"ပင်နံပါတ်အသစ်မှာ တိုလွန်းနေသည်။"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"ပင်နံပါတ်အသစ်မှာ ရှည်လွန်းနေသည်။"</string>
diff --git a/java/com/android/voicemail/impl/res/values-nb/strings.xml b/java/com/android/voicemail/impl/res/values-nb/strings.xml
index b6a1e1c6d..7139887b9 100644
--- a/java/com/android/voicemail/impl/res/values-nb/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-nb/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Endre PIN-koden"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Du må slå på visuell talepost for å endre PIN-koden"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuell talepost er ikke slått på ennå – prøv igjen senere"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Gammel PIN-kode"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Ny PIN-kode"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Vent litt."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Den nye PIN-koden er for kort."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Den nye PIN-koden er for lang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ne/strings.xml b/java/com/android/voicemail/impl/res/values-ne/strings.xml
index f0b4bd88f..44c8bb0fb 100644
--- a/java/com/android/voicemail/impl/res/values-ne/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ne/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN परिवर्तन गर्नुहोस्"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN परिवर्तन गर्न अनिवार्य रूपले भिजुअल भ्वाइस मेललाई सक्षम पारिनुपर्छ"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"भिजुअल भ्वाइस मेललाई अझै सक्रिय पारिएको छैन, कृपया पुन: प्रयास गर्नुहोस्"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"पुरानो PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"नयाँ PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"कृपया प्रतीक्षा गर्नुहोस्।"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"नयाँ PIN अत्यन्त छोटो छ।"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"नयाँ PIN अत्यन्त लामो छ।"</string>
diff --git a/java/com/android/voicemail/impl/res/values-nl/strings.xml b/java/com/android/voicemail/impl/res/values-nl/strings.xml
index f32723b20..1e3788df4 100644
--- a/java/com/android/voicemail/impl/res/values-nl/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-nl/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Pincode wijzigen"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visuele voicemail moet zijn ingeschakeld om de pincode te wijzigen"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuele voicemail is nog niet geactiveerd. Probeer het later opnieuw."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Oude pincode"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nieuwe pincode"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Even geduld."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"De nieuwe pincode is te kort."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"De nieuwe pincode is te lang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-no/strings.xml b/java/com/android/voicemail/impl/res/values-no/strings.xml
index b6a1e1c6d..7139887b9 100644
--- a/java/com/android/voicemail/impl/res/values-no/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-no/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Endre PIN-koden"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Du må slå på visuell talepost for å endre PIN-koden"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuell talepost er ikke slått på ennå – prøv igjen senere"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Gammel PIN-kode"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Ny PIN-kode"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Vent litt."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Den nye PIN-koden er for kort."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Den nye PIN-koden er for lang."</string>
diff --git a/java/com/android/voicemail/impl/res/values-pa/strings.xml b/java/com/android/voicemail/impl/res/values-pa/strings.xml
index 635308577..d65588d50 100644
--- a/java/com/android/voicemail/impl/res/values-pa/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-pa/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN ਬਦਲੋ"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ਦ੍ਰਿਸ਼ਟਾਂਤਕ ਵੌਇਸਮੇਲ ਨੂੰ PIN ਬਦਲਣ ਲਈ ਯੋਗ ਬਣਾਇਆ ਜਾਣਾ ਲਾਜ਼ਮੀ ਹੈ"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ਦ੍ਰਿਸ਼ਟਾਂਤਕ ਵੌਇਸਮੇਲ ਹਾਲੇ ਕਿਰਿਆਸ਼ੀਲ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"ਪੁਰਾਣਾ PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"ਨਵਾਂ PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"ਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕ ਕਰੋ।"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"ਨਵਾਂ PIN ਬਹੁਤ ਹੀ ਛੋਟਾ ਹੈ।"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"ਨਵਾਂ PIN ਬਹੁਤ ਹੀ ਲੰਬਾ ਹੈ।"</string>
diff --git a/java/com/android/voicemail/impl/res/values-pl/strings.xml b/java/com/android/voicemail/impl/res/values-pl/strings.xml
index 17382149a..ae3dcf75d 100644
--- a/java/com/android/voicemail/impl/res/values-pl/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-pl/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Zmień kod PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Aby można było zmienić kod PIN, wizualna poczta głosowa musi być włączona"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Wizualna poczta głosowa nie została jeszcze aktywowana – spróbuj ponownie później"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Stary kod PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nowy kod PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Poczekaj."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Nowy kod PIN jest za krótki."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Nowy kod PIN jest za długi."</string>
diff --git a/java/com/android/voicemail/impl/res/values-pt-rBR/strings.xml b/java/com/android/voicemail/impl/res/values-pt-rBR/strings.xml
index 69f285b15..f2c2f4e38 100644
--- a/java/com/android/voicemail/impl/res/values-pt-rBR/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-pt-rBR/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Alterar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"O correio de voz visual precisa ser ativado para alterar o PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"O correio de voz visual ainda não foi ativado, tente novamente mais tarde"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN antigo"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Novo PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Aguarde."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"O novo PIN é curto demais."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"O novo PIN é longo demais."</string>
diff --git a/java/com/android/voicemail/impl/res/values-pt-rPT/strings.xml b/java/com/android/voicemail/impl/res/values-pt-rPT/strings.xml
index ddff14a3b..b92a54c7b 100644
--- a/java/com/android/voicemail/impl/res/values-pt-rPT/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-pt-rPT/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Alterar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"A mensagem de correio de voz visual tem de estar ativada para poder alterar o PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"A mensagem de correio de voz visual ainda não está ativada. Tente novamente mais tarde"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN antigo"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Novo PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Aguarde."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"O novo PIN é demasiado curto."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"O novo PIN é demasiado longo."</string>
diff --git a/java/com/android/voicemail/impl/res/values-pt/strings.xml b/java/com/android/voicemail/impl/res/values-pt/strings.xml
index 69f285b15..f2c2f4e38 100644
--- a/java/com/android/voicemail/impl/res/values-pt/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-pt/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Alterar PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"O correio de voz visual precisa ser ativado para alterar o PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"O correio de voz visual ainda não foi ativado, tente novamente mais tarde"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN antigo"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Novo PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Aguarde."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"O novo PIN é curto demais."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"O novo PIN é longo demais."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ro/strings.xml b/java/com/android/voicemail/impl/res/values-ro/strings.xml
index 00eee2441..165171bf4 100644
--- a/java/com/android/voicemail/impl/res/values-ro/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ro/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Schimbați codul PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Mesageria vocală vizuală trebuie activată pentru a schimba codul PIN."</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Mesageria vocală vizuală nu este activată încă. Încercați din nou mai târziu."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Codul PIN vechi"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Codul PIN nou"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Așteptați."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Codul PIN nou este prea scurt."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Codul PIN nou este prea lung."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ru/strings.xml b/java/com/android/voicemail/impl/res/values-ru/strings.xml
index 8537ac90a..99a0b5404 100644
--- a/java/com/android/voicemail/impl/res/values-ru/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ru/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Изменение PIN-кода"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Чтобы изменить PIN-код, включите визуальную голосовую почту"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Визуальная голосовая почта пока не активирована, повторите попытку позже"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Прежний PIN-код"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Новый PIN-код"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Подождите…"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Новый PIN-код слишком короткий."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Новый PIN-код слишком длинный."</string>
diff --git a/java/com/android/voicemail/impl/res/values-si/strings.xml b/java/com/android/voicemail/impl/res/values-si/strings.xml
index a72200fee..7879678bf 100644
--- a/java/com/android/voicemail/impl/res/values-si/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-si/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN අංකය වෙනස් කරන්න"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN අංකය වෙනස් කිරීමට දෘශ්‍ය හඬ තැපෑල සබල කළ යුතුය"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"දෘශ්‍ය හඬ තැපෑල තවම සක්‍රිය කර නැත, කරුණාකර පසුව නැවත උත්සාහ කරන්න"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"පැරණි PIN අංකය"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"නව PIN අංකය"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"කරුණාකර රැඳී සිටින්න."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"නව PIN අංකය කෙටි වැඩිය."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"නව PIN අංකය දිග වැඩිය."</string>
diff --git a/java/com/android/voicemail/impl/res/values-sk/strings.xml b/java/com/android/voicemail/impl/res/values-sk/strings.xml
index 8e06b68bb..a6deaa6c3 100644
--- a/java/com/android/voicemail/impl/res/values-sk/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-sk/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Zmena kódu PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN možno zmeniť až po povolení vizuálnej hlasovej schránky"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizuálna hlasová schránka ešte nie je aktivovaná, skúste to znova neskôr"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Starý PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nový PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Čakajte."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Nový PIN je príliš krátky."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Nový PIN je príliš dlhý."</string>
diff --git a/java/com/android/voicemail/impl/res/values-sl/strings.xml b/java/com/android/voicemail/impl/res/values-sl/strings.xml
index a62fa90d3..bf515c0ad 100644
--- a/java/com/android/voicemail/impl/res/values-sl/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-sl/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Sprememba kode PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Če želite spremeniti kodo PIN, morajo biti vizualna sporočila v odzivniku omogočena"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizualna sporočila v odzivniku še niso aktivirana. Poskusite znova pozneje"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Stara koda PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Nova koda PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Počakajte."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Nova koda PIN je prekratka."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Nova koda PIN je predolga."</string>
diff --git a/java/com/android/voicemail/impl/res/values-sq/strings.xml b/java/com/android/voicemail/impl/res/values-sq/strings.xml
index c0f1b1235..09104c886 100644
--- a/java/com/android/voicemail/impl/res/values-sq/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-sq/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Ndrysho kodin PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Duhet të aktivizohet posta zanore vizuale për të ndryshuar kodin PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Posta zanore vizuale nuk është aktivizuar ende. Provo përsëri më vonë"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Kodi PIN i vjetër"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Kodi PIN i ri"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Prit..."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Kodi i ri PIN është shumë i shkurtër."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Kodi i ri PIN është shumë i gjatë."</string>
diff --git a/java/com/android/voicemail/impl/res/values-sr/strings.xml b/java/com/android/voicemail/impl/res/values-sr/strings.xml
index ec6d6a420..ea0ce7b74 100644
--- a/java/com/android/voicemail/impl/res/values-sr/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-sr/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Промените PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Морате да омогућите визуелну говорну пошту да бисте променили PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Визуелна говорна пошта још увек није активирана, пробајте поново касније"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Стари PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Нови PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Сачекајте."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Нови PIN је прекратак."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Нови PIN је предугачак."</string>
diff --git a/java/com/android/voicemail/impl/res/values-sv/strings.xml b/java/com/android/voicemail/impl/res/values-sv/strings.xml
index a23875328..89a1e230a 100644
--- a/java/com/android/voicemail/impl/res/values-sv/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-sv/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Ändra pinkod"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Visuell röstbrevlåda måste vara aktiverat för att ändra pinkoden"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Visuell röstbrevlåda är ännu inte aktiverad, försök igen senare"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Gammal pinkod"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Ny pinkod"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Vänta."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Den nya pinkoden är för kort."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Den nya pinkoden är för lång."</string>
diff --git a/java/com/android/voicemail/impl/res/values-sw/strings.xml b/java/com/android/voicemail/impl/res/values-sw/strings.xml
index d749ddfac..d8c7557ba 100644
--- a/java/com/android/voicemail/impl/res/values-sw/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-sw/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Badilisha PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Lazima uruhusu kipengele cha ujumbe wa sauti unaoonekana ili ubadilishe PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Kipengele cha ujumbe wa sauti unaoonekana bado hakijawashwa, tafadhali jaribu tena baadaye"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN ya zamani"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN mpya"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Tafadhali subiri."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"PIN mpya ni fupi mno."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"PIN mpya ni ndefu mno."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ta/strings.xml b/java/com/android/voicemail/impl/res/values-ta/strings.xml
index de0dc4afc..1b965aa53 100644
--- a/java/com/android/voicemail/impl/res/values-ta/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ta/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"பின்னை மாற்று"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"பின்னை மாற்ற, விஷுவல் குரலஞ்சலை இயக்க வேண்டும்"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"விஷுவல் குரலஞ்சல் இன்னும் இயக்கப்படவில்லை. பிறகு முயலவும்"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"பழைய பின்"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"புதிய பின்"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"காத்திருக்கவும்."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"புதிய பின் மிகவும் சிறியதாக உள்ளது."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"புதிய பின் மிகவும் நீளமாக உள்ளது."</string>
diff --git a/java/com/android/voicemail/impl/res/values-te/strings.xml b/java/com/android/voicemail/impl/res/values-te/strings.xml
index 1459ddc76..089a1ba63 100644
--- a/java/com/android/voicemail/impl/res/values-te/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-te/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PINను మార్చండి"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PINని మార్చడానికి తప్పనిసరిగా దృశ్యమాన వాయిస్ మెయిల్‌ను ప్రారంభించాలి"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"దృశ్యమాన వాయిస్ మెయిల్‌ ఇంకా సక్రియం కాలేదు, దయచేసి తర్వాత మళ్లీ ప్రయత్నించండి"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"పాత PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"కొత్త PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"దయచేసి వేచి ఉండండి."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"కొత్త PIN చాలా చిన్నదిగా ఉంది."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"కొత్త PIN చాలా పొడవుగా ఉంది."</string>
diff --git a/java/com/android/voicemail/impl/res/values-th/strings.xml b/java/com/android/voicemail/impl/res/values-th/strings.xml
index 056800c6f..130ea26ff 100644
--- a/java/com/android/voicemail/impl/res/values-th/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-th/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"เปลี่ยน PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"ต้องเปิดใช้ข้อความเสียงพร้อมภาพเพื่อเปลี่ยน PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"ยังไม่ได้เปิดใช้งานข้อความเสียงพร้อมภาพ โปรดลองอีกครั้งในภายหลัง"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"PIN เก่า"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"PIN ใหม่"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"โปรดรอสักครู่"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"PIN ใหม่สั้นเกินไป"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"PIN ใหม่ยาวเกินไป"</string>
diff --git a/java/com/android/voicemail/impl/res/values-tl/strings.xml b/java/com/android/voicemail/impl/res/values-tl/strings.xml
index c32236231..58d18837a 100644
--- a/java/com/android/voicemail/impl/res/values-tl/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-tl/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Palitan ang PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Dapat naka-enable ang visual na voicemail upang palitan ang PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Hindi pa naka-activate ang visual na voicemail, pakisubukang muli sa ibang pagkakataon"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Lumang PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Bagong PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Pakihintay."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Masyadong maikli ang bagong PIN."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Masyadong mahaba ang bagong PIN."</string>
diff --git a/java/com/android/voicemail/impl/res/values-tr/strings.xml b/java/com/android/voicemail/impl/res/values-tr/strings.xml
index a80b40b99..578cf959a 100644
--- a/java/com/android/voicemail/impl/res/values-tr/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-tr/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN\'i değiştirin"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN\'i değiştirebilmek için görsel sesli mesaj etkinleştirilmelidir"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Görsel sesli mesaj henüz etkinleştirilmedi. Lütfen daha sonra tekrar deneyin."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Eski PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Yeni PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Lütfen bekleyin."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Yeni PIN çok kısa."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Yeni PIN çok uzun."</string>
diff --git a/java/com/android/voicemail/impl/res/values-uk/strings.xml b/java/com/android/voicemail/impl/res/values-uk/strings.xml
index a0b3d8f13..b1d7c1036 100644
--- a/java/com/android/voicemail/impl/res/values-uk/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-uk/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Змінити PIN-код"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Щоб змінити PIN-код, потрібно ввімкнути візуальну голосову пошту"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Візуальну голосову пошту ще не активовано, повторіть спробу пізніше"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Старий PIN-код"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Новий PIN-код"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Зачекайте."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Новий PIN-код закороткий."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Новий PIN-код задовгий."</string>
diff --git a/java/com/android/voicemail/impl/res/values-ur/strings.xml b/java/com/android/voicemail/impl/res/values-ur/strings.xml
index 81f913fbb..7b1f8d329 100644
--- a/java/com/android/voicemail/impl/res/values-ur/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-ur/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"‏PIN تبدیل کریں"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"‏PIN تبدیل کرنے کیلئے بصری صوتی میل اہل ہونی چاہئیے"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"بصری صوتی میل ابھی فعال نہیں ہے، براہ کرم بعد میں دوبارہ کوشش کریں"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"‏پرانا PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"‏نیا PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"براہ کرم انتظار کریں۔"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"‏نیا PIN بہت مختصر ہے۔"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"‏نیا PIN بہت طویل ہے۔"</string>
diff --git a/java/com/android/voicemail/impl/res/values-uz/strings.xml b/java/com/android/voicemail/impl/res/values-uz/strings.xml
index 8771da7f1..92a7536ae 100644
--- a/java/com/android/voicemail/impl/res/values-uz/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-uz/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"PIN kodni o‘zgartirish"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"PIN kodni o‘zgartirish uchun vizual ovozli pochtani yoqish lozim."</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Vizual ovozli pochta yoqilmadi. Keyinroq qayta urinib ko‘ring."</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Eski PIN kod"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Yangi PIN kod"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Iltimos, kuting…"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Yangi PIN kod juda qisqa."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Yangi PIN kod juda uzun."</string>
diff --git a/java/com/android/voicemail/impl/res/values-vi/strings.xml b/java/com/android/voicemail/impl/res/values-vi/strings.xml
index cdca9bb60..972c74c28 100644
--- a/java/com/android/voicemail/impl/res/values-vi/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-vi/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Thay đổi mã PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Phải bật thư thoại kèm theo hình ảnh để thay đổi mã PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Thư thoại kèm theo hình ảnh chưa được kích hoạt, hãy thử lại sau"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"Mã PIN cũ"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"Mã PIN mới"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Vui lòng đợi."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"Mã PIN mới quá ngắn."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"Mã PIN mới quá dài."</string>
diff --git a/java/com/android/voicemail/impl/res/values-zh-rCN/strings.xml b/java/com/android/voicemail/impl/res/values-zh-rCN/strings.xml
index 8b0dde0bd..21edad6f5 100644
--- a/java/com/android/voicemail/impl/res/values-zh-rCN/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-zh-rCN/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"更改 PIN 码"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"必须启用可视语音信箱才可更改 PIN 码"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"可视语音信箱尚未激活,请稍后再试"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"旧 PIN 码"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"新 PIN 码"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"请稍候。"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"新的 PIN 码太短。"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"新的 PIN 码太长。"</string>
diff --git a/java/com/android/voicemail/impl/res/values-zh-rHK/strings.xml b/java/com/android/voicemail/impl/res/values-zh-rHK/strings.xml
index 0ee826952..d80cbba09 100644
--- a/java/com/android/voicemail/impl/res/values-zh-rHK/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-zh-rHK/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"變更 PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"必須啟用視像留言才能變更 PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"視像留言尚未啟用,請稍後再試"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"舊的 PIN"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"新的 PIN"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"請稍候。"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"新的 PIN 太短。"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"新的 PIN 太長。"</string>
diff --git a/java/com/android/voicemail/impl/res/values-zh-rTW/strings.xml b/java/com/android/voicemail/impl/res/values-zh-rTW/strings.xml
index d33c989e2..7d2380679 100644
--- a/java/com/android/voicemail/impl/res/values-zh-rTW/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-zh-rTW/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"變更 PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"必須啟用視覺化語音信箱才能變更 PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"視覺化語音信箱尚未啟用,請稍後再試"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"舊的語音信箱密碼"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"新的語音信箱密碼"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"請稍候。"</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"新的語音信箱密碼太短。"</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"新的語音信箱密碼太長。"</string>
diff --git a/java/com/android/voicemail/impl/res/values-zu/strings.xml b/java/com/android/voicemail/impl/res/values-zu/strings.xml
index b76209178..630f288e2 100644
--- a/java/com/android/voicemail/impl/res/values-zu/strings.xml
+++ b/java/com/android/voicemail/impl/res/values-zu/strings.xml
@@ -26,8 +26,6 @@
<string name="voicemail_change_pin_preference_title" msgid="8944570865151211693">"Shintsha i-PIN"</string>
<string name="voicemail_change_pin_preference_summary_disable" msgid="2787334822298063691">"Ivoyisimeyili ebonakalayo kumele inikwe amandla ukuze ishintshe i-PIN"</string>
<string name="voicemail_change_pin_preference_summary_not_activated" msgid="8794039647258533633">"Ivoyisimeyili ebonakalayo ayisebenzi okwamanje, sicela uzame futhi emuva kwesikhathi"</string>
- <string name="vm_change_pin_old_pin" msgid="3732582036597386047">"I-PIN endala"</string>
- <string name="vm_change_pin_new_pin" msgid="5167496290646066333">"I-PIN entsha"</string>
<string name="vm_change_pin_progress_message" msgid="4143209637626661679">"Sicela ulinde."</string>
<string name="vm_change_pin_error_too_short" msgid="2825020644385639921">"I-PIN entsha imfushane kakhulu."</string>
<string name="vm_change_pin_error_too_long" msgid="683260438529171998">"I-PIN entsha yinde kakhulu."</string>
diff --git a/java/com/android/voicemail/impl/res/values/strings.xml b/java/com/android/voicemail/impl/res/values/strings.xml
index 375a1e9ba..66c0e62b0 100644
--- a/java/com/android/voicemail/impl/res/values/strings.xml
+++ b/java/com/android/voicemail/impl/res/values/strings.xml
@@ -61,11 +61,6 @@
<string name="voicemail_change_pin_preference_summary_disable">Visual voicemail must be enabled to change PIN</string>
<string name="voicemail_change_pin_preference_summary_not_activated">Visual voicemail is not activated yet, please try again later</string>
- <!-- Hint for the old PIN field in the change vociemail PIN dialog -->
- <string name="vm_change_pin_old_pin">Old PIN</string>
- <!-- Hint for the new PIN field in the change vociemail PIN dialog -->
- <string name="vm_change_pin_new_pin">New PIN</string>
-
<!-- Message on the dialog when PIN changing is in progress -->
<string name="vm_change_pin_progress_message">Please wait.</string>
<!-- Error message for the voicemail PIN change if the PIN is too short -->
@@ -107,4 +102,8 @@
<string name="change_pin_succeeded">Voicemail PIN updated</string>
<!-- The error message to show if the server reported an error while attempting to change the voicemail PIN -->
<string name="change_pin_system_error">Unable to set PIN</string>
+
+ <string name="vvm_config_override_load_current_key" translatable="false">vvm_config_override_load_current</string>
+ <string name="vvm_config_override_enabled_key" translatable="false">vvm_config_override_enabled</string>
+
</resources>
diff --git a/java/com/android/voicemail/impl/scheduling/TaskExecutor.java b/java/com/android/voicemail/impl/scheduling/TaskExecutor.java
index e3b718e50..afa77c58c 100644
--- a/java/com/android/voicemail/impl/scheduling/TaskExecutor.java
+++ b/java/com/android/voicemail/impl/scheduling/TaskExecutor.java
@@ -129,7 +129,7 @@ final class TaskExecutor {
private final MainThreadHandler mainThreadHandler;
- private final Context context;
+ private final Context appContext;
/** Main thread only, access through {@link #getTasks()} */
private final TaskQueue tasks = new TaskQueue();
@@ -179,7 +179,7 @@ final class TaskExecutor {
VvmLog.i("JobFinishedPoller.run", "Job finished");
if (!getTasks().isEmpty()) {
TaskSchedulerJobService.scheduleJob(
- context, serializePendingTasks(), delayMillis, isNewJob);
+ appContext, serializePendingTasks(), delayMillis, isNewJob);
tasks.clear();
}
terminate();
@@ -259,7 +259,7 @@ final class TaskExecutor {
}
private TaskExecutor(Context context) {
- this.context = context;
+ this.appContext = context.getApplicationContext();
HandlerThread thread = new HandlerThread("VvmTaskExecutor");
thread.start();
@@ -274,7 +274,7 @@ final class TaskExecutor {
job = null;
workerThreadHandler.getLooper().quit();
instance = null;
- TaskReceiver.resendDeferredBroadcasts(context);
+ TaskReceiver.resendDeferredBroadcasts(appContext);
}
@MainThread
@@ -391,7 +391,7 @@ final class TaskExecutor {
public void onStartJob(Job job, List<Bundle> pendingTasks) {
VvmLog.i(TAG, "onStartJob");
this.job = job;
- tasks.fromBundles(context, pendingTasks);
+ tasks.fromBundles(appContext, pendingTasks);
maybeRunNextTask();
}
diff --git a/java/com/android/voicemail/impl/scheduling/TaskSchedulerJobService.java b/java/com/android/voicemail/impl/scheduling/TaskSchedulerJobService.java
index 107234edc..baf58041f 100644
--- a/java/com/android/voicemail/impl/scheduling/TaskSchedulerJobService.java
+++ b/java/com/android/voicemail/impl/scheduling/TaskSchedulerJobService.java
@@ -30,6 +30,7 @@ import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.support.annotation.MainThread;
import com.android.dialer.constants.ScheduledJobIds;
+import com.android.dialer.strictmode.DialerStrictMode;
import com.android.voicemail.impl.Assert;
import com.android.voicemail.impl.VvmLog;
import java.util.ArrayList;
@@ -58,7 +59,8 @@ public class TaskSchedulerJobService extends JobService implements TaskExecutor.
public boolean onStartJob(JobParameters params) {
int jobId = params.getTransientExtras().getInt(EXTRA_JOB_ID);
int expectedJobId =
- PreferenceManager.getDefaultSharedPreferences(this).getInt(EXPECTED_JOB_ID, 0);
+ DialerStrictMode.bypass(
+ () -> PreferenceManager.getDefaultSharedPreferences(this).getInt(EXPECTED_JOB_ID, 0));
if (jobId != expectedJobId) {
VvmLog.e(
TAG, "Job " + jobId + " is not the last scheduled job " + expectedJobId + ", ignoring");
diff --git a/java/com/android/voicemail/impl/scheduling/TaskSchedulerService.java b/java/com/android/voicemail/impl/scheduling/TaskSchedulerService.java
deleted file mode 100644
index 5ad2447de..000000000
--- a/java/com/android/voicemail/impl/scheduling/TaskSchedulerService.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.voicemail.impl.scheduling;
-
-import android.annotation.TargetApi;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.support.annotation.MainThread;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.annotation.WorkerThread;
-import com.android.voicemail.impl.Assert;
-import com.android.voicemail.impl.NeededForTesting;
-import com.android.voicemail.impl.VvmLog;
-import com.android.voicemail.impl.scheduling.TaskQueue.NextTask;
-import java.util.List;
-
-/**
- * A service to queue and run {@link Task} with the {@link android.app.job.JobScheduler}. A task is
- * queued using {@link Context#startService(Intent)}. The intent should contain enough information
- * in {@link Intent#getExtras()} to construct the task (see {@link Tasks#createIntent(Context,
- * Class)}).
- *
- * <p>All tasks are ran in the background with a wakelock being held by the {@link
- * android.app.job.JobScheduler}, which is between {@link #onStartJob(Job, List)} and {@link
- * #finishJob()}. The {@link TaskSchedulerJobService} also has a {@link TaskQueue}, but the data is
- * stored in the {@link android.app.job.JobScheduler} instead of the process memory, so if the
- * process is killed the queued tasks will be restored. If a new task is added, a new {@link
- * TaskSchedulerJobService} will be scheduled to run the task. If the job is already scheduled, the
- * new task will be pushed into the queue of the scheduled job. If the job is already running, the
- * job will be queued in process memory.
- *
- * <p>Only one task will be ran at a time, and same task cannot exist in the queue at the same time.
- * Refer to {@link TaskQueue} for queuing and execution order.
- *
- * <p>If there are still tasks in the queue but none are executable immediately, the service will
- * enter a "sleep", pushing all remaining task into a new job and end the current job.
- *
- * <p>The service will be started when a intent is received, and stopped when there are no more
- * tasks in the queue.
- *
- * <p>{@link android.app.job.JobScheduler} is not used directly due to:
- *
- * <ul>
- * <li>The {@link android.telecom.PhoneAccountHandle} used to differentiate task can not be easily
- * mapped into an integer for job id
- * <li>A job cannot be mutated to store information such as retry count.
- * </ul>
- */
-@SuppressWarnings("AndroidApiChecker") /* stream() */
-@TargetApi(VERSION_CODES.O)
-public class TaskSchedulerService extends Service {
-
- interface Job {
- void finish();
- }
-
- private static final String TAG = "VvmTaskScheduler";
-
- private static final int READY_TOLERANCE_MILLISECONDS = 100;
-
- /**
- * Threshold to determine whether to do a short or long sleep when a task is scheduled in the
- * future.
- *
- * <p>A short sleep will continue the job and use {@link Handler#postDelayed(Runnable, long)} to
- * wait for the next task.
- *
- * <p>A long sleep will finish the job and schedule a new one. The exact execution time is
- * subjected to {@link android.app.job.JobScheduler} battery optimization, and is not exact.
- */
- private static final int SHORT_SLEEP_THRESHOLD_MILLISECONDS = 10_000;
- /**
- * When there are no more tasks to be run the service should be stopped. But when all tasks has
- * finished there might still be more tasks in the message queue waiting to be processed,
- * especially the ones submitted in {@link Task#onCompleted()}. Wait for a while before stopping
- * the service to make sure there are no pending messages.
- */
- private static final int STOP_DELAY_MILLISECONDS = 5_000;
-
- // The thread to run tasks on
- private volatile WorkerThreadHandler mWorkerThreadHandler;
-
- /**
- * Used by tests to turn task handling into a single threaded process by calling {@link
- * Handler#handleMessage(Message)} directly
- */
- private MessageSender mMessageSender = new MessageSender();
-
- private MainThreadHandler mMainThreadHandler;
-
- // Binder given to clients
- private final IBinder mBinder = new LocalBinder();
-
- /** Main thread only, access through {@link #getTasks()} */
- private final TaskQueue mTasks = new TaskQueue();
-
- private boolean mWorkerThreadIsBusy = false;
-
- private Job mJob;
-
- private final Runnable mStopServiceWithDelay =
- new Runnable() {
- @MainThread
- @Override
- public void run() {
- VvmLog.i(TAG, "Stopping service");
- finishJob();
- stopSelf();
- }
- };
-
- /** Should attempt to run the next task when a task has finished or been added. */
- private boolean mTaskAutoRunDisabledForTesting = false;
-
- @VisibleForTesting
- final class WorkerThreadHandler extends Handler {
-
- public WorkerThreadHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- @WorkerThread
- public void handleMessage(Message msg) {
- Assert.isNotMainThread();
- Task task = (Task) msg.obj;
- try {
- VvmLog.i(TAG, "executing task " + task);
- task.onExecuteInBackgroundThread();
- } catch (Throwable throwable) {
- VvmLog.e(TAG, "Exception while executing task " + task + ":", throwable);
- }
-
- Message schedulerMessage = mMainThreadHandler.obtainMessage();
- schedulerMessage.obj = task;
- mMessageSender.send(schedulerMessage);
- }
- }
-
- @VisibleForTesting
- final class MainThreadHandler extends Handler {
-
- public MainThreadHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- @MainThread
- public void handleMessage(Message msg) {
- Assert.isMainThread();
- Task task = (Task) msg.obj;
- getTasks().remove(task);
- task.onCompleted();
- mWorkerThreadIsBusy = false;
- maybeRunNextTask();
- }
- }
-
- @Override
- @MainThread
- public void onCreate() {
- super.onCreate();
- HandlerThread thread = new HandlerThread("VvmTaskSchedulerService");
- thread.start();
-
- mWorkerThreadHandler = new WorkerThreadHandler(thread.getLooper());
- mMainThreadHandler = new MainThreadHandler(Looper.getMainLooper());
- }
-
- @Override
- public void onDestroy() {
- mWorkerThreadHandler.getLooper().quit();
- }
-
- @Override
- @MainThread
- public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
- Assert.isMainThread();
- if (intent == null) {
- VvmLog.w(TAG, "null intent received");
- return START_NOT_STICKY;
- }
- Task task = Tasks.createTask(this, intent.getExtras());
- Assert.isTrue(task != null);
- addTask(task);
-
- mMainThreadHandler.removeCallbacks(mStopServiceWithDelay);
- VvmLog.i(TAG, "task added");
- if (mJob == null) {
- scheduleJob(0, true);
- } else {
- maybeRunNextTask();
- }
- // STICKY means the service will be automatically restarted will the last intent if it is
- // killed.
- return START_NOT_STICKY;
- }
-
- @MainThread
- @VisibleForTesting
- void addTask(Task task) {
- Assert.isMainThread();
- getTasks().add(task);
- }
-
- @MainThread
- @VisibleForTesting
- TaskQueue getTasks() {
- Assert.isMainThread();
- return mTasks;
- }
-
- @MainThread
- private void maybeRunNextTask() {
- Assert.isMainThread();
- if (mWorkerThreadIsBusy) {
- return;
- }
- if (mTaskAutoRunDisabledForTesting) {
- // If mTaskAutoRunDisabledForTesting is true, runNextTask() must be explicitly called
- // to run the next task.
- return;
- }
-
- runNextTask();
- }
-
- @VisibleForTesting
- @MainThread
- void runNextTask() {
- Assert.isMainThread();
- if (getTasks().isEmpty()) {
- prepareStop();
- return;
- }
- NextTask nextTask = getTasks().getNextTask(READY_TOLERANCE_MILLISECONDS);
-
- if (nextTask.task != null) {
- nextTask.task.onBeforeExecute();
- Message message = mWorkerThreadHandler.obtainMessage();
- message.obj = nextTask.task;
- mWorkerThreadIsBusy = true;
- mMessageSender.send(message);
- return;
- }
- VvmLog.i(TAG, "minimal wait time:" + nextTask.minimalWaitTimeMillis);
- if (!mTaskAutoRunDisabledForTesting && nextTask.minimalWaitTimeMillis != null) {
- // No tasks are currently ready. Sleep until the next one should be.
- // If a new task is added during the sleep the service will wake immediately.
- sleep(nextTask.minimalWaitTimeMillis);
- }
- }
-
- @MainThread
- private void sleep(long timeMillis) {
- VvmLog.i(TAG, "sleep for " + timeMillis + " millis");
- if (timeMillis < SHORT_SLEEP_THRESHOLD_MILLISECONDS) {
- mMainThreadHandler.postDelayed(
- new Runnable() {
- @Override
- public void run() {
- maybeRunNextTask();
- }
- },
- timeMillis);
- return;
- }
- finishJob();
- mMainThreadHandler.post(() -> scheduleJob(timeMillis, false));
- }
-
- private List<Bundle> serializePendingTasks() {
- return getTasks().toBundles();
- }
-
- private void prepareStop() {
- VvmLog.i(
- TAG,
- "no more tasks, stopping service if no task are added in "
- + STOP_DELAY_MILLISECONDS
- + " millis");
- mMainThreadHandler.postDelayed(mStopServiceWithDelay, STOP_DELAY_MILLISECONDS);
- }
-
- @NeededForTesting
- static class MessageSender {
-
- public void send(Message message) {
- message.sendToTarget();
- }
- }
-
- @NeededForTesting
- void setTaskAutoRunDisabledForTest(boolean value) {
- mTaskAutoRunDisabledForTesting = value;
- }
-
- @NeededForTesting
- void setMessageSenderForTest(MessageSender sender) {
- mMessageSender = sender;
- }
-
- /**
- * The {@link TaskSchedulerJobService} has started and all queued task should be executed in the
- * worker thread.
- */
- @MainThread
- public void onStartJob(Job job, List<Bundle> pendingTasks) {
- VvmLog.i(TAG, "onStartJob");
- mJob = job;
- mTasks.fromBundles(this, pendingTasks);
- maybeRunNextTask();
- }
-
- /**
- * The {@link TaskSchedulerJobService} is being terminated by the system (timeout or network
- * lost). A new job will be queued to resume all pending tasks. The current unfinished job may be
- * ran again.
- */
- @MainThread
- public void onStopJob() {
- VvmLog.e(TAG, "onStopJob");
- if (isJobRunning()) {
- finishJob();
- mMainThreadHandler.post(() -> scheduleJob(0, true));
- }
- }
-
- /**
- * Serializes all pending tasks and schedule a new {@link TaskSchedulerJobService}.
- *
- * @param delayMillis the delay before stating the job, see {@link
- * android.app.job.JobInfo.Builder#setMinimumLatency(long)}. This must be 0 if {@code
- * isNewJob} is true.
- * @param isNewJob a new job will be requested to run immediately, bypassing all requirements.
- */
- @MainThread
- private void scheduleJob(long delayMillis, boolean isNewJob) {
- Assert.isMainThread();
- TaskSchedulerJobService.scheduleJob(this, serializePendingTasks(), delayMillis, isNewJob);
- mTasks.clear();
- }
-
- /**
- * Signals {@link TaskSchedulerJobService} the current session of tasks has finished, and the wake
- * lock can be released. Note: this only takes effect after the main thread has been returned. If
- * a new job need to be scheduled, it should be posted on the main thread handler instead of
- * calling directly.
- */
- @MainThread
- private void finishJob() {
- Assert.isMainThread();
- VvmLog.i(TAG, "finishing Job");
- mJob.finish();
- mJob = null;
- }
-
- @Override
- @Nullable
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- @NeededForTesting
- class LocalBinder extends Binder {
-
- @NeededForTesting
- public TaskSchedulerService getService() {
- return TaskSchedulerService.this;
- }
- }
-
- private boolean isJobRunning() {
- return mJob != null;
- }
-}
diff --git a/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java b/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java
index ac5f3cac9..4860649b3 100644
--- a/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java
+++ b/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java
@@ -22,6 +22,7 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
+import android.provider.Settings;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
@@ -29,7 +30,6 @@ import com.android.dialer.common.Assert;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.notification.NotificationChannelManager;
-import com.android.dialer.notification.NotificationChannelManager.Channel;
import com.android.voicemail.VoicemailClient;
import com.android.voicemail.VoicemailComponent;
import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper;
@@ -43,8 +43,7 @@ import com.android.voicemail.impl.sync.VvmAccountManager;
*/
@TargetApi(VERSION_CODES.O)
public class VoicemailSettingsFragment extends PreferenceFragment
- implements Preference.OnPreferenceChangeListener,
- VvmAccountManager.Listener {
+ implements Preference.OnPreferenceChangeListener, VvmAccountManager.Listener {
private static final String TAG = "VmSettingsActivity";
@@ -83,9 +82,8 @@ public class VoicemailSettingsFragment extends PreferenceFragment
voicemailNotificationPreference =
findPreference(getString(R.string.voicemail_notifications_key));
- voicemailNotificationPreference.setIntent(
- NotificationChannelManager.getInstance()
- .getSettingsIntentForChannel(getContext(), Channel.VOICEMAIL, phoneAccountHandle));
+ voicemailNotificationPreference.setIntent(getNotificationSettingsIntent());
+
voicemailNotificationPreference.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
@Override
@@ -233,4 +231,12 @@ public class VoicemailSettingsFragment extends PreferenceFragment
updateChangePin();
}
}
+
+ private Intent getNotificationSettingsIntent() {
+ String channelId =
+ NotificationChannelManager.getVoicemailChannelId(getContext(), phoneAccountHandle);
+ return new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
+ .putExtra(Settings.EXTRA_CHANNEL_ID, channelId)
+ .putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());
+ }
}
diff --git a/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java b/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java
index 5decf6376..e902825c0 100644
--- a/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java
+++ b/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java
@@ -79,6 +79,7 @@ public class LegacyModeSmsHandler {
VvmLog.i(TAG, "sending voicemail notification");
Intent intent = new Intent(VoicemailClient.ACTION_SHOW_LEGACY_VOICEMAIL);
intent.setPackage(context.getPackageName());
+ intent.putExtra(VoicemailClient.EXTRA_IS_LEGACY_MODE, true);
intent.putExtra(TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
// Setting voicemail message count to non-zero will show the telephony voicemail
// notification, and zero will clear it.
diff --git a/java/com/android/voicemail/impl/sms/OmtpMessageReceiver.java b/java/com/android/voicemail/impl/sms/OmtpMessageReceiver.java
index ef0bf10e9..43835276b 100644
--- a/java/com/android/voicemail/impl/sms/OmtpMessageReceiver.java
+++ b/java/com/android/voicemail/impl/sms/OmtpMessageReceiver.java
@@ -35,7 +35,6 @@ import com.android.voicemail.impl.Voicemail.Builder;
import com.android.voicemail.impl.VvmLog;
import com.android.voicemail.impl.protocol.VisualVoicemailProtocol;
import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
-import com.android.voicemail.impl.sync.OmtpVvmSyncService;
import com.android.voicemail.impl.sync.SyncOneTask;
import com.android.voicemail.impl.sync.SyncTask;
import com.android.voicemail.impl.sync.VoicemailsQueryHelper;
@@ -71,6 +70,10 @@ public class OmtpMessageReceiver extends BroadcastReceiver {
}
OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(mContext, phone);
+ if (!helper.isValid()) {
+ VvmLog.e(TAG, "vvm config no longer valid");
+ return;
+ }
if (!VisualVoicemailSettingsUtil.isEnabled(mContext, phone)) {
if (helper.isLegacyModeEnabled()) {
LegacyModeSmsHandler.handle(context, sms);
@@ -148,7 +151,7 @@ public class OmtpMessageReceiver extends BroadcastReceiver {
}
break;
case OmtpConstants.MAILBOX_UPDATE:
- SyncTask.start(mContext, phone, OmtpVvmSyncService.SYNC_DOWNLOAD_ONLY);
+ SyncTask.start(mContext, phone);
break;
case OmtpConstants.GREETINGS_UPDATE:
// Not implemented in V1
diff --git a/java/com/android/voicemail/impl/sms/OmtpMessageSender.java b/java/com/android/voicemail/impl/sms/OmtpMessageSender.java
index e9d145cde..19661e99d 100644
--- a/java/com/android/voicemail/impl/sms/OmtpMessageSender.java
+++ b/java/com/android/voicemail/impl/sms/OmtpMessageSender.java
@@ -22,6 +22,7 @@ import android.telecom.PhoneAccountHandle;
import android.telephony.SmsManager;
import com.android.voicemail.impl.OmtpConstants;
import com.android.voicemail.impl.TelephonyMangerCompat;
+import com.android.voicemail.impl.VvmLog;
/**
* Send client originated OMTP messages to the OMTP server.
@@ -75,6 +76,11 @@ public abstract class OmtpMessageSender {
public void requestVvmStatus(@Nullable PendingIntent sentIntent) {}
protected void sendSms(String text, PendingIntent sentIntent) {
+
+ VvmLog.v(
+ TAG,
+ String.format("Sending sms '%s' to %s:%d", text, mDestinationNumber, mApplicationPort));
+
TelephonyMangerCompat.sendVisualVoicemailSms(
mContext, mPhoneAccountHandle, mDestinationNumber, mApplicationPort, text, sentIntent);
}
diff --git a/java/com/android/voicemail/impl/sync/OmtpVvmSyncReceiver.java b/java/com/android/voicemail/impl/sync/OmtpVvmSyncReceiver.java
index b2ec49e9f..1b59eccfc 100644
--- a/java/com/android/voicemail/impl/sync/OmtpVvmSyncReceiver.java
+++ b/java/com/android/voicemail/impl/sync/OmtpVvmSyncReceiver.java
@@ -52,7 +52,7 @@ public class OmtpVvmSyncReceiver extends BroadcastReceiver {
VvmLog.i(TAG, "Unactivated account " + phoneAccount + " found, activating");
ActivationTask.start(context, phoneAccount, null);
} else {
- SyncTask.start(context, phoneAccount, OmtpVvmSyncService.SYNC_FULL_SYNC);
+ SyncTask.start(context, phoneAccount);
}
}
}
diff --git a/java/com/android/voicemail/impl/sync/OmtpVvmSyncService.java b/java/com/android/voicemail/impl/sync/OmtpVvmSyncService.java
index 793388362..5b5d6b054 100644
--- a/java/com/android/voicemail/impl/sync/OmtpVvmSyncService.java
+++ b/java/com/android/voicemail/impl/sync/OmtpVvmSyncService.java
@@ -43,6 +43,7 @@ import com.android.voicemail.impl.sync.VvmNetworkRequest.NetworkWrapper;
import com.android.voicemail.impl.sync.VvmNetworkRequest.RequestFailedException;
import com.android.voicemail.impl.utils.LoggerUtils;
import com.android.voicemail.impl.utils.VoicemailDatabaseUtil;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -50,22 +51,13 @@ import java.util.Map;
@TargetApi(VERSION_CODES.O)
public class OmtpVvmSyncService {
- private static final String TAG = OmtpVvmSyncService.class.getSimpleName();
+ private static final String TAG = "OmtpVvmSyncService";
- /** Signifies a sync with both uploading to the server and downloading from the server. */
- public static final String SYNC_FULL_SYNC = "full_sync";
- /** Only upload to the server. */
- public static final String SYNC_UPLOAD_ONLY = "upload_only";
- /** Only download from the server. */
- public static final String SYNC_DOWNLOAD_ONLY = "download_only";
- /** Only download single voicemail transcription. */
- public static final String SYNC_DOWNLOAD_ONE_TRANSCRIPTION = "download_one_transcription";
/** Threshold for whether we should archive and delete voicemails from the remote VM server. */
private static final float AUTO_DELETE_ARCHIVE_VM_THRESHOLD = 0.75f;
private final Context mContext;
-
- private VoicemailsQueryHelper mQueryHelper;
+ private final VoicemailsQueryHelper mQueryHelper;
public OmtpVvmSyncService(Context context) {
mContext = context;
@@ -74,23 +66,21 @@ public class OmtpVvmSyncService {
public void sync(
BaseTask task,
- String action,
PhoneAccountHandle phoneAccount,
Voicemail voicemail,
VoicemailStatus.Editor status) {
Assert.isTrue(phoneAccount != null);
- VvmLog.v(TAG, "Sync requested: " + action + " - for account: " + phoneAccount);
- setupAndSendRequest(task, phoneAccount, voicemail, action, status);
+ VvmLog.v(TAG, "Sync requested for account: " + phoneAccount);
+ setupAndSendRequest(task, phoneAccount, voicemail, status);
}
private void setupAndSendRequest(
BaseTask task,
PhoneAccountHandle phoneAccount,
Voicemail voicemail,
- String action,
VoicemailStatus.Editor status) {
if (!VisualVoicemailSettingsUtil.isEnabled(mContext, phoneAccount)) {
- VvmLog.v(TAG, "Sync requested for disabled account");
+ VvmLog.e(TAG, "Sync requested for disabled account");
return;
}
if (!VvmAccountManager.isAccountActivated(mContext, phoneAccount)) {
@@ -102,7 +92,7 @@ public class OmtpVvmSyncService {
LoggerUtils.logImpressionOnMainThread(mContext, DialerImpression.Type.VVM_SYNC_STARTED);
// DATA_IMAP_OPERATION_STARTED posting should not be deferred. This event clears all data
// channel errors, which should happen when the task starts, not when it ends. It is the
- // "Sync in progress..." status.
+ // "Sync in progress..." status, which is currently displayed to the user as no error.
config.handleEvent(
VoicemailStatus.edit(mContext, phoneAccount), OmtpEvents.DATA_IMAP_OPERATION_STARTED);
try (NetworkWrapper network = VvmNetworkRequest.getNetwork(config, phoneAccount, status)) {
@@ -111,7 +101,7 @@ public class OmtpVvmSyncService {
task.fail();
return;
}
- doSync(task, network.get(), phoneAccount, voicemail, action, status);
+ doSync(task, network.get(), phoneAccount, voicemail, status);
} catch (RequestFailedException e) {
config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
task.fail();
@@ -123,14 +113,13 @@ public class OmtpVvmSyncService {
Network network,
PhoneAccountHandle phoneAccount,
Voicemail voicemail,
- String action,
VoicemailStatus.Editor status) {
try (ImapHelper imapHelper = new ImapHelper(mContext, phoneAccount, network, status)) {
boolean success;
if (voicemail == null) {
- success = syncAll(action, imapHelper, phoneAccount);
+ success = syncAll(imapHelper, phoneAccount);
} else {
- success = syncOne(imapHelper, voicemail, phoneAccount);
+ success = downloadOneVoicemail(imapHelper, voicemail, phoneAccount);
}
if (success) {
// TODO: b/30569269 failure should interrupt all subsequent task via exceptions
@@ -219,79 +208,33 @@ public class OmtpVvmSyncService {
}
}
- private boolean syncAll(String action, ImapHelper imapHelper, PhoneAccountHandle account) {
- boolean uploadSuccess = true;
- boolean downloadSuccess = true;
-
- if (SYNC_FULL_SYNC.equals(action) || SYNC_UPLOAD_ONLY.equals(action)) {
- uploadSuccess = upload(account, imapHelper);
- }
- if (SYNC_FULL_SYNC.equals(action) || SYNC_DOWNLOAD_ONLY.equals(action)) {
- downloadSuccess = download(imapHelper, account);
- }
+ private boolean syncAll(ImapHelper imapHelper, PhoneAccountHandle account) {
- VvmLog.v(
- TAG,
- "upload succeeded: ["
- + String.valueOf(uploadSuccess)
- + "] download succeeded: ["
- + String.valueOf(downloadSuccess)
- + "]");
-
- return uploadSuccess && downloadSuccess;
- }
+ List<Voicemail> serverVoicemails = imapHelper.fetchAllVoicemails();
+ List<Voicemail> localVoicemails = mQueryHelper.getAllVoicemails(account);
+ List<Voicemail> deletedVoicemails = mQueryHelper.getDeletedVoicemails(account);
+ boolean succeeded = true;
- private boolean syncOne(ImapHelper imapHelper, Voicemail voicemail, PhoneAccountHandle account) {
- if (shouldPerformPrefetch(account, imapHelper)) {
- VoicemailFetchedCallback callback =
- new VoicemailFetchedCallback(mContext, voicemail.getUri(), account);
- imapHelper.fetchVoicemailPayload(callback, voicemail.getSourceData());
+ if (localVoicemails == null || serverVoicemails == null) {
+ // Null value means the query failed.
+ VvmLog.e(TAG, "syncAll: query failed");
+ return false;
}
- return imapHelper.fetchTranscription(
- new TranscriptionFetchedCallback(mContext, voicemail), voicemail.getSourceData());
- }
-
- private boolean upload(PhoneAccountHandle phoneAccountHandle, ImapHelper imapHelper) {
- List<Voicemail> readVoicemails = mQueryHelper.getReadVoicemails(phoneAccountHandle);
- List<Voicemail> deletedVoicemails = mQueryHelper.getDeletedVoicemails(phoneAccountHandle);
-
- boolean success = true;
-
if (deletedVoicemails.size() > 0) {
if (imapHelper.markMessagesAsDeleted(deletedVoicemails)) {
- // We want to delete selectively instead of all the voicemails for this provider
- // in case the state changed since the IMAP query was completed.
+ // Delete only the voicemails that was deleted on the server, in case more are deleted
+ // since the IMAP query was completed.
mQueryHelper.deleteFromDatabase(deletedVoicemails);
} else {
- success = false;
+ succeeded = false;
}
}
- if (readVoicemails.size() > 0) {
- VvmLog.i(TAG, "Marking voicemails as read");
- if (imapHelper.markMessagesAsRead(readVoicemails)) {
- VvmLog.i(TAG, "Marking voicemails as clean");
- mQueryHelper.markCleanInDatabase(readVoicemails);
- } else {
- success = false;
- }
- }
-
- return success;
- }
-
- private boolean download(ImapHelper imapHelper, PhoneAccountHandle account) {
- List<Voicemail> serverVoicemails = imapHelper.fetchAllVoicemails();
- List<Voicemail> localVoicemails = mQueryHelper.getAllVoicemails(account);
-
- if (localVoicemails == null || serverVoicemails == null) {
- // Null value means the query failed.
- return false;
- }
-
Map<String, Voicemail> remoteMap = buildMap(serverVoicemails);
+ List<Voicemail> localReadVoicemails = new ArrayList<>();
+
// Go through all the local voicemails and check if they are on the server.
// They may be read or deleted on the server but not locally. Perform the
// appropriate local operation if the status differs from the server. Remove
@@ -310,6 +253,8 @@ public class OmtpVvmSyncService {
} else {
if (remoteVoicemail.isRead() && !localVoicemail.isRead()) {
mQueryHelper.markReadInDatabase(localVoicemail);
+ } else if (localVoicemail.isRead() && !remoteVoicemail.isRead()) {
+ localReadVoicemails.add(localVoicemail);
}
if (!TextUtils.isEmpty(remoteVoicemail.getTranscription())
@@ -321,6 +266,16 @@ public class OmtpVvmSyncService {
}
}
+ if (localReadVoicemails.size() > 0) {
+ VvmLog.i(TAG, "Marking voicemails as read");
+ if (imapHelper.markMessagesAsRead(localReadVoicemails)) {
+ VvmLog.i(TAG, "Marking voicemails as clean");
+ mQueryHelper.markCleanInDatabase(localReadVoicemails);
+ } else {
+ return false;
+ }
+ }
+
// The leftover messages are messages that exist on the server but not locally.
boolean prefetchEnabled = shouldPerformPrefetch(account, imapHelper);
for (Voicemail remoteVoicemail : remoteMap.values()) {
@@ -336,7 +291,19 @@ public class OmtpVvmSyncService {
}
}
- return true;
+ return succeeded;
+ }
+
+ private boolean downloadOneVoicemail(
+ ImapHelper imapHelper, Voicemail voicemail, PhoneAccountHandle account) {
+ if (shouldPerformPrefetch(account, imapHelper)) {
+ VoicemailFetchedCallback callback =
+ new VoicemailFetchedCallback(mContext, voicemail.getUri(), account);
+ imapHelper.fetchVoicemailPayload(callback, voicemail.getSourceData());
+ }
+
+ return imapHelper.fetchTranscription(
+ new TranscriptionFetchedCallback(mContext, voicemail), voicemail.getSourceData());
}
private boolean shouldPerformPrefetch(PhoneAccountHandle account, ImapHelper imapHelper) {
diff --git a/java/com/android/voicemail/impl/sync/SyncOneTask.java b/java/com/android/voicemail/impl/sync/SyncOneTask.java
index cd2782abb..70c6bd890 100644
--- a/java/com/android/voicemail/impl/sync/SyncOneTask.java
+++ b/java/com/android/voicemail/impl/sync/SyncOneTask.java
@@ -39,17 +39,14 @@ public class SyncOneTask extends BaseTask {
private static final int RETRY_INTERVAL_MILLIS = 5_000;
private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle";
- private static final String EXTRA_SYNC_TYPE = "extra_sync_type";
private static final String EXTRA_VOICEMAIL = "extra_voicemail";
private PhoneAccountHandle mPhone;
- private String mSyncType;
private Voicemail mVoicemail;
public static void start(Context context, PhoneAccountHandle phone, Voicemail voicemail) {
Intent intent = BaseTask.createIntent(context, SyncOneTask.class, phone);
intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phone);
- intent.putExtra(EXTRA_SYNC_TYPE, OmtpVvmSyncService.SYNC_DOWNLOAD_ONE_TRANSCRIPTION);
intent.putExtra(EXTRA_VOICEMAIL, voicemail);
context.sendBroadcast(intent);
}
@@ -63,14 +60,13 @@ public class SyncOneTask extends BaseTask {
public void onCreate(Context context, Bundle extras) {
super.onCreate(context, extras);
mPhone = extras.getParcelable(EXTRA_PHONE_ACCOUNT_HANDLE);
- mSyncType = extras.getString(EXTRA_SYNC_TYPE);
mVoicemail = extras.getParcelable(EXTRA_VOICEMAIL);
}
@Override
public void onExecuteInBackgroundThread() {
OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
- service.sync(this, mSyncType, mPhone, mVoicemail, VoicemailStatus.edit(getContext(), mPhone));
+ service.sync(this, mPhone, mVoicemail, VoicemailStatus.edit(getContext(), mPhone));
}
@Override
@@ -78,7 +74,6 @@ public class SyncOneTask extends BaseTask {
LoggerUtils.logImpressionOnMainThread(getContext(), DialerImpression.Type.VVM_AUTO_RETRY_SYNC);
Intent intent = super.createRestartIntent();
intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, mPhone);
- intent.putExtra(EXTRA_SYNC_TYPE, mSyncType);
intent.putExtra(EXTRA_VOICEMAIL, mVoicemail);
return intent;
}
diff --git a/java/com/android/voicemail/impl/sync/SyncTask.java b/java/com/android/voicemail/impl/sync/SyncTask.java
index 0b3e090bf..68ce0122e 100644
--- a/java/com/android/voicemail/impl/sync/SyncTask.java
+++ b/java/com/android/voicemail/impl/sync/SyncTask.java
@@ -37,17 +37,14 @@ public class SyncTask extends BaseTask {
private static final int MINIMAL_INTERVAL_MILLIS = 60_000;
private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle";
- private static final String EXTRA_SYNC_TYPE = "extra_sync_type";
private final RetryPolicy mRetryPolicy;
private PhoneAccountHandle mPhone;
- private String mSyncType;
- public static void start(Context context, PhoneAccountHandle phone, String syncType) {
+ public static void start(Context context, PhoneAccountHandle phone) {
Intent intent = BaseTask.createIntent(context, SyncTask.class, phone);
intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phone);
- intent.putExtra(EXTRA_SYNC_TYPE, syncType);
context.sendBroadcast(intent);
}
@@ -62,13 +59,12 @@ public class SyncTask extends BaseTask {
public void onCreate(Context context, Bundle extras) {
super.onCreate(context, extras);
mPhone = extras.getParcelable(EXTRA_PHONE_ACCOUNT_HANDLE);
- mSyncType = extras.getString(EXTRA_SYNC_TYPE);
}
@Override
public void onExecuteInBackgroundThread() {
OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
- service.sync(this, mSyncType, mPhone, null, mRetryPolicy.getVoicemailStatusEditor());
+ service.sync(this, mPhone, null, mRetryPolicy.getVoicemailStatusEditor());
}
@Override
@@ -76,7 +72,6 @@ public class SyncTask extends BaseTask {
LoggerUtils.logImpressionOnMainThread(getContext(), DialerImpression.Type.VVM_AUTO_RETRY_SYNC);
Intent intent = super.createRestartIntent();
intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, mPhone);
- intent.putExtra(EXTRA_SYNC_TYPE, mSyncType);
return intent;
}
}
diff --git a/java/com/android/voicemail/impl/sync/UploadTask.java b/java/com/android/voicemail/impl/sync/UploadTask.java
index f2b2036b5..d8f06db47 100644
--- a/java/com/android/voicemail/impl/sync/UploadTask.java
+++ b/java/com/android/voicemail/impl/sync/UploadTask.java
@@ -63,10 +63,6 @@ public class UploadTask extends BaseTask {
return;
}
service.sync(
- this,
- OmtpVvmSyncService.SYNC_UPLOAD_ONLY,
- phoneAccountHandle,
- null,
- VoicemailStatus.edit(getContext(), phoneAccountHandle));
+ this, phoneAccountHandle, null, VoicemailStatus.edit(getContext(), phoneAccountHandle));
}
}
diff --git a/java/com/android/voicemail/impl/sync/VoicemailsQueryHelper.java b/java/com/android/voicemail/impl/sync/VoicemailsQueryHelper.java
index 9b295dbb7..316e1ca61 100644
--- a/java/com/android/voicemail/impl/sync/VoicemailsQueryHelper.java
+++ b/java/com/android/voicemail/impl/sync/VoicemailsQueryHelper.java
@@ -49,8 +49,6 @@ public class VoicemailsQueryHelper {
public static final int DELETED = 3;
public static final int TRANSCRIPTION = 4;
- static final String READ_SELECTION =
- Voicemails.DIRTY + "=1 AND " + Voicemails.DELETED + "!=1 AND " + Voicemails.IS_READ + "=1";
static final String DELETED_SELECTION = Voicemails.DELETED + "=1";
static final String ARCHIVED_SELECTION = Voicemails.ARCHIVED + "=0";
@@ -65,15 +63,6 @@ public class VoicemailsQueryHelper {
}
/**
- * Get all the local read voicemails that have not been synced to the server.
- *
- * @return A list of read voicemails.
- */
- public List<Voicemail> getReadVoicemails(@NonNull PhoneAccountHandle phoneAccountHandle) {
- return getLocalVoicemails(phoneAccountHandle, READ_SELECTION);
- }
-
- /**
* Get all the locally deleted voicemails that have not been synced to the server.
*
* @return A list of deleted voicemails.
diff --git a/java/com/android/voicemail/impl/sync/VvmAccountManager.java b/java/com/android/voicemail/impl/sync/VvmAccountManager.java
index cc4e31fe3..2625fba0c 100644
--- a/java/com/android/voicemail/impl/sync/VvmAccountManager.java
+++ b/java/com/android/voicemail/impl/sync/VvmAccountManager.java
@@ -15,14 +15,20 @@
*/
package com.android.voicemail.impl.sync;
+import android.annotation.TargetApi;
import android.content.Context;
+import android.os.Build.VERSION_CODES;
+import android.os.UserManager;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.util.ArraySet;
import com.android.dialer.common.Assert;
+import com.android.dialer.common.PerAccountSharedPreferences;
import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.util.DialerUtils;
import com.android.voicemail.impl.OmtpConstants;
import com.android.voicemail.impl.VisualVoicemailPreferences;
import com.android.voicemail.impl.VoicemailStatus;
@@ -40,6 +46,7 @@ import java.util.Set;
* #removeAccount(Context, PhoneAccountHandle)} should be called to clear the connection information
* and allow reactivation.
*/
+@TargetApi(VERSION_CODES.O)
public class VvmAccountManager {
public static final String TAG = "VvmAccountManager";
@@ -49,7 +56,7 @@ public class VvmAccountManager {
void onActivationStateChanged(PhoneAccountHandle phoneAccountHandle, boolean isActivated);
}
- private static final String IS_ACCOUNT_ACTIVATED = "is_account_activated";
+ @VisibleForTesting static final String IS_ACCOUNT_ACTIVATED = "is_account_activated";
private static Set<Listener> listeners = new ArraySet<>();
@@ -57,7 +64,8 @@ public class VvmAccountManager {
Context context, PhoneAccountHandle phoneAccountHandle, StatusMessage statusMessage) {
VisualVoicemailPreferences preferences =
new VisualVoicemailPreferences(context, phoneAccountHandle);
- statusMessage.putStatus(preferences.edit()).putBoolean(IS_ACCOUNT_ACTIVATED, true).apply();
+ statusMessage.putStatus(preferences.edit()).apply();
+ setAccountActivated(context, phoneAccountHandle, true);
ThreadUtil.postOnUiThread(
() -> {
@@ -69,10 +77,10 @@ public class VvmAccountManager {
public static void removeAccount(Context context, PhoneAccountHandle phoneAccount) {
VoicemailStatus.disable(context, phoneAccount);
+ setAccountActivated(context, phoneAccount, false);
VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(context, phoneAccount);
preferences
.edit()
- .putBoolean(IS_ACCOUNT_ACTIVATED, false)
.putString(OmtpConstants.IMAP_USER_NAME, null)
.putString(OmtpConstants.IMAP_PASSWORD, null)
.apply();
@@ -86,7 +94,9 @@ public class VvmAccountManager {
public static boolean isAccountActivated(Context context, PhoneAccountHandle phoneAccount) {
Assert.isNotNull(phoneAccount);
- VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(context, phoneAccount);
+ PerAccountSharedPreferences preferences =
+ getPreferenceForActivationState(context, phoneAccount);
+ migrateActivationState(context, preferences, phoneAccount);
return preferences.getBoolean(IS_ACCOUNT_ACTIVATED, false);
}
@@ -113,4 +123,47 @@ public class VvmAccountManager {
Assert.isMainThread();
listeners.remove(listener);
}
+
+ /**
+ * The activation state is moved from credential protected storage to device protected storage
+ * after v10, so it can be checked under FBE. The state should be migrated to avoid reactivation.
+ */
+ private static void migrateActivationState(
+ Context context,
+ PerAccountSharedPreferences deviceProtectedPreference,
+ PhoneAccountHandle phoneAccountHandle) {
+ if (!context.getSystemService(UserManager.class).isUserUnlocked()) {
+ return;
+ }
+ if (deviceProtectedPreference.contains(IS_ACCOUNT_ACTIVATED)) {
+ return;
+ }
+
+ PerAccountSharedPreferences credentialProtectedPreference =
+ new VisualVoicemailPreferences(context, phoneAccountHandle);
+
+ deviceProtectedPreference
+ .edit()
+ .putBoolean(
+ IS_ACCOUNT_ACTIVATED,
+ credentialProtectedPreference.getBoolean(IS_ACCOUNT_ACTIVATED, false))
+ .apply();
+ }
+
+ private static void setAccountActivated(
+ Context context, PhoneAccountHandle phoneAccountHandle, boolean activated) {
+ Assert.isNotNull(phoneAccountHandle);
+ getPreferenceForActivationState(context, phoneAccountHandle)
+ .edit()
+ .putBoolean(IS_ACCOUNT_ACTIVATED, activated)
+ .apply();
+ }
+
+ private static PerAccountSharedPreferences getPreferenceForActivationState(
+ Context context, PhoneAccountHandle phoneAccountHandle) {
+ return new PerAccountSharedPreferences(
+ context,
+ phoneAccountHandle,
+ DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context));
+ }
}
diff --git a/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java b/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java
index 067eff803..068b19b70 100644
--- a/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java
+++ b/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java
@@ -128,7 +128,7 @@ public abstract class VvmNetworkRequestCallback extends ConnectivityManager.Netw
@CallSuper
public void onUnavailable() {
- // TODO: b/32637799 this is hidden, do we really need this?
+ // TODO(twyen): b/32637799 this is hidden, do we really need this?
mResultReceived = true;
onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java b/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java
new file mode 100644
index 000000000..f3c6e64f4
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionBackfillService.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.JobWorkItem;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.WorkerThread;
+import android.support.v4.app.JobIntentService;
+import android.support.v4.os.BuildCompat;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.constants.ScheduledJobIds;
+import java.util.List;
+
+/**
+ * JobScheduler service for transcribing old voicemails. This service does a database scan for
+ * un-transcribed voicemails and schedules transcription tasks for them, once we have an un-metered
+ * network connection.
+ */
+public class TranscriptionBackfillService extends JobIntentService {
+
+ /** Schedule a task to scan the database for untranscribed voicemails */
+ public static boolean scheduleTask(Context context) {
+ if (BuildCompat.isAtLeastO()) {
+ LogUtil.enterBlock("TranscriptionBackfillService.transcribeOldVoicemails");
+ ComponentName componentName = new ComponentName(context, TranscriptionBackfillService.class);
+ JobInfo.Builder builder =
+ new JobInfo.Builder(ScheduledJobIds.VVM_TRANSCRIPTION_BACKFILL_JOB, componentName)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
+ JobScheduler scheduler = context.getSystemService(JobScheduler.class);
+ return scheduler.enqueue(builder.build(), makeWorkItem()) == JobScheduler.RESULT_SUCCESS;
+ } else {
+ LogUtil.i("TranscriptionBackfillService.transcribeOldVoicemails", "not supported");
+ return false;
+ }
+ }
+
+ private static JobWorkItem makeWorkItem() {
+ Intent intent = new Intent();
+ return new JobWorkItem(intent);
+ }
+
+ @Override
+ @WorkerThread
+ protected void onHandleWork(Intent intent) {
+ LogUtil.enterBlock("TranscriptionBackfillService.onHandleWork");
+
+ TranscriptionDbHelper dbHelper = new TranscriptionDbHelper(this);
+ List<Uri> untranscribed = dbHelper.getUntranscribedVoicemails();
+ LogUtil.i(
+ "TranscriptionBackfillService.onHandleWork",
+ "found " + untranscribed.size() + " untranscribed voicemails");
+ // TODO(mdooley): Consider doing the actual transcriptions here instead of scheduling jobs.
+ for (Uri uri : untranscribed) {
+ ThreadUtil.postOnUiThread(
+ () -> {
+ TranscriptionService.scheduleNewVoicemailTranscriptionJob(this, uri, false);
+ });
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ LogUtil.enterBlock("TranscriptionBackfillService.onDestroy");
+ super.onDestroy();
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java b/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java
new file mode 100644
index 000000000..83f04dab8
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.content.Context;
+import com.android.dialer.configprovider.ConfigProviderBindings;
+
+/** Provides configuration values needed to connect to the transcription server. */
+public class TranscriptionConfigProvider {
+ private final Context context;
+
+ public TranscriptionConfigProvider(Context context) {
+ this.context = context;
+ }
+
+ public boolean isVoicemailTranscriptionEnabled() {
+ return ConfigProviderBindings.get(context).getBoolean("voicemail_transcription_enabled", false);
+ }
+
+ public String getServerAddress() {
+ // Private voicemail transcription service
+ return ConfigProviderBindings.get(context)
+ .getString(
+ "voicemail_transcription_server_address", "voicemailtranscription-pa.googleapis.com");
+ }
+
+ public String getApiKey() {
+ // Android API key restricted to com.google.android.dialer
+ return ConfigProviderBindings.get(context)
+ .getString(
+ "voicemail_transcription_client_api_key", "AIzaSyAXdDnif6B7sBYxU8hzw9qAp3pRPVHs060");
+ }
+
+ public String getAuthToken() {
+ return null;
+ }
+
+ public boolean shouldUsePlaintext() {
+ return ConfigProviderBindings.get(context)
+ .getBoolean("voicemail_transcription_server_use_plaintext", false);
+ }
+
+ public boolean shouldUseSyncApi() {
+ return ConfigProviderBindings.get(context)
+ .getBoolean("voicemail_transcription_server_use_sync_api", false);
+ }
+
+ public long getMaxTranscriptionRetries() {
+ return ConfigProviderBindings.get(context)
+ .getLong("voicemail_transcription_max_transcription_retries", 2L);
+ }
+
+ public long getMaxGetTranscriptPolls() {
+ return ConfigProviderBindings.get(context)
+ .getLong("voicemail_transcription_max_get_transcript_polls", 20L);
+ }
+
+ public long getGetTranscriptPollIntervalMillis() {
+ return ConfigProviderBindings.get(context)
+ .getLong("voicemail_transcription_get_transcript_poll_interval_millis", 1000L);
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "{ address: %s, api key: %s, auth token: %s, plaintext: %b, sync: %b, retries: %d, polls:"
+ + " %d, poll ms: %d }",
+ getServerAddress(),
+ getApiKey(),
+ getAuthToken(),
+ shouldUsePlaintext(),
+ shouldUseSyncApi(),
+ getMaxTranscriptionRetries(),
+ getMaxGetTranscriptPolls(),
+ getGetTranscriptPollIntervalMillis());
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionDbHelper.java b/java/com/android/voicemail/impl/transcribe/TranscriptionDbHelper.java
new file mode 100644
index 000000000..9d3c2e4a7
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionDbHelper.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.annotation.TargetApi;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build.VERSION_CODES;
+import android.provider.VoicemailContract.Voicemails;
+import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
+import android.support.v4.os.BuildCompat;
+import android.util.Pair;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Helper class for reading and writing transcription data in the database */
+@TargetApi(VERSION_CODES.O)
+public class TranscriptionDbHelper {
+ @VisibleForTesting
+ static final String[] PROJECTION =
+ new String[] {
+ Voicemails._ID, // 0
+ Voicemails.TRANSCRIPTION, // 1
+ VoicemailCompat.TRANSCRIPTION_STATE // 2
+ };
+
+ static final int ID = 0;
+ static final int TRANSCRIPTION = 1;
+ static final int TRANSCRIPTION_STATE = 2;
+
+ private final ContentResolver contentResolver;
+ private final Uri uri;
+
+ TranscriptionDbHelper(Context context, Uri uri) {
+ Assert.isNotNull(uri);
+ this.contentResolver = context.getContentResolver();
+ this.uri = uri;
+ }
+
+ TranscriptionDbHelper(Context context) {
+ this(context, Voicemails.buildSourceUri(context.getPackageName()));
+ }
+
+ @WorkerThread
+ @TargetApi(VERSION_CODES.M) // used for try with resources
+ Pair<String, Integer> getTranscriptionAndState() {
+ Assert.checkState(BuildCompat.isAtLeastO());
+ Assert.isWorkerThread();
+ try (Cursor cursor = contentResolver.query(uri, PROJECTION, null, null, null)) {
+ if (cursor == null) {
+ LogUtil.e("TranscriptionDbHelper.getTranscriptionAndState", "query failed.");
+ return null;
+ }
+
+ if (cursor.moveToFirst()) {
+ String transcription = cursor.getString(TRANSCRIPTION);
+ int transcriptionState = cursor.getInt(TRANSCRIPTION_STATE);
+ return new Pair<>(transcription, transcriptionState);
+ }
+ }
+ LogUtil.i("TranscriptionDbHelper.getTranscriptionAndState", "query returned no results");
+ return null;
+ }
+
+ @WorkerThread
+ @TargetApi(VERSION_CODES.M) // used for try with resources
+ List<Uri> getUntranscribedVoicemails() {
+ Assert.checkArgument(BuildCompat.isAtLeastO());
+ Assert.isWorkerThread();
+ List<Uri> untranscribed = new ArrayList<>();
+ String whereClause =
+ Voicemails.TRANSCRIPTION + " is NULL AND " + VoicemailCompat.TRANSCRIPTION_STATE + "=?";
+ String[] whereArgs = {String.valueOf(VoicemailCompat.TRANSCRIPTION_NOT_STARTED)};
+ try (Cursor cursor = contentResolver.query(uri, PROJECTION, whereClause, whereArgs, null)) {
+ if (cursor == null) {
+ LogUtil.e("TranscriptionDbHelper.getUntranscribedVoicemails", "query failed.");
+ } else {
+ while (cursor.moveToNext()) {
+ untranscribed.add(ContentUris.withAppendedId(uri, cursor.getLong(ID)));
+ }
+ }
+ }
+ return untranscribed;
+ }
+
+ @WorkerThread
+ void setTranscriptionState(int transcriptionState) {
+ Assert.isWorkerThread();
+ LogUtil.i(
+ "TranscriptionDbHelper.setTranscriptionState",
+ "uri: " + uri + ", state: " + transcriptionState);
+ ContentValues values = new ContentValues();
+ values.put(VoicemailCompat.TRANSCRIPTION_STATE, transcriptionState);
+ updateDatabase(values);
+ }
+
+ @WorkerThread
+ void setTranscriptionAndState(String transcription, int transcriptionState) {
+ Assert.isWorkerThread();
+ LogUtil.i(
+ "TranscriptionDbHelper.setTranscriptionAndState",
+ "uri: " + uri + ", state: " + transcriptionState);
+ ContentValues values = new ContentValues();
+ values.put(Voicemails.TRANSCRIPTION, transcription);
+ values.put(VoicemailCompat.TRANSCRIPTION_STATE, transcriptionState);
+ updateDatabase(values);
+ }
+
+ private void updateDatabase(ContentValues values) {
+ int updatedCount = contentResolver.update(uri, values, null, null);
+ if (updatedCount != 1) {
+ LogUtil.e(
+ "TranscriptionDbHelper.updateDatabase",
+ "Wrong row count, should have updated 1 row, was: " + updatedCount);
+ }
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionService.java b/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
new file mode 100644
index 000000000..2ca16fbf2
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionService.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.job.JobWorkItem;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.MainThread;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.os.BuildCompat;
+import android.text.TextUtils;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.constants.ScheduledJobIds;
+import com.android.dialer.logging.DialerImpression;
+import com.android.dialer.logging.Logger;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionClientFactory;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Job scheduler callback for launching voicemail transcription tasks. The transcription tasks will
+ * run in the background and will typically last for approximately the length of the voicemail audio
+ * (since thats how long the backend transcription service takes to do the transcription).
+ */
+public class TranscriptionService extends JobService {
+ @VisibleForTesting static final String EXTRA_VOICEMAIL_URI = "extra_voicemail_uri";
+
+ private ExecutorService executorService;
+ private JobParameters jobParameters;
+ private TranscriptionClientFactory clientFactory;
+ private TranscriptionConfigProvider configProvider;
+
+ /** Callback used by a task to indicate it has finished processing its work item */
+ interface JobCallback {
+ void onWorkCompleted(JobWorkItem completedWorkItem);
+ }
+
+ // Schedule a task to transcribe the indicated voicemail, return true if transcription task was
+ // scheduled.
+ @MainThread
+ public static boolean scheduleNewVoicemailTranscriptionJob(
+ Context context, Uri voicemailUri, boolean highPriority) {
+ Assert.isMainThread();
+ if (BuildCompat.isAtLeastO()) {
+ LogUtil.i(
+ "TranscriptionService.scheduleNewVoicemailTranscriptionJob", "scheduling transcription");
+ Logger.get(context).logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_VOICEMAIL_RECEIVED);
+
+ ComponentName componentName = new ComponentName(context, TranscriptionService.class);
+ JobInfo.Builder builder =
+ new JobInfo.Builder(ScheduledJobIds.VVM_TRANSCRIPTION_JOB, componentName);
+ if (highPriority) {
+ builder
+ .setMinimumLatency(0)
+ .setOverrideDeadline(0)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
+ } else {
+ builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
+ }
+ JobScheduler scheduler = context.getSystemService(JobScheduler.class);
+ JobWorkItem workItem = makeWorkItem(voicemailUri);
+ return scheduler.enqueue(builder.build(), workItem) == JobScheduler.RESULT_SUCCESS;
+ } else {
+ LogUtil.i("TranscriptionService.scheduleNewVoicemailTranscriptionJob", "not supported");
+ return false;
+ }
+ }
+
+ // Cancel all transcription tasks
+ @MainThread
+ public static void cancelTranscriptions(Context context) {
+ Assert.isMainThread();
+ LogUtil.enterBlock("TranscriptionService.cancelTranscriptions");
+ JobScheduler scheduler = context.getSystemService(JobScheduler.class);
+ scheduler.cancel(ScheduledJobIds.VVM_TRANSCRIPTION_JOB);
+ }
+
+ @MainThread
+ public TranscriptionService() {
+ Assert.isMainThread();
+ }
+
+ @VisibleForTesting
+ TranscriptionService(
+ ExecutorService executorService,
+ TranscriptionClientFactory clientFactory,
+ TranscriptionConfigProvider configProvider) {
+ this.executorService = executorService;
+ this.clientFactory = clientFactory;
+ this.configProvider = configProvider;
+ }
+
+ @Override
+ @MainThread
+ public boolean onStartJob(JobParameters params) {
+ Assert.isMainThread();
+ LogUtil.enterBlock("TranscriptionService.onStartJob");
+ if (!getConfigProvider().isVoicemailTranscriptionEnabled()) {
+ LogUtil.i("TranscriptionService.onStartJob", "transcription not enabled, exiting.");
+ return false;
+ } else if (TextUtils.isEmpty(getConfigProvider().getServerAddress())) {
+ LogUtil.i("TranscriptionService.onStartJob", "transcription server not configured, exiting.");
+ return false;
+ } else {
+ LogUtil.i(
+ "TranscriptionService.onStartJob",
+ "transcription server address: " + configProvider.getServerAddress());
+ jobParameters = params;
+ return checkForWork();
+ }
+ }
+
+ @Override
+ @MainThread
+ public boolean onStopJob(JobParameters params) {
+ Assert.isMainThread();
+ LogUtil.enterBlock("TranscriptionService.onStopJob");
+ cleanup();
+ return true;
+ }
+
+ @Override
+ @MainThread
+ public void onDestroy() {
+ Assert.isMainThread();
+ LogUtil.enterBlock("TranscriptionService.onDestroy");
+ cleanup();
+ }
+
+ private void cleanup() {
+ if (clientFactory != null) {
+ clientFactory.shutdown();
+ clientFactory = null;
+ }
+ if (executorService != null) {
+ executorService.shutdownNow();
+ executorService = null;
+ }
+ }
+
+ @MainThread
+ private boolean checkForWork() {
+ Assert.isMainThread();
+ JobWorkItem workItem = jobParameters.dequeueWork();
+ if (workItem != null) {
+ TranscriptionTask task =
+ configProvider.shouldUseSyncApi()
+ ? new TranscriptionTaskSync(
+ this, new Callback(), workItem, getClientFactory(), configProvider)
+ : new TranscriptionTaskAsync(
+ this, new Callback(), workItem, getClientFactory(), configProvider);
+ getExecutorService().execute(task);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ static Uri getVoicemailUri(JobWorkItem workItem) {
+ return workItem.getIntent().getParcelableExtra(EXTRA_VOICEMAIL_URI);
+ }
+
+ private ExecutorService getExecutorService() {
+ if (executorService == null) {
+ // The common use case is transcribing a single voicemail so just use a single thread executor
+ // The reason we're not using DialerExecutor here is because the transcription task can be
+ // very long running (ie. multiple minutes).
+ executorService = Executors.newSingleThreadExecutor();
+ }
+ return executorService;
+ }
+
+ private class Callback implements JobCallback {
+ @Override
+ @MainThread
+ public void onWorkCompleted(JobWorkItem completedWorkItem) {
+ Assert.isMainThread();
+ LogUtil.i("TranscriptionService.Callback.onWorkCompleted", completedWorkItem.toString());
+ jobParameters.completeWork(completedWorkItem);
+ checkForWork();
+ }
+ }
+
+ private static JobWorkItem makeWorkItem(Uri voicemailUri) {
+ Intent intent = new Intent();
+ intent.putExtra(EXTRA_VOICEMAIL_URI, voicemailUri);
+ return new JobWorkItem(intent);
+ }
+
+ private TranscriptionConfigProvider getConfigProvider() {
+ if (configProvider == null) {
+ configProvider = new TranscriptionConfigProvider(this);
+ }
+ return configProvider;
+ }
+
+ private TranscriptionClientFactory getClientFactory() {
+ if (clientFactory == null) {
+ clientFactory = new TranscriptionClientFactory(this, getConfigProvider());
+ }
+ return clientFactory;
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionTask.java b/java/com/android/voicemail/impl/transcribe/TranscriptionTask.java
new file mode 100644
index 000000000..b5f29da00
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionTask.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.annotation.TargetApi;
+import android.app.job.JobWorkItem;
+import android.content.Context;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Pair;
+import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.logging.DialerImpression;
+import com.android.dialer.logging.Logger;
+import com.android.voicemail.impl.VvmLog;
+import com.android.voicemail.impl.transcribe.TranscriptionService.JobCallback;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionClient;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionClientFactory;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionResponse;
+import com.google.internal.communications.voicemailtranscription.v1.AudioFormat;
+import com.google.internal.communications.voicemailtranscription.v1.TranscriptionStatus;
+import com.google.protobuf.ByteString;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Background task to get a voicemail transcription and update the database.
+ *
+ * <pre>
+ * This task performs the following steps:
+ * 1. Update the transcription-state in the database to 'in-progress'
+ * 2. Create grpc client and transcription request
+ * 3. Make synchronous or asynchronous grpc transcription request to backend server
+ * 3a. On response
+ * Update the database with transcription (if successful) and new transcription-state
+ * 3b. On network error
+ * If retry-count < max then increment retry-count and retry the request
+ * Otherwise update the transcription-state in the database to 'transcription-failed'
+ * 4. Notify the callback that the work item is complete
+ * </pre>
+ */
+public abstract class TranscriptionTask implements Runnable {
+ private static final String TAG = "TranscriptionTask";
+
+ private final Context context;
+ private final JobCallback callback;
+ private final JobWorkItem workItem;
+ private final TranscriptionClientFactory clientFactory;
+ private final Uri voicemailUri;
+ private final TranscriptionDbHelper databaseHelper;
+ protected final TranscriptionConfigProvider configProvider;
+ protected ByteString audioData;
+ protected AudioFormat encoding;
+
+ static final String AMR_PREFIX = "#!AMR\n";
+
+ /** Functional interface for sending requests to the transcription server */
+ public interface Request {
+ TranscriptionResponse getResponse(TranscriptionClient client);
+ }
+
+ TranscriptionTask(
+ Context context,
+ JobCallback callback,
+ JobWorkItem workItem,
+ TranscriptionClientFactory clientFactory,
+ TranscriptionConfigProvider configProvider) {
+ this.context = context;
+ this.callback = callback;
+ this.workItem = workItem;
+ this.clientFactory = clientFactory;
+ this.voicemailUri = TranscriptionService.getVoicemailUri(workItem);
+ this.configProvider = configProvider;
+ databaseHelper = new TranscriptionDbHelper(context, voicemailUri);
+ }
+
+ @Override
+ public void run() {
+ VvmLog.i(TAG, "run");
+ if (readAndValidateAudioFile()) {
+ updateTranscriptionState(VoicemailCompat.TRANSCRIPTION_IN_PROGRESS);
+ transcribeVoicemail();
+ } else {
+ if (AudioFormat.AUDIO_FORMAT_UNSPECIFIED.equals(encoding)) {
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_VOICEMAIL_FORMAT_NOT_SUPPORTED);
+ } else {
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_VOICEMAIL_INVALID_DATA);
+ }
+ updateTranscriptionState(VoicemailCompat.TRANSCRIPTION_FAILED);
+ }
+ ThreadUtil.postOnUiThread(
+ () -> {
+ callback.onWorkCompleted(workItem);
+ });
+ }
+
+ protected abstract Pair<String, TranscriptionStatus> getTranscription();
+
+ protected abstract DialerImpression.Type getRequestSentImpression();
+
+ private void transcribeVoicemail() {
+ VvmLog.i(TAG, "transcribeVoicemail");
+ Pair<String, TranscriptionStatus> pair = getTranscription();
+ String transcript = pair.first;
+ TranscriptionStatus status = pair.second;
+ if (!TextUtils.isEmpty(transcript)) {
+ updateTranscriptionAndState(transcript, VoicemailCompat.TRANSCRIPTION_AVAILABLE);
+ VvmLog.i(TAG, "transcribeVoicemail, got response");
+ Logger.get(context).logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_SUCCESS);
+ } else {
+ VvmLog.i(TAG, "transcribeVoicemail, transcription unsuccessful, " + status);
+ switch (status) {
+ case FAILED_LANGUAGE_NOT_SUPPORTED:
+ Logger.get(context)
+ .logImpression(
+ DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_LANGUAGE_NOT_SUPPORTED);
+ break;
+ case FAILED_NO_SPEECH_DETECTED:
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_NO_SPEECH_DETECTED);
+ break;
+ case EXPIRED:
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_EXPIRED);
+ break;
+ default:
+ Logger.get(context).logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_EMPTY);
+ break;
+ }
+ updateTranscriptionAndState(transcript, VoicemailCompat.TRANSCRIPTION_FAILED);
+ }
+ }
+
+ protected TranscriptionResponse sendRequest(Request request) {
+ VvmLog.i(TAG, "sendRequest");
+ TranscriptionClient client = clientFactory.getClient();
+ for (int i = 0; i < configProvider.getMaxTranscriptionRetries(); i++) {
+ VvmLog.i(TAG, "sendRequest, try: " + (i + 1));
+ if (i == 0) {
+ Logger.get(context).logImpression(getRequestSentImpression());
+ } else {
+ Logger.get(context).logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_REQUEST_RETRY);
+ }
+
+ TranscriptionResponse response = request.getResponse(client);
+ if (response.hasRecoverableError()) {
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_RECOVERABLE_ERROR);
+ backoff(i);
+ } else {
+ return response;
+ }
+ }
+
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.VVM_TRANSCRIPTION_RESPONSE_TOO_MANY_ERRORS);
+ return null;
+ }
+
+ private static void backoff(int retryCount) {
+ VvmLog.i(TAG, "backoff, count: " + retryCount);
+ long millis = (1L << retryCount) * 1000;
+ sleep(millis);
+ }
+
+ protected static void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ VvmLog.w(TAG, "interrupted");
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private void updateTranscriptionAndState(String transcript, int newState) {
+ databaseHelper.setTranscriptionAndState(transcript, newState);
+ }
+
+ private void updateTranscriptionState(int newState) {
+ databaseHelper.setTranscriptionState(newState);
+ }
+
+ // Uses try-with-resource
+ @TargetApi(android.os.Build.VERSION_CODES.M)
+ private boolean readAndValidateAudioFile() {
+ if (voicemailUri == null) {
+ VvmLog.i(TAG, "Transcriber.readAndValidateAudioFile, file not found.");
+ return false;
+ } else {
+ VvmLog.i(TAG, "Transcriber.readAndValidateAudioFile, reading: " + voicemailUri);
+ }
+
+ try (InputStream in = context.getContentResolver().openInputStream(voicemailUri)) {
+ audioData = ByteString.readFrom(in);
+ VvmLog.i(TAG, "Transcriber.readAndValidateAudioFile, read " + audioData.size() + " bytes");
+ } catch (IOException e) {
+ VvmLog.e(TAG, "Transcriber.readAndValidateAudioFile", e);
+ return false;
+ }
+
+ if (audioData.startsWith(ByteString.copyFromUtf8(AMR_PREFIX))) {
+ encoding = AudioFormat.AMR_NB_8KHZ;
+ } else {
+ VvmLog.i(TAG, "Transcriber.readAndValidateAudioFile, unknown encoding");
+ encoding = AudioFormat.AUDIO_FORMAT_UNSPECIFIED;
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionTaskAsync.java b/java/com/android/voicemail/impl/transcribe/TranscriptionTaskAsync.java
new file mode 100644
index 000000000..3c41aef89
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionTaskAsync.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.app.job.JobWorkItem;
+import android.content.Context;
+import android.util.Pair;
+import com.android.dialer.common.Assert;
+import com.android.dialer.logging.DialerImpression;
+import com.android.voicemail.impl.VvmLog;
+import com.android.voicemail.impl.transcribe.TranscriptionService.JobCallback;
+import com.android.voicemail.impl.transcribe.grpc.GetTranscriptResponseAsync;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionClientFactory;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionResponseAsync;
+import com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest;
+import com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest;
+import com.google.internal.communications.voicemailtranscription.v1.TranscriptionStatus;
+
+/**
+ * Background task to get a voicemail transcription using the asynchronous API. The async API works
+ * as follows:
+ *
+ * <ol>
+ * <li>client uploads voicemail data to the server
+ * <li>server responds with a transcription-id and an estimated transcription wait time
+ * <li>client waits appropriate amount of time then begins polling for the result
+ * </ol>
+ *
+ * This implementation blocks until the response or an error is received, even though it is using
+ * the asynchronous server API.
+ */
+public class TranscriptionTaskAsync extends TranscriptionTask {
+ private static final String TAG = "TranscriptionTaskAsync";
+
+ public TranscriptionTaskAsync(
+ Context context,
+ JobCallback callback,
+ JobWorkItem workItem,
+ TranscriptionClientFactory clientFactory,
+ TranscriptionConfigProvider configProvider) {
+ super(context, callback, workItem, clientFactory, configProvider);
+ }
+
+ @Override
+ protected Pair<String, TranscriptionStatus> getTranscription() {
+ VvmLog.i(TAG, "getTranscription");
+
+ TranscriptionResponseAsync uploadResponse =
+ (TranscriptionResponseAsync)
+ sendRequest((client) -> client.sendUploadRequest(getUploadRequest()));
+
+ if (uploadResponse == null) {
+ VvmLog.i(TAG, "getTranscription, failed to upload voicemail.");
+ return new Pair<>(null, TranscriptionStatus.FAILED_NO_RETRY);
+ } else {
+ waitForTranscription(uploadResponse);
+ return pollForTranscription(uploadResponse);
+ }
+ }
+
+ @Override
+ protected DialerImpression.Type getRequestSentImpression() {
+ return DialerImpression.Type.VVM_TRANSCRIPTION_REQUEST_SENT_ASYNC;
+ }
+
+ private static void waitForTranscription(TranscriptionResponseAsync uploadResponse) {
+ long millis = uploadResponse.getEstimatedWaitMillis();
+ VvmLog.i(TAG, "waitForTranscription, " + millis + " millis");
+ sleep(millis);
+ }
+
+ private Pair<String, TranscriptionStatus> pollForTranscription(
+ TranscriptionResponseAsync uploadResponse) {
+ VvmLog.i(TAG, "pollForTranscription");
+ GetTranscriptRequest request = getGetTranscriptRequest(uploadResponse);
+ for (int i = 0; i < configProvider.getMaxGetTranscriptPolls(); i++) {
+ GetTranscriptResponseAsync response =
+ (GetTranscriptResponseAsync)
+ sendRequest((client) -> client.sendGetTranscriptRequest(request));
+ if (response == null) {
+ VvmLog.i(TAG, "pollForTranscription, no transcription result.");
+ } else if (response.isTranscribing()) {
+ VvmLog.i(TAG, "pollForTranscription, poll count: " + (i + 1));
+ } else if (response.hasFatalError()) {
+ VvmLog.i(TAG, "pollForTranscription, fail. " + response.getErrorDescription());
+ return new Pair<>(null, response.getTranscriptionStatus());
+ } else {
+ VvmLog.i(TAG, "pollForTranscription, got transcription");
+ return new Pair<>(response.getTranscript(), TranscriptionStatus.SUCCESS);
+ }
+ sleep(configProvider.getGetTranscriptPollIntervalMillis());
+ }
+ VvmLog.i(TAG, "pollForTranscription, timed out.");
+ return new Pair<>(null, TranscriptionStatus.FAILED_NO_RETRY);
+ }
+
+ private TranscribeVoicemailAsyncRequest getUploadRequest() {
+ return TranscribeVoicemailAsyncRequest.newBuilder()
+ .setVoicemailData(audioData)
+ .setAudioFormat(encoding)
+ .build();
+ }
+
+ private GetTranscriptRequest getGetTranscriptRequest(TranscriptionResponseAsync uploadResponse) {
+ Assert.checkArgument(uploadResponse.getTranscriptionId() != null);
+ return GetTranscriptRequest.newBuilder()
+ .setTranscriptionId(uploadResponse.getTranscriptionId())
+ .build();
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionTaskSync.java b/java/com/android/voicemail/impl/transcribe/TranscriptionTaskSync.java
new file mode 100644
index 000000000..bee68590a
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/TranscriptionTaskSync.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+import android.app.job.JobWorkItem;
+import android.content.Context;
+import android.util.Pair;
+import com.android.dialer.logging.DialerImpression;
+import com.android.voicemail.impl.VvmLog;
+import com.android.voicemail.impl.transcribe.TranscriptionService.JobCallback;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionClientFactory;
+import com.android.voicemail.impl.transcribe.grpc.TranscriptionResponseSync;
+import com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest;
+import com.google.internal.communications.voicemailtranscription.v1.TranscriptionStatus;
+
+/** Background task to get a voicemail transcription using the synchronous API */
+public class TranscriptionTaskSync extends TranscriptionTask {
+ private static final String TAG = "TranscriptionTaskSync";
+
+ public TranscriptionTaskSync(
+ Context context,
+ JobCallback callback,
+ JobWorkItem workItem,
+ TranscriptionClientFactory clientFactory,
+ TranscriptionConfigProvider configProvider) {
+ super(context, callback, workItem, clientFactory, configProvider);
+ }
+
+ @Override
+ protected Pair<String, TranscriptionStatus> getTranscription() {
+ VvmLog.i(TAG, "getTranscription");
+
+ TranscriptionResponseSync response =
+ (TranscriptionResponseSync)
+ sendRequest((client) -> client.sendSyncRequest(getSyncRequest()));
+ if (response == null) {
+ VvmLog.i(TAG, "getTranscription, failed to transcribe voicemail.");
+ return new Pair<>(null, TranscriptionStatus.FAILED_NO_RETRY);
+ } else {
+ VvmLog.i(TAG, "getTranscription, got transcription");
+ return new Pair<>(response.getTranscript(), TranscriptionStatus.SUCCESS);
+ }
+ }
+
+ @Override
+ protected DialerImpression.Type getRequestSentImpression() {
+ return DialerImpression.Type.VVM_TRANSCRIPTION_REQUEST_SENT;
+ }
+
+ private TranscribeVoicemailRequest getSyncRequest() {
+ return TranscribeVoicemailRequest.newBuilder()
+ .setVoicemailData(audioData)
+ .setAudioFormat(encoding)
+ .build();
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/VoicemailCompat.java b/java/com/android/voicemail/impl/transcribe/VoicemailCompat.java
new file mode 100644
index 000000000..c6e30c6de
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/VoicemailCompat.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe;
+
+/**
+ * Provide access to new API constants before they're publicly available
+ *
+ * <p>Copied from android.provider.VoicemailContract.Voicemails. These should become public in O-MR1
+ * and these constants can be removed then.
+ */
+public class VoicemailCompat {
+
+ /**
+ * The state of the voicemail transcription.
+ *
+ * <p>Possible values: {@link #TRANSCRIPTION_NOT_STARTED}, {@link #TRANSCRIPTION_IN_PROGRESS},
+ * {@link #TRANSCRIPTION_FAILED}, {@link #TRANSCRIPTION_AVAILABLE}.
+ *
+ * <p>Type: INTEGER
+ */
+ public static final String TRANSCRIPTION_STATE = "transcription_state";
+
+ /**
+ * Value of {@link #TRANSCRIPTION_STATE} when the voicemail transcription has not yet been
+ * attempted.
+ */
+ public static final int TRANSCRIPTION_NOT_STARTED = 0;
+
+ /**
+ * Value of {@link #TRANSCRIPTION_STATE} when the voicemail transcription has begun but is not yet
+ * complete.
+ */
+ public static final int TRANSCRIPTION_IN_PROGRESS = 1;
+
+ /**
+ * Value of {@link #TRANSCRIPTION_STATE} when the voicemail transcription has been attempted and
+ * failed.
+ */
+ public static final int TRANSCRIPTION_FAILED = 2;
+
+ /**
+ * Value of {@link #TRANSCRIPTION_STATE} when the voicemail transcription has completed and the
+ * result has been stored in the {@link #TRANSCRIPTION} column.
+ */
+ public static final int TRANSCRIPTION_AVAILABLE = 3;
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/GetTranscriptResponseAsync.java b/java/com/android/voicemail/impl/transcribe/grpc/GetTranscriptResponseAsync.java
new file mode 100644
index 000000000..f979d69ce
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/GetTranscriptResponseAsync.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe.grpc;
+
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import com.android.dialer.common.Assert;
+import com.google.internal.communications.voicemailtranscription.v1.GetTranscriptResponse;
+import com.google.internal.communications.voicemailtranscription.v1.TranscriptionStatus;
+import io.grpc.Status;
+
+/** Container for response and status objects for an asynchronous get-transcript request */
+public class GetTranscriptResponseAsync extends TranscriptionResponse {
+ @Nullable private final GetTranscriptResponse response;
+
+ @VisibleForTesting
+ public GetTranscriptResponseAsync(GetTranscriptResponse response) {
+ Assert.checkArgument(response != null);
+ this.response = response;
+ }
+
+ @VisibleForTesting
+ public GetTranscriptResponseAsync(Status status) {
+ super(status);
+ this.response = null;
+ }
+
+ public @Nullable String getTranscript() {
+ if (response != null) {
+ return response.getTranscript();
+ }
+ return null;
+ }
+
+ public @Nullable String getErrorDescription() {
+ if (!hasRecoverableError() && !hasFatalError()) {
+ return null;
+ }
+ if (status != null) {
+ return "Grpc error: " + status;
+ }
+ if (response != null) {
+ return "Transcription error: " + response.getStatus();
+ }
+ Assert.fail("Impossible state");
+ return null;
+ }
+
+ public TranscriptionStatus getTranscriptionStatus() {
+ if (response == null) {
+ return TranscriptionStatus.TRANSCRIPTION_STATUS_UNSPECIFIED;
+ } else {
+ return response.getStatus();
+ }
+ }
+
+ public boolean isTranscribing() {
+ return response != null && response.getStatus() == TranscriptionStatus.PENDING;
+ }
+
+ @Override
+ public boolean hasRecoverableError() {
+ if (super.hasRecoverableError()) {
+ return true;
+ }
+
+ if (response != null) {
+ return response.getStatus() == TranscriptionStatus.EXPIRED
+ || response.getStatus() == TranscriptionStatus.FAILED_RETRY;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean hasFatalError() {
+ if (super.hasFatalError()) {
+ return true;
+ }
+
+ if (response != null) {
+ return response.getStatus() == TranscriptionStatus.FAILED_NO_RETRY
+ || response.getStatus() == TranscriptionStatus.FAILED_LANGUAGE_NOT_SUPPORTED
+ || response.getStatus() == TranscriptionStatus.FAILED_NO_SPEECH_DETECTED;
+ }
+
+ return false;
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClient.java b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClient.java
new file mode 100644
index 000000000..b18d95627
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClient.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe.grpc;
+
+import android.support.annotation.WorkerThread;
+import com.google.internal.communications.voicemailtranscription.v1.GetTranscriptRequest;
+import com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncRequest;
+import com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailRequest;
+import com.google.internal.communications.voicemailtranscription.v1.VoicemailTranscriptionServiceGrpc;
+import io.grpc.StatusRuntimeException;
+
+/** Wrapper around Grpc transcription server stub */
+public class TranscriptionClient {
+
+ private final VoicemailTranscriptionServiceGrpc.VoicemailTranscriptionServiceBlockingStub stub;
+
+ TranscriptionClient(
+ VoicemailTranscriptionServiceGrpc.VoicemailTranscriptionServiceBlockingStub stub) {
+ this.stub = stub;
+ }
+
+ @WorkerThread
+ public TranscriptionResponseSync sendSyncRequest(TranscribeVoicemailRequest request) {
+ try {
+ return new TranscriptionResponseSync(stub.transcribeVoicemail(request));
+ } catch (StatusRuntimeException e) {
+ return new TranscriptionResponseSync(e.getStatus());
+ }
+ }
+
+ @WorkerThread
+ public TranscriptionResponseAsync sendUploadRequest(TranscribeVoicemailAsyncRequest request) {
+ try {
+ return new TranscriptionResponseAsync(stub.transcribeVoicemailAsync(request));
+ } catch (StatusRuntimeException e) {
+ return new TranscriptionResponseAsync(e.getStatus());
+ }
+ }
+
+ @WorkerThread
+ public GetTranscriptResponseAsync sendGetTranscriptRequest(GetTranscriptRequest request) {
+ try {
+ return new GetTranscriptResponseAsync(stub.getTranscript(request));
+ } catch (StatusRuntimeException e) {
+ return new GetTranscriptResponseAsync(e.getStatus());
+ }
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClientFactory.java b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClientFactory.java
new file mode 100644
index 000000000..c57b01fd7
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionClientFactory.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe.grpc;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.text.TextUtils;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import com.android.voicemail.impl.transcribe.TranscriptionConfigProvider;
+import com.google.internal.communications.voicemailtranscription.v1.VoicemailTranscriptionServiceGrpc;
+import io.grpc.CallOptions;
+import io.grpc.Channel;
+import io.grpc.ClientCall;
+import io.grpc.ClientInterceptor;
+import io.grpc.ClientInterceptors;
+import io.grpc.ForwardingClientCall;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor;
+import io.grpc.okhttp.OkHttpChannelBuilder;
+import java.security.MessageDigest;
+
+/**
+ * Factory for creating grpc clients that talk to the transcription server. This allows all clients
+ * to share the same channel, which is relatively expensive to create.
+ */
+public class TranscriptionClientFactory {
+ private static final String DIGEST_ALGORITHM_SHA1 = "SHA1";
+ private static final char[] HEX_UPPERCASE = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ private final TranscriptionConfigProvider configProvider;
+ private final ManagedChannel originalChannel;
+ private final String packageName;
+ private final String cert;
+
+ public TranscriptionClientFactory(Context context, TranscriptionConfigProvider configProvider) {
+ this(context, configProvider, getManagedChannel(configProvider));
+ }
+
+ public TranscriptionClientFactory(
+ Context context, TranscriptionConfigProvider configProvider, ManagedChannel managedChannel) {
+ this.configProvider = configProvider;
+ this.packageName = context.getPackageName();
+ this.cert = getCertificateFingerprint(context);
+ originalChannel = managedChannel;
+ }
+
+ public TranscriptionClient getClient() {
+ LogUtil.enterBlock("TranscriptionClientFactory.getClient");
+ Assert.checkState(!originalChannel.isShutdown());
+ Channel channel =
+ ClientInterceptors.intercept(
+ originalChannel,
+ new Interceptor(
+ packageName, cert, configProvider.getApiKey(), configProvider.getAuthToken()));
+ return new TranscriptionClient(VoicemailTranscriptionServiceGrpc.newBlockingStub(channel));
+ }
+
+ public void shutdown() {
+ LogUtil.enterBlock("TranscriptionClientFactory.shutdown");
+ if (!originalChannel.isShutdown()) {
+ originalChannel.shutdown();
+ }
+ }
+
+ private static ManagedChannel getManagedChannel(TranscriptionConfigProvider configProvider) {
+ ManagedChannelBuilder<OkHttpChannelBuilder> builder =
+ OkHttpChannelBuilder.forTarget(configProvider.getServerAddress());
+ // Only use plaintext for debugging
+ if (configProvider.shouldUsePlaintext()) {
+ // Just passing 'false' doesnt have the same effect as not setting this field
+ builder.usePlaintext(true);
+ }
+ return builder.build();
+ }
+
+ private static String getCertificateFingerprint(Context context) {
+ try {
+ PackageInfo packageInfo =
+ context
+ .getPackageManager()
+ .getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
+ if (packageInfo != null
+ && packageInfo.signatures != null
+ && packageInfo.signatures.length > 0) {
+ MessageDigest messageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ if (messageDigest == null) {
+ LogUtil.w(
+ "TranscriptionClientFactory.getCertificateFingerprint", "error getting digest.");
+ return null;
+ }
+ byte[] bytes = messageDigest.digest(packageInfo.signatures[0].toByteArray());
+ if (bytes == null) {
+ LogUtil.w(
+ "TranscriptionClientFactory.getCertificateFingerprint", "empty message digest.");
+ return null;
+ }
+
+ int length = bytes.length;
+ StringBuilder out = new StringBuilder(length * 2);
+ for (int i = 0; i < length; i++) {
+ out.append(HEX_UPPERCASE[(bytes[i] & 0xf0) >>> 4]);
+ out.append(HEX_UPPERCASE[bytes[i] & 0x0f]);
+ }
+ return out.toString();
+ } else {
+ LogUtil.w(
+ "TranscriptionClientFactory.getCertificateFingerprint",
+ "failed to get package signature.");
+ }
+ } catch (Exception e) {
+ LogUtil.e(
+ "TranscriptionClientFactory.getCertificateFingerprint",
+ "error getting certificate fingerprint.",
+ e);
+ }
+
+ return null;
+ }
+
+ private static final class Interceptor implements ClientInterceptor {
+ private final String packageName;
+ private final String cert;
+ private final String apiKey;
+ private final String authToken;
+
+ private static final Metadata.Key<String> API_KEY_HEADER =
+ Metadata.Key.of("X-Goog-Api-Key", Metadata.ASCII_STRING_MARSHALLER);
+ private static final Metadata.Key<String> ANDROID_PACKAGE_HEADER =
+ Metadata.Key.of("X-Android-Package", Metadata.ASCII_STRING_MARSHALLER);
+ private static final Metadata.Key<String> ANDROID_CERT_HEADER =
+ Metadata.Key.of("X-Android-Cert", Metadata.ASCII_STRING_MARSHALLER);
+ private static final Metadata.Key<String> AUTHORIZATION_HEADER =
+ Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);
+
+ public Interceptor(String packageName, String cert, String apiKey, String authToken) {
+ this.packageName = packageName;
+ this.cert = cert;
+ this.apiKey = apiKey;
+ this.authToken = authToken;
+ }
+
+ @Override
+ public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
+ MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
+ LogUtil.enterBlock(
+ "TranscriptionClientFactory.interceptCall, intercepted " + method.getFullMethodName());
+ ClientCall<ReqT, RespT> call = next.newCall(method, callOptions);
+
+ call =
+ new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(call) {
+ @Override
+ public void start(Listener<RespT> responseListener, Metadata headers) {
+ if (!TextUtils.isEmpty(packageName)) {
+ LogUtil.i(
+ "TranscriptionClientFactory.interceptCall",
+ "attaching package name: " + packageName);
+ headers.put(ANDROID_PACKAGE_HEADER, packageName);
+ }
+ if (!TextUtils.isEmpty(cert)) {
+ LogUtil.i("TranscriptionClientFactory.interceptCall", "attaching android cert");
+ headers.put(ANDROID_CERT_HEADER, cert);
+ }
+ if (!TextUtils.isEmpty(apiKey)) {
+ LogUtil.i("TranscriptionClientFactory.interceptCall", "attaching API Key");
+ headers.put(API_KEY_HEADER, apiKey);
+ }
+ if (!TextUtils.isEmpty(authToken)) {
+ LogUtil.i("TranscriptionClientFactory.interceptCall", "attaching auth token");
+ headers.put(AUTHORIZATION_HEADER, "Bearer " + authToken);
+ }
+ super.start(responseListener, headers);
+ }
+ };
+ return call;
+ }
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponse.java b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponse.java
new file mode 100644
index 000000000..f0823de32
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponse.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe.grpc;
+
+import android.support.annotation.Nullable;
+import com.android.dialer.common.Assert;
+import io.grpc.Status;
+
+/**
+ * Base class for encapulating a voicemail transcription server response. This handles the Grpc
+ * status response, subclasses will handle request specific responses.
+ */
+public abstract class TranscriptionResponse {
+ @Nullable public final Status status;
+
+ TranscriptionResponse() {
+ this.status = null;
+ }
+
+ TranscriptionResponse(Status status) {
+ Assert.checkArgument(status != null);
+ this.status = status;
+ }
+
+ public boolean hasRecoverableError() {
+ if (status != null) {
+ return status.getCode() == Status.Code.UNAVAILABLE;
+ }
+
+ return false;
+ }
+
+ public boolean hasFatalError() {
+ if (status != null) {
+ return status.getCode() != Status.Code.OK && status.getCode() != Status.Code.UNAVAILABLE;
+ }
+
+ return false;
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseAsync.java b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseAsync.java
new file mode 100644
index 000000000..38b463053
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseAsync.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe.grpc;
+
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import com.android.dialer.common.Assert;
+import com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailAsyncResponse;
+import io.grpc.Status;
+
+/** Container for response and status objects for an asynchronous transcription upload request */
+public class TranscriptionResponseAsync extends TranscriptionResponse {
+ @Nullable private final TranscribeVoicemailAsyncResponse response;
+
+ @VisibleForTesting
+ public TranscriptionResponseAsync(TranscribeVoicemailAsyncResponse response) {
+ Assert.checkArgument(response != null);
+ this.response = response;
+ }
+
+ @VisibleForTesting
+ public TranscriptionResponseAsync(Status status) {
+ super(status);
+ this.response = null;
+ }
+
+ public @Nullable String getTranscriptionId() {
+ if (response != null) {
+ return response.getTranscriptionId();
+ }
+ return null;
+ }
+
+ public long getEstimatedWaitMillis() {
+ if (response != null) {
+ return response.getEstimatedWaitSecs() * 1_000L;
+ }
+ return 0;
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseSync.java b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseSync.java
new file mode 100644
index 000000000..d2e2e218c
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/TranscriptionResponseSync.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.voicemail.impl.transcribe.grpc;
+
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import com.android.dialer.common.Assert;
+import com.google.internal.communications.voicemailtranscription.v1.TranscribeVoicemailResponse;
+import io.grpc.Status;
+
+/** Container for response and status objects for a synchronous transcription request */
+public class TranscriptionResponseSync extends TranscriptionResponse {
+ @Nullable private final TranscribeVoicemailResponse response;
+
+ @VisibleForTesting
+ public TranscriptionResponseSync(Status status) {
+ super(status);
+ this.response = null;
+ }
+
+ @VisibleForTesting
+ public TranscriptionResponseSync(TranscribeVoicemailResponse response) {
+ Assert.checkArgument(response != null);
+ this.response = response;
+ }
+
+ public @Nullable String getTranscript() {
+ return (response != null) ? response.getTranscript() : null;
+ }
+}
diff --git a/java/com/android/voicemail/impl/transcribe/grpc/voicemail_transcription.proto b/java/com/android/voicemail/impl/transcribe/grpc/voicemail_transcription.proto
new file mode 100644
index 000000000..a2064d193
--- /dev/null
+++ b/java/com/android/voicemail/impl/transcribe/grpc/voicemail_transcription.proto
@@ -0,0 +1,133 @@
+// LINT.IfChange
+
+syntax = "proto2";
+
+package google.internal.communications.voicemailtranscription.v1;
+
+option java_multiple_files = true;
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.internal.communications.voicemailtranscription.v1";
+
+// Enum that specifies supported audio formats.
+enum AudioFormat {
+ // Default but invalid value.
+ AUDIO_FORMAT_UNSPECIFIED = 0;
+
+ // Adaptive Multi-Rate Narrowband, 8kHz sampling frequency.
+ // https://en.wikipedia.org/wiki/Adaptive_Multi-Rate_audio_codec
+ AMR_NB_8KHZ = 1;
+}
+
+// Enum that describes the status of the transcription process.
+enum TranscriptionStatus {
+ // Default but invalid value.
+ TRANSCRIPTION_STATUS_UNSPECIFIED = 0;
+
+ // Transcription was successful and the transcript is present.
+ SUCCESS = 1;
+
+ // Transcription is progress. Check again later.
+ PENDING = 2;
+
+ // Transcription was successful, but the expiration period has passed, which
+ // means that the sensative data (including the transcript) has been deleted.
+ // Resend the voicemail through TranscribeVoicemailAsync to retry.
+ EXPIRED = 3;
+
+ // Internal error encountered during the transcription.
+ // Resend the voicemail through TranscribeVoicemailAsync to retry.
+ // This is a catch-all status for all retriable errors that aren't captured by
+ // a more specfic status.
+ FAILED_RETRY = 4;
+
+ // Internal error encountered during the transcription.
+ // Do not resend the voicemail.
+ // This is a catch-all status for all non-retriable errors that aren't
+ // captured by a more specfic status.
+ FAILED_NO_RETRY = 5;
+
+ // The language detected is not yet supported by this service.
+ // Do not resend the voicemail.
+ FAILED_LANGUAGE_NOT_SUPPORTED = 6;
+
+ // No speech was detected in the voicemail.
+ // Do not resend the voicemail.
+ FAILED_NO_SPEECH_DETECTED = 7;
+}
+
+// Request for synchronous voicemail transcription.
+message TranscribeVoicemailRequest {
+ // Voicemail audio file containing the raw bytes we receive from the carrier.
+ optional bytes voicemail_data = 1;
+
+ // Audio format of the voicemail file.
+ optional AudioFormat audio_format = 2;
+}
+
+// Response for synchronous voicemail transcription.
+message TranscribeVoicemailResponse {
+ // The transcribed text of the voicemail.
+ optional string transcript = 1;
+}
+
+// Request for asynchronous voicemail transcription.
+message TranscribeVoicemailAsyncRequest {
+ // Voicemail audio data encoded in the format specified by audio_format.
+ optional bytes voicemail_data = 1;
+
+ // Audio format of the voicemail file.
+ optional AudioFormat audio_format = 2;
+}
+
+// Response for asynchronous voicemail transcription containing information
+// needed to fetch the transcription results through the GetTranscript method.
+message TranscribeVoicemailAsyncResponse {
+ // Unique ID for the transcription. This ID is used for retrieving the
+ // voicemail transcript later.
+ optional string transcription_id = 1;
+
+ // The estimated amount of time in seconds before the transcription will be
+ // available.
+ // The client should not call GetTranscript until this time has elapsed, but
+ // the transcript is not guaranteed to be ready by this time.
+ optional int64 estimated_wait_secs = 2;
+}
+
+// Request for retrieving an asynchronously generated transcript.
+message GetTranscriptRequest {
+ // Unique ID for the transcription. This ID was returned by
+ // TranscribeVoicemailAsync.
+ optional string transcription_id = 1;
+}
+
+// Response for retrieving an asynchronously generated transcript.
+message GetTranscriptResponse {
+ // Status of the trascription process.
+ optional TranscriptionStatus status = 1;
+
+ // The transcribed text of the voicemail. This is only present if the status
+ // is SUCCESS.
+ optional string transcript = 2;
+}
+
+// RPC service for transcribing voicemails.
+service VoicemailTranscriptionService {
+ // Returns a transcript of the given voicemail.
+ rpc TranscribeVoicemail(TranscribeVoicemailRequest)
+ returns (TranscribeVoicemailResponse) {}
+
+ // Schedules a transcription of the given voicemail. The transcript can be
+ // retrieved using the returned ID.
+ rpc TranscribeVoicemailAsync(TranscribeVoicemailAsyncRequest)
+ returns (TranscribeVoicemailAsyncResponse) {
+ }
+
+ // Returns the transcript corresponding to the given ID, which was returned
+ // by TranscribeVoicemailAsync.
+ rpc GetTranscript(GetTranscriptRequest) returns (GetTranscriptResponse) {
+ }
+}
+
+// LINT.ThenChange(//depot/google3/google/internal/communications/voicemailtranscription/v1/\
+// voicemail_transcription.proto)
diff --git a/java/com/android/voicemail/permissions.xml b/java/com/android/voicemail/permissions.xml
deleted file mode 100644
index bedf06898..000000000
--- a/java/com/android/voicemail/permissions.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.voicemailomtp">
-
- <uses-sdk
- android:minSdkVersion="23"
- android:targetSdkVersion="26"/>
-
- <!-- Applications using this module should merge these permissions using android_manifest_merge -->
-
- <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"/>
- <uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
- <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"/>
- <uses-permission android:name="android.permission.WAKE_LOCK"/>
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <uses-permission android:name="android.permission.SEND_SMS"/>
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.INTERNET"/>
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-
- <application/>
-</manifest>
diff --git a/java/com/android/voicemail/stub/StubVoicemailClient.java b/java/com/android/voicemail/stub/StubVoicemailClient.java
index e2b470799..992950340 100644
--- a/java/com/android/voicemail/stub/StubVoicemailClient.java
+++ b/java/com/android/voicemail/stub/StubVoicemailClient.java
@@ -18,6 +18,9 @@ package com.android.voicemail.stub;
import android.content.Context;
import android.content.Intent;
+import android.os.PersistableBundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
import com.android.voicemail.VoicemailClient;
@@ -81,4 +84,22 @@ public final class StubVoicemailClient implements VoicemailClient {
public boolean isActivated(Context context, PhoneAccountHandle phoneAccountHandle) {
return false;
}
+
+ @Override
+ public void showConfigUi(@NonNull Context context) {}
+
+ @Override
+ public PersistableBundle getConfig(
+ @NonNull Context context, @Nullable PhoneAccountHandle phoneAccountHandle) {
+ return new PersistableBundle();
+ }
+
+ @Override
+ public void onBoot(@NonNull Context context) {}
+
+ @Override
+ public void onShutdown(@NonNull Context context) {}
+
+ @Override
+ public void onTosAccepted(Context context) {}
}