diff options
Diffstat (limited to 'java/com/android/voicemail')
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) {} } |