Import translations. DO NOT MERGE
am: 41c8c2a57b -s ours
Change-Id: I51f7808fe5334cd3ace7e5309b067afffeacca9c
diff --git a/Android.mk b/Android.mk
index f3fff79..cbebc44 100644
--- a/Android.mk
+++ b/Android.mk
@@ -11,7 +11,9 @@
LOCAL_JAVA_LIBRARIES := telephony-common voip-common ims-common
LOCAL_STATIC_JAVA_LIBRARIES := \
- guava
+ org.apache.http.legacy \
+ guava \
+ volley
LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
LOCAL_SRC_FILES += \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 61257f8..0a9a6a5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -55,8 +55,9 @@
<protected-broadcast android:name= "android.intent.action.stk.session_end" />
<protected-broadcast android:name= "android.intent.action.stk.icc_status_change" />
<protected-broadcast android:name= "android.intent.action.stk.alpha_notify" />
- <protected-broadcast android:name= "android.intent.action.REDIRECTION_DETECTED" />
- <protected-broadcast android:name= "android.intent.action.REQUEST_NETWORK_FAILED" />
+ <protected-broadcast android:name= "android.intent.action.CARRIER_SIGNAL_REDIRECTED" />
+ <protected-broadcast android:name= "android.intent.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED" />
+ <protected-broadcast android:name= "android.intent.action.CARRIER_SIGNAL_PCO_VALUE" />
<protected-broadcast android:name= "com.android.intent.isim_refresh" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
@@ -656,8 +657,7 @@
<receiver android:name="com.android.phone.vvm.omtp.sms.OmtpMessageReceiver"
android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.DATA_SMS_RECEIVED" />
- <data android:scheme="sms" />
+ <action android:name="android.intent.action.VOICEMAIL_SMS_RECEIVED"/>
</intent-filter>
</receiver>
<receiver
@@ -676,18 +676,18 @@
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
- <receiver
- android:name="com.android.phone.vvm.omtp.fetch.FetchVoicemailReceiver"
- android:exported="true"
- android:permission="com.android.voicemail.permission.READ_VOICEMAIL">
- <intent-filter>
- <action android:name="android.intent.action.FETCH_VOICEMAIL" />
- <data
- android:scheme="content"
- android:host="com.android.voicemail"
- android:mimeType="vnd.android.cursor.item/voicemail" />
- </intent-filter>
- </receiver>
+ <receiver
+ android:name="com.android.phone.vvm.omtp.fetch.FetchVoicemailReceiver"
+ android:exported="true"
+ android:permission="com.android.voicemail.permission.READ_VOICEMAIL">
+ <intent-filter>
+ <action android:name="android.intent.action.FETCH_VOICEMAIL" />
+ <data
+ android:scheme="content"
+ android:host="com.android.voicemail"
+ android:mimeType="vnd.android.cursor.item/voicemail" />
+ </intent-filter>
+ </receiver>
<receiver
android:name="com.android.phone.vvm.omtp.sync.OmtpVvmSyncReceiver"
android:exported="true"
@@ -696,27 +696,31 @@
<action android:name="android.provider.action.SYNC_VOICEMAIL"/>
</intent-filter>
</receiver>
- <receiver
- android:name="com.android.phone.vvm.omtp.sync.VoicemailProviderChangeReceiver"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.PROVIDER_CHANGED" />
- <data
- android:scheme="content"
- android:host="com.android.voicemail"
- android:mimeType="vnd.android.cursor.dir/voicemails"/>
- </intent-filter>
- </receiver>
- <service
+ <receiver
+ android:name="com.android.phone.vvm.omtp.sync.VoicemailProviderChangeReceiver"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.PROVIDER_CHANGED" />
+ <data
+ android:scheme="content"
+ android:host="com.android.voicemail"
+ android:mimeType="vnd.android.cursor.dir/voicemails"/>
+ </intent-filter>
+ </receiver>
+ <service
android:name="com.android.phone.vvm.omtp.sync.OmtpVvmSyncService"
- android:exported="false"
- />
- <receiver android:name="com.android.phone.vvm.omtp.VvmPackageInstallReceiver">
- <intent-filter>
- <action android:name="android.intent.action.PACKAGE_INSTALL" />
- <action android:name="android.intent.action.PACKAGE_ADDED" />
- <data android:scheme="package"/>
- </intent-filter>
- </receiver>
+ android:exported="false" />
+
+ <service
+ android:name="com.android.phone.vvm.omtp.sms.OmtpProvisioningService"
+ android:exported="false" />
+
+ <receiver android:name="com.android.phone.vvm.omtp.VvmPackageInstallReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.PACKAGE_INSTALL" />
+ <action android:name="android.intent.action.PACKAGE_ADDED" />
+ <data android:scheme="package"/>
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/proguard.flags b/proguard.flags
index c4af490..41e26a1 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -1 +1,6 @@
+# Keep classes and methods that have the guava @VisibleForTesting annotation
+-keep @**.VisibleForTesting class *
+-keepclassmembers class * {
+@**.VisibleForTesting *;
+}
-verbose
diff --git a/res/layout/voicemail_dialog_change_pin.xml b/res/layout/voicemail_dialog_change_pin.xml
new file mode 100644
index 0000000..a5cfa80
--- /dev/null
+++ b/res/layout/voicemail_dialog_change_pin.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="?android:attr/dialogPreferredPadding">
+
+ <TextView
+ android:id="@+id/vm_old_pin_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/vm_change_pin_old_pin"
+ android:labelFor="@+id/vm_old_pin"/>
+
+ <EditText android:id="@id/vm_old_pin"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="?android:attr/textColorSecondary"
+ android:inputType="numberPassword"/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/vm_change_pin_new_pin"
+ android:labelFor="@+id/vm_new_pin"/>
+
+ <EditText android:id="@id/vm_new_pin"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="?android:attr/textColorSecondary"
+ android:inputType="numberPassword"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index f0bcc3a..8bd5c69 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Geen veranderinge is gemaak nie."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Kies stemboodskapdiens"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Jou diensverskaffer"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Ou PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nuwe PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Verander tans PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Die nuwe PIN is te kort."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Die nuwe PIN is te lank."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Die nuwe PIN is te swak. \'n Sterk wagwoord moenie daaropvolgend wees of syfers bevat wat herhaal nie."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Die ou PIN pas nie."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Die nuwe PIN bevat ongeldige karakters."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Kan nie PIN verander nie"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Selnetwerkinstellings"</string>
<string name="label_available" msgid="1181658289009300430">"Beskikbare netwerke"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Soek tans…"</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibreer"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibreer"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuele stemboodskapdiens"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Verander PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Klank"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Luitoon en vibreer"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Ingeboude SIM-kaarte"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index d7da5f1..152ae85 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"ምንም ለውጥ አልተደረገም።"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"የድምፅ መልዕክት አገልግሎት ምረጥ"</string>
<string name="voicemail_default" msgid="2001233554889016880">"የእርስዎ ድምጸ ተያያዥ ሞደም"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"የቀድሞ ፒን"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"አዲስ ፒን"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"ፒን በመቀየር ላይ"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"አዲሱ ፒን በጣም አጭር ነው።"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"አዲሱ ፒን በጣም ረጅም ነው።"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"አዲሱ ፒን በጣም ደካማ ነው። ጠንካራ የይለፍ ቃል ተከታታይ ቅጥልጥል ወይም ተደጋጋሚ አኃዞች ሊኖሩት አይገባም።"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"የቀድሞ ፒን አልተዛመደም።"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"አዲሱ ፒን ልክ ያልሆኑ ቁምፊዎችን ይዟል።"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"ፒን መቀየር አልተቻለም።"</string>
<string name="mobile_networks" msgid="2843854043339307375">"የተንቀሳቃሽ ስልክ አውታረ መረብ ቅንብሮች"</string>
<string name="label_available" msgid="1181658289009300430">"የሚገኙ አውታረመረቦች"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"በመፈለግ ላይ…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"ንዘር"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"ንዘር"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ምስላዊ የድመጽ መልዕከት"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"ፒን ቀይር"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ድምፅ"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"የደወል ቅላጼ እና ንዘረት"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"አብሮገነብ ሲም ካርዶች"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index c5e57b0..cffda11 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"لم يتم إجراء أية تغييرات."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"اختيار خدمة البريد الصوتي"</string>
<string name="voicemail_default" msgid="2001233554889016880">"مشغل شبكة الجوّال"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"رقم التعريف الشخصي القديم"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"رقم التعريف الشخصي الجديد"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"تغيير رقم التعريف الشخصي"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"رقم التعريف الشخصي الجديد قصير جدًا."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"رقم التعريف الشخصي الجديد طويل جدًا."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"رقم التعريف الشخصي الجديد ضعيف جدًا. لا ينبغي أن تكون كلمة المرور القوية عبارة عن تسلسل متتالٍ أو أرقام متكررة."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"رقم التعريف الشخصي القديم غير مُطابِق."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"رقم التعريف الشخصي الجديد يحتوي على أحرف غير صالحة."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"غير قادر على تغيير رقم التعريف الشخصي"</string>
<string name="mobile_networks" msgid="2843854043339307375">"إعدادات شبكة الجوّال"</string>
<string name="label_available" msgid="1181658289009300430">"الشبكات المتاحة"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"جارِ البحث…"</string>
@@ -552,6 +561,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"الاهتزاز"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"الاهتزاز"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"بريد صوتي مرئي"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"تغيير رقم التعريف الشخصي"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"الصوت"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"نغمة الرنين والاهتزاز"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"بطاقات SIM مدمجة"</string>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index a76abfc..9fc08dd 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Heç bir dəyişiklik edilmədi."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Səsli poçt xidmətinizi seçin"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operatorunuz"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Köhnə PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Yeni PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN kod dəyişdirilir"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Yeni PIN kod çox qısadır."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Yeni PIN kod çox uzundur."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Yeni PIN kod çox zəifdir. Güclü parol ardıcıllıqdan və ya təkrarlanan rəqəmlərdən ibarət olmamalıdır."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Köhnə PIN kod uyğun gəlmir."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Yeni PIN kod yanlış simvollardan ibarətdir."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN kodu dəyişmək mümkün olmadı"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobil şəbəkə ayarları"</string>
<string name="label_available" msgid="1181658289009300430">"Əlçatımlı şəbəkələr"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Axtarılır..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrasiya"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrasiya"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizual Səsli Mesaj"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN kodu dəyişin"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Səs"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Zəng səsi & Vibrasiya"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Daxili SIM kartlar"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index f9073af..5911044 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -107,12 +107,12 @@
<string name="sum_cfb_enabled" msgid="5984198104833116690">"Prosleđuje se na <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
<string name="sum_cfb_disabled" msgid="4913145177320506827">"Isključeno"</string>
<string name="disable_cfb_forbidden" msgid="3506984333877998061">"Operater ne podržava onemogućavanje preusmeravanja poziva kada je telefon zauzet."</string>
- <string name="labelCFNRy" msgid="1736067178393744351">"Kad se ne javim"</string>
- <string name="messageCFNRy" msgid="672317899884380374">"Broj kad se ne javim"</string>
+ <string name="labelCFNRy" msgid="1736067178393744351">"Kad se ne javite"</string>
+ <string name="messageCFNRy" msgid="672317899884380374">"Broj kad se ne javite"</string>
<string name="sum_cfnry_enabled" msgid="6955775691317662910">"Prosleđuje se na <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
<string name="sum_cfnry_disabled" msgid="3884684060443538097">"Isključeno"</string>
<string name="disable_cfnry_forbidden" msgid="4308233959150658058">"Operater ne podržava onemogućavanje preusmeravanja poziva kada se na poziv ne odgovori."</string>
- <string name="labelCFNRc" msgid="2614827454402079766">"Kad sam nedostupan/a"</string>
+ <string name="labelCFNRc" msgid="2614827454402079766">"Kada je nedostupno"</string>
<string name="messageCFNRc" msgid="6380695421020295119">"Broj kad je nedostupno"</string>
<string name="sum_cfnrc_enabled" msgid="7010898346095497421">"Prosleđuje se na <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
<string name="sum_cfnrc_disabled" msgid="7222141261321276464">"Onemogućeno"</string>
@@ -332,19 +332,19 @@
<string name="cdma_activate_device" msgid="3793805892364814518">"Aktiviranje uređaja"</string>
<string name="cdma_lte_data_service" msgid="4255018217292548962">"Podesite usl. prenosa podataka"</string>
<string name="carrier_settings_title" msgid="9028166176523012300">"Podešavanja operatera"</string>
- <string name="fdn" msgid="7878832555095183202">"Brojevi za fiksno biranje"</string>
+ <string name="fdn" msgid="7878832555095183202">"Fiksni birani brojevi"</string>
<string name="fdn_with_label" msgid="187084204115493366">"Brojevi za fiksno biranje (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
<string name="manage_fdn_list" msgid="8777755791892122369">"Lista brojeva za fiksno biranje"</string>
<string name="fdn_list_with_label" msgid="7437232552210469217">"Lista brojeva za fiksno biranje (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
<string name="fdn_activation" msgid="2156479741307463576">"FDN aktivacija"</string>
- <string name="fdn_enabled" msgid="5238109009915521240">"Omogućeni su brojevi za fiksno biranje"</string>
- <string name="fdn_disabled" msgid="4700049736675368279">"Onemogućeni su brojevi za fiksno biranje"</string>
+ <string name="fdn_enabled" msgid="5238109009915521240">"Omogućeni su fiksni birani brojevi"</string>
+ <string name="fdn_disabled" msgid="4700049736675368279">"Onemogućeni su fiksni birani brojevi"</string>
<string name="enable_fdn" msgid="3740191529180493851">"Omogući broj za fiksno biranje"</string>
<string name="disable_fdn" msgid="7944020890722540616">"Onemogući broj za fiksno biranje"</string>
<string name="change_pin2" msgid="2153563695382176676">"Promeni PIN2"</string>
<string name="enable_fdn_ok" msgid="7215588870329688132">"Onemogući broj za fiksno biranje"</string>
<string name="disable_fdn_ok" msgid="5727046928930740173">"Omogući broj za fiksno biranje"</string>
- <string name="sum_fdn" msgid="1959399454900272878">"Upravljanje brojevima za fiksno biranje"</string>
+ <string name="sum_fdn" msgid="1959399454900272878">"Upravljanje fiksnim biranim brojevima"</string>
<string name="sum_fdn_change_pin" msgid="6666549734792827932">"Promeni PIN za pristup broju za fiksno biranje"</string>
<string name="sum_fdn_manage_list" msgid="8431088265332628316">"Upravljanje listom telefonskih brojeva"</string>
<string name="voice_privacy" msgid="3776841382844614716">"Privatnost glasa"</string>
@@ -473,7 +473,7 @@
<string name="hac_mode_title" msgid="8740268574688743289">"Slušni aparat"</string>
<string name="hac_mode_summary" msgid="6833851160514929341">"Uključi kompatibilnost sa slušnim aparatom"</string>
<string-array name="tty_mode_entries">
- <item msgid="512950011423868021">"TTY je isključen"</item>
+ <item msgid="512950011423868021">"TTY isključeno"</item>
<item msgid="3971695875449640648">"TTY je pun"</item>
<item msgid="1937509904407445684">"TTY HCO"</item>
<item msgid="5644925873488772224">"TTY VCO"</item>
diff --git a/res/values-be-rBY/arrays.xml b/res/values-be-rBY/arrays.xml
index 773739b..640fba1 100644
--- a/res/values-be-rBY/arrays.xml
+++ b/res/values-be-rBY/arrays.xml
@@ -18,7 +18,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="preferred_network_mode_choices_world_mode">
- <item msgid="3391522821603584785">"Global"</item>
+ <item msgid="3391522821603584785">"Глабальныя"</item>
<item msgid="6753774959494729275">"LTE / CDMA"</item>
<item msgid="8658695584186942227">"LTE / GSM / UMTS"</item>
</string-array>
diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml
index 1f1ad70..45fbc9a 100644
--- a/res/values-be-rBY/strings.xml
+++ b/res/values-be-rBY/strings.xml
@@ -101,16 +101,16 @@
<string name="sum_cfu_enabled_indicator" msgid="4014187342724130197">"Пераадрасацыя ўсіх выклікаў"</string>
<string name="sum_cfu_enabled" msgid="2450052502198827927">"Пераадрасацыя ўсіх тэлефанаванняў на <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
<string name="sum_cfu_enabled_no_number" msgid="6591985777096823616">"Нумар недаступны"</string>
- <string name="sum_cfu_disabled" msgid="8384177689501334080">"Выкл."</string>
+ <string name="sum_cfu_disabled" msgid="8384177689501334080">"Адкл."</string>
<string name="labelCFB" msgid="6139853033106283172">"Калі заняты"</string>
<string name="messageCFB" msgid="3711089705936187129">"Нумар, калі занята"</string>
<string name="sum_cfb_enabled" msgid="5984198104833116690">"Пераадрасацыя на <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfb_disabled" msgid="4913145177320506827">"Выкл."</string>
+ <string name="sum_cfb_disabled" msgid="4913145177320506827">"Адкл."</string>
<string name="disable_cfb_forbidden" msgid="3506984333877998061">"Ваш аператар не падтрымлівае адключэнне перанакіравання выклікаў, калі тэлефон заняты."</string>
<string name="labelCFNRy" msgid="1736067178393744351">"Калі няма адказу"</string>
<string name="messageCFNRy" msgid="672317899884380374">"Нумар, калі няма адказу"</string>
<string name="sum_cfnry_enabled" msgid="6955775691317662910">"Пераадрасацыя на <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfnry_disabled" msgid="3884684060443538097">"Выкл."</string>
+ <string name="sum_cfnry_disabled" msgid="3884684060443538097">"Адкл."</string>
<string name="disable_cfnry_forbidden" msgid="4308233959150658058">"Ваш аператар не падтрымлівае адключэнне перанакіравання выклікаў, калі тэлефон не адказвае."</string>
<string name="labelCFNRc" msgid="2614827454402079766">"Калі недасягальны"</string>
<string name="messageCFNRc" msgid="6380695421020295119">"Нумар, калі недаступны"</string>
@@ -147,7 +147,7 @@
<string name="no_change" msgid="3186040086622435212">"Змены не выкананы."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Выберыце службу галасавой пошты"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Ваш аператар"</string>
- <string name="mobile_networks" msgid="2843854043339307375">"Налады сотавай сеткі"</string>
+ <string name="mobile_networks" msgid="2843854043339307375">"Налады мабільнай сеткі"</string>
<string name="label_available" msgid="1181658289009300430">"Даступныя сеткі"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Пошук..."</string>
<string name="empty_networks_list" msgid="4249426905018815316">"Сеткі не знойдзены."</string>
@@ -162,9 +162,9 @@
<string name="select_automatically" msgid="5628402124471810174">"Выбраць аўтаматычна"</string>
<string name="sum_select_automatically" msgid="5614890115123292400">"Аўтаматычна выбраць прыярытэтную сетку"</string>
<string name="register_automatically" msgid="6017849844573519637">"Аўтаматычная рэгістрацыя..."</string>
- <string name="preferred_network_mode_title" msgid="2336624679902659306">"Прыярытэтны тып сеткі"</string>
+ <string name="preferred_network_mode_title" msgid="2336624679902659306">"Пажаданы тып сеткі"</string>
<string name="preferred_network_mode_summary" msgid="1434820673166126609">"Змяніць рэжым работы сеткі"</string>
- <string name="preferred_network_mode_dialogtitle" msgid="4048082093347807230">"Прыярытэтны тып сеткі"</string>
+ <string name="preferred_network_mode_dialogtitle" msgid="4048082093347807230">"Пажаданы тып сеткі"</string>
<string name="preferred_network_mode_wcdma_perf_summary" msgid="8521677230113533809">"Пераважны рэжым сеткі: пераважна WCDMA"</string>
<string name="preferred_network_mode_gsm_only_summary" msgid="3352445413437453511">"Пераважны рэжым сеткі: толькі GSM"</string>
<string name="preferred_network_mode_wcdma_only_summary" msgid="2836897236221063413">"Пераважны рэжым сеткі: толькі WCDMA"</string>
@@ -202,16 +202,16 @@
<string name="data_enabled" msgid="5972538663568715366">"Дадзеныя ўключаныя"</string>
<string name="data_enable_summary" msgid="2382798156640007971">"Дазволіць выкарыстанне даных"</string>
<string name="dialog_alert_title" msgid="6751344986194435476">"Увага"</string>
- <string name="roaming" msgid="8871412572928323707">"Перадача даных у роўмінгу"</string>
- <string name="roaming_enable" msgid="7331106985174381987">"Падключацца да сэрвісаў перадачы даных у роўмінгу"</string>
- <string name="roaming_disable" msgid="1843417228755568110">"Падключацца да сэрвісаў перадачы даных у роўмінгу"</string>
+ <string name="roaming" msgid="8871412572928323707">"Перадача дадзеных у роўмінгу"</string>
+ <string name="roaming_enable" msgid="7331106985174381987">"Злучацца з паслугамі перадачы дадзеных ў роўмінгу"</string>
+ <string name="roaming_disable" msgid="1843417228755568110">"Злучацца з паслугамі перадачы дадзеных у роўмінгу"</string>
<string name="roaming_reenable_message" msgid="8913735676127858115">"Падлучэнне для перадачы дадзеных страчана, таму што вы выйшлі з зоны пакрыцця сваёй сеткі, а перадача дадзеных у роўмінгу адключана."</string>
<string name="roaming_warning" msgid="1603164667540144353">"Гэта можа прывесці да значных выдаткаў."</string>
<string name="roaming_alert_title" msgid="3654815360303826008">"Дазволіць перадачу даных у роўмінгу?"</string>
<string name="gsm_umts_options" msgid="6538311689850981686">"Параметры GSM/UMTS"</string>
<string name="cdma_options" msgid="4016822858172249884">"Параметры CDMA"</string>
- <string name="throttle_data_usage" msgid="3715677828160555808">"Выкарыстанне трафіку"</string>
- <string name="throttle_current_usage" msgid="8762280193043815361">"Выкарыстанне даных у бягучы перыяд"</string>
+ <string name="throttle_data_usage" msgid="3715677828160555808">"Выкарыстанне дадзеных"</string>
+ <string name="throttle_current_usage" msgid="8762280193043815361">"Выкарыстанне дадзеных у бягучы перыяд"</string>
<string name="throttle_time_frame" msgid="1915198770363734685">"Перыяд выкарыстання дадзеных"</string>
<string name="throttle_rate" msgid="4710388992676803508">"Палітыка хуткасці перадачы дадзеных"</string>
<string name="throttle_help" msgid="243651091785169900">"Дадатковая iнфармацыя"</string>
@@ -349,7 +349,7 @@
<string name="sum_fdn_manage_list" msgid="8431088265332628316">"Кіраванне спісам тэлефонных нумароў"</string>
<string name="voice_privacy" msgid="3776841382844614716">"Палiтыка прыватнасцi Voice"</string>
<string name="voice_privacy_summary" msgid="3159383389833516214">"Уключыць пашыраны рэжым прыватнасці"</string>
- <string name="tty_mode_option_title" msgid="9033098925144434669">"Рэжым TTY"</string>
+ <string name="tty_mode_option_title" msgid="9033098925144434669">"TTY рэжым"</string>
<string name="tty_mode_option_summary" msgid="1073835131534808732">"Задаць рэжым TTY"</string>
<string name="auto_retry_mode_title" msgid="4073265511427813322">"Аўтаматычны паўтор"</string>
<string name="auto_retry_mode_summary" msgid="4973886004067532288">"Уключыць рэжым аўтаматычнага паўтору"</string>
@@ -533,8 +533,8 @@
<string name="alert_dialog_yes" msgid="6674268047820703974">"Так"</string>
<string name="alert_dialog_no" msgid="1476091437797628703">"Не"</string>
<string name="alert_dialog_dismiss" msgid="2491494287075907171">"Скасаваць"</string>
- <string name="voicemail_provider" msgid="5135942703327136909">"Сэрвіс"</string>
- <string name="voicemail_settings" msgid="72448049107749316">"Наладка"</string>
+ <string name="voicemail_provider" msgid="5135942703327136909">"Служба"</string>
+ <string name="voicemail_settings" msgid="72448049107749316">"Налады"</string>
<string name="voicemail_number_not_set" msgid="6724904736891087856">"<Не заданы>"</string>
<string name="other_settings" msgid="3672912580359716394">"Іншыя налады выкліку"</string>
<string name="calling_via_template" msgid="4839419581866928142">"Званкі праз правайдара <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 3829920..65e3a3e 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Не бяха направени промени."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Избор на услугата за гласова поща"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Вашият оператор"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Стар ПИН"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Нов ПИН"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"ПИН се променя"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Новият ПИН е твърде къс."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Новият ПИН е твърде дълъг."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Новият ПИН не е достатъчно надежден. Надеждната парола не бива да има последователни или повтарящи се цифри."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Старият ПИН не съответства."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Новият ПИН съдържа невалидни знаци."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Промяната на ПИН не е възможна"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Настройки за клетъчна мрежа"</string>
<string name="label_available" msgid="1181658289009300430">"Налични мрежи"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Търси се…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Вибриране"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Вибриране"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Визуална гласова поща"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Промяна на ПИН"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Звук"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Мелодия и вибриране"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Вградени SIM карти"</string>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 3c9411e..d3106d4 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"কোনো পরিবর্তন করা হয়নি৷"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ভয়েসমেল পরিষেবা বেছে নিন"</string>
<string name="voicemail_default" msgid="2001233554889016880">"আপনার পরিষেবা প্রদানকারী"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"পুরানো পিন"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"নতুন পিন"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"পিন পরিবর্তন করুন"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"নতুন পিনটি খুবই ছোট৷"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"নতুন পিনটি খুবই দীর্ঘ৷"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"নতুন পিনটি খুবই দুর্বল৷ একটি শক্তিশালী পাসওয়ার্ডে ধারাবাহিক ক্রম বা পুনরাবৃত্ত সংখ্যা থাকা উচিৎ নয়৷"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"পুরানো পিন মিলছে না৷"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"নতুন পিনে অবৈধ অক্ষর রয়েছে৷"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"পিন পরিবর্তন করা গেল না"</string>
<string name="mobile_networks" msgid="2843854043339307375">"সেলুলার নেটওয়ার্ক সেটিংস"</string>
<string name="label_available" msgid="1181658289009300430">"উপলব্ধ নেটওয়ার্কগুলি"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"অনুসন্ধান করছে..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"কম্পন"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"কম্পন"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ভিজ্যুয়াল ভয়েসমেল"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"পিন পরিবর্তন করুন"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"শব্দ"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"রিংটোন ও কম্পন"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"বিল্ট-ইন সিম কার্ডগুলি"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index b3ed481..d207d23 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"No s\'ha fet cap canvi."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Trieu un servei de bústia de veu"</string>
<string name="voicemail_default" msgid="2001233554889016880">"EL teu operador"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN antic"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN nou"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"S\'està canviant el PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"El PIN nou és massa curt."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"El PIN nou és massa llarg."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"El PIN nou no és prou segur. Les contrasenyes segures no poden contenir seqüències contínues ni dígits repetits."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"El PIN antic no coincideix."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"El PIN nou conté caràcters que no són vàlids."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"No es pot canviar el PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Configuració de la xarxa mòbil"</string>
<string name="label_available" msgid="1181658289009300430">"Xarxes disponibles"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"S\'està cercant…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibra"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibra"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Bústia de veu visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Canvia el PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"So"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"So i vibració"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Targetes SIM integrades"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index d7fe3f3..00fd03c 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nebyly provedeny žádné změny."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Zvolte službu hlasové schránky"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Váš operátor"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Starý kód PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nový kód PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Změna kódu PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Nový kód PIN je příliš krátký."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Nový kód PIN je příliš dlouhý."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Nový kód PIN je příliš slabý. Silný kód by neměl obsahovat postupnou řadu čísel ani opakující se čísla."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Starý kód PIN se neshoduje."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Nový kód PIN obsahuje neplatné znaky."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Kód PIN se nepodařilo změnit"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Nastavení mobilní sítě"</string>
<string name="label_available" msgid="1181658289009300430">"Dostupné sítě"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Vyhledávání..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrace"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrace"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizuální hlasová schránka"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Změnit kód PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Zvuk"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Vyzvánění a vibrace"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Vestavěné SIM karty"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 435ca41..2b7e2e8 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Der blev ikke foretaget nogen ændringer."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Vælg telefonsvarertjeneste"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Dit mobilselskab"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Nuværende pinkode"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Ny pinkode"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Skifter pinkoden"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Den nye pinkode er for kort."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Den nye pinkode er for lang."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Denne pinkode er for svag. En stærk adgangskode består ikke af en række tal og har ikke flere af de samme tal efter hinanden."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Den gamle pinkode er forkert."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Den nye pinkode har ugyldige tegn."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Pinkoden kan ikke ændres"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Indstillinger for mobilnetværk"</string>
<string name="label_available" msgid="1181658289009300430">"Tilgængelige netværk"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Søger..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibration"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibration"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuel telefonsvarer"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Skift pinkode"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Lyd"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringetone og vibration"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Indbyggede SIM-kort"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 5dad837..8f75543 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Es wurden keine Änderungen vorgenommen."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Mailbox-Dienst auswählen"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Mobilfunkanbieter"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Alte PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Neue PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN wird geändert"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Die neue PIN ist zu kurz."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Die neue PIN ist zu lang."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Die neue PIN ist zu unsicher. Ein sicheres Passwort sollte keine aufeinanderfolgenden oder wiederholten Zeichen enthalten."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Die alte PIN stimmt nicht überein."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Die neue PIN enthält ungültige Zeichen."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN kann nicht geändert werden"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Einstellungen für Mobilfunknetze"</string>
<string name="label_available" msgid="1181658289009300430">"Verfügbare Netzwerke"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Suche läuft..."</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibration"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibration"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuelle Mailbox"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN ändern"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Töne"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Klingelton & Vibration"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Integrierte SIM-Karten"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index d791f02..1d52966 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Δεν έγιναν αλλαγές."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Επιλογή υπηρεσίας αυτόματου τηλεφωνητή"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Ο πάροχος κινητής τηλεφωνίας"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Παλιό PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Νέο PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Αλλαγή PIN σε εξέλιξη"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Το νέο PIN είναι πολύ μικρό."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Το νέο PIN είναι πολύ μεγάλo."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Το νέο PIN είναι πολύ αδύναμο. Ένας ισχυρός κωδικός πρόσβασης δεν θα πρέπει να αποτελείται από ακολουθίες χαρακτήρων ή επαναλαμβανόμενα ψηφία."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Το παλιό PIN δεν αντιστοιχεί."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Το νέο PIN περιέχει μη έγκυρους χαρακτήρες."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Δεν είναι δυνατή η αλλαγή του PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Ρυθμίσεις δικτ. κιν. τηλ."</string>
<string name="label_available" msgid="1181658289009300430">"Διαθέσιμα δίκτυα"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Αναζήτηση..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Δόνηση"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Δόνηση"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Οπτικός αυτόματος τηλεφ."</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Αλλαγή PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Ήχος"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ήχος κλήσης & δόνηση"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Ενσωματωμένες κάρτες SIM"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index b06fe88..fe6b526 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"No changes were made."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Choose voicemail service"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Your operator"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Old PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"New PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Changing PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"The new PIN is too short."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"The new PIN is too long."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"The new PIN is too weak. A strong password should not have a continuous sequence or repeated digits."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"The old PIN doesn\'t match."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"The new PIN contains invalid characters."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Unable to change PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobile network settings"</string>
<string name="label_available" msgid="1181658289009300430">"Available networks"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Searching…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrate"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrate"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visual Voicemail"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Change PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sound"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringtone & Vibrate"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Built-in SIM cards"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index b06fe88..fe6b526 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"No changes were made."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Choose voicemail service"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Your operator"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Old PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"New PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Changing PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"The new PIN is too short."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"The new PIN is too long."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"The new PIN is too weak. A strong password should not have a continuous sequence or repeated digits."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"The old PIN doesn\'t match."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"The new PIN contains invalid characters."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Unable to change PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobile network settings"</string>
<string name="label_available" msgid="1181658289009300430">"Available networks"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Searching…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrate"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrate"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visual Voicemail"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Change PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sound"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringtone & Vibrate"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Built-in SIM cards"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index b06fe88..fe6b526 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"No changes were made."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Choose voicemail service"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Your operator"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Old PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"New PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Changing PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"The new PIN is too short."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"The new PIN is too long."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"The new PIN is too weak. A strong password should not have a continuous sequence or repeated digits."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"The old PIN doesn\'t match."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"The new PIN contains invalid characters."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Unable to change PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobile network settings"</string>
<string name="label_available" msgid="1181658289009300430">"Available networks"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Searching…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrate"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrate"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visual Voicemail"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Change PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sound"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringtone & Vibrate"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Built-in SIM cards"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 0a7c4d3..dacf247 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"No se realizaron cambios."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Elegir servicio de buzón de voz"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Tu proveedor"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN anterior"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nuevo PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Cambiando el PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"El nuevo PIN es demasiado corto."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"El nuevo PIN es demasiado largo."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"El nuevo PIN no es muy seguro. Una contraseña segura no debería tener secuencias continuas ni dígitos repetidos."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"El PIN anterior no coincide."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"El nuevo PIN contiene caracteres no válidos."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"No se puede cambiar el PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Configuración de la red móvil"</string>
<string name="label_available" msgid="1181658289009300430">"Redes disponibles"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Buscando..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Buzón de voz visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Cambiar PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sonido"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tono y vibración"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Tarjetas SIM integradas"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 44944eb..0cc1cc9 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"No se ha realizado ningún cambio."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Seleccionar servicio de buzón de voz"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Tu operador"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN antiguo"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN nuevo"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Cambiando PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"El PIN nuevo es muy corto."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"El PIN nuevo es muy largo."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"El PIN nuevo no es lo bastante seguro. Una contraseña segura no debería contener secuencias continuas ni dígitos repetidos."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"El PIN antiguo no coincide."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"El PIN nuevo contiene caracteres no válidos."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"No se puede cambiar el PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Ajustes de red móvil"</string>
<string name="label_available" msgid="1181658289009300430">"Redes disponibles"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Buscando..."</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Buzón de voz visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Cambiar PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sonido"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tono y vibración"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Tarjetas SIM integradas"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index bbf0274..a338c1e 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Muudatusi ei tehtud."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Valige kõnepostiteenus"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Teie operaator"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Vana PIN-kood"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Uus PIN-kood"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN-koodi muutmine"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Uus PIN-kood on liiga lühike."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Uus PIN-kood on liiga pikk."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Uus PIN-kood on liiga nõrk. Tugevas paroolis ei tohi olla mitut järjestikust samasugust tähemärki ega korduvaid numbreid."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Vana PIN-kood ei sobi."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Uus PIN-kood sisaldab sobimatuid tähemärke."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN-koodi ei õnnestu muuta"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobiilsidevõrgu seaded"</string>
<string name="label_available" msgid="1181658289009300430">"Saadaolevad võrgud"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Otsimine ..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibreerimine"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibreerimine"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuaalne kõnepost"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN-koodi muutmine"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Heli"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Helin ja vibratsioon"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Sisseehitatud SIM-kaardid"</string>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index aef9587..df93f33 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Ez da aldaketarik egin."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Aukeratu erantzungailu-zerbitzua"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operadorea"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN kode zaharra"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN kode berria"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN kodea aldatzen"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Laburregia da PIN kode berria."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Luzeegia da PIN kode berria."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Ahulegia da PIN kode berria. Pasahitz sendo batek ez luke eduki beharko zenbaki-segida edo errepikatutako zenbakirik."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"PIN kode zaharra ez dator bat."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Balio ez duten karaktereak ditu PIN kode berriak"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Ezin da aldatu PIN kodea"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Sare mugikorraren ezarpenak"</string>
<string name="label_available" msgid="1181658289009300430">"Sare erabilgarriak"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Bilatzen…"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Egin dar-dar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Egin dar-dar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Erantzungailu bisuala"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Aldatu PIN kodea"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Soinua"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tonua eta dardara"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"SIM txartel integratuak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index c7f8430..673f500 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"تغییری انجام نشده است."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"انتخاب سرویس پست صوتی"</string>
<string name="voicemail_default" msgid="2001233554889016880">"شرکت مخابراتی شما"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"پین قدیمی"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"پین جدید"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"تغییر پین"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"پین جدید خیلی کوتاه است."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"پین جدید خیلی طولانی است."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"پین جدید خیلی ضعیف است. گذرواژه قوی نباید توالی از اعداد باشد یا عدد تکراری داشته باشد."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"پین قدیمی مطابقت ندارد."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"پین جدید نویسههای نامعتبری دارد."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"پین تغییر نکرد"</string>
<string name="mobile_networks" msgid="2843854043339307375">"تنظیمات شبکه تلفن همراه"</string>
<string name="label_available" msgid="1181658289009300430">"شبکههای موجود"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"در حال جستجو…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"لرزش"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"لرزش"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"پست صوتی تصویری"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"تغییر پین"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"صدا"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"آهنگ زنگ و لرزش"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"سیمکارتهای داخلی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 98ff6a2..4a6fa68 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Muutoksia ei tehty."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Valitse puhelinvastaajapalvelu"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operaattorisi"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Vanha PIN-koodi"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Uusi PIN-koodi"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN-koodia vaihdetaan"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Uusi PIN-koodi on liian lyhyt."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Uusi PIN-koodi on liian pitkä."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Uusi PIN-koodi on liian heikko. Vahvassa salasanassa ei saa olla peräkkäisiä tai toistuvia numeroita."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Vanha PIN-koodi ei täsmää."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Uusi PIN-koodi sisältää virheellisiä merkkejä."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN-koodin vaihtaminen epäonnistui."</string>
<string name="mobile_networks" msgid="2843854043339307375">"Matkapuhelinverkon asetukset"</string>
<string name="label_available" msgid="1181658289009300430">"Käytettävissä olevat verkot"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Haetaan…"</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Värinä"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Värinä"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuaalinen puhelinvastaaja"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Vaihda PIN-koodi"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Ääni"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Soittoääni ja värinä"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Sisäiset SIM-kortit"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index a7d8a21..d1b91fb 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Aucune modification n\'a été apportée."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Choisissez un service de messagerie vocale."</string>
<string name="voicemail_default" msgid="2001233554889016880">"Votre fournisseur de services"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Ancien NIP"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nouveau NIP"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Modification du NIP en cours…"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Le nouveau NIP est trop court."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Le nouveau NIP est trop long."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Le nouveau NIP n\'est pas assez robuste. Il ne devrait pas contenir de séquences continues ni de chiffres répétés."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Le NIP saisi ne correspond pas à l\'ancien NIP."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Le nouveau NIP contient des caractères incorrects."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Impossible de modifier le NIP"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Paramètres réseaux cellulaires"</string>
<string name="label_available" msgid="1181658289009300430">"Réseaux disponibles"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Recherche en cours…"</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibreur"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibreur"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Messagerie vocale visuelle"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Modifier le NIP"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Son"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Sonnerie et vibreur"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Cartes SIM intégrées"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f94c9e8..75116ec 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Aucune modification n\'a été apportée."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Choisissez un service de messagerie vocale."</string>
<string name="voicemail_default" msgid="2001233554889016880">"Votre opérateur"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Ancien code"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nouveau code"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Modification du code..."</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Le nouveau code est trop court."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Le nouveau code est trop long."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Le nouveau code n\'est pas suffisamment sécurisé. Pour qu\'un mot de passe soit sûr, il ne doit pas contenir de chiffres qui se suivent ou qui se répètent."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"L\'ancien code est erroné."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Le nouveau code contient des caractères incorrects."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Impossible de modifier le code"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Paramètres réseau mobile"</string>
<string name="label_available" msgid="1181658289009300430">"Réseaux disponibles"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Recherche..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibreur"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibreur"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Messagerie vocale visuelle"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Modifier le code"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sonnerie"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Sonnerie et vibreur"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Cartes SIM intégrées"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index f12d9ee..54df51f 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Non se fixeron cambios."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Escolle o servizo de correo de voz"</string>
<string name="voicemail_default" msgid="2001233554889016880">"O teu operador"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN antigo"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN novo"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Cambiando PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"O PIN novo é demasiado curto."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"O PIN novo é demasiado longo."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"O novo PIN é pouco seguro. Para que sexa seguro, non debe conter secuencias continuas nin díxitos repetidos."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"O PIN antigo non coincide."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"O novo PIN contén caracteres non válidos."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Non se puido cambiar o PIN."</string>
<string name="mobile_networks" msgid="2843854043339307375">"Configuración da rede móbil"</string>
<string name="label_available" msgid="1181658289009300430">"Redes dispoñibles"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Buscando..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Correo de voz visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Cambiar PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Son"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ton de chamada e vibración"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Tarxetas SIM integradas"</string>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index b3006f9..2e8c706 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"કોઇ બદલાવો થયાં ન હતાં."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"વૉઇસમેઇલ સેવા પસંદ કરો"</string>
<string name="voicemail_default" msgid="2001233554889016880">"તમારો કેરિઅર"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"જૂનો PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"નવો PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN બદલી રહ્યાં છે"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"નવો PIN ખૂબ ટૂંકો છે."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"નવો PIN ખૂબ લાંબો છે."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"નવો PIN ખૂબ નબળો છે. સશક્ત પાસવર્ડ સતત ક્રમ અથવા પુનરાવર્તિત અંકો ધરાવતો હોવો જોઇએ નહીં."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"જૂનો PIN મેળ ખાતો નથી."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"નવો PIN અમાન્ય અક્ષરો ધરાવે છે."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN બદલવામાં અસમર્થ"</string>
<string name="mobile_networks" msgid="2843854043339307375">"સેલ્યુલર નેટવર્ક સેટિંગ્સ"</string>
<string name="label_available" msgid="1181658289009300430">"ઉપલબ્ધ નેટવર્ક્સ"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"શોધી રહ્યું છે..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"વાઇબ્રેટ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"વાઇબ્રેટ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"વિઝ્યુઅલ વૉઇસમેઇલ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN બદલો"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ધ્વનિ"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"રિંગટોન અને વાઇબ્રેટ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"બિલ્ટ-ઇન SIM કાર્ડ્સ"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 92bffd1..ab6c5e5 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"कोई परिवर्तन नहीं किए गए."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"वॉयस मेल सेवा चुनें"</string>
<string name="voicemail_default" msgid="2001233554889016880">"आपका वाहक"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"पुराना पिन"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"नया पिन"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"पिन बदला जा रहा है"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"नया पिन बहुत छोटा है."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"नया पिन बहुत बड़ा है."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"नया पिन बहुत कमज़ोर है. किसी सशक्त पासवर्ड में निरंतर क्रम या अंकों का दोहराव नहीं होना चाहिए."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"पुराने पिन का मिलान नहीं हो रहा है."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"नए पिन में अमान्य वर्ण शामिल हैं."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"पिन बदलने में असमर्थ"</string>
<string name="mobile_networks" msgid="2843854043339307375">"सेल्युलर नेटवर्क सेटिंग"</string>
<string name="label_available" msgid="1181658289009300430">"उपलब्ध नेटवर्क"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"खोज रहा है..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"कंपन करें"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"कंपन करें"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"विज़ुअल वॉइसमेल"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"पिन बदलें"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ध्वनि"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"रिंगटोन और कंपन"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"अंतर्निहित सिम कार्ड"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 2cd1fe5..8efb8f8 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nisu izvršene nikakve promjene."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Odaberite uslugu govorne pošte"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Vaš mobilni operater"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Stari PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Novi PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Promjena PIN-a"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Novi PIN je prekratak."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Novi PIN je predugačak."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Novi je PIN preslab. Jaka zaporka ne smije sadržavati kontinuirani niz ili ponovljene znamenke."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Stari se PIN ne podudara."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Novi PIN sadrži nevažeće znakove."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN se ne može promijeniti"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Postavke mobilne mreže"</string>
<string name="label_available" msgid="1181658289009300430">"Dostupne mreže"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Pretraživanje…"</string>
@@ -543,6 +552,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibracija"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibracija"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizualna govorna pošta"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Promjena PIN-a"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Zvuk"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Melodija zvona i vibracija"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Ugrađene SIM kartice"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index d0bcb6f..dd4493f 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nem történt változtatás."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Válassza ki a hangposta-szolgáltatást"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Saját mobilszolgáltató"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Régi PIN-kód"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Új PIN-kód"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN-kód módosítása"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Az új PIN-kód túl rövid."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Az új PIN-kód túl hosszú."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Az új PIN-kód túl gyenge. Az erős jelszavak nem tartalmaznak egymás után következő számokat vagy ismétlődő számjegyeket."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"A régi PIN-kód nem egyezik a tárolttal."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Az új PIN-kód érvénytelen karaktereket tartalmaz."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Nem sikerült módosítani a PIN-kódot"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobilhálózati beállítások"</string>
<string name="label_available" msgid="1181658289009300430">"Elérhető hálózatok"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Keresés…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Rezgés"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Rezgés"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizuális hangpostaüzenet"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN-kód módosítása"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Hang"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Csengőhang és rezgés"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Beépített SIM kártyák"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index b71e012..be7bb8a 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Ոչ մի փոփոխություն կատարված չէ:"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Ընտրել ձայնային փոստի ծառայությունը"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Ձեր օպերատորը"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Հին PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Նոր PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN-ը փոխվում է"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Նոր PIN-ը չափազանց կարճ է:"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Նոր PIN-ը չափազանց երկար է:"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Նոր PIN-ը բավականաչափ հուսալի չէ: Հուսալի գաղտնաբառը չպետք է ունենա շարունակական հաջորդականություն կամ կրկնվող թվեր:"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Հին PIN-ը չի համընկնում:"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Նոր PIN-ը պարունակում է անվավեր գրանշաններ:"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Չհաջողվեց փոխել PIN-ը"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Բջջային ցանցի կարգավորումները"</string>
<string name="label_available" msgid="1181658289009300430">"Հասանելի ցանցեր"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Որոնում..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Թրթռալ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Թրթռալ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Տեսանելի ձայնային փոստ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Փոխել PIN-ը"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Ձայն"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ձայներանգ & Թրթռոց"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Ներկառուցված SIM քարտեր"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 56711b7..e699d02 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Tidak ada perubahan yang dilakukan."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Pilih layanan kotak pesan"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operator Anda"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN Lama"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN Baru"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Mengubah PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"PIN baru terlalu pendek."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"PIN baru terlalu panjang."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"PIN baru terlalu lemah. Sandi yang kuat tidak boleh memiliki urutan karakter kontinu atau digit berulang."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"PIN lama tidak cocok."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"PIN baru berisi karakter yang tidak valid."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Tidak dapat mengubah PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Setelan jaringan seluler"</string>
<string name="label_available" msgid="1181658289009300430">"Jaringan yang tersedia"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Menelusuri…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Getar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Getar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Kotak Pesan Visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Ubah PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Suara"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Nada dering & Getar"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Kartu SIM internal"</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 8bf57ea..fa52e5b 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Engu var breytt."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Velja talhólfsþjónustu"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Símafyrirtækið þitt"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Gamla PIN-númerið"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nýtt PIN-númer"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Skipt um PIN-númer"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Nýja PIN-númerið er of stutt."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Nýja PIN-númerið er of langt."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Nýja PIN-númerið er ekki nógu sterkt. Sterk aðgangsorð mega ekki vera með tölustafi í beinni röð eða endurtekna tölustafi."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Gamla PIN-númerið passar ekki."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Nýja PIN-númerið inniheldur ógilda stafi."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Ekki var hægt að breyta PIN-númerinu"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Farsímakerfisstillingar"</string>
<string name="label_available" msgid="1181658289009300430">"Símkerfi í boði"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Leitar…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Titringur"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Titringur"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Myndrænt talhólf"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Breyta PIN-númeri"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Hljóð"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Hringitónn og titringur"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Innbyggð SIM-kort"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 7c26677..206b3f4 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nessuna modifica effettuata."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Scegli il servizio di segreteria"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operatore"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Vecchio PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nuovo PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Modifica del PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Il nuovo PIN è troppo corto."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Il nuovo PIN è troppo lungo."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Il nuovo PIN è troppo semplice. Una password efficace non deve contenere sequenze continue o cifre ripetute."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Il vecchio PIN non corrisponde."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Il nuovo PIN contiene caratteri non validi."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Impossibile cambiare il PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Impostazioni rete cellulare"</string>
<string name="label_available" msgid="1181658289009300430">"Reti disponibili"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Ricerca..."</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrazione"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrazione"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Leggi la segreteria"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Cambia PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Suono"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Suoneria e vibrazione"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Schede SIM integrate"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 1ee7865..211c2b0 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"לא בוצעו שינויים."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"בחר שירות של דואר קולי"</string>
<string name="voicemail_default" msgid="2001233554889016880">"הספק שלך"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"קוד גישה ישן"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"קוד גישה חדש"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"משנה את קוד הגישה"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"קוד הגישה החדש קצר מדי."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"קוד הגישה החדש ארוך מדי."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"קוד הגישה החדש חלש מדי. בסיסמה חזקה אסור שיהיו ספרות ברצף מספרי או ספרות שחוזרות על עצמן."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"קוד הגישה הישן אינו תואם."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"קוד הגישה החדש מכיל תווים לא חוקיים."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"לא ניתן לשנות את קוד הגישה"</string>
<string name="mobile_networks" msgid="2843854043339307375">"הגדרות רשת סלולרית"</string>
<string name="label_available" msgid="1181658289009300430">"רשתות זמינות"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"מחפש..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"רטט"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"רטט"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"דואר קולי ויזואלי"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"שינוי קוד הגישה"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"צליל"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"רינגטון ורטט"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"כרטיסי SIM מובנים"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index d3de4fd..6db4bc1 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"変更されていません。"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ボイスメールサービスを選択"</string>
<string name="voicemail_default" msgid="2001233554889016880">"携帯通信会社"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"古い PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"新しい PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN を変更しています"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"新しい PIN が短すぎます。"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"新しい PIN が長すぎます。"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"新しい PIN の強度が弱すぎます。パスワードには連続する文字や、数字の繰り返しは使用しないでください。"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"古い PIN が一致しません。"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"新しい PIN に無効な文字が含まれています。"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN を変更できませんでした"</string>
<string name="mobile_networks" msgid="2843854043339307375">"モバイルネットワーク設定"</string>
<string name="label_available" msgid="1181658289009300430">"利用可能なネットワーク"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"検索中..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"バイブレーション"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"バイブレーション"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ビジュアルボイスメール"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN の変更"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"通知音"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"着信音とバイブレーション"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"内蔵のSIMカード"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 924dc17..241801b 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"ცვლილებები არ განხორციელებულა."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ხმოვანი ფოსტის სერვისის არჩევა"</string>
<string name="voicemail_default" msgid="2001233554889016880">"თქვენი ოპერატორი"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"ძველი PIN-კოდი"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"ახალი PIN-კოდი"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"მიმდინარეობს PIN-კოდის შეცვლა"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"ახალი PIN-კოდი ძალიან მოკლეა."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"ახალი PIN-კოდი ძალიან გრძელია."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"ახალი PIN-კოდი ძალიან სუსტია. ძლიერი პაროლი არ უნდა შეიცავდეს გამეორებული ციფრების გრძელ თანმიმდევრობას."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"ძველი PIN-კოდი არ თანხვდება."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"ახალი PIN-კოდი არასწორ სიმბოლოებს შეიცავს."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN-კოდის შეცვლა შეუძლებელია"</string>
<string name="mobile_networks" msgid="2843854043339307375">"ფიჭური ქსელის პარამეტრებიჶ"</string>
<string name="label_available" msgid="1181658289009300430">"ხელმისაწვდომი ქსელები"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"ძიება..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"ვიბრაცია"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"ვიბრაცია"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ვიზუალური ხმოვანი ფოსტა"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN-კოდის შეცვლა"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ხმა"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"ზარის მელოდია & ვიბრაცია"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"ჩაშენებული SIM ბარათები"</string>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index b810ec3..57314a4 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Еш өзгеріс жасалмаған."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Дауыс хабары қызметін таңдау"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Операторыңыз"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Ескі PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Жаңа PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN өзгерту"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Жаңа PIN код тым қысқа."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Жаңа PIN код тым ұзын."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Жаңа PIN код тым әлсіз. Күшті құпия сөзде үздіксіз реттік немесе қайталанатын таңбалар болмауы тиіс."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Ескі PIN код сәйкес келмейді."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Жаңа PIN кодта жарамсыз таңбалар бар."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN кодты өзгерту мүмкін емес"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Ұялы желі параметрлері"</string>
<string name="label_available" msgid="1181658289009300430">"Қол жетімді желілер"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Іздеуде…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Діріл"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Діріл"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Визуалды дауыс поштасы"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN кодты өзгерту"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Дыбыс"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Рингтон& Діріл"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Кірістірілген SIM карталары"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 6e5aaca..c0f998c 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"មិនបានប្ដូរ។"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ជ្រើសសេវាសារជាសំឡេង"</string>
<string name="voicemail_default" msgid="2001233554889016880">"អ្នកផ្តល់សេវាទូរស័ព្ទរបស់អ្នក"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"លេខកូដ PIN ថ្មី"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"លេខកូដ PIN ថ្មី"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"កំពុងប្ដូរលេខកូដ PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"លេខកូដ PIN ថ្មីខ្លីពេក។"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"លេខកូដ PIN ថ្មីវែងពេក។"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"លេខកូដ PIN ថ្មីខ្សោយពេក។ ពាក្យសម្ងាត់ដែលខ្លាំងមិនគួរមានលេខរៀងតគ្នា ឬស្ទួនគ្នាទេ។"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"លេខកូដ PIN ចាស់មិនត្រូវគ្នា។"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"លេខកូដ PIN ថ្មីមានតួអក្សរមិនត្រឹមត្រូវ។"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"មិនអាចប្ដូរលេខកូដ PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"ការកំណត់បណ្ដាញចល័ត"</string>
<string name="label_available" msgid="1181658289009300430">"បណ្ដាញដែលមាន"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"កំពុងស្វែងរក..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"ញ័រ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"ញ័រ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"សារជាសំឡេងអាចមើលឃើញ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"ប្ដូរលេខកូដ PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"សំឡេង"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"សំឡេងរោទ៍ & ញ័រ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"ស៊ីមកាតជាប់ជាមួយ"</string>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 8c036e6..ecb4a16 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"ಯಾವುದೇ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲಿಲ್ಲ."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ಧ್ವನಿಮೇಲ್ ಸೇವೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="voicemail_default" msgid="2001233554889016880">"ನನ್ನ ವಾಹಕ"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"ಹಳೆಯ ಪಿನ್"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"ಹೊಸ ಪಿನ್"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"ಪಿನ್ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"ಹೊಸ ಪಿನ್ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"ಹೊಸ ಪಿನ್ ತುಂಬಾ ಉದ್ದವಾಗಿದೆ."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"ಹೊಸ ಪಿನ್ ತುಂಬಾ ದುರ್ಬಲವಾಗಿದೆ. ಪ್ರಬಲ ಪಾಸ್ವರ್ಡ್ ನಿರಂತರ ಅನುಕ್ರಮ ಅಥವಾ ಪುನರಾವರ್ತಿತ ಅಂಕಿಗಳನ್ನು ಹೊಂದುವಂತಿಲ್ಲ."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"ಹಳೆಯ ಪಿನ್ ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"ಹೊಸ ಪಿನ್ ಅಮಾನ್ಯವಾದ ಅಕ್ಷರಗಳನ್ನು ಒಳಗೊಂಡಿದೆ."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"ಪಿನ್ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="mobile_networks" msgid="2843854043339307375">"ಸೆಲ್ಯುಲಾರ್ ನೆಟ್ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="label_available" msgid="1181658289009300430">"ಲಭ್ಯವಿರುವ ನೆಟ್ವರ್ಕ್ಗಳು"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"ವೈಬ್ರೇಟ್"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"ವೈಬ್ರೇಟ್"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ದೃಶ್ಯ ಧ್ವನಿಮೇಲ್"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"ಪಿನ್ ಬದಲಾಯಿಸಿ"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ಧ್ವನಿ"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"ರಿಂಗ್ಟೋನ್ & ವೈಬ್ರೇಟ್"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"ಅಂತರ್-ರಚಿತ ಸಿಮ್ ಕಾರ್ಡ್ಗಳು"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 7c49406..3b9b86e 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"변경사항이 없습니다."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"음성사서함 서비스 선택"</string>
<string name="voicemail_default" msgid="2001233554889016880">"이동통신사"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"이전 PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"새 PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN 변경 중"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"새 PIN이 너무 짧습니다."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"새 PIN이 너무 깁니다."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"새 PIN의 안정성이 낮습니다. 안전한 비밀번호에는 연속되는 숫자 또는 반복되는 숫자를 사용하지 말아야 합니다."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"이전 PIN이 일치하지 않습니다."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"새 PIN에 잘못된 문자가 있습니다."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN을 변경할 수 없습니다."</string>
<string name="mobile_networks" msgid="2843854043339307375">"이동통신망 설정"</string>
<string name="label_available" msgid="1181658289009300430">"사용 가능한 네트워크"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"검색 중..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"진동"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"진동"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"시각적 음성사서함"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN 변경"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"알림음"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"벨소리 및 진동"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"내장된 SIM 카드"</string>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 9730d53..b03984c 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Эч өзгөртүү киргизилген жок."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Үн почтасынын кызматын тандаңыз"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Операторуңуз"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Эски PIN код"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Жаңы PIN код"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN код өзгөртүлүүдө"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Жаңы PIN код өтө эле кыска."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Жаңы PIN код өтө эле узун."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Жаңы PIN код өтө эле туруксуз. Туруктуу сырсөз үзгүлтүксүз катардан же кайталанган сандардан турбашы керек."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Эски PIN код дал келген жок."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Жаңы PIN коддо жараксыз белгилер бар."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN код өзгөртүлгөн жок"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Мобилдик тармактын жөндөөлөрү"</string>
<string name="label_available" msgid="1181658289009300430">"Жеткиликтүү тармактар"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Изделүүдө…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Дирилдөө"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Дирилдөө"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Визуалдык үн почтасы"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN кодду өзгөртүү"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Үнү"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Рингтон жана Титирөө"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Кыналган SIM карталар"</string>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 9b9a6db..76f1978 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"ບໍ່ມີການປ່ຽນແປງເກີດຂຶ້ນ."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ເລືອກບໍລິການຂໍ້ຄວາມສຽງ"</string>
<string name="voicemail_default" msgid="2001233554889016880">"ຜູ້ໃຫ້ບໍລິການຂອງທ່ານ"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"ລະຫັດ PIN ເກົ່າ"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"ລະຫັດ PIN ໃໝ່"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"ກຳລັງປ່ຽນລະຫັດ PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"ລະຫັດ PIN ໃໝ່ສັ້ນເກີນໄປ."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"ລະຫັດ PIN ໃໝ່ຍາວເກີນໄປ."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"ລະຫັດ PIN ໃໝ່ງ່າຍເກີນໄປ. ລະຫັດຜ່ານທີ່ຍາກບໍ່ຄວນຈະມີຕົວເລກຕໍ່ເນື່ອງ ຫຼື ຕົວເລກຊໍ້າໆກັນ."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"ລະຫັດ PIN ເກົ່າບໍ່ກົງກັນ."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"ລະຫັດ PIN ໃໝ່ມີຕົວອັກສອນທີ່ບໍ່ຖືກຕ້ອງ."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"ບໍ່ສາມາດປ່ຽນລະຫັດ PIN ໄດ້"</string>
<string name="mobile_networks" msgid="2843854043339307375">"ການຕັ້ງຄ່າເຄືອຂ່າຍມືຖື"</string>
<string name="label_available" msgid="1181658289009300430">"ເຄືອຂ່າຍທີ່ມີ"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"ກຳລັງຊອກຫາ..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"ສັ່ນເຕືອນ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"ສັ່ນເຕືອນ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ຂໍ້ຄວາມສຽງປະກອບພາບ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"ປ່ຽນລະຫັດ PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ສຽງ"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"ຣິງໂທນ & ການສັ່ນເຕືອນ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"SIM ກາດທີ່ມາກັບເຄື່ອງ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index c92a8cc..362bfd0 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Neatlikta jokių pakeitimų."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Pasirinkti balso pašto paslaugą"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Jūsų operatorius"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Senas PIN kodas"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Naujas PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN kodo keitimas"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Naujas PIN kodas per trumpas."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Naujas PIN kodas per ilgas."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Naujas PIN kodas nepakankamai patikimas. Patikimame slaptažodyje neturėtų būti kelių vienodų simbolių iš eilės ar pasikartojančių skaitmenų."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Senas PIN kodas nesutampa."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Naujame PIN kode yra netinkamų simbolių."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Nepavyko pakeisti PIN kodo"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Korinio tinklo nustatymai"</string>
<string name="label_available" msgid="1181658289009300430">"Galimi tinklai"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Ieškoma…"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibruoti"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibruoti"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vaizdinis balso paštas"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Keisti PIN kodą"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Garsas"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Skambėjimo tonas ir vibracija"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Įtaisytosios SIM kortelės"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b7f2902..ceafb8d 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Izmaiņas netika veiktas."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Izvēlieties balss pasta pakalpojumu"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Jūsu operators"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Iepriekšējais PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Jaunais PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Notiek PIN maiņa"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Jaunais PIN ir pārāk īss."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Jaunais PIN ir pārāk garš."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Jaunais PIN nav pietiekami drošs. Droša parole nedrīkst ietvert secīgus vai atkārtotus ciparus."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Vecais PIN neatbilst."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Jaunajā PIN ir ietvertas nederīgas rakstzīmes."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Neizdevās mainīt PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobilā tīkla iestatījumi"</string>
<string name="label_available" msgid="1181658289009300430">"Pieejamie tīkli"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Notiek meklēšana…"</string>
@@ -545,6 +554,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrozvans"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrozvans"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizuālais balss pasts"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Mainīt PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Signāls"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Zvana signāls un vibrācija"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Iebūvētās SIM kartes"</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 5af6a34..a3edcea 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Не беа направени промени."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Избери услуга на говорна пошта"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Вашиот оператор"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Стар PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Нов PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN-кодот се променува"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Новиот PIN е премногу кус."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Новиот PIN е премногу долг."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Новиот PIN е премногу слаб. Силна лозинка не треба да содржи непрекината серија или цифри што се повторуваат."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Стариот PIN не се совпаѓа."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Новиот PIN содржи погрешни знаци."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN-кодот не може да се промени"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Поставки за мобилна мрежа"</string>
<string name="label_available" msgid="1181658289009300430">"Достапни мрежи"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Се пребарува..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Вибрирање"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Вибрирање"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Визуелна говорна пошта"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Променете PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Звук"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Мелодија и вибрации"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Вградени СИМ-картички"</string>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 957b3b3..3d23868 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"മാറ്റങ്ങളൊന്നും വരുത്തിയിട്ടില്ല."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"വോയ്സ്മെയിൽ സേവനങ്ങൾ തിരഞ്ഞെടുക്കുക"</string>
<string name="voicemail_default" msgid="2001233554889016880">"നിങ്ങളുടെ കാരിയർ"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"പഴയ പിൻ"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"പുതിയ പിൻ"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"പിൻ മാറ്റുന്നു"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"പുതിയ പിൻ വളരെ ചെറുതാണ്."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"പുതിയ പിൻ വളരെ ദൈർഘ്യമേറിയതാണ്."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"പുതിയ പിൻ വളരെ ദുർബലമാണ്. ഒരു ദൃഢമായ പാസ്വേഡിൽ തുടർച്ചയായി വരുന്നതോ ആവർത്തിച്ച് വരുന്നതോ ആയ അക്കങ്ങൾ ഉണ്ടാവരുത്."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"പഴയ പിന്നുമായി യോജിക്കുന്നില്ല."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"പുതിയ പിന്നിൽ അസാധുവായ പ്രതീകങ്ങൾ അടങ്ങിയിരിക്കുന്നു."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"പിൻ മാറ്റാനായില്ല"</string>
<string name="mobile_networks" msgid="2843854043339307375">"സെല്ലുലാർ നെറ്റ്വർക്ക് ക്രമീകരണങ്ങൾ"</string>
<string name="label_available" msgid="1181658289009300430">"ലഭ്യമായ നെറ്റ്വർക്കുകൾ"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"തിരയുന്നു…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"വൈബ്രേറ്റുചെയ്യുക"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"വൈബ്രേറ്റുചെയ്യുക"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"വിഷ്വൽ വോയ്സ്മെയിൽ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"പിൻ മാറ്റുക"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ശബ്ദം"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"റിംഗ്ടോണും വൈബ്രേറ്റുചെയ്യലും"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"അന്തർ നിർമ്മിത സിം കാർഡുകൾ"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index a922251..15176d7 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Ямар ч өөрчлөлт хийгдсэнгүй."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Дуут шуудангийн үйлчилгээг сонгох"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Таны оператор компани"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Хуучин PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Шинэ PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN өөрчилж байна"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Шинэ PIN хэт богино байна."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Шинэ PIN хэт урт байна."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Шинэ PIN хэт амархан байна. Сайн нууц үгэнд үргэлжилсэн дараалал буюу давтагдсан цифр ордоггүй."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Хуучин PIN таарахгүй байна."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Шинэ PIN-д буруу тэмдэгт агуулагдаж байна."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN-г өөрчлөх боломжгүй"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Үүрэн сүлжээний тохиргоо"</string>
<string name="label_available" msgid="1181658289009300430">"Боломжтой сүлжээнүүд"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Хайж байна..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Чичиргээ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Чичиргээ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Уншиж болохуйц дуут шуудан"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN өөрчлөх"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Дуу"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Хонхны ая & Чичиргээ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Суурилагдсан SIM карт"</string>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 2e9b8c3..c26cd36 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"कोणतेही बदल केले नाहीत."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"व्हॉइसमेल सेवा निवडा"</string>
<string name="voicemail_default" msgid="2001233554889016880">"आपला वाहक"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"जुना पिन"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"नवीन पिन"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"पिन बदलत आहे"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"नवीन पिन खूप लहान आहे."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"नवीन पिन खूप दीर्घ आहे."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"नवीन पिन खूप कमकुवत आहे. सशक्त संकेतशब्दामध्ये अखंड क्रमवारी किंवा पुनरावृत्ती केलेले अंक नसावेत."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"जुना पिन जुळत नाही."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"नवीन पिन मध्ये अवैध वर्ण आहेत."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"पिन बदलण्यात अक्षम"</string>
<string name="mobile_networks" msgid="2843854043339307375">"सेल्युलर नेटवर्क सेटिंग्ज"</string>
<string name="label_available" msgid="1181658289009300430">"उपलब्ध नेटवर्क"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"शोधत आहे..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"कंपन होणे"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"कंपन होणे"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"दृश्यमान व्हॉइसमेल"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"पिन बदला"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ध्वनी"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"रिंगटोन आणि कंपन"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"अंगभूत सिम कार्डे"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index bc0b731..ec18bbc 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Tiada perubahan dibuat."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Pilih perkhidmatan mel suara"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Pembawa anda"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN lama"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN baharu"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Menukar PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"PIN baharu terlalu pendek."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"PIN baharu terlalu panjang."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"PIN baharu terlalu lemah. Kata laluan yang kukuh tidak seharusnya mempunyai digit yang berturutan atau berulangan."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"PIN lama tidak sepadan."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"PIN baharu mengandungi aksara yang tidak sah."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Tidak dapat menukar PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Tetapan rangkaian selular"</string>
<string name="label_available" msgid="1181658289009300430">"Rangkaian sedia ada"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Mencari..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Getar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Getar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Mel Suara Visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Tukar PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Bunyi"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Nada dering & Bergetar"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Kad SIM terbina dalam"</string>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index 9a6f2e3..81aa492 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"အပြောင်းအလဲများ မပြုလုပ်ထားပါ"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"အသံစာပို့စနစ် ဝန်ဆောင်မှု ရွေးပါ"</string>
<string name="voicemail_default" msgid="2001233554889016880">"သင့် မိုဘိုင်းဆက်သွယ်ရေး ဝန်ဆောင်မှုဌာန"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"ပင်နံပါတ်အဟောင်း"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"ပင်နံပါတ်အသစ်"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"ပင်နံပါတ်ပြောင်းနေသည်"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"ပင်နံပါတ်အသစ်မှာ တိုလွန်းနေသည်။"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"ပင်နံပါတ်အသစ်မှာ ရှည်လွန်းနေသည်။"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"ပင်နံပါတ်အသစ်မှာ အားနည်းလွန်းနေသည်။ အားကောင်းသောစကားဝှက်တစ်ခုတွင် အစဉ်လိုက်စာလုံးများ (သို့) ထပ်တလဲလဲသုံးထားသောကိန်းဂဏန်းများ မပါသင့်ပါ။"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"ပင်နံပါတ်အဟောင်းမှာ မကိုက်ညီပါ။"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"ပင်နံပါတ်အသစ်တွင် အသုံးပြု၍မရသောစာလုံးများ ပါဝင်နေပါသည်။"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"ပင်နံပါတ်ကို ပြောင်း၍မရပါ"</string>
<string name="mobile_networks" msgid="2843854043339307375">"ဆဲလ်လူလာ ကွန်ရက် ဆက်တင်များ"</string>
<string name="label_available" msgid="1181658289009300430">"ရရှိနိုင်သော ကွန်ယက်များ"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"ရှာဖွေနေသည်…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"တုန်ခါခြင်း"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"တုန်ခါခြင်း"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"အမြင် အသံမေးလ်"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"ပင်နံပါတ်ပြောင်းပါ"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"အသံ"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"ဖုန်းမြည်သံ & တုန်ခါသံ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"တပ်ဆင်ပြီး ဆင်းမ် ကဒ်များ"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 2211850..62c5538 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Ingen endringer ble utført."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Velg leverandør for talepostkasse"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operatøren din"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Gammel PIN-kode"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Ny PIN-kode"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Bytter PIN-kode"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Den nye PIN-koden er for kort."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Den nye PIN-koden er for lang."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Den nye PIN-koden er for svak. Sterke passord inneholder ikke sammenhengende sekvenser eller gjentatte sifre."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Den gamle PIN-koden er feil."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Den nye PIN-koden inneholder ugyldige tegn."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Kan ikke bytte PIN-kode"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobilnettinnstillinger"</string>
<string name="label_available" msgid="1181658289009300430">"Tilgjengelige nettverk"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Søker …"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrering"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrering"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuell talepostkasse"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Bytt PIN-kode"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Lyd"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringetone og vibrering"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Innebygde SIM-kort"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index 23ab2a9..8e1deda 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"केही पनि फेरबदल गरिएन।"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"भ्वाइसमेल सेवा छान्नुहोस्"</string>
<string name="voicemail_default" msgid="2001233554889016880">"तपाईंको वाहक"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"पुरानो PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"नयाँ PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN परिवर्तन गर्दै"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"नयाँ PIN अत्यन्त छोटो छ।"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"नयाँ PIN अत्यन्त लामो छ।"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"नयाँ PIN अत्यन्त कमजोर छ। बलियो पासवर्डमा लगातारको अनुक्रम वा दोहोरिएका अङ्कहरू हुनु हुँदैन।"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"पुरानो PIN मेल खाँदैन।"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"नयाँ PIN मा अमान्य वर्णहरू छन्।"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN परिवर्तन गर्न सकिएन"</string>
<string name="mobile_networks" msgid="2843854043339307375">"सेलुलर सञ्जाल सेटिङहरू"</string>
<string name="label_available" msgid="1181658289009300430">"उपलब्ध नेटवर्कहरू"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"खोजी गर्दै..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"भाइब्रेट"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"भाइब्रेट"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"भिजुअल भ्वाइस मेल"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN परिवर्तन गर्नुहोस्"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"आवाज:"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"रिङ्गटोन र भाइब्रेट"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"निर्मित SIM कार्डहरू"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 6277a82..7563ff9 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Er zijn geen wijzigingen aangebracht."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Service voor voicemail selecteren"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Je provider"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Oude pincode"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nieuwe pincode"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Pincode wijzigen"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"De nieuwe pincode is te kort."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"De nieuwe pincode is te lang."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"De nieuwe pincode is niet sterk genoeg. Een sterk wachtwoord mag geen opeenvolgende cijferreeks of herhaalde cijfers bevatten."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"De oude pincode komt niet overeen."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"De nieuwe pincode bevat ongeldige tekens."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Kan pincode niet wijzigen"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Instellingen voor mobiele netwerken"</string>
<string name="label_available" msgid="1181658289009300430">"Beschikbare netwerken"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Zoeken..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Trillen"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Trillen"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuele voicemail"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Pincode wijzigen"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Geluid"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Beltoon en trillen"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Ingebouwde simkaarten"</string>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index c85d93e..a2ce946 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"ਕੋਈ ਬਦਲਾਵ ਨਹੀਂ ਕੀਤੇ ਗਏ ਹਨ।"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"ਵੌਇਸਮੇਲ ਸੇਵਾ ਚੁਣੋ"</string>
<string name="voicemail_default" msgid="2001233554889016880">"ਤੁਹਾਡਾ ਕੈਰੀਅਰ"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"ਪੁਰਾਣਾ PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"ਨਵਾਂ PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN ਬਦਲਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"ਨਵਾਂ PIN ਬਹੁਤ ਹੀ ਛੋਟਾ ਹੈ।"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"ਨਵਾਂ PIN ਬਹੁਤ ਹੀ ਵੱਡਾ ਹੈ।"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"ਨਵਾਂ PIN ਬਹੁਤ ਹੀ ਕਮਜ਼ੋਰ ਹੈ। ਮਜ਼ਬੂਤ ਪਾਸਵਰਡ ਵਿੱਚ ਨਿਰੰਤਰ ਲੜੀ ਜਾਂ ਦੁਹਰਾਏ ਗਏ ਅੰਕ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ।"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"ਪੁਰਾਣਾ PIN ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ।"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"ਨਵੇਂ PIN ਵਿੱਚ ਅਵੈਧ ਅੱਖਰ-ਚਿੰਨ੍ਹ ਹਨ।"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN ਨੂੰ ਬਦਲਣ ਵਿੱਚ ਅਸਮਰੱਥ"</string>
<string name="mobile_networks" msgid="2843854043339307375">"ਸੈਲਿਊਲਰ ਨੈਟਵਰਕ ਸੈਟਿੰਗਾਂ"</string>
<string name="label_available" msgid="1181658289009300430">"ਉਪਲਬਧ ਨੈਟਵਰਕ"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"ਖੋਜ ਰਿਹਾ ਹੈ..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"ਥਰਥਰਾਹਟ ਕਰੋ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"ਥਰਥਰਾਹਟ ਕਰੋ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ਵਿਜੁਅਲ ਵੌਇਸਮੇਲ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN ਬਦਲੋ"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ਅਵਾਜ਼"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"ਰਿੰਗਟੋਨ ਅਤੇ ਥਰਥਰਾਹਟ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"ਬਿਲਟ-ਇਨ SIM ਕਾਰਡ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 59dd841..734a205 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nie dokonano żadnych zmian."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Wybierz usługę poczty głosowej"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Mój operator"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Stary PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nowy PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Zmieniam PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Nowy PIN jest za krótki."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Nowy PIN jest za długi."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Nowy PIN jest zbyt słaby. Silne hasło nie może zawierać ciągu kolejnych cyfr lub powtarzających się cyfr."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Stary PIN jest nieprawidłowy."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Nowy PIN zawiera nieprawidłowe znaki."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Nie udało się zmienić kodu PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Ustawienia sieci komórkowej"</string>
<string name="label_available" msgid="1181658289009300430">"Dostępne sieci"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Wyszukiwanie..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Wibracje"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Wibracje"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Wizualna poczta głosowa"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Zmień PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Dźwięk"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Dzwonek i wibracje"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Wbudowane karty SIM"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 40caee6..8e7498c 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Não foram efectuadas alterações."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Escolha o serviço de correio de voz"</string>
<string name="voicemail_default" msgid="2001233554889016880">"O seu operador"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN antigo"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Novo PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"A alterar o PIN…"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"O novo PIN é demasiado curto."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"O novo PIN é demasiado longo."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"O novo PIN é demasiado fraco. Uma palavra-passe forte não deve ter uma sequência de dígitos contínua ou repetida."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"O PIN antigo é diferente."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"O novo PIN contém carateres inválidos."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Não é possível alterar o PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Definições de rede móvel"</string>
<string name="label_available" msgid="1181658289009300430">"Redes disponíveis"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"A pesquisar..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Correio de voz visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Alterar PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Som"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tocar e Vibrar"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Cartões SIM incorporados"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index fe89fbd..6194cfb 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nenhuma alteração foi feita."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Escolha o serviço de correio de voz"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Sua operadora"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN antigo"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Novo PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Alterando o PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"O novo PIN é curto demais."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"O novo PIN é longo demais."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"O novo PIN é fácil demais. Uma senha segura não deve ter uma sequência contínua nem dígitos repetidos."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"O PIN antigo não corresponde."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"O novo PIN contém caracteres inválidos."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Não foi possível alterar o PIN."</string>
<string name="mobile_networks" msgid="2843854043339307375">"Configurações de rede celular"</string>
<string name="label_available" msgid="1181658289009300430">"Redes disponíveis"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Pesquisando..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrar"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrar"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Correio de voz visual"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Alterar PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Som"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Toque e vibração"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Cartões SIM integrados"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 3cc8422..2e763b4 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nicio schimbare efectuată."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Alegeți serviciul de mesagerie vocală"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operatorul dvs."</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Codul PIN vechi"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Codul PIN nou"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Se schimbă codul PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Codul PIN nou este prea scurt."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Codul PIN nou este prea lung."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Codul PIN nou este prea slab. O parolă puternică nu ar trebui să aibă o secvență continuă sau cifre repetitive."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Codul PIN vechi nu corespunde."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Codul PIN nou conține caractere nevalide."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Nu se poate schimba codul PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Setările pentru rețeaua mobilă"</string>
<string name="label_available" msgid="1181658289009300430">"Rețele disponibile"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Se caută…"</string>
@@ -543,6 +552,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrații"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrații"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Mesagerie vocală vizuală"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Schimbați codul PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sunet"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ton de apel și vibrare"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Carduri SIM încorporate"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 29e07a9..e666ec2 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Номер не изменен."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Выберите службу голосовой почты"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Ваш оператор связи"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Старый PIN-код"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Новый PIN-код"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Изменение PIN-кода…"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Новый PIN-код слишком короткий"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Новый PIN-код слишком длинный"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Новый PIN-код слишком простой. Чтобы пароль был надежным, он не должен содержать непрерывную последовательность чисел или повторяющиеся цифры."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Старый PIN-код указан неверно"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Новый PIN-код содержит недопустимые символы"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Не удалось сменить PIN-код"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Настройки мобильных сетей"</string>
<string name="label_available" msgid="1181658289009300430">"Доступные сети"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Поиск…"</string>
@@ -548,6 +557,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Вибросигнал"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Вибросигнал"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Визуальная голосовая почта"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Изменение PIN-кода"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Звук"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Рингтон и вибросигнал"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Встроенные SIM-карты"</string>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 95dc439..021e157 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"කිසිඳු වෙනස්කමක් සිදු නොකෙරුණි."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"හඬ තැපැල් සේවාව තෝරන්න"</string>
<string name="voicemail_default" msgid="2001233554889016880">"ඔබගේ වාහකයා"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"පැරණි PIN අංකය"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"නව PIN අංකය"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN අංකය වෙනස් කරමින්"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"නව PIN අංකය කෙටි වැඩිය."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"නව PIN අංකය දිග වැඩිය."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"නව PIN අංකය දුර්වල වැඩිය. ශක්තිමත් මුරපදයක අඛණ්ඩ අනුපිළිවෙළක් හෝ පුනරාවර්ත ඉලක්කම් නොතිබිය යුතුය."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"පැරණි PIN අංකය නොගැළපේ."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"නව PIN අංකයෙහි අවලංගු අනුලකුණු අන්තර්ගත වේ."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN අංකය මාරු කිරීමට නොහැකිය"</string>
<string name="mobile_networks" msgid="2843854043339307375">"සෙලියුලර් ජාල සැකසීම්"</string>
<string name="label_available" msgid="1181658289009300430">"තිබෙන ජාල"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"සොයමින්..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"කම්පනය වීම"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"කම්පනය වීම"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"දෘශ්ය හඬ තැපෑල"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN අංකය වෙනස් කරන්න"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ශබ්දය"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"රිගින් ටෝන් සහ කම්පනය කරන්න"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"තිළැලි SIM කාඩ් පත්"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index afcde37..dd8a79c 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Neuskutočnili sa žiadne zmeny."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Zvoliť službu hlasovej schránky"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Váš operátor"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Starý PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nový PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Mení sa PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Nový PIN je príliš krátky."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Nový PIN je príliš dlhý."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Nový PIN je príliš slabý. Silné heslo by nemalo obsahovať postupnosť ani opakujúce sa číslice."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Starý PIN sa nezhoduje."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Nový PIN obsahuje neplatné znaky."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN nie je možné zmeniť"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Nastavenia mobilnej siete"</string>
<string name="label_available" msgid="1181658289009300430">"Dostupné siete"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Hľadá sa…"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrovať"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrovať"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizuálna hlasová schránka"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Zmena kódu PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Zvuk"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tón zvonenia a vibrovanie"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Vstavané SIM karty"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 306a0fb..3d4100c 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Narejena ni bila nobena sprememba."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Izberite storitev glasovne pošte"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Vaš operater"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Stara koda PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Nova koda PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Spreminjanje kode PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Nova koda PIN je prekratka."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Nova koda PIN je predolga."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Nova koda PIN je prešibka. Zapleteno geslo ne sme vsebovati zaporednih ali ponavljajočih se števk."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Stara koda PIN se ne ujema."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Nova koda PIN vsebuje neveljavne znake."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Ni mogoče spremeniti kode PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Nastavitve mobilnega omrežja"</string>
<string name="label_available" msgid="1181658289009300430">"Razpoložljiva omrežja"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Iskanje ..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibriraj"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibriraj"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizualno sporočilo v odzivniku"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Sprememba kode PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Zvok"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Zvonjenje in vibriranje"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Vgrajene kartice SIM"</string>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index d28cc8c..bd91c9b 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Nuk u bë asnjë ndryshim."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Zgjidh shërbimin e postës zanore"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operatori yt"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Kodi PIN i vjetër"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Kodi PIN i ri"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Kodi PIN po ndryshohet"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Kodi i ri PIN është shumë i shkurtër."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Kodi i ri PIN është shumë i gjatë."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Kodi i ri PIN është shumë i dobët. Një fjalëkalim i fortë nuk duhet të ketë rend të vazhdueshëm ose shifra të përsëritura."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Kodi PIN i vjetër nuk përputhet."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Kodi PIN i ri përmban karaktere të pavlefshme."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Kodi PIN nuk u ndryshua."</string>
<string name="mobile_networks" msgid="2843854043339307375">"Cilësimet e rrjetit celular"</string>
<string name="label_available" msgid="1181658289009300430">"Rrjete të arritshme"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Po kërkon..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Dridhja"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Dridhja"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Posta zanore vizuale"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Ndrysho kodin PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Tingulli"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Me zile dhe me dridhje"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Kartat e integruara SIM"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 50b4ae0..a32a160 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Нису извршене никакве промене."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Одаберите услугу говорне поште"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Мобилни оператер"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Стари PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Нови PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Мењамо PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Нови PIN је прекратак."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Нови PIN је предугачак."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Нови PIN је преслаб. Јака лозинка не треба да садржи узастопни низ ни поновљене цифре."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Стари PIN се не подудара."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Нови PIN садржи неважеће знакове."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Промена PIN-а није успела"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Подешавања мобилне мреже"</string>
<string name="label_available" msgid="1181658289009300430">"Доступне мреже"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Претражује се…"</string>
@@ -543,6 +552,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Вибрација"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Вибрација"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Визуелна говорна пошта"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Промените PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Звук"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Мелодија звона и вибрација"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Уграђене SIM картице"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index a59ad9b..feb4a9d 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Du har inte gjort några ändringar."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Välj tjänst för röstbrevlådan"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Din operatör"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Gammal pinkod"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Ny pinkod"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Pinkoden ändras"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Den nya pinkoden är för kort."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Den nya pinkoden är för lång."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Den nya pinkoden är för svag. Ett säkert lösenord bör inte ha siffror i ordningsföljd eller upprepade siffror."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Den gamla pinkoden stämmer inte."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Den nya pinkoden innehåller ogiltiga tecken."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Det gick inte att ändra pinkoden"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Inställningar för mobilnätverk"</string>
<string name="label_available" msgid="1181658289009300430">"Tillgängliga nätverk"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Söker…"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Vibrera"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibrera"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visuell röstbrevlåda"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Byt pinkod"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Ljud"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringsignal och vibrera"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Inbyggda SIM-kort"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 9e8c0ff..df4e626 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Hakuna mabadiliko yaliyofanywa"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Chagua huduma ya barua ya sauti"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Mtoa huduma wako"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN ya zamani"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN mpya"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Inabadilisha PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"PIN mpya ni fupi mno."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"PIN mpya ni ndefu mno."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"PIN mpya ni dhaifu mno. Nenosiri thabiti halifai kuwa na herufi zinazofuatana mfululizo au tarakimu zinazorudiwa."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"PIN ya zamani si sahihi."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"PIN mpya ina herufi zisizostahiki."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Imeshindwa kubadilisha PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mipangilio ya mitandao ya simu"</string>
<string name="label_available" msgid="1181658289009300430">"Mitandao inayopatikana"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Inatafuta…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Mtetemo"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Mtetemo"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Ujumbe wa Sauti Unaoonekana"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Badilisha PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sauti"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Mlio wa simu na Mtetemo"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"SIM kadi zilizojengewa ndani"</string>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index c316e31..791d9db 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"மாற்றங்கள் எவையும் செய்யப்படவில்லை."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"குரலஞ்சல் சேவையைத் தேர்வுசெய்க"</string>
<string name="voicemail_default" msgid="2001233554889016880">"உங்கள் மொபைல் நிறுவனம்"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"பழைய பின்"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"புதிய பின்"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"பின்னை மாற்றுகிறது"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"புதிய பின் மிகவும் சிறியதாக உள்ளது."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"புதிய பின் மிகவும் நீளமாக உள்ளது."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"புதிய பின் மிகவும் வலுவற்றதாக உள்ளது. வலுவான கடவுச்சொல்லில் தொடர்வரிசையோ மீண்டும் மீண்டும் வரும் இலக்கங்களோ இருக்கக்கூடாது."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"பழைய பின் பொருந்தவில்லை."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"புதிய பின்னில் தவறான எழுத்துக்குறிகள் உள்ளன."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"பின்னை மாற்ற முடியவில்லை"</string>
<string name="mobile_networks" msgid="2843854043339307375">"செல்லுலார் நெட்வொர்க் அமைப்பு"</string>
<string name="label_available" msgid="1181658289009300430">"கிடைக்கின்ற நெட்வொர்க்குகள்"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"தேடுகிறது..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"அதிர்வு"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"அதிர்வு"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"விஷூவல் குரலஞ்சல்"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"பின்னை மாற்றவும்"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ஒலி"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"ரிங்டோன் & அதிர்வு"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"உள்ளமைந்த சிம் கார்டுகள்"</string>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index 0845e46..15ba603 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"మార్పులు ఏవీ చేయబడలేదు."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"వాయిస్ మెయిల్ సేవను ఎంచుకోండి"</string>
<string name="voicemail_default" msgid="2001233554889016880">"మీ క్యారియర్"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"పాత PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"కొత్త PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PINను మార్చుతోంది"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"కొత్త PIN చాలా చిన్నదిగా ఉంది."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"కొత్త PIN చాలా పొడవు ఉంది."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"కొత్త PIN చాలా బలహీనంగా ఉంది. శక్తివంతమైన పాస్వర్డ్లో వరుస శ్రేణిలో అక్షరాలు/అంకెలు లేదా పునరావృత అంకెలు ఉండకూడదు."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"పాత PIN సరిపోలలేదు."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"కొత్త PIN చెల్లని అక్షరాలను కలిగి ఉంది."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PINని మార్చడం సాధ్యపడలేదు"</string>
<string name="mobile_networks" msgid="2843854043339307375">"సెల్యులార్ నెట్వర్క్ సెట్టింగ్లు"</string>
<string name="label_available" msgid="1181658289009300430">"అందుబాటులో ఉన్న నెట్వర్క్లు"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"శోధిస్తోంది..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"వైబ్రేట్"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"వైబ్రేట్"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"దృశ్యమాన వాయిస్మెయిల్"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PINను మార్చు"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"ధ్వని"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"రింగ్టోన్ & వైబ్రేట్"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"అంతర్నిర్మిత SIM కార్డులు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 9f2aa13..eb8e4b3 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"ไม่มีการเปลี่ยนแปลง"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"เลือกบริการข้อความเสียง"</string>
<string name="voicemail_default" msgid="2001233554889016880">"ผู้ให้บริการของคุณ"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"PIN เก่า"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"PIN ใหม่"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"กำลังเปลี่ยน PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"PIN ใหม่สั้นเกินไป"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"PIN ใหม่ยาวเกินไป"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"PIN ใหม่เดาง่ายเกินไป รหัสผ่านที่เดายากไม่ควรมีตัวเลขที่เรียงค่ากันหรือตัวเลขซ้ำๆ"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"PIN เก่าไม่ถูกต้อง"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"PIN ใหม่มีอักขระที่ไม่ถูกต้อง"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"ไม่สามารถเปลี่ยน PIN ได้"</string>
<string name="mobile_networks" msgid="2843854043339307375">"การตั้งค่าเครือข่ายมือถือ"</string>
<string name="label_available" msgid="1181658289009300430">"เครือข่ายที่ใช้งานได้"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"กำลังค้นหา…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"สั่น"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"สั่น"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"ข้อความเสียงพร้อมภาพ"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"เปลี่ยน PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"เสียง"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"เสียงเรียกเข้าและสั่น"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"ซิมการ์ดในตัว"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index b5f7cc3..9b643a4 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Walang ginawang mga pagbabago."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Piliin ang serbisyo ng voicemail"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Ang iyong carrier"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Lumang PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Bagong PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Binabago ang PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Masyadong maikli ang bagong PIN."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Masyadong mahaba ang bagong PIN."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Masyadong mahina ang bagong PIN. Ang isang malakas na password ay hindi dapat magkaroon ng tuloy-tuloy na sequence o paulit-ulit na mga digit."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Hindi tumutugma ang lumang PIN."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Ang bagong PIN ay naglalaman ng mga di-wastong character."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Hindi nabago ang PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Setting ng cellular network"</string>
<string name="label_available" msgid="1181658289009300430">"Mga available na network"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Naghahanap…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Mag-vibrate"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Mag-vibrate"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visual Voicemail"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Baguhin ang PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Tunog"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ringtone at Pag-vibrate"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Mga built-in na SIM card"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 5fe17d7..9b62fa7 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Hiçbir değişiklik yapılmadı."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Sesli mesaj hizmetini seç"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Operatörünüz"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Eski PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Yeni PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN değiştiriliyor"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Yeni PIN çok kısa."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Yeni PIN çok uzun."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Yeni PIN çok zayıf. Güçlü bir şifrede birbirini sıralı şekilde takip eden veya yinelenen rakamlar bulunmamalıdır."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Eski PIN eşleşmiyor."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Yeni PIN, geçersiz karakterler içeriyor."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN değiştirilemedi"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Hücresel ağ ayarları"</string>
<string name="label_available" msgid="1181658289009300430">"Kullanılabilir ağlar"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Aranıyor..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Titreşim"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Titreşim"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Görsel Sesli Mesaj"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN\'i değiştirin"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Ses"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Zil Sesi ve Titreşim"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Yerleşik SIM kartlar"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 0e15703..a818d3a 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Не здійсн. жодних змін."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Вибер. службу голос. пошти"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Ваш оператор"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Старий PIN-код"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Новий PIN-код"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Змінення PIN-коду"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Новий PIN-код закороткий."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Новий PIN-код задовгий."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Новий PIN-код недостатньо надійний. Надійний PIN-код не має містити прямих послідовностей або повторюваних цифр."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Старий PIN-код неправильний."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Новий PIN-код містить недійсні символи"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Не вдалося змінити PIN-код"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Налаштування моб. мереж"</string>
<string name="label_available" msgid="1181658289009300430">"Доступні мережі"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Пошук…"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Вібросигнал"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Вібросигнал"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Візуальна голосова пошта"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Змінити PIN-код"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Звук"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Сигнал дзвінка та вібросигнал"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Вбудовані SIM-карти"</string>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 02f1237..0ecee83 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"کوئی تبدیلیاں نہیں ہوئی تھیں۔"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"صوتی میل سروس کا انتخاب کریں"</string>
<string name="voicemail_default" msgid="2001233554889016880">"آپ کا کیریئر"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"پرانا PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"نیا PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN تبدیل ہو رہا ہے"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"نیا PIN بہت ہی مختصر ہے۔"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"نیا PIN بہت ہی طویل ہے۔"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"نیا PIN بہت ہی کمزور ہے۔ مضبوط پاسورڈ میں مسلسل ترتیب یا دہرے عدد نہیں ہونے چاہئیں۔"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"پرانا PIN مماثل نہیں ہے۔"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"نئے PIN میں غلط کریکٹرز شامل ہیں۔"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN تبدیل کرنے سے قاصر"</string>
<string name="mobile_networks" msgid="2843854043339307375">"سیلولر نیٹ ورک کی ترتیبات"</string>
<string name="label_available" msgid="1181658289009300430">"دستیاب نیٹ ورکس"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"تلاش کر رہا ہے…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"وائبریٹ"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"وائبریٹ"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"بصری صوتی میل"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN تبدیل کریں"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"آواز"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"رنگ ٹون اور وائبریٹ"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"پہلے سے شامل SIM کارڈز"</string>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 4da2538..daec968 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"O‘zgarishlar qilinmadi."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Ovozli xabar xizmatini tanlash"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Aloqa operatoringiz"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Eski PIN kod"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Yangi PIN kod"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"PIN kod o‘zgartirilmoqda"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Yangi PIN kod juda qisqa."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Yangi PIN kod juda uzun."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Yangi PIN kod juda sodda. Ishonchli PIN kodda ketma-ket takrorlanadigan raqamlar bo‘lmasligi lozim."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Eski PIN kod mos kelmayapti."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Yangi PIN kodda yaroqsiz belgilar mavjud."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"PIN kodni o‘zgartirib bo‘lmadi"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Mobil tarmoq sozlamalari"</string>
<string name="label_available" msgid="1181658289009300430">"Mavjud tarmoqlar"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Qidirilmoqda…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Tebranish"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Tebratish"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Vizual ovozli pochta"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"PIN kodni o‘zgartirish"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Ovoz"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Qo‘ng‘iroq ohangi & tebranish"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Ichki o‘rnatilgan SIM kartalar"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 220bf6a..13ac8c8 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Không thay đổi nào được thực hiện."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Chọn dịch vụ thư thoại"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Nhà cung cấp dịch vụ của bạn"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"Mã PIN cũ"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"Mã PIN mới"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Đang thay đổi mã PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"Mã PIN mới quá ngắn."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"Mã PIN mới quá dài."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"Mã PIN mới quá yếu. Một mật khẩu mạnh không nên có các chữ số lặp lại hoặc chuỗi liên tiếp."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"Mã PIN cũ không khớp."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"Mã PIN mới chứa các ký tự không hợp lệ."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Không thể thay đổi mã PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Cài đặt mạng di động"</string>
<string name="label_available" msgid="1181658289009300430">"Mạng khả dụng"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Đang tìm kiếm…"</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Rung"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Rung"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Thư thoại kèm theo hình ảnh"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Thay đổi mã PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Âm thanh"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Nhạc chuông và rung"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Thẻ SIM tích hợp sẵn"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index f013c7b..aa61e49 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"未做任何更改。"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"选择语音信箱服务"</string>
<string name="voicemail_default" msgid="2001233554889016880">"您的运营商"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"旧的 PIN 码"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"新的 PIN 码"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"正在更改 PIN 码"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"新的 PIN 码太短。"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"新的 PIN 码太长。"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"新的 PIN 码安全系数太低。如要提高密码强度,请勿使用连续或重复的数字。"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"旧的 PIN 码不匹配。"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"新的 PIN 码包含无效字符。"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"无法更改 PIN 码"</string>
<string name="mobile_networks" msgid="2843854043339307375">"移动网络设置"</string>
<string name="label_available" msgid="1181658289009300430">"可用网络"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"正在搜索..."</string>
@@ -540,6 +549,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"振动"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"振动"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"可视语音邮箱"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"更改 PIN 码"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"提示音"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"铃声和振动"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"内置SIM卡"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index d2749b4..6323d12 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"沒有更改。"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"選擇語音信箱服務"</string>
<string name="voicemail_default" msgid="2001233554889016880">"您的流動網絡供應商"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"舊的 PIN"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"新的 PIN"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"正在變更 PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"新的 PIN 太短。"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"新的 PIN 太長。"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"新的 PIN 太弱。強效密碼不應包含連續序列或重複數字。"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"舊的 PIN 不符。"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"新的 PIN 包含無效字元。"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"無法變更 PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"流動網絡設定"</string>
<string name="label_available" msgid="1181658289009300430">"可用的網絡"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"正在搜尋..."</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"震動"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"震動"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Visual Voicemail"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"變更 PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"音效"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"鈴聲與震動"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"內置 SIM 卡"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 111896a..09c6406 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"未變更設定。"</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"選擇語音信箱服務"</string>
<string name="voicemail_default" msgid="2001233554889016880">"您的行動通訊業者"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"舊的 PIN 碼"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"新的 PIN 碼"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"正在變更 PIN 碼"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"新的 PIN 碼太短。"</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"新的 PIN 碼太長。"</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"新的 PIN 碼不夠安全。安全強度高的密碼不得使用連續或重複的數字。"</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"舊的 PIN 碼不符。"</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"新的 PIN 碼包含無效的字元。"</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"無法變更 PIN 碼"</string>
<string name="mobile_networks" msgid="2843854043339307375">"行動網路設定"</string>
<string name="label_available" msgid="1181658289009300430">"可用的網路"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"搜尋中…"</string>
@@ -546,6 +555,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"震動"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"震動"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"具有畫面的語音信箱"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"變更 PIN 碼"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"音效"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"鈴聲與震動"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"內建 SIM 卡"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index a146aeb..28316e8 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -147,6 +147,15 @@
<string name="no_change" msgid="3186040086622435212">"Azikho izinguquko ezenziwe."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Khetha insizikalo yemeyili yezwi"</string>
<string name="voicemail_default" msgid="2001233554889016880">"Inkampani yakho yenethiwekhi"</string>
+ <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"I-PIN endala"</string>
+ <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"I-PIN entsha"</string>
+ <string name="vm_change_pin_progress_message" msgid="6727847908454506025">"Ishintsha i-PIN"</string>
+ <string name="vm_change_pin_error_too_short" msgid="5974971097302710497">"I-PIN entsha imfushane kakhulu."</string>
+ <string name="vm_change_pin_error_too_long" msgid="8476870806115051865">"I-PIN entsha yinde kakhulu."</string>
+ <string name="vm_change_pin_error_too_weak" msgid="7883744811891784882">"I-PIN entsha ibuthakathaka. Iphasiwedi eqinile akufanele ibe nokulandelana okuqhubekayo noma amadijithi aphindaphindiwe."</string>
+ <string name="vm_change_pin_error_mismatch" msgid="2754685537970757317">"I-PIN endala ayifani."</string>
+ <string name="vm_change_pin_error_invalid" msgid="3972205462701668653">"I-PIN entsha iqukethe izinhlamvu ezingavumelekile."</string>
+ <string name="vm_change_pin_error_system_error" msgid="6610603326230000207">"Ayikwazi ukushintsha i-PIN"</string>
<string name="mobile_networks" msgid="2843854043339307375">"Izilungiselelo zenethiwekhi yeselula"</string>
<string name="label_available" msgid="1181658289009300430">"Amanethiwekhi atholakalayo"</string>
<string name="load_networks_progress" msgid="5230707536168902952">"Iyasesha..."</string>
@@ -544,6 +553,7 @@
<string name="voicemail_notification_vibrate_when_title" msgid="8361970092063604886">"Dlidliza"</string>
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Dlidliza"</string>
<string name="voicemail_visual_voicemail_switch_title" msgid="5012622186976275457">"Ivoyisimeyili ebonakalayo"</string>
+ <string name="voicemail_change_pin_dialog_title" msgid="6035421908626121564">"Shintsha i-PIN"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Umsindo"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Ithoni yokukhala nokudlidliza"</string>
<string name="pstn_connection_service_label" msgid="1743245930577325900">"Amakhadi we-SIM akhelwe ngaphakathi"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b30f8ce..0fbd08d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -330,6 +330,26 @@
<!-- Call settings screen, "Voicemail" screen, default option - Your Carrier -->
<string name="voicemail_default">Your carrier</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">Changing PIN</string>
+ <!-- Error message for the voicemail PIN change if the PIN is too short -->
+ <string name="vm_change_pin_error_too_short">The new PIN is too short.</string>
+ <!-- Error message for the voicemail PIN change if the PIN is too long -->
+ <string name="vm_change_pin_error_too_long">The new PIN is too long.</string>
+ <!-- Error message for the voicemail PIN change if the PIN is too weak -->
+ <string name="vm_change_pin_error_too_weak">The new PIN is too weak. A strong password should not have continuous sequence or repeated digits.</string>
+ <!-- Error message for the voicemail PIN change if the old PIN entered doesn't match -->
+ <string name="vm_change_pin_error_mismatch">The old PIN does not match.</string>
+ <!-- Error message for the voicemail PIN change if the new PIN contains invalid character -->
+ <string name="vm_change_pin_error_invalid">The new PIN contains invalid characters.</string>
+ <!-- Error message for the voicemail PIN change if operation has failed -->
+ <string name="vm_change_pin_error_system_error">Unable to change PIN</string>
+
<!-- networks setting strings --><skip/>
<!-- Mobile network settings screen title -->
<string name="mobile_networks">Cellular network settings</string>
@@ -1235,6 +1255,9 @@
<!-- Visual voicemail on/off title [CHAR LIMIT=40] -->
<string name="voicemail_visual_voicemail_switch_title">Visual Voicemail</string>
+ <!-- Voicemail change PIN dialog title [CHAR LIMIT=40] -->
+ <string name="voicemail_change_pin_dialog_title">Change PIN</string>
+
<!-- Voicemail ringtone title. The user clicks on this preference to select
which sound to play when a voicemail notification is received.
[CHAR LIMIT=30] -->
@@ -1302,6 +1325,8 @@
<string name="voicemail_notification_vibrate_key">voicemail_notification_vibrate_key</string>
<!-- DO NOT TRANSLATE. Internal key for a visual voicemail preference. -->
<string name="voicemail_visual_voicemail_key">voicemail_visual_voicemail_key</string>
+ <!-- DO NOT TRANSLATE. Internal key for a voicemail change pin preference. -->
+ <string name="voicemail_change_pin_key">voicemail_change_pin_key</string>
<!-- DO NOT TRANSLATE. Internal key for tty mode preference. -->
<string name="tty_mode_key">button_tty_mode_key</string>
<!-- DO NOT TRANSLATE. Internal key for a voicemail notification preference. -->
diff --git a/res/xml/voicemail_settings.xml b/res/xml/voicemail_settings.xml
index 9334566..734d9d7 100644
--- a/res/xml/voicemail_settings.xml
+++ b/res/xml/voicemail_settings.xml
@@ -60,8 +60,13 @@
android:key="@string/voicemail_notification_vibrate_key"
android:title="@string/voicemail_notification_vibrate_when_title"
android:persistent="true" />
+
<SwitchPreference
android:key="@string/voicemail_visual_voicemail_key"
android:title="@string/voicemail_visual_voicemail_switch_title" />"
+ <com.android.phone.settings.VoicemailChangePinDialogPreference
+ android:key="@string/voicemail_change_pin_key"
+ android:title="@string/voicemail_change_pin_dialog_title" />
+
</PreferenceScreen>
diff --git a/res/xml/vvm_config.xml b/res/xml/vvm_config.xml
new file mode 100644
index 0000000..79edaa6
--- /dev/null
+++ b/res/xml/vvm_config.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<list name="carrier_config_list">
+ <pbundle_as_map>
+ <!-- Test -->
+ <string-array name="mccmnc">
+ <item value="TEST"/>
+ </string-array>
+ </pbundle_as_map>
+
+ <pbundle_as_map>
+ <!-- Orange France -->
+ <string-array name="mccmnc">
+ <item value="20801"/>
+ <item value="20802"/>
+ </string-array>
+
+ <int name="vvm_port_number_int" value="20481"/>
+ <string name="vvm_destination_number_string">21101</string>
+ <string-array name="carrier_vvm_package_name_string_array">
+ <item value="com.orange.vvm"/>
+ </string-array>
+ <string name="vvm_type_string">vvm_type_omtp</string>
+ <boolean name="vvm_cellular_data_required_bool" value="true"/>
+ </pbundle_as_map>
+
+ <pbundle_as_map>
+ <!-- Orange UK -->
+ <string-array name="mccmnc">
+ <item value="23433"/>
+ <item value="23434"/>
+ </string-array>
+
+ <int name="vvm_port_number_int" value="20481"/>
+ <string name="vvm_destination_number_string">881</string>
+ <string name="vvm_type_string">vvm_type_omtp</string>
+ </pbundle_as_map>
+
+ <pbundle_as_map>
+ <!-- T-Mobile USA-->
+ <string-array name="mccmnc">
+ <item value="310160"/>
+ <item value="310200"/>
+ <item value="310210"/>
+ <item value="310220"/>
+ <item value="310230"/>
+ <item value="310240"/>
+ <item value="310250"/>
+ <item value="310260"/>
+ <item value="310270"/>
+ <item value="310300"/>
+ <item value="310310"/>
+ <item value="310490"/>
+ <item value="310530"/>
+ <item value="310590"/>
+ <item value="310640"/>
+ <item value="310660"/>
+ <item value="310800"/>
+ </string-array>
+
+ <int name="vvm_port_number_int" value="1808"/>
+ <int name="vvm_ssl_port_number_int" value="993"/>
+ <string name="vvm_destination_number_string">122</string>
+ <string-array name="carrier_vvm_package_name_string_array">
+ <item value="com.tmobile.vvm.application"/>
+ </string-array>
+ <string name="vvm_type_string">vvm_type_cvvm</string>>
+ <string-array name="vvm_disabled_capabilities_string_array">
+ <!-- b/28717550 -->
+ <item value="AUTH=DIGEST-MD5"/>
+ </string-array>
+ </pbundle_as_map>
+
+ <pbundle_as_map>
+ <!-- Verizon USA -->
+ <string-array name="mccmnc">
+ <item value="310004"/>
+ <item value="310010"/>
+ <item value="310012"/>
+ <item value="310013"/>
+ <item value="310590"/>
+ <item value="310890"/>
+ <item value="310910"/>
+ <item value="311110"/>
+ <item value="311270"/>
+ <item value="311271"/>
+ <item value="311272"/>
+ <item value="311273"/>
+ <item value="311274"/>
+ <item value="311275"/>
+ <item value="311276"/>
+ <item value="311277"/>
+ <item value="311278"/>
+ <item value="311279"/>
+ <item value="311280"/>
+ <item value="311281"/>
+ <item value="311282"/>
+ <item value="311283"/>
+ <item value="311284"/>
+ <item value="311285"/>
+ <item value="311286"/>
+ <item value="311287"/>
+ <item value="311288"/>
+ <item value="311289"/>
+ <item value="311390"/>
+ <item value="311480"/>
+ <item value="311481"/>
+ <item value="311482"/>
+ <item value="311483"/>
+ <item value="311484"/>
+ <item value="311485"/>
+ <item value="311486"/>
+ <item value="311487"/>
+ <item value="311488"/>
+ <item value="311489"/>
+ </string-array>
+
+ <int name="vvm_port_number_int" value="0"/>
+ <string name="vvm_destination_number_string">900080006200</string>
+ <string name="vvm_type_string">vvm_type_vvm3</string>
+ <string name="vvm_client_prefix_string">//VZWVVM</string>
+ <boolean name="vvm_cellular_data_required_bool" value="true"/>
+ </pbundle_as_map>
+</list>
\ No newline at end of file
diff --git a/sip/res/values-pa-rIN/strings.xml b/sip/res/values-pa-rIN/strings.xml
index 3a9755d..15dccb0 100644
--- a/sip/res/values-pa-rIN/strings.xml
+++ b/sip/res/values-pa-rIN/strings.xml
@@ -20,7 +20,7 @@
<string name="sip_accounts" msgid="85559497282185405">"SIP ਖਾਤੇ"</string>
<string name="sip_accounts_title" msgid="2082527045326874519">"ਖਾਤੇ"</string>
<string name="sip_receive_calls" msgid="426678617137462173">"ਇਨਕਮਿੰਗ ਕਾਲਾਂ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
- <string name="sip_receive_calls_summary" msgid="946161517528227523">"ਬੈਟਰੀ ਦੀ ਖਪਤ ਵਧ ਜਾਂਦੀ ਹੈ"</string>
+ <string name="sip_receive_calls_summary" msgid="946161517528227523">"ਵੱਧ ਬੈਟਰੀ ਸਮਰੱਥਾ ਵਰਤਦਾ ਹੈ"</string>
<string name="sip_call_options_title" msgid="8421210494703869806">"SIP ਕਾਲਿੰਗ ਵਰਤੋ"</string>
<string name="sip_call_options_wifi_only_title" msgid="5112579243580893890">"SIP ਕਾਲਿੰਗ ਵਰਤੋ (ਕੇਵਲ Wi-Fi)"</string>
<string name="sip_call_options_entry_1" msgid="7217659161237099900">"ਜਦੋਂ ਡਾਟਾ ਨੈਟਵਰਕ ਉਪਲਬਧ ਹੋਵੇ ਤਾਂ ਸਾਰੀਆਂ ਕਾਲਾਂ ਲਈ"</string>
@@ -45,27 +45,27 @@
<string name="registration_status_not_running" msgid="514205414303796800">"ਖਾਤਾ ਰਜਿਸਟਰੇਸ਼ਨ ਅਸਫਲ।"</string>
<string name="registration_status_done" msgid="3264961069247314253">"ਕਾਲਾਂ ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ।"</string>
<string name="registration_status_failed_try_later" msgid="2199970021756384317">"ਖਾਤਾ ਰਜਿਸਟਰੇਸ਼ਨ ਅਸਫਲ: (<xliff:g id="REGISTRATION_ERROR_MESSAGE">%s</xliff:g>); ਬਾਅਦ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ"</string>
- <string name="registration_status_invalid_credentials" msgid="8406872554323334182">"ਖਾਤਾ ਰਜਿਸਟਰੇਸ਼ਨ ਅਸਫਲ: ਗ਼ਲਤ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
+ <string name="registration_status_invalid_credentials" msgid="8406872554323334182">"ਖਾਤਾ ਰਜਿਸਟਰੇਸ਼ਨ ਅਸਫਲ: ਗ਼ਲਤ ਉਪਭੋਗਤਾ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
<string name="registration_status_server_unreachable" msgid="7710275557045148634">"ਖਾਤਾ ਰਜਿਸਟਰੇਸ਼ਨ ਅਸਫਲ: ਸਰਵਰ ਨਾਮ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
<string name="third_party_account_summary" msgid="9041060473615403041">"ਇਹ ਖਾਤਾ ਇਸ ਵੇਲੇ <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> ਐਪ ਵੱਲੋਂ ਵਰਤੋਂ ਵਿੱਚ ਹੈ।"</string>
<string name="sip_edit_title" msgid="1967247832635750410">"SIP ਖਾਤਾ ਵੇਰਵੇ"</string>
<string name="sip_edit_new_title" msgid="266414118302574305">"SIP ਖਾਤਾ ਵੇਰਵੇ"</string>
<string name="domain_address_title" msgid="1968479941328225423">"ਸਰਵਰ"</string>
- <string name="username_title" msgid="6770064611005663470">"ਵਰਤੋਂਕਾਰ ਨਾਮ"</string>
+ <string name="username_title" msgid="6770064611005663470">"ਉਪਭੋਗਤਾ ਨਾਮ"</string>
<string name="password_title" msgid="5289013731515564295">"ਪਾਸਵਰਡ"</string>
<string name="display_name_title" msgid="579241787583079773">"ਡਿਸਪਲੇ ਨਾਮ"</string>
<string name="proxy_address_title" msgid="6890163365640631841">"ਆਊਟਬਾਊਂਡ ਪ੍ਰੌਕਸੀ ਪਤਾ"</string>
<string name="port_title" msgid="6693965912656593862">"ਪੋਰਟ ਨੰਬਰ"</string>
- <string name="transport_title" msgid="889155457465372527">"ਟ੍ਰਾਂਸਪੋਰਟ ਦੀ ਕਿਸਮ"</string>
+ <string name="transport_title" msgid="889155457465372527">"ਟ੍ਰਾਂਸਪੋਰਟ ਪ੍ਰਕਾਰ"</string>
<string name="send_keepalive_title" msgid="599627072150501159">"ਕੀਪ-ਅਲਾਈਵ ਭੇਜੋ"</string>
- <string name="advanced_settings" msgid="6622996380747040711">"ਵਿਕਲਪਕ ਸੈਟਿੰਗਾਂ"</string>
- <string name="auth_username_title" msgid="8262491689004708265">"ਪ੍ਰਮਾਣੀਕਰਨ ਵਰਤੋਂਕਾਰ ਨਾਮ"</string>
- <string name="auth_username_summary" msgid="941160241371436473">"ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਵਰਤਿਆ ਗਿਆ ਵਰਤੋਂਕਾਰ ਨਾਮ"</string>
- <string name="default_preference_summary" msgid="1979249643719483249">"<ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ>"</string>
- <string name="display_name_summary" msgid="7155076491675565407">"<ਉਹੀ ਹੈ ਜੋ ਵਰਤੋਂਕਾਰ ਨਾਮ ਹੈ>"</string>
- <string name="optional_summary" msgid="2363105560396317624">"<ਵਿਕਲਪਕ>"</string>
- <string name="advanced_settings_show" msgid="7838761602853998622">"▷ ਸਾਰੇ ਦਿਖਾਉਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ"</string>
- <string name="advanced_settings_hide" msgid="3480554978705290228">"▽ ਸਾਰੇ ਲੁਕਾਉਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ"</string>
+ <string name="advanced_settings" msgid="6622996380747040711">"ਚੋਣ ਸੰਬੰਧੀ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="auth_username_title" msgid="8262491689004708265">"ਪ੍ਰਮਾਣੀਕਰਨ ਉਪਭੋਗਤਾ ਨਾਮ"</string>
+ <string name="auth_username_summary" msgid="941160241371436473">"ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਵਰਤਿਆ ਗਿਆ ਉਪਭੋਗਤਾ ਨਾਮ"</string>
+ <string name="default_preference_summary" msgid="1979249643719483249">"<ਸੈਟ ਨਹੀਂ ਕੀਤਾ>"</string>
+ <string name="display_name_summary" msgid="7155076491675565407">"<ਉਪਭੋਗਤਾ ਨਾਮ ਦੇ ਸਮਾਨ>"</string>
+ <string name="optional_summary" msgid="2363105560396317624">"<ਚੋਣਵਾਂ>"</string>
+ <string name="advanced_settings_show" msgid="7838761602853998622">"▷ ਸਾਰੇ ਦਿਖਾਉਣ ਲਈ ਛੋਹਵੋ"</string>
+ <string name="advanced_settings_hide" msgid="3480554978705290228">"▽ ਸਾਰੇ ਲੁਕਾਉਣ ਲਈ ਛੋਹਵੋ"</string>
<string name="all_empty_alert" msgid="4087734950375192387">"ਨਵੇਂ SIP ਖਾਤੇ ਦੇ ਵੇਰਵੇ ਦਾਖ਼ਲ ਕਰੋ।"</string>
<string name="empty_alert" msgid="6659484914371384024">"<xliff:g id="INPUT_FIELD_NAME">%s</xliff:g> ਲੁੜੀਂਦਾ ਹੈ ਅਤੇ ਇਸਨੂੰ ਖਾਲੀ ਨਹੀਂ ਛੱਡਿਆ ਜਾ ਸਕਦਾ।"</string>
<string name="not_a_valid_port" msgid="7931422555587011830">"ਪੋਰਟ ਨੰਬਰ 1000 ਅਤੇ 65534 ਵਿਚਕਾਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
diff --git a/src/com/android/phone/Assert.java b/src/com/android/phone/Assert.java
new file mode 100644
index 0000000..d4233b2
--- /dev/null
+++ b/src/com/android/phone/Assert.java
@@ -0,0 +1,40 @@
+/*
+ * 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.phone;
+
+import android.os.Looper;
+
+/**
+ * Assertions which will result in program termination.
+ */
+public class Assert {
+
+ public static void isTrue(boolean condition) {
+ if (!condition) {
+ throw new AssertionError("Expected condition to be true");
+ }
+ }
+
+ public static void isNotMainThread() {
+ isTrue(!Looper.getMainLooper().equals(Looper.myLooper()));
+ }
+
+ public static void fail() {
+ throw new AssertionError("Fail");
+ }
+}
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index df1a127..3204a9f 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -689,6 +689,7 @@
switch (simState) {
case IccCardConstants.INTENT_VALUE_ICC_ABSENT:
case IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR:
+ case IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED:
case IccCardConstants.INTENT_VALUE_ICC_UNKNOWN:
mHandler.sendMessage(mHandler.obtainMessage(EVENT_CLEAR_CONFIG, phoneId, -1));
break;
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 0a583a0..0932cce 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -41,6 +41,7 @@
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -125,6 +126,27 @@
mNotificationComponent = notificationComponent != null
? ComponentName.unflattenFromString(notificationComponent) : null;
+
+ mSubscriptionManager.addOnSubscriptionsChangedListener(
+ new OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ updateActivePhonesMwi();
+ }
+ });
+ }
+
+ public void updateActivePhonesMwi() {
+ List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
+
+ if (subInfos == null) {
+ return;
+ }
+
+ for (int i = 0; i < subInfos.size(); i++) {
+ int subId = subInfos.get(i).getSubscriptionId();
+ refreshMwi(subId);
+ }
}
/**
@@ -302,12 +324,12 @@
Uri ringtoneUri = null;
if (enableNotificationSound) {
- ringtoneUri = VoicemailNotificationSettingsUtil.getRingtoneUri(mPhone);
+ ringtoneUri = VoicemailNotificationSettingsUtil.getRingtoneUri(phone);
}
Resources res = mContext.getResources();
PersistableBundle carrierConfig = PhoneGlobals.getInstance().getCarrierConfigForSubId(
- mPhone.getSubId());
+ subId);
Notification.Builder builder = new Notification.Builder(mContext);
builder.setSmallIcon(resId)
.setWhen(System.currentTimeMillis())
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 7738b77..2ace8e1 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -16,6 +16,8 @@
package com.android.phone;
+import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
+
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.ComponentName;
@@ -38,19 +40,22 @@
import android.os.UserManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.service.carrier.CarrierIdentifier;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.CellInfo;
import android.telephony.IccOpenLogicalChannelResponse;
+import android.telephony.ModemActivityInfo;
import android.telephony.NeighboringCellInfo;
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
-import android.telephony.ModemActivityInfo;
+import android.telephony.VisualVoicemailSmsFilterSettings;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -67,9 +72,10 @@
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.ProxyController;
-import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.RIL;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.uicc.IccIoResult;
@@ -79,8 +85,6 @@
import com.android.internal.util.HexDump;
import com.android.phone.settings.VoicemailNotificationSettingsUtil;
-import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -138,6 +142,10 @@
private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
+ private static final int CMD_SET_ALLOWED_CARRIERS = 43;
+ private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
+ private static final int CMD_GET_ALLOWED_CARRIERS = 45;
+ private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
/** The singleton instance. */
private static PhoneInterfaceManager sInstance;
@@ -760,6 +768,68 @@
}
break;
+ case CMD_SET_ALLOWED_CARRIERS:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
+ mPhone.setAllowedCarriers(
+ (List<CarrierIdentifier>) request.argument,
+ onCompleted);
+ break;
+
+ case EVENT_SET_ALLOWED_CARRIERS_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ if (ar.exception == null && ar.result != null) {
+ request.result = ar.result;
+ } else {
+ if (ar.result == null) {
+ loge("setAllowedCarriers: Empty response");
+ } else if (ar.exception instanceof CommandException) {
+ loge("setAllowedCarriers: CommandException: " +
+ ar.exception);
+ } else {
+ loge("setAllowedCarriers: Unknown exception");
+ }
+ }
+ // Result cannot be null. Return -1 on error.
+ if (request.result == null) {
+ request.result = new int[]{-1};
+ }
+ synchronized (request) {
+ request.notifyAll();
+ }
+ break;
+
+ case CMD_GET_ALLOWED_CARRIERS:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
+ mPhone.getAllowedCarriers(onCompleted);
+ break;
+
+ case EVENT_GET_ALLOWED_CARRIERS_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ if (ar.exception == null && ar.result != null) {
+ request.result = ar.result;
+ } else {
+ if (ar.result == null) {
+ loge("getAllowedCarriers: Empty response");
+ } else if (ar.exception instanceof CommandException) {
+ loge("getAllowedCarriers: CommandException: " +
+ ar.exception);
+ } else {
+ loge("getAllowedCarriers: Unknown exception");
+ }
+ }
+ // Result cannot be null. Return empty list of CarrierIdentifier.
+ if (request.result == null) {
+ request.result = new ArrayList<CarrierIdentifier>(0);
+ }
+ synchronized (request) {
+ request.notifyAll();
+ }
+ break;
+
default:
Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
break;
@@ -1827,6 +1897,37 @@
return success;
}
+ @Override
+ public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
+ VisualVoicemailSmsFilterSettings settings) {
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ VisualVoicemailSmsFilterConfig
+ .enableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId,
+ settings);
+ }
+
+ @Override
+ public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ VisualVoicemailSmsFilterConfig
+ .disableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId);
+ }
+
+ @Override
+ public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
+ String callingPackage, int subId) {
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ return VisualVoicemailSmsFilterConfig
+ .getVisualVoicemailSmsFilterSettings(mPhone.getContext(), callingPackage, subId);
+ }
+
+ @Override
+ public VisualVoicemailSmsFilterSettings getSystemVisualVoicemailSmsFilterSettings(
+ String packageName, int subId) {
+ enforceReadPrivilegedPermission();
+ return VisualVoicemailSmsFilterConfig
+ .getVisualVoicemailSmsFilterSettings(mPhone.getContext(), packageName, subId);
+ }
/**
* Returns the unread count of voicemails
*/
@@ -2759,7 +2860,7 @@
TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
TelephonyManager telephonyManager =
(TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
- return !telephonyManager.isMultiSimEnabled() && telecomManager.isTtySupported();
+ return telecomManager.isTtySupported();
}
@Override
@@ -3049,4 +3150,143 @@
return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone);
}
+ /**
+ * Make sure either called from same process as self (phone) or IPC caller has read privilege.
+ *
+ * @throws SecurityException if the caller does not have the required permission
+ */
+ private void enforceReadPrivilegedPermission() {
+ mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ null);
+ }
+
+ /**
+ * Return the application ID for the app type.
+ *
+ * @param subId the subscription ID that this request applies to.
+ * @param appType the uicc app type.
+ * @return Application ID for specificied app type, or null if no uicc.
+ */
+ @Override
+ public String getAidForAppType(int subId, int appType) {
+ enforceReadPrivilegedPermission();
+ Phone phone = getPhone(subId);
+ if (phone == null) {
+ return null;
+ }
+ String aid = null;
+ try {
+ aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
+ .getApplicationByType(appType).getAid();
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
+ }
+ return aid;
+ }
+
+ /**
+ * Return the Electronic Serial Number.
+ *
+ * @param subId the subscription ID that this request applies to.
+ * @return ESN or null if error.
+ */
+ @Override
+ public String getEsn(int subId) {
+ enforceReadPrivilegedPermission();
+ Phone phone = getPhone(subId);
+ if (phone == null) {
+ return null;
+ }
+ String esn = null;
+ try {
+ esn = phone.getEsn();
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
+ }
+ return esn;
+ }
+
+ /**
+ * Get snapshot of Telephony histograms
+ * @return List of Telephony histograms
+ * @hide
+ */
+ @Override
+ public List<TelephonyHistogram> getTelephonyHistograms() {
+ enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+ return RIL.getTelephonyRILTimingHistograms();
+ }
+
+ /**
+ * {@hide}
+ * Set the allowed carrier list for slotId
+ * Require system privileges. In the future we may add this to carrier APIs.
+ *
+ * @return The number of carriers set successfully, should match length of carriers
+ */
+ @Override
+ public int setAllowedCarriers(int slotId, List<CarrierIdentifier> carriers) {
+ enforceModifyPermission();
+ int subId = SubscriptionManager.getSubId(slotId)[0];
+ int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId);
+ return retVal[0];
+ }
+
+ /**
+ * {@hide}
+ * Get the allowed carrier list for slotId.
+ * Require system privileges. In the future we may add this to carrier APIs.
+ *
+ * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
+ * means all carriers are allowed.
+ */
+ @Override
+ public List<CarrierIdentifier> getAllowedCarriers(int slotId) {
+ enforceReadPrivilegedPermission();
+ int subId = SubscriptionManager.getSubId(slotId)[0];
+ return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId);
+ }
+
+ /**
+ * Action set from carrier signalling broadcast receivers to enable/disable metered apns
+ * @param subId the subscription ID that this action applies to.
+ * @param enabled control enable or disable metered apns.
+ * {@hide}
+ */
+ @Override
+ public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
+ enforceModifyPermission();
+ final Phone phone = getPhone(subId);
+ if (phone == null) {
+ loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
+ return;
+ }
+ try {
+ phone.carrierActionSetMeteredApnsEnabled(enabled);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
+ }
+ }
+
+ /**
+ * Action set from carrier signalling broadcast receivers to enable/disable radio
+ * @param subId the subscription ID that this action applies to.
+ * @param enabled control enable or disable radio.
+ * {@hide}
+ */
+ @Override
+ public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
+ enforceModifyPermission();
+ final Phone phone = getPhone(subId);
+ if (phone == null) {
+ loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
+ return;
+ }
+ try {
+ phone.carrierActionSetRadioEnabled(enabled);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
+ }
+ }
+
}
diff --git a/src/com/android/phone/VisualVoicemailSmsFilterConfig.java b/src/com/android/phone/VisualVoicemailSmsFilterConfig.java
new file mode 100644
index 0000000..2b2e2f5
--- /dev/null
+++ b/src/com/android/phone/VisualVoicemailSmsFilterConfig.java
@@ -0,0 +1,165 @@
+/*
+ * 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.phone;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.util.ArraySet;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Stores the config values needed for visual voicemail sms filtering. The values from
+ * OmtpVvmCarrierConfigHelper are stored here during activation instead. These values are read and
+ * written through TelephonyManager.
+ */
+public class VisualVoicemailSmsFilterConfig {
+
+ private static final String VVM_SMS_FILTER_COFIG_SHARED_PREFS_KEY_PREFIX =
+ "vvm_sms_filter_config_";
+ private static final String ENABLED_KEY = "_enabled";
+ private static final String PREFIX_KEY = "_prefix";
+ private static final String ORIGINATING_NUMBERS_KEY = "_originating_numbers";
+ private static final String DESTINATION_PORT_KEY = "_destination_port";
+
+ public static void enableVisualVoicemailSmsFilter(Context context, String callingPackage,
+ int subId,
+ VisualVoicemailSmsFilterSettings settings) {
+ new Editor(context, callingPackage, subId)
+ .setBoolean(ENABLED_KEY, true)
+ .setString(PREFIX_KEY, settings.clientPrefix)
+ .setStringList(ORIGINATING_NUMBERS_KEY, settings.originatingNumbers)
+ .setInt(DESTINATION_PORT_KEY, settings.destinationPort)
+ .apply();
+ }
+
+ public static void disableVisualVoicemailSmsFilter(Context context, String callingPackage,
+ int subId) {
+ new Editor(context, callingPackage, subId)
+ .setBoolean(ENABLED_KEY, false)
+ .apply();
+ }
+
+ @Nullable
+ public static VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
+ Context context,
+ String packageName, int subId) {
+ Reader reader = new Reader(context, packageName, subId);
+ if (!reader.getBoolean(ENABLED_KEY, false)) {
+ return null;
+ }
+ return new VisualVoicemailSmsFilterSettings.Builder()
+ .setClientPrefix(reader.getString(PREFIX_KEY,
+ VisualVoicemailSmsFilterSettings.DEFAULT_CLIENT_PREFIX))
+ .setOriginatingNumbers(reader.getStringSet(ORIGINATING_NUMBERS_KEY,
+ VisualVoicemailSmsFilterSettings.DEFAULT_ORIGINATING_NUMBERS))
+ .setDestinationPort(reader.getInt(DESTINATION_PORT_KEY,
+ VisualVoicemailSmsFilterSettings.DEFAULT_DESTINATION_PORT))
+ .build();
+ }
+ private static SharedPreferences getSharedPreferences(Context context) {
+ return PreferenceManager
+ .getDefaultSharedPreferences(context.createDeviceProtectedStorageContext());
+ }
+
+ private static String makePerPhoneAccountKeyPrefix(String packageName, int subId) {
+ // subId is persistent across reboot and upgrade, but not across devices.
+ // ICC id is better as a key but it involves more trouble to get one as subId is more
+ // commonly passed around.
+ return VVM_SMS_FILTER_COFIG_SHARED_PREFS_KEY_PREFIX + packageName + "_"
+ + subId;
+ }
+
+ private static class Editor {
+
+ private final SharedPreferences.Editor mPrefsEditor;
+ private final String mKeyPrefix;
+
+ public Editor(Context context, String packageName, int subId) {
+ mPrefsEditor = getSharedPreferences(context).edit();
+ mKeyPrefix = makePerPhoneAccountKeyPrefix(packageName, subId);
+ }
+
+ private Editor setInt(String key, int value) {
+ mPrefsEditor.putInt(makeKey(key), value);
+ return this;
+ }
+
+ private Editor setString(String key, String value) {
+ mPrefsEditor.putString(makeKey(key), value);
+ return this;
+ }
+
+ private Editor setBoolean(String key, boolean value) {
+ mPrefsEditor.putBoolean(makeKey(key), value);
+ return this;
+ }
+
+ private Editor setStringList(String key, List<String> value) {
+ mPrefsEditor.putStringSet(makeKey(key), new ArraySet(value));
+ return this;
+ }
+
+ public void apply() {
+ mPrefsEditor.apply();
+ }
+
+ private String makeKey(String key) {
+ return mKeyPrefix + key;
+ }
+ }
+
+
+ private static class Reader {
+
+ private final SharedPreferences mPrefs;
+ private final String mKeyPrefix;
+
+ public Reader(Context context, String packageName, int subId) {
+ mPrefs = getSharedPreferences(context);
+ mKeyPrefix = makePerPhoneAccountKeyPrefix(packageName, subId);
+ }
+
+ private int getInt(String key, int defaultValue) {
+ return mPrefs.getInt(makeKey(key), defaultValue);
+ }
+
+ private String getString(String key, String defaultValue) {
+ return mPrefs.getString(makeKey(key), defaultValue);
+ }
+
+ private boolean getBoolean(String key, boolean defaultValue) {
+ return mPrefs.getBoolean(makeKey(key), defaultValue);
+ }
+
+ private List<String> getStringSet(String key, List<String> defaultValue) {
+ Set<String> result = mPrefs.getStringSet(makeKey(key), null);
+ if (result == null) {
+ return defaultValue;
+ }
+ return new ArrayList<>(result);
+ }
+
+ private String makeKey(String key) {
+ return mKeyPrefix + key;
+ }
+ }
+}
diff --git a/src/com/android/phone/VoicemailStatus.java b/src/com/android/phone/VoicemailStatus.java
new file mode 100644
index 0000000..062e734
--- /dev/null
+++ b/src/com/android/phone/VoicemailStatus.java
@@ -0,0 +1,92 @@
+/*
+ * 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.phone;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.VoicemailContract;
+import android.provider.VoicemailContract.Status;
+import android.telecom.PhoneAccountHandle;
+
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
+
+public class VoicemailStatus {
+
+
+ public static class Editor {
+
+ private final Context mContext;
+ private final PhoneAccountHandle mPhoneAccountHandle;
+
+ private ContentValues mValues = new ContentValues();
+
+ private Editor(Context context, PhoneAccountHandle phoneAccountHandle) {
+ mContext = context;
+ mPhoneAccountHandle = phoneAccountHandle;
+ }
+
+ public Editor setType(String type) {
+ mValues.put(Status.SOURCE_TYPE, type);
+ return this;
+ }
+
+ public Editor setConfigurationState(int configurationState) {
+ mValues.put(Status.CONFIGURATION_STATE, configurationState);
+ return this;
+ }
+
+ public Editor setDataChannelState(int dataChannelState) {
+ mValues.put(Status.DATA_CHANNEL_STATE, dataChannelState);
+ return this;
+ }
+
+ public Editor setNotificationChannelState(int notificationChannelState) {
+ mValues.put(Status.NOTIFICATION_CHANNEL_STATE, notificationChannelState);
+ return this;
+ }
+
+ public Editor setQuota(int occupied, int total) {
+ if (occupied == VoicemailContract.Status.QUOTA_UNAVAILABLE
+ && total == VoicemailContract.Status.QUOTA_UNAVAILABLE) {
+ return this;
+ }
+
+ mValues.put(Status.QUOTA_OCCUPIED, occupied);
+ mValues.put(Status.QUOTA_TOTAL, total);
+ return this;
+ }
+
+ public void apply() {
+ mValues.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
+ mPhoneAccountHandle.getComponentName().flattenToString());
+ mValues.put(Status.PHONE_ACCOUNT_ID, mPhoneAccountHandle.getId());
+ ContentResolver contentResolver = mContext.getContentResolver();
+ Uri statusUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
+ contentResolver.insert(statusUri, mValues);
+ }
+ }
+
+ public static Editor edit(Context context, PhoneAccountHandle phoneAccountHandle) {
+ return new Editor(context, phoneAccountHandle);
+ }
+
+ public static Editor edit(Context context, int subId) {
+ return new Editor(context, PhoneAccountHandleConverter.fromSubId(subId));
+ }
+}
diff --git a/src/com/android/phone/VoicemailUtils.java b/src/com/android/phone/VoicemailUtils.java
deleted file mode 100644
index f67c64b..0000000
--- a/src/com/android/phone/VoicemailUtils.java
+++ /dev/null
@@ -1,49 +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.phone;
-
-import android.content.Context;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
-import android.telecom.PhoneAccountHandle;
-
-public class VoicemailUtils {
-
- public static void setConfigurationState(Context context, PhoneAccountHandle accountHandle,
- int configurationState) {
- VoicemailContract.Status.setStatus(context, accountHandle,
- configurationState,
- Status.DATA_CHANNEL_STATE_IGNORE,
- Status.NOTIFICATION_CHANNEL_STATE_IGNORE);
- }
-
- public static void setDataChannelState(Context context, PhoneAccountHandle accountHandle,
- int dataChannelState) {
- VoicemailContract.Status.setStatus(context, accountHandle,
- Status.CONFIGURATION_STATE_IGNORE,
- dataChannelState,
- Status.NOTIFICATION_CHANNEL_STATE_IGNORE);
- }
-
- public static void setNotificationChannelState(Context context,
- PhoneAccountHandle accountHandle, int notificationChannelState) {
- VoicemailContract.Status.setStatus(context, accountHandle,
- Status.CONFIGURATION_STATE_IGNORE,
- Status.DATA_CHANNEL_STATE_IGNORE,
- notificationChannelState);
- }
-}
diff --git a/src/com/android/phone/common/mail/MailTransport.java b/src/com/android/phone/common/mail/MailTransport.java
index f452bab..47b273c 100644
--- a/src/com/android/phone/common/mail/MailTransport.java
+++ b/src/com/android/phone/common/mail/MailTransport.java
@@ -17,11 +17,11 @@
import android.content.Context;
import android.net.Network;
-import android.provider.VoicemailContract.Status;
import com.android.internal.annotations.VisibleForTesting;
import com.android.phone.common.mail.store.ImapStore;
import com.android.phone.common.mail.utils.LogUtils;
+import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.imap.ImapHelper;
import java.io.BufferedInputStream;
@@ -32,7 +32,6 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
-import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
@@ -66,6 +65,7 @@
private BufferedOutputStream mOut;
private final int mFlags;
private SocketCreator mSocketCreator;
+ private InetSocketAddress mAddress;
public MailTransport(Context context, ImapHelper imapHelper, Network network, String address,
int port, int flags) {
@@ -117,7 +117,7 @@
}
} catch (IOException ioe) {
LogUtils.d(TAG, ioe.toString());
- mImapHelper.setDataChannelState(Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR);
+ mImapHelper.handleEvent(OmtpEvents.DATA_CANNOT_RESOLVE_HOST_ON_NETWORK);
throw new MessagingException(MessagingException.IOERROR, ioe.toString());
}
}
@@ -126,37 +126,28 @@
while (socketAddresses.size() > 0) {
mSocket = createSocket();
try {
- InetSocketAddress address = socketAddresses.remove(0);
- mSocket.connect(address, SOCKET_CONNECT_TIMEOUT);
+ mAddress = socketAddresses.remove(0);
+ mSocket.connect(mAddress, SOCKET_CONNECT_TIMEOUT);
if (canTrySslSecurity()) {
- /**
- * {@link SSLSocket} must connect in its constructor, or create through a
- * already connected socket. Since we need to use
- * {@link Socket#connect(SocketAddress, int) } to set timeout, we can only
- * create it here.
+ /*
+ SSLSocket cannot be created with a connection timeout, so instead of doing a
+ direct SSL connection, we connect with a normal connection and upgrade it into
+ SSL
*/
- LogUtils.d(TAG, "open: converting to SSL socket");
- mSocket = HttpsURLConnection.getDefaultSSLSocketFactory()
- .createSocket(mSocket, address.getHostName(), address.getPort(), true);
- // After the socket connects to an SSL server, confirm that the hostname is as
- // expected
- if (!canTrustAllCertificates()) {
- verifyHostname(mSocket, mHost);
- }
+ reopenTls();
+ } else {
+ mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
+ mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
+ mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
}
-
- mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
- mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
- mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
success = true;
return;
} catch (IOException ioe) {
LogUtils.d(TAG, ioe.toString());
if (socketAddresses.size() == 0) {
// Only throw an error when there are no more sockets to try.
- mImapHelper
- .setDataChannelState(Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR);
+ mImapHelper.handleEvent(OmtpEvents.DATA_ALL_SOCKET_CONNECTION_FAILED);
throw new MessagingException(MessagingException.IOERROR, ioe.toString());
}
} finally {
@@ -205,6 +196,32 @@
}
/**
+ * Attempts to reopen a normal connection into a TLS connection.
+ */
+ public void reopenTls() throws MessagingException {
+ try {
+ LogUtils.d(TAG, "open: converting to TLS socket");
+ mSocket = HttpsURLConnection.getDefaultSSLSocketFactory()
+ .createSocket(mSocket, mAddress.getHostName(), mAddress.getPort(), true);
+ // After the socket connects to an SSL server, confirm that the hostname is as
+ // expected
+ if (!canTrustAllCertificates()) {
+ verifyHostname(mSocket, mHost);
+ }
+ mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
+ mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
+ mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
+
+ } catch (SSLException e) {
+ LogUtils.d(TAG, e.toString());
+ throw new CertificateValidationException(e.getMessage(), e);
+ } catch (IOException ioe) {
+ LogUtils.d(TAG, ioe.toString());
+ throw new MessagingException(MessagingException.IOERROR, ioe.toString());
+ }
+ }
+
+ /**
* Lightweight version of SSLCertificateSocketFactory.verifyHostname, which provides this
* service but is not in the public API.
*
@@ -229,7 +246,7 @@
SSLSession session = ssl.getSession();
if (session == null) {
- mImapHelper.setDataChannelState(Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR);
+ mImapHelper.handleEvent(OmtpEvents.DATA_CANNOT_ESTABLISH_SSL_SESSION);
throw new SSLException("Cannot verify SSL socket without session");
}
// TODO: Instead of reporting the name of the server we think we're connecting to,
@@ -237,7 +254,7 @@
// in the verifier code and is not available in the verifier API, and extracting the
// CN & alts is beyond the scope of this patch.
if (!HOSTNAME_VERIFIER.verify(hostname, session)) {
- mImapHelper.setDataChannelState(Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR);
+ mImapHelper.handleEvent(OmtpEvents.DATA_SSL_INVALID_HOST_NAME);
throw new SSLPeerUnverifiedException("Certificate hostname not useable for server: "
+ session.getPeerPrincipal());
}
@@ -272,6 +289,10 @@
mSocket = null;
}
+ public String getHost() {
+ return mHost;
+ }
+
public InputStream getInputStream() {
return mIn;
}
diff --git a/src/com/android/phone/common/mail/store/ImapConnection.java b/src/com/android/phone/common/mail/store/ImapConnection.java
index 9207aa9..de40f2c 100644
--- a/src/com/android/phone/common/mail/store/ImapConnection.java
+++ b/src/com/android/phone/common/mail/store/ImapConnection.java
@@ -15,23 +15,28 @@
*/
package com.android.phone.common.mail.store;
-import android.provider.VoicemailContract.Status;
import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Base64;
import com.android.phone.common.mail.AuthenticationFailedException;
import com.android.phone.common.mail.CertificateValidationException;
import com.android.phone.common.mail.MailTransport;
import com.android.phone.common.mail.MessagingException;
+import com.android.phone.common.mail.store.ImapStore.ImapException;
+import com.android.phone.common.mail.store.imap.DigestMd5Utils;
import com.android.phone.common.mail.store.imap.ImapConstants;
import com.android.phone.common.mail.store.imap.ImapResponse;
import com.android.phone.common.mail.store.imap.ImapResponseParser;
import com.android.phone.common.mail.store.imap.ImapUtility;
import com.android.phone.common.mail.utils.LogUtils;
-import com.android.phone.common.mail.store.ImapStore.ImapException;
+import com.android.phone.vvm.omtp.OmtpEvents;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.SSLException;
@@ -46,6 +51,7 @@
private ImapStore mImapStore;
private MailTransport mTransport;
private ImapResponseParser mParser;
+ private Set<String> mCapabilities = new ArraySet<>();
static final String IMAP_REDACTED_LOG = "[IMAP command redacted]";
@@ -87,7 +93,7 @@
return mLoginPhrase;
}
- void open() throws IOException, MessagingException {
+ public void open() throws IOException, MessagingException {
if (mTransport != null && mTransport.isOpen()) {
return;
}
@@ -102,16 +108,31 @@
createParser();
+ // The server should greet us with something like
+ // * OK IMAP4rev1 Server
+ // consume the response before doing anything else.
+ ImapResponse response = mParser.readResponse();
+ if (!response.isOk()) {
+ mImapStore.getImapHelper()
+ .handleEvent(OmtpEvents.DATA_INVALID_INITIAL_SERVER_RESPONSE);
+ throw new MessagingException(
+ MessagingException.AUTHENTICATION_FAILED_OR_SERVER_ERROR,
+ "Invalid server initial response");
+ }
+
+ queryCapability();
+
+ maybeDoStartTls();
+
// LOGIN
doLogin();
} catch (SSLException e) {
LogUtils.d(TAG, "SSLException ", e);
- mImapStore.getImapHelper().setDataChannelState(Status.DATA_CHANNEL_STATE_SERVER_ERROR);
+ mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_SSL_EXCEPTION);
throw new CertificateValidationException(e.getMessage(), e);
} catch (IOException ioe) {
LogUtils.d(TAG, "IOException", ioe);
- mImapStore.getImapHelper()
- .setDataChannelState(Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR);
+ mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_IOE_ON_OPEN);
throw ioe;
} finally {
destroyResponses();
@@ -133,11 +154,30 @@
}
/**
+ * Attempts to convert the connection into secure connection.
+ */
+ private void maybeDoStartTls() throws IOException, MessagingException {
+ // STARTTLS is required in the OMTP standard but not every implementation support it.
+ // Make sure the server does have this capability
+ if (hasCapability(ImapConstants.CAPABILITY_STARTTLS)) {
+ executeSimpleCommand(ImapConstants.STARTTLS);
+ mTransport.reopenTls();
+ createParser();
+ // The cached capabilities should be refreshed after TLS is established.
+ queryCapability();
+ }
+ }
+
+ /**
* Logs into the IMAP server
*/
private void doLogin() throws IOException, MessagingException, AuthenticationFailedException {
try {
- executeSimpleCommand(getLoginPhrase(), true);
+ if (mCapabilities.contains(ImapConstants.CAPABILITY_AUTH_DIGEST_MD5)) {
+ doDigestMd5Auth();
+ } else {
+ executeSimpleCommand(getLoginPhrase(), true);
+ }
} catch (ImapException ie) {
LogUtils.d(TAG, "ImapException", ie);
final String status = ie.getStatus();
@@ -148,8 +188,7 @@
if (ImapConstants.AUTHENTICATIONFAILED.equals(code) ||
ImapConstants.EXPIRED.equals(code) ||
(ImapConstants.NO.equals(status) && TextUtils.isEmpty(code))) {
- mImapStore.getImapHelper()
- .setDataChannelState(Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION);
+ mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_BAD_IMAP_CREDENTIAL);
throw new AuthenticationFailedException(alertText, ie);
}
@@ -157,6 +196,84 @@
}
}
+ private void doDigestMd5Auth() throws IOException, MessagingException {
+
+ // Initiate the authentication.
+ // The server will issue us a challenge, asking to run MD5 on the nonce with our password
+ // and other data, including the cnonce we randomly generated.
+ //
+ // C: a AUTHENTICATE DIGEST-MD5
+ // S: (BASE64) realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
+ // algorithm=md5-sess,charset=utf-8
+ List<ImapResponse> responses = executeSimpleCommand(
+ ImapConstants.AUTHENTICATE + " " + ImapConstants.AUTH_DIGEST_MD5);
+ String decodedChallenge = decodeBase64(responses.get(0).getStringOrEmpty(0).getString());
+
+ Map<String, String> challenge = DigestMd5Utils.parseDigestMessage(decodedChallenge);
+ DigestMd5Utils.Data data = new DigestMd5Utils.Data(mImapStore, mTransport, challenge);
+
+ String response = data.createResponse();
+ // Respond to the challenge. If the server accepts it, it will reply a response-auth which
+ // is the MD5 of our password and the cnonce we've provided, to prove the server does know
+ // the password.
+ //
+ // C: (BASE64) charset=utf-8,username="chris",realm="elwood.innosoft.com",
+ // nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
+ // digest-uri="imap/elwood.innosoft.com",
+ // response=d388dad90d4bbd760a152321f2143af7,qop=auth
+ // S: (BASE64) rspauth=ea40f60335c427b5527b84dbabcdfffd
+
+ responses = executeContinuationResponse(encodeBase64(response), true);
+
+ // Verify response-auth.
+ // If failed verifyResponseAuth() will throw a MessagingException, terminating the
+ // connection
+ String decodedResponseAuth = decodeBase64(responses.get(0).getStringOrEmpty(0).getString());
+ data.verifyResponseAuth(decodedResponseAuth);
+
+ // Send a empty response to indicate we've accepted the response-auth
+ //
+ // C: (empty)
+ // S: a OK User logged in
+ executeContinuationResponse("", false);
+
+ }
+
+ private static String decodeBase64(String string) {
+ return new String(Base64.decode(string, Base64.DEFAULT));
+ }
+
+ private static String encodeBase64(String string) {
+ return Base64.encodeToString(string.getBytes(), Base64.NO_WRAP);
+ }
+
+ private void queryCapability() throws IOException, MessagingException {
+ List<ImapResponse> responses = executeSimpleCommand(ImapConstants.CAPABILITY);
+ mCapabilities.clear();
+ Set<String> disabledCapabilities = mImapStore.getImapHelper().getConfig()
+ .getDisabledCapabilities();
+ for (ImapResponse response : responses) {
+ if (response.isTagged()) {
+ continue;
+ }
+ for (int i = 0; i < response.size(); i++) {
+ String capability = response.getStringOrEmpty(i).getString();
+ if (disabledCapabilities != null) {
+ if (!disabledCapabilities.contains(capability)) {
+ mCapabilities.add(capability);
+ }
+ } else {
+ mCapabilities.add(capability);
+ }
+ }
+ }
+
+ LogUtils.d(TAG, "Capabilities: " + mCapabilities.toString());
+ }
+
+ private boolean hasCapability(String capability) {
+ return mCapabilities.contains(capability);
+ }
/**
* Create an {@link ImapResponseParser} from {@code mTransport.getInputStream()} and
* set it to {@link #mParser}.
@@ -170,17 +287,17 @@
}
- void destroyResponses() {
+ public void destroyResponses() {
if (mParser != null) {
mParser.destroyResponses();
}
}
- ImapResponse readResponse() throws IOException, MessagingException {
+ public ImapResponse readResponse() throws IOException, MessagingException {
return mParser.readResponse();
}
- List<ImapResponse> executeSimpleCommand(String command)
+ public List<ImapResponse> executeSimpleCommand(String command)
throws IOException, MessagingException{
return executeSimpleCommand(command, false);
}
@@ -197,7 +314,7 @@
* @throws IOException
* @throws MessagingException
*/
- List<ImapResponse> executeSimpleCommand(String command, boolean sensitive)
+ public List<ImapResponse> executeSimpleCommand(String command, boolean sensitive)
throws IOException, MessagingException {
// TODO: It may be nice to catch IOExceptions and close the connection here.
// Currently, we expect callers to do that, but if they fail to we'll be in a broken state.
@@ -205,7 +322,8 @@
return getCommandResponses();
}
- String sendCommand(String command, boolean sensitive) throws IOException, MessagingException {
+ public String sendCommand(String command, boolean sensitive)
+ throws IOException, MessagingException {
open();
if (mTransport == null) {
@@ -214,10 +332,15 @@
String tag = Integer.toString(mNextCommandTag.incrementAndGet());
String commandToSend = tag + " " + command;
mTransport.writeLine(commandToSend, (sensitive ? IMAP_REDACTED_LOG : command));
-
return tag;
}
+ List<ImapResponse> executeContinuationResponse(String response, boolean sensitive)
+ throws IOException, MessagingException {
+ mTransport.writeLine(response, (sensitive ? IMAP_REDACTED_LOG : response));
+ return getCommandResponses();
+ }
+
/**
* Read and return all of the responses from the most recent command sent to the server
*
@@ -231,15 +354,15 @@
do {
response = mParser.readResponse();
responses.add(response);
- } while (!response.isTagged());
+ } while (!(response.isTagged() || response.isContinuationRequest()));
- if (!response.isOk()) {
+ if (!(response.isOk() || response.isContinuationRequest())) {
final String toString = response.toString();
final String status = response.getStatusOrEmpty().getString();
final String alert = response.getAlertTextOrEmpty().getString();
final String responseCode = response.getResponseCodeOrEmpty().getString();
destroyResponses();
- mImapStore.getImapHelper().setDataChannelState(Status.DATA_CHANNEL_STATE_SERVER_ERROR);
+ mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_REJECTED_SERVER_RESPONSE);
// if the response code indicates an error occurred within the server, indicate that
if (ImapConstants.UNAVAILABLE.equals(responseCode)) {
diff --git a/src/com/android/phone/common/mail/store/ImapFolder.java b/src/com/android/phone/common/mail/store/ImapFolder.java
index 13c7424..fe3df30 100644
--- a/src/com/android/phone/common/mail/store/ImapFolder.java
+++ b/src/com/android/phone/common/mail/store/ImapFolder.java
@@ -17,14 +17,8 @@
import android.annotation.Nullable;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
-import android.telecom.Voicemail;
import android.text.TextUtils;
import android.util.Base64DataException;
-import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.phone.common.R;
@@ -49,6 +43,7 @@
import com.android.phone.common.mail.store.imap.ImapString;
import com.android.phone.common.mail.utils.LogUtils;
import com.android.phone.common.mail.utils.Utility;
+import com.android.phone.vvm.omtp.OmtpEvents;
import java.io.IOException;
import java.io.InputStream;
@@ -107,6 +102,7 @@
return;
} catch (IOException ioe) {
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
ioExceptionHandler(mConnection, ioe);
} finally {
destroyResponses();
@@ -207,6 +203,7 @@
return Utility.EMPTY_STRINGS; // Not found
} catch (IOException ioe) {
LogUtils.d(TAG, "IOException in search: " + searchCriteria, ioe);
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
throw ioExceptionHandler(mConnection, ioe);
}
} finally {
@@ -432,6 +429,7 @@
}
} while (!response.isTagged());
} catch (IOException ioe) {
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
throw ioExceptionHandler(mConnection, ioe);
}
}
@@ -667,6 +665,7 @@
try {
handleUntaggedResponses(mConnection.executeSimpleCommand(ImapConstants.EXPUNGE));
} catch (IOException ioe) {
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
throw ioExceptionHandler(mConnection, ioe);
} finally {
destroyResponses();
@@ -703,6 +702,7 @@
allFlags));
} catch (IOException ioe) {
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
throw ioExceptionHandler(mConnection, ioe);
} finally {
destroyResponses();
@@ -731,7 +731,7 @@
mMode = MODE_READ_WRITE;
}
} else if (response.isTagged()) { // Not OK
- mStore.getImapHelper().setDataChannelState(Status.DATA_CHANNEL_STATE_SERVER_ERROR);
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_MAILBOX_OPEN_FAILED);
throw new MessagingException("Can't open mailbox: "
+ response.getStatusResponseTextOrEmpty());
}
@@ -774,6 +774,7 @@
}
}
} catch (IOException ioe) {
+ mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
throw ioExceptionHandler(mConnection, ioe);
} finally {
destroyResponses();
@@ -794,7 +795,6 @@
mConnection = null; // To prevent close() from returning the connection to the pool.
close(false);
}
- mStore.getImapHelper().setDataChannelState(Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR);
return new MessagingException(MessagingException.IOERROR, "IO Error", ioe);
}
diff --git a/src/com/android/phone/common/mail/store/imap/DigestMd5Utils.java b/src/com/android/phone/common/mail/store/imap/DigestMd5Utils.java
new file mode 100644
index 0000000..e6376a3
--- /dev/null
+++ b/src/com/android/phone/common/mail/store/imap/DigestMd5Utils.java
@@ -0,0 +1,333 @@
+/*
+ * 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.phone.common.mail.store.imap;
+
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.util.Base64;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.common.mail.MailTransport;
+import com.android.phone.common.mail.MessagingException;
+import com.android.phone.common.mail.store.ImapStore;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Map;
+
+public class DigestMd5Utils {
+
+ private static final String TAG = "DigestMd5Utils";
+
+ private static final String DIGEST_CHARSET = "CHARSET";
+ private static final String DIGEST_USERNAME = "username";
+ private static final String DIGEST_REALM = "realm";
+ private static final String DIGEST_NONCE = "nonce";
+ private static final String DIGEST_NC = "nc";
+ private static final String DIGEST_CNONCE = "cnonce";
+ private static final String DIGEST_URI = "digest-uri";
+ private static final String DIGEST_RESPONSE = "response";
+ private static final String DIGEST_QOP = "qop";
+
+ private static final String RESPONSE_AUTH_HEADER = "rspauth=";
+ private static final String HEX_CHARS = "0123456789abcdef";
+
+ /**
+ * Represents the set of data we need to generate the DIGEST-MD5 response.
+ */
+ public static class Data {
+
+ private static final String CHARSET = "utf-8'";
+
+ public String username;
+ public String password;
+ public String realm;
+ public String nonce;
+ public String nc;
+ public String cnonce;
+ public String digestUri;
+ public String qop;
+
+ @VisibleForTesting
+ Data() {
+ // Do nothing
+ }
+
+ public Data(ImapStore imapStore, MailTransport transport, Map<String, String> challenge) {
+ username = imapStore.getUsername();
+ password = imapStore.getPassword();
+ realm = challenge.getOrDefault(DIGEST_REALM, "");
+ nonce = challenge.get(DIGEST_NONCE);
+ cnonce = createCnonce();
+ nc = "00000001"; // Subsequent Authentication not supported, nounce count always 1.
+ qop = "auth"; // Other config not supported
+ digestUri = "imap/" + transport.getHost();
+ }
+
+ private static String createCnonce() {
+ SecureRandom generator = new SecureRandom();
+
+ // At least 64 bits of entropy is required
+ byte[] rawBytes = new byte[8];
+ generator.nextBytes(rawBytes);
+
+ return Base64.encodeToString(rawBytes, Base64.NO_WRAP);
+ }
+
+ /**
+ * Verify the response-auth returned by the server is correct.
+ */
+ public void verifyResponseAuth(String response)
+ throws MessagingException {
+ if (!response.startsWith(RESPONSE_AUTH_HEADER)) {
+ throw new MessagingException("response-auth expected");
+ }
+ if (!response.substring(RESPONSE_AUTH_HEADER.length())
+ .equals(DigestMd5Utils.getResponse(this, true))) {
+ throw new MessagingException("invalid response-auth return from the server.");
+ }
+ }
+
+ public String createResponse() {
+ String response = getResponse(this, false);
+ ResponseBuilder builder = new ResponseBuilder();
+ builder
+ .append(DIGEST_CHARSET, CHARSET)
+ .appendQuoted(DIGEST_USERNAME, username)
+ .appendQuoted(DIGEST_REALM, realm)
+ .appendQuoted(DIGEST_NONCE, nonce)
+ .append(DIGEST_NC, nc)
+ .appendQuoted(DIGEST_CNONCE, cnonce)
+ .appendQuoted(DIGEST_URI, digestUri)
+ .append(DIGEST_RESPONSE, response)
+ .append(DIGEST_QOP, qop);
+ return builder.toString();
+ }
+
+ private static class ResponseBuilder {
+
+ private StringBuilder mBuilder = new StringBuilder();
+
+ public ResponseBuilder appendQuoted(String key, String value) {
+ if (mBuilder.length() != 0) {
+ mBuilder.append(",");
+ }
+ mBuilder.append(key).append("=\"").append(value).append("\"");
+ return this;
+ }
+
+ public ResponseBuilder append(String key, String value) {
+ if (mBuilder.length() != 0) {
+ mBuilder.append(",");
+ }
+ mBuilder.append(key).append("=").append(value);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return mBuilder.toString();
+ }
+ }
+ }
+
+ /*
+ response-value =
+ toHex( getKeyDigest ( toHex(getMd5(a1)),
+ { nonce-value, ":" nc-value, ":",
+ cnonce-value, ":", qop-value, ":", toHex(getMd5(a2)) }))
+ * @param isResponseAuth is the response the one the server is returning us. response-auth has
+ * different a2 format.
+ */
+ @VisibleForTesting
+ static String getResponse(Data data, boolean isResponseAuth) {
+ StringBuilder a1 = new StringBuilder();
+ a1.append(new String(
+ getMd5(data.username + ":" + data.realm + ":" + data.password),
+ StandardCharsets.ISO_8859_1));
+ a1.append(":").append(data.nonce).append(":").append(data.cnonce);
+
+ StringBuilder a2 = new StringBuilder();
+ if (!isResponseAuth) {
+ a2.append("AUTHENTICATE");
+ }
+ a2.append(":").append(data.digestUri);
+
+ return toHex(getKeyDigest(
+ toHex(getMd5(a1.toString())),
+ data.nonce + ":" + data.nc + ":" + data.cnonce + ":" + data.qop + ":" + toHex(
+ getMd5(a2.toString()))
+ ));
+ }
+
+ /**
+ * Let getMd5(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.
+ */
+ private static byte[] getMd5(String s) {
+ try {
+ MessageDigest digester = MessageDigest.getInstance("MD5");
+ digester.update(s.getBytes(StandardCharsets.ISO_8859_1));
+ return digester.digest();
+ } catch (NoSuchAlgorithmException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Let getKeyDigest(k, s) be getMd5({k, ":", s}), i.e., the 16 octet hash of the string k, a colon and the
+ * string s.
+ */
+ private static byte[] getKeyDigest(String k, String s) {
+ StringBuilder builder = new StringBuilder(k).append(":").append(s);
+ return getMd5(builder.toString());
+ }
+
+ /**
+ * Let toHex(n) be the representation of the 16 octet MD5 hash n as a string of 32 hex digits
+ * (with alphabetic characters always in lower case, since MD5 is case sensitive).
+ */
+ private static String toHex(byte[] n) {
+ StringBuilder result = new StringBuilder();
+ for (byte b : n) {
+ int unsignedByte = b & 0xFF;
+ result.append(HEX_CHARS.charAt(unsignedByte / 16))
+ .append(HEX_CHARS.charAt(unsignedByte % 16));
+ }
+ return result.toString();
+ }
+
+ public static Map<String, String> parseDigestMessage(String message) throws MessagingException {
+ Map<String, String> result = new DigestMessageParser(message).parse();
+ if (!result.containsKey(DIGEST_NONCE)) {
+ throw new MessagingException("nonce missing from server DIGEST-MD5 challenge");
+ }
+ return result;
+ }
+
+ /**
+ * Parse the key-value pair returned by the server.
+ */
+ private static class DigestMessageParser {
+
+ private final String mMessage;
+ private int mPosition = 0;
+ private Map<String, String> mResult = new ArrayMap<>();
+
+ public DigestMessageParser(String message) {
+ mMessage = message;
+ }
+
+ @Nullable
+ public Map<String, String> parse() {
+ try {
+ while (mPosition < mMessage.length()) {
+ parsePair();
+ if (mPosition != mMessage.length()) {
+ expect(',');
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, e.toString());
+ return null;
+ }
+ return mResult;
+ }
+
+ private void parsePair() {
+ String key = parseKey();
+ expect('=');
+ String value = parseValue();
+ mResult.put(key, value);
+ }
+
+ private void expect(char c) {
+ if (pop() != c) {
+ throw new IllegalStateException(
+ "unexpected character " + mMessage.charAt(mPosition));
+ }
+ }
+
+ private char pop() {
+ char result = peek();
+ mPosition++;
+ return result;
+ }
+
+ private char peek() {
+ return mMessage.charAt(mPosition);
+ }
+
+ private void goToNext(char c) {
+ while (peek() != c) {
+ mPosition++;
+ }
+ }
+
+ private String parseKey() {
+ int start = mPosition;
+ goToNext('=');
+ return mMessage.substring(start, mPosition);
+ }
+
+ private String parseValue() {
+ if (peek() == '"') {
+ return parseQuotedValue();
+ } else {
+ return parseUnquotedValue();
+ }
+ }
+
+ private String parseQuotedValue() {
+ expect('"');
+ StringBuilder result = new StringBuilder();
+ while (true) {
+ char c = pop();
+ if (c == '\\') {
+ result.append(pop());
+ } else if (c == '"') {
+ break;
+ } else {
+ result.append(c);
+ }
+ }
+ return result.toString();
+ }
+
+ private String parseUnquotedValue() {
+ StringBuilder result = new StringBuilder();
+ while (true) {
+ char c = pop();
+ if (c == '\\') {
+ result.append(pop());
+ } else if (c == ',') {
+ mPosition--;
+ break;
+ } else {
+ result.append(c);
+ }
+
+ if (mPosition == mMessage.length()) {
+ break;
+ }
+ }
+ return result.toString();
+ }
+ }
+}
diff --git a/src/com/android/phone/common/mail/store/imap/ImapConstants.java b/src/com/android/phone/common/mail/store/imap/ImapConstants.java
index 63dda8c..9e6e247 100644
--- a/src/com/android/phone/common/mail/store/imap/ImapConstants.java
+++ b/src/com/android/phone/common/mail/store/imap/ImapConstants.java
@@ -109,4 +109,15 @@
public static final String EXPIRED = "EXPIRED";
public static final String AUTHENTICATIONFAILED = "AUTHENTICATIONFAILED";
public static final String UNAVAILABLE = "UNAVAILABLE";
+
+ /**
+ * capabilities
+ */
+ public static final String CAPABILITY_AUTH_DIGEST_MD5 = "AUTH=DIGEST-MD5";
+ public static final String CAPABILITY_STARTTLS = "STARTTLS";
+
+ /**
+ * authentication
+ */
+ public static final String AUTH_DIGEST_MD5 = "DIGEST-MD5";
}
\ No newline at end of file
diff --git a/src/com/android/phone/settings/VoicemailChangePinDialogPreference.java b/src/com/android/phone/settings/VoicemailChangePinDialogPreference.java
new file mode 100644
index 0000000..d960dc4
--- /dev/null
+++ b/src/com/android/phone/settings/VoicemailChangePinDialogPreference.java
@@ -0,0 +1,210 @@
+/*
+ * 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.phone.settings;
+
+import android.annotation.Nullable;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.Network;
+import android.preference.DialogPreference;
+import android.preference.PreferenceManager;
+import android.telecom.PhoneAccountHandle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.phone.PhoneUtils;
+import com.android.phone.R;
+import com.android.phone.common.mail.MessagingException;
+import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.OmtpConstants.ChangePinResult;
+import com.android.phone.vvm.omtp.imap.ImapHelper;
+import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
+
+/**
+ * Dialog to change the voicemail PIN. The TUI PIN is used when accessing traditional voicemail through
+ * phone call.
+ */
+public class VoicemailChangePinDialogPreference extends DialogPreference {
+
+ private static final String TAG = "VmChangePinDialog";
+
+ private EditText mOldPin;
+ private EditText mNewPin;
+ private PhoneAccountHandle mPhoneAccountHandle;
+
+ private ProgressDialog mProgressDialog;
+
+ private static final String DEFAULT_OLD_PIN_KEY = "default_old_pin";
+
+ public VoicemailChangePinDialogPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public VoicemailChangePinDialogPreference(Context context, AttributeSet attrs,
+ int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected View onCreateDialogView() {
+ setDialogLayoutResource(R.layout.voicemail_dialog_change_pin);
+
+ View dialog = super.onCreateDialogView();
+
+ mOldPin = (EditText) dialog.findViewById(R.id.vm_old_pin);
+ mNewPin = (EditText) dialog.findViewById(R.id.vm_new_pin);
+ String defaultOldPin = getDefaultOldPin(getContext(), mPhoneAccountHandle);
+ if (defaultOldPin != null) {
+ // If the old PIN was set by the system, read its' value and hide the input box.
+ mOldPin.setText(defaultOldPin);
+ mOldPin.setVisibility(View.GONE);
+ dialog.findViewById(R.id.vm_old_pin_label).setVisibility(View.GONE);
+ }
+ return dialog;
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ if (positiveResult) {
+ processPinChange();
+ }
+ super.onDialogClosed(positiveResult);
+ }
+
+ public VoicemailChangePinDialogPreference setPhoneAccountHandle(PhoneAccountHandle handle) {
+ mPhoneAccountHandle = handle;
+ return this;
+ }
+
+ @Nullable
+ public static String getDefaultOldPin(Context context, PhoneAccountHandle handle) {
+ return getSharedPreference(context)
+ .getString(getPerPhoneAccountKey(handle, DEFAULT_OLD_PIN_KEY), null);
+ }
+
+ public static void setDefaultOldPIN(Context context, PhoneAccountHandle handle,
+ @Nullable String pin) {
+ SharedPreferences preferences = getSharedPreference(context);
+ preferences.edit()
+ .putString(getPerPhoneAccountKey(handle, DEFAULT_OLD_PIN_KEY), pin)
+ .apply();
+ }
+
+ private static String getPerPhoneAccountKey(PhoneAccountHandle handle, String key) {
+ return "voicemail_pin_dialog_preference_"
+ + PhoneUtils.getSubIdForPhoneAccountHandle(handle) + "_" + key;
+ }
+
+ private static SharedPreferences getSharedPreference(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context);
+ }
+
+ private void processPinChange() {
+ mProgressDialog = new ProgressDialog(getContext());
+ mProgressDialog.setCancelable(false);
+ mProgressDialog.setMessage(getContext().getString(R.string.vm_change_pin_progress_message));
+ mProgressDialog.show();
+
+ ChangePinNetworkRequestCallback callback = new ChangePinNetworkRequestCallback();
+ callback.requestNetwork();
+ }
+
+ private void finishPinChange() {
+ mProgressDialog.dismiss();
+ }
+
+ private void showError(@ChangePinResult int result) {
+ if (result != OmtpConstants.CHANGE_PIN_SUCCESS) {
+ CharSequence message;
+ switch (result) {
+ case OmtpConstants.CHANGE_PIN_TOO_SHORT:
+ message = getContext().getString(R.string.vm_change_pin_error_too_short);
+ break;
+ case OmtpConstants.CHANGE_PIN_TOO_LONG:
+ message = getContext().getString(R.string.vm_change_pin_error_too_long);
+ break;
+
+ case OmtpConstants.CHANGE_PIN_TOO_WEAK:
+ message = getContext().getString(R.string.vm_change_pin_error_too_weak);
+ break;
+ case OmtpConstants.CHANGE_PIN_INVALID_CHARACTER:
+ message = getContext().getString(R.string.vm_change_pin_error_invalid);
+ break;
+ case OmtpConstants.CHANGE_PIN_MISMATCH:
+ message = getContext().getString(R.string.vm_change_pin_error_mismatch);
+ break;
+ case OmtpConstants.CHANGE_PIN_SYSTEM_ERROR:
+ message = getContext().getString(R.string.vm_change_pin_error_system_error);
+ break;
+ default:
+ Log.wtf(TAG, "Unexpected ChangePinResult " + result);
+ return;
+ }
+ new AlertDialog.Builder(getContext())
+ .setMessage(message)
+ .setPositiveButton(android.R.string.ok, null)
+ .show();
+ }
+ }
+
+ private class ChangePinNetworkRequestCallback extends VvmNetworkRequestCallback {
+
+ public ChangePinNetworkRequestCallback() {
+ super(getContext(), mPhoneAccountHandle);
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+ ImapHelper helper = new ImapHelper(getContext(), mPhoneAccountHandle, network);
+ try {
+ @ChangePinResult int result =
+ helper.changePin(mOldPin.getText().toString(),
+ mNewPin.getText().toString());
+ finishPinChange();
+ if (result != OmtpConstants.CHANGE_PIN_SUCCESS) {
+ showError(result);
+ }
+
+ if (result == OmtpConstants.CHANGE_PIN_SUCCESS
+ || result == OmtpConstants.CHANGE_PIN_MISMATCH) {
+ // If the PIN change succeeded we no longer know what the old (current) PIN is.
+ // If the default old PIN is rejected by the server, the PIN is probably changed
+ // through other means.
+ // Wipe the default old PIN so the old PIN input box will be shown to the user
+ // on the next time.
+ setDefaultOldPIN(mContext, mPhoneAccountHandle, null);
+ }
+ } catch (MessagingException e) {
+ finishPinChange();
+ showError(OmtpConstants.CHANGE_PIN_SYSTEM_ERROR);
+ }
+
+ }
+
+ @Override
+ public void onFailed(String reason) {
+ super.onFailed(reason);
+ finishPinChange();
+ showError(OmtpConstants.CHANGE_PIN_SYSTEM_ERROR);
+ }
+ }
+}
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index a08fe30..fc53f15 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -30,7 +30,6 @@
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.provider.ContactsContract.CommonDataKinds;
-import android.telephony.TelephonyManager;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
@@ -41,10 +40,10 @@
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.phone.R;
import com.android.phone.EditPhoneNumberPreference;
import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneUtils;
+import com.android.phone.R;
import com.android.phone.SubscriptionInfoHelper;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
@@ -202,7 +201,7 @@
private VoicemailRingtonePreference mVoicemailNotificationRingtone;
private CheckBoxPreference mVoicemailNotificationVibrate;
private SwitchPreference mVoicemailVisualVoicemail;
-
+ private VoicemailChangePinDialogPreference mVoicemailChangePinPreference;
//*********************************************************************************************
// Preference Activity Methods
@@ -261,13 +260,22 @@
mVoicemailVisualVoicemail = (SwitchPreference) findPreference(
getResources().getString(R.string.voicemail_visual_voicemail_key));
- if (TelephonyManager.VVM_TYPE_OMTP.equals(mOmtpVvmCarrierConfigHelper.getVvmType()) ||
- TelephonyManager.VVM_TYPE_CVVM.equals(mOmtpVvmCarrierConfigHelper.getVvmType())) {
+
+ mVoicemailChangePinPreference = (VoicemailChangePinDialogPreference) findPreference(
+ getResources().getString(R.string.voicemail_change_pin_key));
+ mVoicemailChangePinPreference
+ .setPhoneAccountHandle(PhoneUtils.makePstnPhoneAccountHandle(mPhone));
+
+ if (mOmtpVvmCarrierConfigHelper.isValid()) {
mVoicemailVisualVoicemail.setOnPreferenceChangeListener(this);
mVoicemailVisualVoicemail.setChecked(
VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(mPhone));
+
+ mVoicemailChangePinPreference
+ .setPhoneAccountHandle(PhoneUtils.makePstnPhoneAccountHandle(mPhone));
} else {
prefSet.removePreference(mVoicemailVisualVoicemail);
+ prefSet.removePreference(mVoicemailChangePinPreference);
}
updateVMPreferenceWidgets(mVoicemailProviders.getValue());
@@ -391,12 +399,15 @@
} else if (preference.getKey().equals(mVoicemailVisualVoicemail.getKey())) {
boolean isEnabled = (Boolean) objValue;
VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(mPhone, isEnabled, true);
+ PreferenceScreen prefSet = getPreferenceScreen();
if (isEnabled) {
OmtpVvmSourceManager.getInstance(mPhone.getContext()).addPhoneStateListener(mPhone);
mOmtpVvmCarrierConfigHelper.startActivation();
+ prefSet.addPreference(mVoicemailChangePinPreference);
} else {
OmtpVvmSourceManager.getInstance(mPhone.getContext()).removeSource(mPhone);
mOmtpVvmCarrierConfigHelper.startDeactivation();
+ prefSet.removePreference(mVoicemailChangePinPreference);
}
}
diff --git a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
new file mode 100644
index 0000000..6816d4c
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
@@ -0,0 +1,160 @@
+/*
+ * 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.phone.vvm.omtp;
+
+import android.content.Context;
+import android.provider.VoicemailContract;
+import android.provider.VoicemailContract.Status;
+
+import com.android.phone.VoicemailStatus;
+import com.android.phone.vvm.omtp.OmtpEvents.Type;
+import com.android.services.telephony.Log;
+
+public class DefaultOmtpEventHandler {
+
+ private static final String TAG = "DefErrorCodeHandler";
+
+ public static void handleEvent(Context context, int subId, OmtpEvents event) {
+ switch (event.getType()) {
+ case Type.CONFIGURATION:
+ handleConfigurationEvent(context, subId, event);
+ break;
+ case Type.DATA_CHANNEL:
+ handleDataChannelEvent(context, subId, event);
+ break;
+ case Type.NOTIFICATION_CHANNEL:
+ handleNotificationChannelEvent(context, subId, event);
+ break;
+ case Type.OTHER:
+ handleOtherEvent(context, subId, event);
+ break;
+ default:
+ Log.wtf(TAG, "invalid event type " + event.getType() + " for " + event);
+ }
+ }
+
+ private static void handleConfigurationEvent(Context context, int subId,
+ OmtpEvents event) {
+ switch (event) {
+ case CONFIG_REQUEST_STATUS_SUCCESS:
+ VoicemailStatus.edit(context, subId)
+ .setConfigurationState(VoicemailContract.Status.CONFIGURATION_STATE_OK)
+ .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
+ .apply();
+ break;
+ default:
+ Log.wtf(TAG, "invalid configuration event " + event);
+ }
+ }
+
+ private static void handleDataChannelEvent(Context context, int subId,
+ OmtpEvents event) {
+ switch (event) {
+ case DATA_IMAP_OPERATION_COMPLETED:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
+ .apply();
+ break;
+
+ case DATA_NO_CONNECTION:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
+ .apply();
+ break;
+
+ case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(
+ Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED)
+ .apply();
+ break;
+ case DATA_INVALID_PORT:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(
+ VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
+ .apply();
+ break;
+ case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(
+ VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR)
+ .apply();
+ break;
+ case DATA_SSL_INVALID_HOST_NAME:
+ case DATA_CANNOT_ESTABLISH_SSL_SESSION:
+ case DATA_IOE_ON_OPEN:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(
+ VoicemailContract.Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR)
+ .apply();
+ break;
+ case DATA_BAD_IMAP_CREDENTIAL:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(
+ VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
+ .apply();
+ break;
+
+ case DATA_REJECTED_SERVER_RESPONSE:
+ case DATA_INVALID_INITIAL_SERVER_RESPONSE:
+ case DATA_SSL_EXCEPTION:
+ case DATA_ALL_SOCKET_CONNECTION_FAILED:
+ VoicemailStatus.edit(context, subId)
+ .setDataChannelState(
+ VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_ERROR)
+ .apply();
+ break;
+
+ default:
+ Log.wtf(TAG, "invalid data channel event " + event);
+ }
+ }
+
+ private static void handleNotificationChannelEvent(Context context, int subId,
+ OmtpEvents event) {
+ switch (event) {
+ case NOTIFICATION_IN_SERVICE:
+ VoicemailStatus.edit(context, subId)
+ .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
+ .apply();
+ break;
+ case NOTIFICATION_SERVICE_LOST:
+ VoicemailStatus.edit(context, subId)
+ .setNotificationChannelState(
+ Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
+ .apply();
+ break;
+ default:
+ Log.wtf(TAG, "invalid notification channel event " + event);
+ }
+ }
+
+ private static void handleOtherEvent(Context context, int subId, OmtpEvents event) {
+ switch (event) {
+ case OTHER_SOURCE_REMOVED:
+ VoicemailStatus.edit(context, subId)
+ .setConfigurationState(Status.CONFIGURATION_STATE_NOT_CONFIGURED)
+ .setNotificationChannelState(
+ Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
+ .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
+ .apply();
+ break;
+ default:
+ Log.wtf(TAG, "invalid other event " + event);
+ }
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/OmtpConstants.java b/src/com/android/phone/vvm/omtp/OmtpConstants.java
index fa3cb63..8975b59 100644
--- a/src/com/android/phone/vvm/omtp/OmtpConstants.java
+++ b/src/com/android/phone/vvm/omtp/OmtpConstants.java
@@ -15,22 +15,24 @@
*/
package com.android.phone.vvm.omtp;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.Map;
/**
- * Wrapper class to hold relevant OMTP constants as defined in the OMTP spec.
- * <p>
- * In essence this is a programmatic representation of the relevant portions of OMTP spec.
+ * Wrapper class to hold relevant OMTP constants as defined in the OMTP spec. <p> In essence this is
+ * a programmatic representation of the relevant portions of OMTP spec.
*/
public class OmtpConstants {
public static final String SMS_FIELD_SEPARATOR = ";";
public static final String SMS_KEY_VALUE_SEPARATOR = "=";
public static final String SMS_PREFIX_SEPARATOR = ":";
- public static final String CLIENT_PREFIX = "//VVM";
- public static final String SYNC_SMS_PREFIX = CLIENT_PREFIX + ":SYNC:";
- public static final String STATUS_SMS_PREFIX = CLIENT_PREFIX + ":STATUS:";
+ public static final String SYNC_SMS_PREFIX = "SYNC";
+ public static final String STATUS_SMS_PREFIX = "STATUS";
// This is the format designated by the OMTP spec.
public static final String DATE_TIME_FORMAT = "dd/MM/yyyy HH:mm Z";
@@ -137,8 +139,6 @@
* <p>
* Referred by {@link OmtpConstants#PROVISIONING_STATUS}.
*/
- // TODO: As per the spec the code could be either be with or w/o quotes = "N"/N). Currently
- // this only handles the w/o quotes values.
public static final String SUBSCRIBER_NEW = "N";
public static final String SUBSCRIBER_READY = "R";
public static final String SUBSCRIBER_PROVISIONED = "P";
@@ -188,6 +188,61 @@
put(RETURN_CODE, RETURN_CODE_VALUES);
}};
+ /**
+ * IMAP command extensions
+ */
+
+ /**
+ * OMTP spec v1.3 2.3.1 Change password request syntax
+ *
+ * This changes the PIN to access the Telephone User Interface, the traditional voicemail
+ * system.
+ */
+ public static final String IMAP_CHANGE_TUI_PWD_FORMAT = "XCHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
+
+ /**
+ * OMTP spec v1.3 2.4.1 Change languate request syntax
+ *
+ * This changes the language in the Telephone User Interface.
+ */
+ public static final String IMAP_CHANGE_VM_LANG_FORMAT = "XCHANGE_VM_LANG LANG=%1$s";
+
+ /**
+ * OMTP spec v1.3 2.5.1 Close NUT Request syntax
+ *
+ * This disables the new user tutorial, the message played to new users calling in the Telephone
+ * User Interface.
+ */
+ public static final String IMAP_CLOSE_NUT = "XCLOSE_NUT";
+
+ /**
+ * Possible NO responses for CHANGE_TUI_PWD
+ */
+
+ public static final String RESPONSE_CHANGE_PIN_TOO_SHORT = "password too short";
+ public static final String RESPONSE_CHANGE_PIN_TOO_LONG = "password too long";
+ public static final String RESPONSE_CHANGE_PIN_TOO_WEAK = "password too weak";
+ public static final String RESPONSE_CHANGE_PIN_MISMATCH = "old password mismatch";
+ public static final String RESPONSE_CHANGE_PIN_INVALID_CHARACTER =
+ "password contains invalid characters";
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {CHANGE_PIN_SUCCESS, CHANGE_PIN_TOO_SHORT, CHANGE_PIN_TOO_LONG,
+ CHANGE_PIN_TOO_WEAK, CHANGE_PIN_MISMATCH, CHANGE_PIN_INVALID_CHARACTER,
+ CHANGE_PIN_SYSTEM_ERROR})
+
+ public @interface ChangePinResult {
+
+ }
+
+ public static final int CHANGE_PIN_SUCCESS = 0;
+ public static final int CHANGE_PIN_TOO_SHORT = 1;
+ public static final int CHANGE_PIN_TOO_LONG = 2;
+ public static final int CHANGE_PIN_TOO_WEAK = 3;
+ public static final int CHANGE_PIN_MISMATCH = 4;
+ 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";
}
diff --git a/src/com/android/phone/vvm/omtp/OmtpEvents.java b/src/com/android/phone/vvm/omtp/OmtpEvents.java
new file mode 100644
index 0000000..6de692e
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/OmtpEvents.java
@@ -0,0 +1,116 @@
+/*
+ * 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.phone.vvm.omtp;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Events internal to the OMTP client. These should be translated into {@link
+ * android.provider.VoicemailContract.Status} error codes before writing into the voicemail status
+ * table.
+ */
+public enum OmtpEvents {
+
+ // Configuration State
+ CONFIG_REQUEST_STATUS_SUCCESS(Type.CONFIGURATION, true),
+
+ // Data channel State
+
+ // Successfully downloaded/uploaded data from the server, which means the data channel is clear.
+ DATA_IMAP_OPERATION_COMPLETED(Type.DATA_CHANNEL, true),
+
+ // The port provided in the STATUS SMS is invalid.
+ DATA_INVALID_PORT(Type.DATA_CHANNEL, false),
+ // No connection to the internet, and the carrier requires cellular data
+ DATA_NO_CONNECTION_CELLULAR_REQUIRED(Type.DATA_CHANNEL, false),
+ // No connection to the internet.
+ DATA_NO_CONNECTION(Type.DATA_CHANNEL, false),
+ // Address lookup for the server hostname failed. DNS error?
+ DATA_CANNOT_RESOLVE_HOST_ON_NETWORK(Type.DATA_CHANNEL, false),
+ // All destination address that resolves to the server hostname are rejected or timed out
+ DATA_ALL_SOCKET_CONNECTION_FAILED(Type.DATA_CHANNEL, false),
+ // Failed to establish SSL with the server, either with a direct SSL connection or by
+ // STARTTLS command
+ DATA_CANNOT_ESTABLISH_SSL_SESSION(Type.DATA_CHANNEL, false),
+ // Identity of the server cannot be verified.
+ DATA_SSL_INVALID_HOST_NAME(Type.DATA_CHANNEL, false),
+ // The server rejected our username/password
+ DATA_BAD_IMAP_CREDENTIAL(Type.DATA_CHANNEL, false),
+ // A command to the server didn't result with an "OK" or continuation request
+ DATA_REJECTED_SERVER_RESPONSE(Type.DATA_CHANNEL, false),
+ // The server did not greet us with a "OK", possibly not a IMAP server.
+ DATA_INVALID_INITIAL_SERVER_RESPONSE(Type.DATA_CHANNEL, false),
+ // An IOException occurred while trying to open an ImapConnection
+ // TODO: reduce scope
+ DATA_IOE_ON_OPEN(Type.DATA_CHANNEL, false),
+ // The SELECT command on a mailbox is rejected
+ DATA_MAILBOX_OPEN_FAILED(Type.DATA_CHANNEL, false),
+ // An IOException has occurred
+ // TODO: reduce scope
+ DATA_GENERIC_IMAP_IOE(Type.DATA_CHANNEL, false),
+ // An SslException has occurred while opening an ImapConnection
+ // TODO: reduce scope
+ DATA_SSL_EXCEPTION(Type.DATA_CHANNEL, false),
+
+ // Notification Channel
+
+ // Cell signal restored, can received VVM SMSs
+ NOTIFICATION_IN_SERVICE(Type.NOTIFICATION_CHANNEL, true),
+ // Cell signal lost, cannot received VVM SMSs
+ NOTIFICATION_SERVICE_LOST(Type.NOTIFICATION_CHANNEL, false),
+
+
+ // Other
+ OTHER_SOURCE_REMOVED(Type.OTHER, false);
+
+
+ public static class Type {
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({CONFIGURATION, DATA_CHANNEL, NOTIFICATION_CHANNEL, OTHER})
+ public @interface Values {
+
+ }
+
+ public static final int CONFIGURATION = 1;
+ public static final int DATA_CHANNEL = 2;
+ public static final int NOTIFICATION_CHANNEL = 3;
+ public static final int OTHER = 4;
+ }
+
+ private final int mType;
+ private final boolean mIsSuccess;
+
+ OmtpEvents(int type, boolean isSuccess) {
+ mType = type;
+ mIsSuccess = isSuccess;
+ }
+
+
+ @Type.Values
+ public int getType() {
+ return mType;
+ }
+
+ public boolean isSuccess() {
+ return mIsSuccess;
+ }
+
+}
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index 9534a10..798f5da 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -15,60 +15,158 @@
*/
package com.android.phone.vvm.omtp;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
import android.os.PersistableBundle;
+import android.telecom.PhoneAccountHandle;
import android.telephony.CarrierConfigManager;
-import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.VisualVoicemailSmsFilterSettings;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
-import com.android.phone.vvm.omtp.sms.OmtpCvvmMessageSender;
-import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
-import com.android.phone.vvm.omtp.sms.OmtpStandardMessageSender;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.VoicemailStatus;
+import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
+import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocolFactory;
+import com.android.phone.vvm.omtp.sms.StatusMessage;
+
+import java.util.Arrays;
+import java.util.Set;
/**
- * Handle activation and deactivation of a visual voicemail source. This class is necessary to
- * retrieve carrier vvm configuration details before sending the appropriate texts.
+ * Manages carrier dependent visual voicemail configuration values. The primary source is the value
+ * retrieved from CarrierConfigManager. If CarrierConfigManager does not provide the config
+ * (KEY_VVM_TYPE_STRING is empty, or "hidden" configs), then the value hardcoded in telephony will
+ * be used (in res/xml/vvm_config.xml)
+ *
+ * Hidden configs are new configs that are planned for future APIs, or miscellaneous settings that
+ * may clutter CarrierConfigManager too much.
+ *
+ * The current hidden configs are: {@link #getSslPort()} {@link #getDisabledCapabilities()}
*/
public class OmtpVvmCarrierConfigHelper {
private static final String TAG = "OmtpVvmCarrierCfgHlpr";
- private Context mContext;
- private int mSubId;
- private PersistableBundle mCarrierConfig;
- private String mVvmType;
+
+ static final String KEY_VVM_TYPE_STRING = CarrierConfigManager.KEY_VVM_TYPE_STRING;
+ 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 =
+ CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING;
+ 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 =
+ CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL;
+
+ /**
+ * @see #getSslPort()
+ */
+ static final String KEY_VVM_SSL_PORT_NUMBER_INT =
+ "vvm_ssl_port_number_int";
+
+ /**
+ * Ban a capability reported by the server from being used. The array of string should be a
+ * subset of the capabilities returned IMAP CAPABILITY command.
+ *
+ * @see #getDisabledCapabilities()
+ */
+ 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";
+
+ private final Context mContext;
+ private final int mSubId;
+ private final PersistableBundle mCarrierConfig;
+ private final String mVvmType;
+ private final VisualVoicemailProtocol mProtocol;
+ private final PersistableBundle mTelephonyConfig;
public OmtpVvmCarrierConfigHelper(Context context, int subId) {
mContext = context;
mSubId = subId;
mCarrierConfig = getCarrierConfig();
+
+ TelephonyManager telephonyManager =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ mTelephonyConfig = new TelephonyVvmConfigManager(context.getResources())
+ .getConfig(telephonyManager.getNetworkOperator(subId));
+
mVvmType = getVvmType();
+ mProtocol = VisualVoicemailProtocolFactory.create(mVvmType);
}
+ @VisibleForTesting
+ OmtpVvmCarrierConfigHelper(PersistableBundle carrierConfig,
+ PersistableBundle telephonyConfig) {
+ mContext = null;
+ mSubId = 0;
+ mCarrierConfig = carrierConfig;
+ mTelephonyConfig = telephonyConfig;
+ mVvmType = getVvmType();
+ mProtocol = VisualVoicemailProtocolFactory.create(mVvmType);
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public int getSubId() {
+ return mSubId;
+ }
+
+ /**
+ * return whether the carrier's visual voicemail is supported, with KEY_VVM_TYPE_STRING set as a
+ * known protocol.
+ */
+ public boolean isValid() {
+ return mProtocol != null;
+ }
+
+ @Nullable
public String getVvmType() {
- if (mCarrierConfig == null) {
- return null;
- }
-
- return mCarrierConfig.getString(
- CarrierConfigManager.KEY_VVM_TYPE_STRING, null);
+ return (String) getValue(KEY_VVM_TYPE_STRING);
}
- public String getCarrierVvmPackageName() {
- if (mCarrierConfig == null) {
- return null;
- }
-
- return mCarrierConfig.getString(
- CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING, null);
+ @Nullable
+ public VisualVoicemailProtocol getProtocol() {
+ return mProtocol;
}
- public boolean isOmtpVvmType() {
- return (TelephonyManager.VVM_TYPE_OMTP.equals(mVvmType) ||
- TelephonyManager.VVM_TYPE_CVVM.equals(mVvmType));
+ @Nullable
+ public Set<String> getCarrierVvmPackageNames() {
+ Set<String> names = getCarrierVvmPackageNames(mCarrierConfig);
+ if (names != null) {
+ return names;
+ }
+ return getCarrierVvmPackageNames(mTelephonyConfig);
+ }
+
+ private static Set<String> getCarrierVvmPackageNames(@Nullable PersistableBundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+ Set<String> names = new ArraySet<>();
+ if (bundle.containsKey(KEY_CARRIER_VVM_PACKAGE_NAME_STRING)) {
+ names.add(bundle.getString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING));
+ }
+ if (bundle.containsKey(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY)) {
+ names.addAll(Arrays.asList(
+ bundle.getStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY)));
+ }
+ if (names.isEmpty()) {
+ return null;
+ }
+ return names;
}
/**
@@ -76,51 +174,133 @@
* so by checking if the carrier's voicemail app is installed.
*/
public boolean isEnabledByDefault() {
- String packageName = mCarrierConfig.getString(
- CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING);
- if (packageName == null) {
+ Set<String> carrierPackages = getCarrierVvmPackageNames();
+ if (carrierPackages == null) {
return true;
}
- try {
- mContext.getPackageManager().getPackageInfo(packageName, 0);
- return false;
- } catch (NameNotFoundException e) {
- return true;
+ for (String packageName : carrierPackages) {
+ try {
+ mContext.getPackageManager().getPackageInfo(packageName, 0);
+ return false;
+ } catch (NameNotFoundException e) {
+ // Do nothing.
+ }
}
+ return true;
}
public boolean isCellularDataRequired() {
- if (mCarrierConfig == null) {
- return false;
- }
- return mCarrierConfig
- .getBoolean(CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL);
+ return (boolean) getValue(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL, false);
}
public boolean isPrefetchEnabled() {
- if (mCarrierConfig == null) {
- return false;
+ return (boolean) getValue(KEY_VVM_PREFETCH_BOOL, true);
+ }
+
+
+ public int getApplicationPort() {
+ return (int) getValue(KEY_VVM_PORT_NUMBER_INT, 0);
+ }
+
+ @Nullable
+ public String getDestinationNumber() {
+ return (String) getValue(KEY_VVM_DESTINATION_NUMBER_STRING);
+ }
+
+ /**
+ * Hidden config.
+ *
+ * @return Port to start a SSL IMAP connection directly.
+ *
+ * TODO: make config public and add to CarrierConfigManager
+ */
+ public int getSslPort() {
+ return (int) getValue(KEY_VVM_SSL_PORT_NUMBER_INT, 0);
+ }
+
+ /**
+ * Hidden Config.
+ *
+ * <p>Sometimes the server states it supports a certain feature but we found they have bug on
+ * the server side. For example, in b/28717550 the server reported AUTH=DIGEST-MD5 capability
+ * but using it to login will cause subsequent response to be erroneous.
+ *
+ * @return A set of capabilities that is reported by the IMAP CAPABILITY command, but determined
+ * to have issues and should not be used.
+ */
+ @Nullable
+ public Set<String> getDisabledCapabilities() {
+ Set<String> disabledCapabilities = getDisabledCapabilities(mCarrierConfig);
+ if (disabledCapabilities != null) {
+ return disabledCapabilities;
}
- return mCarrierConfig
- .getBoolean(CarrierConfigManager.KEY_VVM_PREFETCH_BOOL);
+ return getDisabledCapabilities(mTelephonyConfig);
+ }
+
+ @Nullable
+ private static Set<String> getDisabledCapabilities(@Nullable PersistableBundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+ if (!bundle.containsKey(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY)) {
+ return null;
+ }
+ ArraySet<String> result = new ArraySet<String>();
+ result.addAll(
+ Arrays.asList(bundle.getStringArray(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY)));
+ return result;
+ }
+
+ public String getClientPrefix() {
+ String prefix = (String) getValue(KEY_VVM_CLIENT_PREFIX_STRING);
+ if (prefix != null) {
+ return prefix;
+ }
+ return "//VVM";
}
public void startActivation() {
- OmtpMessageSender messageSender = getMessageSender();
- if (messageSender != null) {
- Log.i(TAG, "Requesting VVM activation for subId: " + mSubId);
- messageSender.requestVvmActivation(null);
+ VoicemailStatus.edit(mContext, mSubId)
+ .setType(getVvmType())
+ .apply();
+
+ TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+ telephonyManager.enableVisualVoicemailSmsFilter(mSubId,
+ new VisualVoicemailSmsFilterSettings.Builder().setClientPrefix(getClientPrefix())
+ .build());
+
+ if (mProtocol != null) {
+ mProtocol.startActivation(this);
}
}
public void startDeactivation() {
- OmtpMessageSender messageSender = getMessageSender();
- if (messageSender != null) {
- Log.i(TAG, "Requesting VVM deactivation for subId: " + mSubId);
- messageSender.requestVvmDeactivation(null);
+ mContext.getSystemService(TelephonyManager.class)
+ .disableVisualVoicemailSmsFilter(mSubId);
+ if (mProtocol != null) {
+ mProtocol.startDeactivation(this);
}
}
+ public void startProvisioning(PhoneAccountHandle phone, StatusMessage message, Bundle data) {
+ if (mProtocol != null) {
+ mProtocol.startProvisioning(phone, this, message, data);
+ }
+ }
+
+ public void requestStatus() {
+ if (mProtocol != null) {
+ mProtocol.requestStatus(this);
+ }
+ }
+
+ public void handleEvent(OmtpEvents event) {
+ if (mProtocol != null) {
+ mProtocol.handleEvent(mContext, mSubId, event);
+ }
+ }
+
+ @Nullable
private PersistableBundle getCarrierConfig() {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
Log.w(TAG, "Invalid subscriptionId or subscriptionId not provided in intent.");
@@ -134,39 +314,35 @@
return null;
}
- return carrierConfigManager.getConfigForSubId(mSubId);
+ PersistableBundle config = carrierConfigManager.getConfigForSubId(mSubId);
+
+ if (TextUtils.isEmpty(config.getString(CarrierConfigManager.KEY_VVM_TYPE_STRING))) {
+ Log.w(TAG, "Carrier config missing VVM type, ignoring.");
+ return null;
+ }
+ return config;
}
- private OmtpMessageSender getMessageSender() {
- if (mCarrierConfig == null) {
- Log.w(TAG, "Empty carrier config.");
- return null;
- }
+ @Nullable
+ private Object getValue(String key) {
+ return getValue(key, null);
+ }
- int applicationPort = mCarrierConfig.getInt(
- CarrierConfigManager.KEY_VVM_PORT_NUMBER_INT, 0);
- String destinationNumber = mCarrierConfig.getString(
- CarrierConfigManager.KEY_VVM_DESTINATION_NUMBER_STRING);
- if (TextUtils.isEmpty(destinationNumber)) {
- Log.w(TAG, "No destination number for this carrier.");
- return null;
+ @Nullable
+ private Object getValue(String key, Object defaultValue) {
+ Object result;
+ if (mCarrierConfig != null) {
+ result = mCarrierConfig.get(key);
+ if (result != null) {
+ return result;
+ }
}
-
- OmtpMessageSender messageSender = null;
- SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(mSubId);
- switch (mVvmType) {
- case TelephonyManager.VVM_TYPE_OMTP:
- messageSender = new OmtpStandardMessageSender(smsManager, (short) applicationPort,
- destinationNumber, null, OmtpConstants.PROTOCOL_VERSION1_1, null);
- break;
- case TelephonyManager.VVM_TYPE_CVVM:
- messageSender = new OmtpCvvmMessageSender(smsManager, (short) applicationPort,
- destinationNumber);
- break;
- default:
- Log.w(TAG, "Unexpected visual voicemail type: " + mVvmType);
+ if (mTelephonyConfig != null) {
+ result = mTelephonyConfig.get(key);
+ if (result != null) {
+ return result;
+ }
}
-
- return messageSender;
+ return defaultValue;
}
}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index 0a37493..01d6bf9 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -28,10 +28,10 @@
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
-import com.android.phone.PhoneUtils;
import com.android.phone.R;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
/**
* This class listens to the {@link CarrierConfigManager#ACTION_CARRIER_CONFIG_CHANGED} and {@link
@@ -87,9 +87,8 @@
public static void processSubId(Context context, int subId) {
OmtpVvmCarrierConfigHelper carrierConfigHelper =
new OmtpVvmCarrierConfigHelper(context, subId);
- if (carrierConfigHelper.isOmtpVvmType()) {
- PhoneAccountHandle phoneAccount = PhoneUtils.makePstnPhoneAccountHandle(
- SubscriptionManager.getPhoneId(subId));
+ if (carrierConfigHelper.isValid()) {
+ PhoneAccountHandle phoneAccount = PhoneAccountHandleConverter.fromSubId(subId);
boolean isUserSet = VisualVoicemailSettingsUtil.isVisualVoicemailUserSet(
context, phoneAccount);
diff --git a/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManager.java b/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManager.java
new file mode 100644
index 0000000..e91481e
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManager.java
@@ -0,0 +1,158 @@
+/*
+ * 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.phone.vvm.omtp;
+
+import android.annotation.Nullable;
+import android.content.res.Resources;
+import android.os.PersistableBundle;
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.R;
+import com.android.phone.vvm.omtp.utils.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Load and caches telephony vvm config from res/xml/vvm_config.xml
+ */
+public class TelephonyVvmConfigManager {
+
+ private static final String TAG = "TelephonyVvmCfgMgr";
+
+ private static final boolean USE_DEBUG_CONFIG = false; //STOPSHIP if true
+
+ private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
+
+ static final String KEY_MCCMNC = "mccmnc";
+
+ private static Map<String, PersistableBundle> sCachedConfigs;
+
+ private final Map<String, PersistableBundle> mConfigs;
+
+ public TelephonyVvmConfigManager(Resources resources) {
+ if (sCachedConfigs == null) {
+ sCachedConfigs = loadConfigs(resources.getXml(R.xml.vvm_config));
+ }
+ mConfigs = sCachedConfigs;
+ }
+
+ @VisibleForTesting
+ TelephonyVvmConfigManager(XmlPullParser parser) {
+ mConfigs = loadConfigs(parser);
+ }
+
+ @Nullable
+ public PersistableBundle getConfig(String mccMnc) {
+ if (USE_DEBUG_CONFIG) {
+ return mConfigs.get("TEST");
+ }
+ return mConfigs.get(mccMnc);
+ }
+
+ private static Map<String, PersistableBundle> loadConfigs(XmlPullParser parser) {
+ Map<String, PersistableBundle> configs = new ArrayMap<>();
+ try {
+ ArrayList list = readBundleList(parser);
+ for (Object object : list) {
+ if (!(object instanceof PersistableBundle)) {
+ throw new IllegalArgumentException("PersistableBundle expected, got " + object);
+ }
+ PersistableBundle bundle = (PersistableBundle) object;
+ String[] mccMncs = bundle.getStringArray(KEY_MCCMNC);
+ if (mccMncs == null) {
+ throw new IllegalArgumentException("MCCMNC is null");
+ }
+ for (String mccMnc : mccMncs) {
+ configs.put(mccMnc, bundle);
+ }
+ }
+ } catch (IOException | XmlPullParserException e) {
+ throw new RuntimeException(e);
+ }
+ return configs;
+ }
+
+ @Nullable
+ public static ArrayList readBundleList(XmlPullParser in) throws IOException,
+ XmlPullParserException {
+ final int outerDepth = in.getDepth();
+ int event;
+ while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
+ (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
+ if (event == XmlPullParser.START_TAG) {
+ final String startTag = in.getName();
+ final String[] tagName = new String[1];
+ in.next();
+ return XmlUtils.readThisListXml(in, startTag, tagName,
+ new MyReadMapCallback(), false);
+ }
+ }
+ return null;
+ }
+
+ public static PersistableBundle restoreFromXml(XmlPullParser in) throws IOException,
+ XmlPullParserException {
+ final int outerDepth = in.getDepth();
+ final String startTag = in.getName();
+ final String[] tagName = new String[1];
+ int event;
+ while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
+ (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
+ if (event == XmlPullParser.START_TAG) {
+ ArrayMap<String, ?> map =
+ XmlUtils.readThisArrayMapXml(in, startTag, tagName,
+ new MyReadMapCallback());
+ PersistableBundle result = new PersistableBundle();
+ for (Entry<String, ?> entry : map.entrySet()) {
+ Object value = entry.getValue();
+ if (value instanceof Integer) {
+ result.putInt(entry.getKey(), (int) value);
+ } else if (value instanceof Boolean) {
+ result.putBoolean(entry.getKey(), (boolean) value);
+ } else if (value instanceof String) {
+ result.putString(entry.getKey(), (String) value);
+ } else if (value instanceof String[]) {
+ result.putStringArray(entry.getKey(), (String[]) value);
+ } else if (value instanceof PersistableBundle) {
+ result.putPersistableBundle(entry.getKey(), (PersistableBundle) value);
+ }
+ }
+ return result;
+ }
+ }
+ return PersistableBundle.EMPTY;
+ }
+
+ static class MyReadMapCallback implements XmlUtils.ReadMapCallback {
+
+ @Override
+ public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
+ throws XmlPullParserException, IOException {
+ if (TAG_PERSISTABLEMAP.equals(tag)) {
+ return restoreFromXml(in);
+ }
+ throw new XmlPullParserException("Unknown tag=" + tag);
+ }
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java b/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
index 0c4eb62..8d438ef 100644
--- a/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
+++ b/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
@@ -52,10 +52,14 @@
OmtpVvmCarrierConfigHelper carrierConfigHelper = new OmtpVvmCarrierConfigHelper(
context, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount));
- if (packageName.equals(carrierConfigHelper.getCarrierVvmPackageName())) {
+ if (carrierConfigHelper.getCarrierVvmPackageNames() == null) {
+ continue;
+ }
+ if (carrierConfigHelper.getCarrierVvmPackageNames().contains(packageName)) {
VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(
context, phoneAccount, false, false);
OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
+ carrierConfigHelper.startDeactivation();
}
}
}
diff --git a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
index 1b2e34e..3438de2 100644
--- a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
+++ b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
@@ -17,7 +17,6 @@
import android.content.Context;
import android.content.Intent;
-import android.provider.VoicemailContract;
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -28,11 +27,13 @@
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
import com.android.phone.vvm.omtp.sync.VoicemailStatusQueryHelper;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
/**
* Check if service is lost and indicate this in the voicemail status.
*/
public class VvmPhoneStateListener extends PhoneStateListener {
+
private static final String TAG = "VvmPhoneStateListener";
private PhoneAccountHandle mPhoneAccount;
@@ -56,18 +57,17 @@
return;
}
+ int subId = PhoneAccountHandleConverter.toSubId(mPhoneAccount);
+ OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(mContext, subId);
+
if (state == ServiceState.STATE_IN_SERVICE) {
VoicemailStatusQueryHelper voicemailStatusQueryHelper =
new VoicemailStatusQueryHelper(mContext);
if (voicemailStatusQueryHelper.isVoicemailSourceConfigured(mPhoneAccount)) {
if (!voicemailStatusQueryHelper.isNotificationsChannelActive(mPhoneAccount)) {
Log.v(TAG, "Notifications channel is active for " + mPhoneAccount.getId());
- VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
- VoicemailContract.Status.CONFIGURATION_STATE_OK,
- VoicemailContract.Status.DATA_CHANNEL_STATE_OK,
- VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK);
- PhoneGlobals.getInstance().clearMwiIndicator(
- PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount));
+ helper.handleEvent(OmtpEvents.NOTIFICATION_IN_SERVICE);
+ PhoneGlobals.getInstance().clearMwiIndicator(subId);
}
}
@@ -88,9 +88,7 @@
// Otherwise initiate an activation because this means that an OMTP source was
// recognized but either the activation text was not successfully sent or a response
// was not received.
- OmtpVvmCarrierConfigHelper carrierConfigHelper = new OmtpVvmCarrierConfigHelper(
- mContext, PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount));
- carrierConfigHelper.startActivation();
+ helper.startActivation();
}
} else {
Log.v(TAG, "Notifications channel is inactive for " + mPhoneAccount.getId());
@@ -101,11 +99,7 @@
if (!OmtpVvmSourceManager.getInstance(mContext).isVvmSourceRegistered(mPhoneAccount)) {
return;
}
-
- VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
- VoicemailContract.Status.CONFIGURATION_STATE_OK,
- VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION,
- VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
+ helper.handleEvent(OmtpEvents.NOTIFICATION_SERVICE_LOST);
}
mPreviousState = state;
}
diff --git a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
index da60ad1..0095f53 100644
--- a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
+++ b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
@@ -16,6 +16,7 @@
package com.android.phone.vvm.omtp.fetch;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -47,10 +48,12 @@
final static String[] PROJECTION = new String[] {
Voicemails.SOURCE_DATA, // 0
Voicemails.PHONE_ACCOUNT_ID, // 1
+ Voicemails.PHONE_ACCOUNT_COMPONENT_NAME, // 2
};
public static final int SOURCE_DATA = 0;
public static final int PHONE_ACCOUNT_ID = 1;
+ public static final int PHONE_ACCOUNT_COMPONENT_NAME = 2;
// Timeout used to call ConnectivityManager.requestNetwork
private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
@@ -105,7 +108,10 @@
}
}
- mPhoneAccount = PhoneUtils.makePstnPhoneAccountHandle(accountId);
+ mPhoneAccount = new PhoneAccountHandle(
+ ComponentName.unflattenFromString(
+ cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME)),
+ cursor.getString(PHONE_ACCOUNT_ID));
if (!OmtpVvmSourceManager.getInstance(context)
.isVvmSourceRegistered(mPhoneAccount)) {
Log.w(TAG, "Account not registered - cannot retrieve message.");
diff --git a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
index 2c10377..ce9e9c3 100644
--- a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
+++ b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
@@ -22,15 +22,13 @@
import android.net.NetworkInfo;
import android.preference.PreferenceManager;
import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
import android.telecom.PhoneAccountHandle;
import android.telecom.Voicemail;
-import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Log;
import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.common.mail.Address;
import com.android.phone.common.mail.Body;
import com.android.phone.common.mail.BodyPart;
@@ -41,12 +39,16 @@
import com.android.phone.common.mail.Multipart;
import com.android.phone.common.mail.TempDirectory;
import com.android.phone.common.mail.internet.MimeMessage;
+import com.android.phone.common.mail.store.ImapConnection;
import com.android.phone.common.mail.store.ImapFolder;
import com.android.phone.common.mail.store.ImapStore;
import com.android.phone.common.mail.store.imap.ImapConstants;
+import com.android.phone.common.mail.store.imap.ImapResponse;
import com.android.phone.common.mail.utils.LogUtils;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.OmtpConstants.ChangePinResult;
+import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.fetch.VoicemailFetchedCallback;
import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService.TranscriptionFetchedCallback;
@@ -59,12 +61,14 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
/**
* A helper interface to abstract commands sent across IMAP interface for a given account.
*/
public class ImapHelper {
- private final String TAG = "ImapHelper";
+
+ private static final String TAG = "ImapHelper";
private ImapFolder mFolder;
private ImapStore mImapStore;
@@ -80,10 +84,14 @@
private int mQuotaOccupied;
private int mQuotaTotal;
+ private final OmtpVvmCarrierConfigHelper mConfig;
+
public ImapHelper(Context context, PhoneAccountHandle phoneAccount, Network network) {
mContext = context;
mPhoneAccount = phoneAccount;
mNetwork = network;
+ mConfig = new OmtpVvmCarrierConfigHelper(context,
+ PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount));
try {
TempDirectory.setTempDirectory(context);
@@ -98,19 +106,16 @@
OmtpConstants.IMAP_PORT, phoneAccount));
int auth = ImapStore.FLAG_NONE;
- OmtpVvmCarrierConfigHelper carrierConfigHelper = new OmtpVvmCarrierConfigHelper(context,
- PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount));
- if (TelephonyManager.VVM_TYPE_CVVM.equals(carrierConfigHelper.getVvmType())) {
- // TODO: move these into the carrier config app
- port = 993;
+ int sslPort = mConfig.getSslPort();
+ if (sslPort != 0) {
+ port = sslPort;
auth = ImapStore.FLAG_SSL;
}
mImapStore = new ImapStore(
context, this, username, password, port, serverName, auth, network);
} catch (NumberFormatException e) {
- VoicemailUtils.setDataChannelState(
- mContext, mPhoneAccount, Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION);
+ mConfig.handleEvent(OmtpEvents.DATA_INVALID_PORT);
LogUtils.w(TAG, "Could not parse port number");
}
@@ -119,8 +124,6 @@
VoicemailContract.Status.QUOTA_UNAVAILABLE);
mQuotaTotal = mPrefs.getInt(getSharedPrefsKey(PREF_KEY_QUOTA_TOTAL),
VoicemailContract.Status.QUOTA_UNAVAILABLE);
-
- Log.v(TAG, "Quota:" + mQuotaOccupied + "/" + mQuotaTotal);
}
/**
@@ -142,6 +145,14 @@
return info.isRoaming();
}
+ public OmtpVvmCarrierConfigHelper getConfig() {
+ return mConfig;
+ }
+
+ public ImapConnection connect() {
+ return mImapStore.getConnection();
+ }
+
/** The caller thread will block until the method returns. */
public boolean markMessagesAsRead(List<Voicemail> voicemails) {
return setFlags(voicemails, Flag.SEEN);
@@ -152,8 +163,8 @@
return setFlags(voicemails, Flag.DELETED);
}
- public void setDataChannelState(int dataChannelState) {
- VoicemailUtils.setDataChannelState(mContext, mPhoneAccount, dataChannelState);
+ public void handleEvent(OmtpEvents event) {
+ mConfig.handleEvent(event);
}
/**
@@ -369,6 +380,83 @@
}
}
+
+ @ChangePinResult
+ public int changePin(String oldPin, String newPin)
+ throws MessagingException {
+ ImapConnection connection = mImapStore.getConnection();
+ try {
+ String command = getConfig().getProtocol()
+ .getCommand(OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT);
+ connection.sendCommand(
+ String.format(Locale.US, command, newPin, oldPin), true);
+ return getChangePinResultFromImapResponse(connection.readResponse());
+ } catch (IOException ioe) {
+ return OmtpConstants.CHANGE_PIN_SYSTEM_ERROR;
+ } finally {
+ connection.destroyResponses();
+ }
+ }
+
+ public void changeVoicemailTuiLanguage(String languageCode)
+ throws MessagingException {
+ ImapConnection connection = mImapStore.getConnection();
+ try {
+ String command = getConfig().getProtocol()
+ .getCommand(OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT);
+ connection.sendCommand(
+ String.format(Locale.US, command, languageCode), true);
+ } catch (IOException ioe) {
+ LogUtils.e(TAG, ioe.toString());
+ } finally {
+ connection.destroyResponses();
+ }
+ }
+
+ public void closeNewUserTutorial() throws MessagingException {
+ ImapConnection connection = mImapStore.getConnection();
+ try {
+ String command = getConfig().getProtocol()
+ .getCommand(OmtpConstants.IMAP_CLOSE_NUT);
+ connection.executeSimpleCommand(command, false);
+ } catch (IOException ioe) {
+ throw new MessagingException(MessagingException.SERVER_ERROR, ioe.toString());
+ } finally {
+ connection.destroyResponses();
+ }
+ }
+
+ @ChangePinResult
+ private static int getChangePinResultFromImapResponse(ImapResponse response)
+ throws MessagingException {
+ if (!response.isTagged()) {
+ throw new MessagingException(MessagingException.SERVER_ERROR,
+ "tagged response expected");
+ }
+ if (!response.isOk()) {
+ String message = response.getStringOrEmpty(1).getString();
+ LogUtils.d(TAG, "change PIN failed: " + message);
+ if (OmtpConstants.RESPONSE_CHANGE_PIN_TOO_SHORT.equals(message)) {
+ return OmtpConstants.CHANGE_PIN_TOO_SHORT;
+ }
+ if (OmtpConstants.RESPONSE_CHANGE_PIN_TOO_LONG.equals(message)) {
+ return OmtpConstants.CHANGE_PIN_TOO_LONG;
+ }
+ if (OmtpConstants.RESPONSE_CHANGE_PIN_TOO_WEAK.equals(message)) {
+ return OmtpConstants.CHANGE_PIN_TOO_WEAK;
+ }
+ if (OmtpConstants.RESPONSE_CHANGE_PIN_MISMATCH.equals(message)) {
+ return OmtpConstants.CHANGE_PIN_MISMATCH;
+ }
+ if (OmtpConstants.RESPONSE_CHANGE_PIN_INVALID_CHARACTER.equals(message)) {
+ return OmtpConstants.CHANGE_PIN_INVALID_CHARACTER;
+ }
+ return OmtpConstants.CHANGE_PIN_SYSTEM_ERROR;
+ }
+ LogUtils.d(TAG, "change PIN succeeded");
+ return OmtpConstants.CHANGE_PIN_SUCCESS;
+ }
+
public void updateQuota() {
try {
mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
@@ -398,8 +486,9 @@
}
mQuotaOccupied = quota.occupied;
mQuotaTotal = quota.total;
- VoicemailContract.Status
- .setQuota(mContext, mPhoneAccount, mQuotaOccupied, mQuotaTotal);
+ VoicemailStatus.edit(mContext, mPhoneAccount)
+ .setQuota(mQuotaOccupied, mQuotaTotal)
+ .apply();
mPrefs.edit()
.putInt(getSharedPrefsKey(PREF_KEY_QUOTA_OCCUPIED), mQuotaOccupied)
.putInt(getSharedPrefsKey(PREF_KEY_QUOTA_TOTAL), mQuotaTotal)
diff --git a/src/com/android/phone/vvm/omtp/protocol/CvvmProtocol.java b/src/com/android/phone/vvm/omtp/protocol/CvvmProtocol.java
new file mode 100644
index 0000000..9960b18
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/CvvmProtocol.java
@@ -0,0 +1,55 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.telephony.SmsManager;
+
+import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.sms.OmtpCvvmMessageSender;
+import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
+
+/**
+ * A flavor of OMTP protocol with a different mobile originated (MO) format
+ *
+ * Used by carriers such as T-Mobile
+ */
+public class CvvmProtocol extends VisualVoicemailProtocol {
+
+ private static String IMAP_CHANGE_TUI_PWD_FORMAT = "CHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
+ private static String IMAP_CHANGE_VM_LANG_FORMAT = "CHANGE_VM_LANG Lang=%1$s";
+ private static String IMAP_CLOSE_NUT = "CLOSE_NUT";
+
+ @Override
+ public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
+ String destinationNumber) {
+ return new OmtpCvvmMessageSender(smsManager, applicationPort, destinationNumber);
+ }
+
+ @Override
+ public String getCommand(String command) {
+ if (command == OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT) {
+ return IMAP_CHANGE_TUI_PWD_FORMAT;
+ }
+ if (command == OmtpConstants.IMAP_CLOSE_NUT) {
+ return IMAP_CLOSE_NUT;
+ }
+ if (command == OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT) {
+ return IMAP_CHANGE_VM_LANG_FORMAT;
+ }
+ return super.getCommand(command);
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java b/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
new file mode 100644
index 0000000..d002652
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
@@ -0,0 +1,33 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.telephony.SmsManager;
+
+import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
+import com.android.phone.vvm.omtp.sms.OmtpStandardMessageSender;
+
+public class OmtpProtocol extends VisualVoicemailProtocol {
+
+ @Override
+ public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
+ String destinationNumber) {
+ return new OmtpStandardMessageSender(smsManager, applicationPort, destinationNumber,
+ null, OmtpConstants.PROTOCOL_VERSION1_1, null);
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/protocol/ProtocolHelper.java b/src/com/android/phone/vvm/omtp/protocol/ProtocolHelper.java
new file mode 100644
index 0000000..d265bd0
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/ProtocolHelper.java
@@ -0,0 +1,43 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.telephony.SmsManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
+
+public class ProtocolHelper {
+
+ private static final String TAG = "ProtocolHelper";
+
+ public static OmtpMessageSender getMessageSender(VisualVoicemailProtocol protocol,
+ OmtpVvmCarrierConfigHelper config) {
+
+ int applicationPort = config.getApplicationPort();
+ String destinationNumber = config.getDestinationNumber();
+ if (TextUtils.isEmpty(destinationNumber)) {
+ Log.w(TAG, "No destination number for this carrier.");
+ return null;
+ }
+
+ SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(config.getSubId());
+ return protocol.createMessageSender(smsManager, (short) applicationPort, destinationNumber);
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
new file mode 100644
index 0000000..9e56d12
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
@@ -0,0 +1,76 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.SmsManager;
+
+import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
+import com.android.phone.vvm.omtp.OmtpEvents;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
+import com.android.phone.vvm.omtp.sms.StatusMessage;
+
+public abstract class VisualVoicemailProtocol {
+
+ public void startActivation(OmtpVvmCarrierConfigHelper config) {
+ OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
+ if (messageSender != null) {
+ messageSender.requestVvmActivation(null);
+ }
+ }
+
+ public void startDeactivation(OmtpVvmCarrierConfigHelper config) {
+ OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
+ if (messageSender != null) {
+ messageSender.requestVvmDeactivation(null);
+ }
+ }
+
+ public void startProvisioning(PhoneAccountHandle handle, OmtpVvmCarrierConfigHelper config,
+ StatusMessage message, Bundle data) {
+ // Do nothing
+ }
+
+ public void requestStatus(OmtpVvmCarrierConfigHelper config) {
+ OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
+ if (messageSender != null) {
+ messageSender.requestVvmStatus(null);
+ }
+ }
+
+ public abstract OmtpMessageSender createMessageSender(SmsManager smsManager,
+ short applicationPort, String destinationNumber);
+
+ /**
+ * Translate an OMTP IMAP command to the protocol specific one. For example, changing the TUI
+ * password on OMTP is XCHANGE_TUI_PWD, but on CVVM and VVM3 it is CHANGE_TUI_PWD.
+ *
+ * @param command A String command in {@link com.android.phone.vvm.omtp.OmtpConstants}, the exact
+ * instance should be used instead of its' value.
+ * @returns Translated command, or {@code null} if not available in this protocol
+ */
+ public String getCommand(String command) {
+ return command;
+ }
+
+ public void handleEvent(Context context, int subId, OmtpEvents event) {
+ DefaultOmtpEventHandler.handleEvent(context, subId, event);
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocolFactory.java b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocolFactory.java
new file mode 100644
index 0000000..dbf38c2
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocolFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.annotation.Nullable;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+public class VisualVoicemailProtocolFactory {
+
+ private static final String TAG = "VvmProtocolFactory";
+
+ private static final String VVM_TYPE_VVM3 = "vvm_type_vvm3";
+
+ @Nullable
+ public static VisualVoicemailProtocol create(String type) {
+ if (type == null) {
+ return null;
+ }
+ switch (type) {
+ case TelephonyManager.VVM_TYPE_OMTP:
+ return new OmtpProtocol();
+ case TelephonyManager.VVM_TYPE_CVVM:
+ return new CvvmProtocol();
+ case VVM_TYPE_VVM3:
+ return new Vvm3Protocol();
+ default:
+ Log.e(TAG, "Unexpected visual voicemail type: " + type);
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
new file mode 100644
index 0000000..e62d1cf
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
@@ -0,0 +1,213 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.annotation.Nullable;
+import android.net.Network;
+import android.os.Bundle;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.SmsManager;
+import android.util.Log;
+
+import com.android.phone.common.mail.MessagingException;
+import com.android.phone.settings.VisualVoicemailSettingsUtil;
+import com.android.phone.settings.VoicemailChangePinDialogPreference;
+import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+import com.android.phone.vvm.omtp.imap.ImapHelper;
+import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
+import com.android.phone.vvm.omtp.sms.StatusMessage;
+import com.android.phone.vvm.omtp.sms.Vvm3MessageSender;
+import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
+
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Locale;
+
+/**
+ * A flavor of OMTP protocol with a different provisioning process
+ *
+ * Used by carriers such as Verizon Wireless
+ */
+public class Vvm3Protocol extends VisualVoicemailProtocol {
+
+ private static String TAG = "Vvm3Protocol";
+
+ private static String IMAP_CHANGE_TUI_PWD_FORMAT = "CHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
+ private static String IMAP_CHANGE_VM_LANG_FORMAT = "CHANGE_VM_LANG Lang=%1$s";
+ private static String IMAP_CLOSE_NUT = "CLOSE_NUT";
+
+ private static String ISO639_Spanish = "es";
+
+ private static String VVM3_VM_LANGUAGE_ENGLISH_STANDARD = "1";
+ private static String VVM3_VM_LANGUAGE_SPANISH_STANDARD = "2";
+
+ private static final int PIN_LENGTH = 6;
+
+ public Vvm3Protocol() {
+ Log.d(TAG, "Vvm3Protocol created");
+ }
+
+ @Override
+ public void startActivation(OmtpVvmCarrierConfigHelper config) {
+ // VVM3 does not support activation SMS.
+ // Send a status request which will start the provisioning process if the user is not
+ // provisioned.
+ config.requestStatus();
+ }
+
+ @Override
+ public void startDeactivation(OmtpVvmCarrierConfigHelper config) {
+ // VVM3 does not support deactivation.
+ // do nothing.
+ }
+
+ @Override
+ public void startProvisioning(PhoneAccountHandle phoneAccountHandle,
+ OmtpVvmCarrierConfigHelper config, StatusMessage message, Bundle data) {
+ Log.i(TAG, "start vvm3 provisioning");
+ if ("U".equals(message.getProvisioningStatus())) {
+ Log.i(TAG, "Provisioning status: Unknown, subscribing");
+ new Vvm3Subscriber(phoneAccountHandle, config, data).subscribe();
+ } else if ("N".equals(message.getProvisioningStatus())) {
+ Log.i(TAG, "setting up new user");
+ VisualVoicemailSettingsUtil.setVisualVoicemailCredentialsFromStatusMessage(
+ config.getContext(), phoneAccountHandle, message);
+ startProvisionNewUser(phoneAccountHandle, config, message);
+ }
+ }
+
+ @Override
+ public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
+ String destinationNumber) {
+ return new Vvm3MessageSender(smsManager, applicationPort, destinationNumber);
+ }
+
+ @Override
+ public String getCommand(String command) {
+ if (command == OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT) {
+ return IMAP_CHANGE_TUI_PWD_FORMAT;
+ }
+ if (command == OmtpConstants.IMAP_CLOSE_NUT) {
+ return IMAP_CLOSE_NUT;
+ }
+ if (command == OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT) {
+ return IMAP_CHANGE_VM_LANG_FORMAT;
+ }
+ return super.getCommand(command);
+ }
+
+ private void startProvisionNewUser(PhoneAccountHandle phoneAccountHandle,
+ OmtpVvmCarrierConfigHelper config, StatusMessage message) {
+ new Vvm3ProvisioningNetworkRequestCallback(config, phoneAccountHandle, message)
+ .requestNetwork();
+ }
+
+ private static class Vvm3ProvisioningNetworkRequestCallback extends VvmNetworkRequestCallback {
+
+ private final OmtpVvmCarrierConfigHelper mConfig;
+ private final StatusMessage mMessage;
+
+ public Vvm3ProvisioningNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
+ PhoneAccountHandle phoneAccountHandle, StatusMessage message) {
+ super(config, phoneAccountHandle);
+ mConfig = config;
+ mMessage = message;
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+ Log.i(TAG, "new user: network available");
+ ImapHelper helper = new ImapHelper(mContext, mPhoneAccount, network);
+
+ try {
+
+ // VVM3 has inconsistent error language code to OMTP. Just issue a raw command
+ // here.
+ // TODO(b/29082671): use LocaleList
+ if (Locale.getDefault().getLanguage()
+ .equals(new Locale(ISO639_Spanish).getLanguage())) {
+ // Spanish
+ helper.changeVoicemailTuiLanguage(VVM3_VM_LANGUAGE_SPANISH_STANDARD);
+ } else {
+ // English
+ helper.changeVoicemailTuiLanguage(VVM3_VM_LANGUAGE_ENGLISH_STANDARD);
+ }
+ Log.i(TAG, "new user: language set");
+
+ if (setPin(helper)) {
+ // Only close new user tutorial if the PIN has been changed.
+ helper.closeNewUserTutorial();
+ Log.i(TAG, "new user: NUT closed");
+
+ mConfig.requestStatus();
+ }
+ } catch (MessagingException | IOException e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+
+ private boolean setPin(ImapHelper helper) throws IOException, MessagingException {
+ String defaultPin = getDefaultPin();
+ if (defaultPin == null) {
+ return false;
+ }
+
+ if (VoicemailChangePinDialogPreference.getDefaultOldPin(mContext, mPhoneAccount)
+ != null) {
+ // The pin was already set
+ return true;
+ }
+ String newPin = generatePin();
+ if (helper.changePin(defaultPin, newPin) == OmtpConstants.CHANGE_PIN_SUCCESS) {
+ VoicemailChangePinDialogPreference
+ .setDefaultOldPIN(mContext, mPhoneAccount, newPin);
+
+ // TODO(b/29082418): set CONFIGURATION_STATE to VVM3_CONFIGURATION_PIN_NOT_SET
+ // to prompt the user to set the PIN
+ }
+ Log.i(TAG, "new user: PIN set");
+ return true;
+ }
+
+ @Nullable
+ private String getDefaultPin() {
+ // The IMAP username is [phone number]@example.com
+ String username = mMessage.getImapUserName();
+ try {
+ String number = username.substring(0, username.indexOf('@'));
+ if (number.length() < 4) {
+ Log.e(TAG, "unable to extract number from IMAP username");
+ return null;
+ }
+ return "1" + number.substring(number.length() - 4);
+ } catch (StringIndexOutOfBoundsException e) {
+ Log.e(TAG, "unable to extract number from IMAP username");
+ return null;
+ }
+
+ }
+ }
+
+ private static String generatePin() {
+ SecureRandom random = new SecureRandom();
+ // TODO(b/29102412): generate base on the length requirement from the server
+ return String.format("%010d", Math.abs(random.nextLong())).substring(0, PIN_LENGTH);
+
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
new file mode 100644
index 0000000..c314ff5
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
@@ -0,0 +1,309 @@
+/*
+ * 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.phone.vvm.omtp.protocol;
+
+import android.annotation.WorkerThread;
+import android.net.Network;
+import android.os.Build;
+import android.os.Bundle;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.TelephonyManager;
+import android.text.Html;
+import android.text.Spanned;
+import android.text.style.URLSpan;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.phone.Assert;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
+import com.android.volley.AuthFailureError;
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.toolbox.HurlStack;
+import com.android.volley.toolbox.RequestFuture;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
+
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Class to subscribe to basic VVM3 visual voicemail, for example, Verizon. Subscription is required
+ * when the user is unprovisioned. This could happen when the user is on a legacy service, or
+ * switched over from devices that used other type of visual voicemail.
+ *
+ * The STATUS SMS will come with a URL to the voicemail management gateway. From it we can find the
+ * self provisioning gateway URL that we can modify voicemail services.
+ *
+ * A request to the self provisioning gateway to activate basic visual voicemail will return us with
+ * a web page. If the user hasn't subscribe to it yet it will contain a link to confirm the
+ * subscription. This link should be clicked through cellular network, and have cookies enabled.
+ *
+ * After the process is completed, the carrier should send us another STATUS SMS with a new or ready
+ * user.
+ */
+public class Vvm3Subscriber {
+
+ private static final String TAG = "Vvm3Subscriber";
+
+ private static final String OPERATION_GET_SPG_URL = "retrieveSPGURL";
+ private static final String SPG_URL_TAG = "spgurl";
+ private static final String TRANSACTION_ID_TAG = "transactionid";
+ //language=XML
+ private static final String VMG_XML_REQUEST_FORMAT = ""
+ + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<VMGVVMRequest>"
+ + " <MessageHeader>"
+ + " <transactionid>%1$s</transactionid>"
+ + " </MessageHeader>"
+ + " <MessageBody>"
+ + " <mdn>%2$s</mdn>"
+ + " <operation>%3$s</operation>"
+ + " <source>Device</source>"
+ + " <devicemodel>%4$s</devicemodel>"
+ + " </MessageBody>"
+ + "</VMGVVMRequest>";
+
+ private static final String VMG_URL_KEY = "vmg_url";
+
+ // Self provisioning POST key/values. VVM3 API 2.1.0 12.3
+ private static final String SPG_VZW_MDN_PARAM = "VZW_MDN";
+ private static final String SPG_VZW_SERVICE_PARAM = "VZW_SERVICE";
+ private static final String SPG_VZW_SERVICE_BASIC = "BVVM";
+ private static final String SPG_DEVICE_MODEL_PARAM = "DEVICE_MODEL";
+ // Value for all android device
+ private static final String SPG_DEVICE_MODEL_ANDROID = "DROID_4G";
+ private static final String SPG_APP_TOKEN_PARAM = "APP_TOKEN";
+ private static final String SPG_APP_TOKEN = "q8e3t5u2o1";
+ private static final String SPG_LANGUAGE_PARAM = "SPG_LANGUAGE_PARAM";
+ private static final String SPG_LANGUAGE_EN = "ENGLISH";
+
+ private static final String BASIC_SUBSCRIBE_LINK_TEXT = "Subscribe to Basic Visual Voice Mail";
+
+ private static final int REQUEST_TIMEOUT_SECONDS = 30;
+
+ private final PhoneAccountHandle mHandle;
+ private final OmtpVvmCarrierConfigHelper mHelper;
+ private final Bundle mData;
+
+ private final String mNumber;
+
+ private RequestQueue mRequestQueue;
+
+ private static class ProvisioningException extends Exception {
+
+ public ProvisioningException(String message) {
+ super(message);
+ }
+ }
+
+ static {
+ // Set the default cookie handler to retain session data for the self provisioning gateway.
+ // Note; this is not ideal as it is application-wide, and can easily get clobbered.
+ // But it seems to be the preferred way to manage cookie for HttpURLConnection, and manually
+ // managing cookies will greatly increase complexity.
+ CookieManager cookieManager = new CookieManager();
+ CookieHandler.setDefault(cookieManager);
+ }
+
+ @WorkerThread
+ public Vvm3Subscriber(PhoneAccountHandle handle, OmtpVvmCarrierConfigHelper helper,
+ Bundle data) {
+ Assert.isNotMainThread();
+ mHandle = handle;
+ mHelper = helper;
+ mData = data;
+
+ // Assuming getLine1Number() will work with VVM3. For unprovisioned users the IMAP username
+ // is not included in the status SMS, thus no other way to get the current phone number.
+ mNumber = mHelper.getContext().getSystemService(TelephonyManager.class)
+ .getLine1Number(mHelper.getSubId());
+ }
+
+ @WorkerThread
+ public void subscribe() {
+ Assert.isNotMainThread();
+ // Cellular data is required to subscribe.
+ // processSubscription() is called after network is available.
+ new Vvm3ProvisioningNetworkRequestCallback(mHelper, mHandle).requestNetwork();
+ }
+
+ private void processSubscription() {
+ try {
+ String gatewayUrl = getSelfProvisioningGateway();
+ String selfProvisionResponse = getSelfProvisionResponse(gatewayUrl);
+ String subscribeLink = findSubscribeLink(selfProvisionResponse);
+ clickSubscribeLink(subscribeLink);
+ } catch (ProvisioningException e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+
+ /**
+ * Get the URL to perform self-provisioning from the voicemail management gateway.
+ */
+ private String getSelfProvisioningGateway() throws ProvisioningException {
+ String response = vvm3XmlRequest(OPERATION_GET_SPG_URL);
+ return extractText(response, SPG_URL_TAG);
+ }
+
+ /**
+ * Sent a request to the self-provisioning gateway, which will return us with a webpage. The
+ * page might contain a "Subscribe to Basic Visual Voice Mail" link to complete the
+ * subscription. The cookie from this response and cellular data is required to click the link.
+ */
+ private String getSelfProvisionResponse(String url) throws ProvisioningException {
+ RequestFuture<String> future = RequestFuture.newFuture();
+
+ StringRequest stringRequest = new StringRequest(Request.Method.POST, url, future, future) {
+ @Override
+ protected Map<String, String> getParams() {
+ Map<String, String> params = new ArrayMap<>();
+ params.put(SPG_VZW_MDN_PARAM, mNumber);
+ params.put(SPG_VZW_SERVICE_PARAM, SPG_VZW_SERVICE_BASIC);
+ params.put(SPG_DEVICE_MODEL_PARAM, SPG_DEVICE_MODEL_ANDROID);
+ params.put(SPG_APP_TOKEN_PARAM, SPG_APP_TOKEN);
+ // Language to display the subscription page. The page is never shown to the user
+ // so just use English.
+ params.put(SPG_LANGUAGE_PARAM, SPG_LANGUAGE_EN);
+ return params;
+ }
+ };
+
+ mRequestQueue.add(stringRequest);
+ try {
+ return future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new ProvisioningException(e.toString());
+ }
+ }
+
+ private void clickSubscribeLink(String subscribeLink) throws ProvisioningException {
+ RequestFuture<String> future = RequestFuture.newFuture();
+
+ StringRequest stringRequest = new StringRequest(Request.Method.POST,
+ subscribeLink, future, future);
+ mRequestQueue.add(stringRequest);
+
+ try {
+ future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new ProvisioningException(e.toString());
+ }
+ }
+
+ private String vvm3XmlRequest(String operation) throws ProvisioningException {
+ Log.d(TAG, "Sending vvm3XmlRequest for " + operation);
+ String voicemailManagementGateway = mData.getString(VMG_URL_KEY);
+ if (voicemailManagementGateway == null) {
+ Log.e(TAG, "voicemailManagementGateway url unknown");
+ return null;
+ }
+ String transactionId = createTransactionId();
+ String body = String.format(Locale.US, VMG_XML_REQUEST_FORMAT,
+ transactionId, mNumber, operation, Build.MODEL);
+
+ RequestFuture<String> future = RequestFuture.newFuture();
+ StringRequest stringRequest = new StringRequest(Request.Method.POST,
+ voicemailManagementGateway, future, future) {
+ @Override
+ public byte[] getBody() throws AuthFailureError {
+ return body.getBytes();
+ }
+ };
+ mRequestQueue.add(stringRequest);
+
+ try {
+ String response = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ if (!transactionId.equals(extractText(response, TRANSACTION_ID_TAG))) {
+ throw new ProvisioningException("transactionId mismatch");
+ }
+ return response;
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new ProvisioningException(e.toString());
+ }
+ }
+
+ private String findSubscribeLink(String response) throws ProvisioningException {
+ Spanned doc = Html.fromHtml(response, Html.FROM_HTML_MODE_LEGACY);
+ URLSpan[] spans = doc.getSpans(0, doc.length(), URLSpan.class);
+ for (URLSpan span : spans) {
+ String text = doc.subSequence(doc.getSpanStart(span), doc.getSpanEnd(span)).toString();
+ if (BASIC_SUBSCRIBE_LINK_TEXT.equals(text)) {
+ return span.getURL();
+ }
+ }
+ throw new ProvisioningException("Subscribe link not found");
+ }
+
+ private String createTransactionId() {
+ return String.valueOf(Math.abs(new Random().nextLong()));
+ }
+
+ private String extractText(String xml, String tag) throws ProvisioningException {
+ Pattern pattern = Pattern.compile("<" + tag + ">(.*)<\\/" + tag + ">");
+ Matcher matcher = pattern.matcher(xml);
+ if (matcher.find()) {
+ return matcher.group(1);
+ }
+ throw new ProvisioningException("Tag " + tag + " not found in xml response");
+ }
+
+ private class Vvm3ProvisioningNetworkRequestCallback extends VvmNetworkRequestCallback {
+
+ public Vvm3ProvisioningNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
+ PhoneAccountHandle phoneAccountHandle) {
+ super(config, phoneAccountHandle);
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+ Log.d(TAG, "provisioning: network available");
+ mRequestQueue = Volley
+ .newRequestQueue(mContext, new NetworkSpecifiedHurlStack(network));
+ processSubscription();
+ }
+ }
+
+ private static class NetworkSpecifiedHurlStack extends HurlStack {
+
+ private final Network mNetwork;
+
+ public NetworkSpecifiedHurlStack(Network network) {
+ mNetwork = network;
+ }
+
+ @Override
+ protected HttpURLConnection createConnection(URL url) throws IOException {
+ return (HttpURLConnection) mNetwork.openConnection(url);
+ }
+
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
index 9ac37a4..feb3c5a 100644
--- a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
+++ b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
@@ -20,23 +20,23 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.Bundle;
import android.os.UserManager;
-import android.provider.Telephony;
import android.provider.VoicemailContract;
import android.telecom.PhoneAccountHandle;
import android.telecom.Voicemail;
-import android.telephony.SmsMessage;
import android.util.Log;
-import com.android.internal.telephony.PhoneConstants;
import com.android.phone.PhoneGlobals;
-import com.android.phone.PhoneUtils;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.vvm.omtp.LocalLogHelper;
import com.android.phone.vvm.omtp.OmtpConstants;
+import com.android.phone.vvm.omtp.OmtpEvents;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
import com.android.phone.vvm.omtp.sync.VoicemailsQueryHelper;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
/**
* Receive SMS messages and send for processing by the OMTP visual voicemail source.
@@ -45,7 +45,6 @@
private static final String TAG = "OmtpMessageReceiver";
private Context mContext;
- private PhoneAccountHandle mPhoneAccount;
@Override
public void onReceive(Context context, Intent intent) {
@@ -56,54 +55,44 @@
}
mContext = context;
- mPhoneAccount = PhoneUtils.makePstnPhoneAccountHandle(
- intent.getExtras().getInt(PhoneConstants.PHONE_KEY));
+ int subId = intent.getExtras().getInt(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID);
+ PhoneAccountHandle phone = PhoneAccountHandleConverter.fromSubId(subId);
- if (mPhoneAccount == null) {
- Log.w(TAG, "Received message for null phone account");
+ if (phone == null) {
+ Log.i(TAG, "Received message for null phone account");
return;
}
- if (!VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(mContext, mPhoneAccount)) {
- Log.v(TAG, "Received vvm message for disabled vvm source.");
+ if (!VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(mContext, phone)) {
+ Log.i(TAG, "Received vvm message for disabled vvm source.");
return;
}
- SmsMessage[] messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
+ String eventType = intent.getExtras()
+ .getString(VoicemailContract.EXTRA_VOICEMAIL_SMS_PREFIX);
+ Bundle data = intent.getExtras().getBundle(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS);
- if (messages == null) {
- Log.w(TAG, "Message does not exist in the intent.");
- return;
- }
+ if (eventType.equals(OmtpConstants.SYNC_SMS_PREFIX)) {
+ SyncMessage message = new SyncMessage(data);
- StringBuilder messageBody = new StringBuilder();
-
- for (int i = 0; i < messages.length; i++) {
- if (messages[i].mWrappedSmsMessage != null) {
- messageBody.append(messages[i].getMessageBody());
- }
- }
-
- WrappedMessageData messageData = OmtpSmsParser.parse(messageBody.toString());
- if (messageData != null) {
- if (messageData.getPrefix() == OmtpConstants.SYNC_SMS_PREFIX) {
- SyncMessage message = new SyncMessage(messageData);
-
- Log.v(TAG, "Received SYNC sms for " + mPhoneAccount.getId() +
- " with event " + message.getSyncTriggerEvent());
- LocalLogHelper.log(TAG, "Received SYNC sms for " + mPhoneAccount.getId() +
- " with event " + message.getSyncTriggerEvent());
- processSync(message);
- } else if (messageData.getPrefix() == OmtpConstants.STATUS_SMS_PREFIX) {
- Log.v(TAG, "Received STATUS sms for " + mPhoneAccount.getId());
- LocalLogHelper.log(TAG, "Received Status sms for " + mPhoneAccount.getId());
- StatusMessage message = new StatusMessage(messageData);
- updateSource(message);
+ Log.v(TAG, "Received SYNC sms for " + phone.getId() +
+ " with event " + message.getSyncTriggerEvent());
+ LocalLogHelper.log(TAG, "Received SYNC sms for " + phone.getId() +
+ " with event " + message.getSyncTriggerEvent());
+ processSync(phone, message);
+ } else if (eventType.equals(OmtpConstants.STATUS_SMS_PREFIX)) {
+ Log.v(TAG, "Received STATUS sms for " + phone.getId());
+ LocalLogHelper.log(TAG, "Received Status sms for " + phone.getId());
+ StatusMessage message = new StatusMessage(data);
+ if (message.getProvisioningStatus().equals(OmtpConstants.SUBSCRIBER_READY)) {
+ updateSource(phone, subId, message);
} else {
- Log.e(TAG, "This should never have happened");
+ Log.v(TAG, "Subscriber not ready, start provisioning");
+ mContext.startService(OmtpProvisioningService.getProvisionIntent(mContext, intent));
}
+ } else {
+ Log.e(TAG, "Unknown prefix: " + eventType);
}
- // Let this fall through: this is not a message we're interested in.
}
/**
@@ -114,13 +103,13 @@
*
* @param message The sync message to extract data from.
*/
- private void processSync(SyncMessage message) {
+ private void processSync(PhoneAccountHandle phone, SyncMessage message) {
Intent serviceIntent = null;
switch (message.getSyncTriggerEvent()) {
case OmtpConstants.NEW_MESSAGE:
Voicemail.Builder builder = Voicemail.createForInsertion(
message.getTimestampMillis(), message.getSender())
- .setPhoneAccount(mPhoneAccount)
+ .setPhoneAccount(phone)
.setSourceData(message.getId())
.setDuration(message.getLength())
.setSourcePackage(mContext.getPackageName());
@@ -131,13 +120,13 @@
Uri uri = VoicemailContract.Voicemails.insert(mContext, voicemail);
voicemail = builder.setId(ContentUris.parseId(uri)).setUri(uri).build();
serviceIntent = OmtpVvmSyncService.getSyncIntent(mContext,
- OmtpVvmSyncService.SYNC_DOWNLOAD_ONE_TRANSCRIPTION, mPhoneAccount,
+ OmtpVvmSyncService.SYNC_DOWNLOAD_ONE_TRANSCRIPTION, phone,
voicemail, true /* firstAttempt */);
}
break;
case OmtpConstants.MAILBOX_UPDATE:
serviceIntent = OmtpVvmSyncService.getSyncIntent(
- mContext, OmtpVvmSyncService.SYNC_DOWNLOAD_ONLY, mPhoneAccount,
+ mContext, OmtpVvmSyncService.SYNC_DOWNLOAD_ONLY, phone,
true /* firstAttempt */);
break;
case OmtpConstants.GREETINGS_UPDATE:
@@ -153,37 +142,34 @@
}
}
- private void updateSource(StatusMessage message) {
+ private void updateSource(PhoneAccountHandle phone, int subId, StatusMessage message) {
OmtpVvmSourceManager vvmSourceManager =
OmtpVvmSourceManager.getInstance(mContext);
if (OmtpConstants.SUCCESS.equals(message.getReturnCode())) {
- VoicemailContract.Status.setStatus(mContext, mPhoneAccount,
- VoicemailContract.Status.CONFIGURATION_STATE_OK,
- VoicemailContract.Status.DATA_CHANNEL_STATE_OK,
- VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK);
+ OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(mContext, subId);
+ helper.handleEvent(OmtpEvents.CONFIG_REQUEST_STATUS_SUCCESS);
// Save the IMAP credentials in preferences so they are persistent and can be retrieved.
VisualVoicemailSettingsUtil.setVisualVoicemailCredentialsFromStatusMessage(
mContext,
- mPhoneAccount,
+ phone,
message);
// Add the source to indicate that it is active.
- vvmSourceManager.addSource(mPhoneAccount);
+ vvmSourceManager.addSource(phone);
Intent serviceIntent = OmtpVvmSyncService.getSyncIntent(
- mContext, OmtpVvmSyncService.SYNC_FULL_SYNC, mPhoneAccount,
+ mContext, OmtpVvmSyncService.SYNC_FULL_SYNC, phone,
true /* firstAttempt */);
mContext.startService(serviceIntent);
- PhoneGlobals.getInstance().clearMwiIndicator(
- PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount));
+ PhoneGlobals.getInstance().clearMwiIndicator(subId);
} else {
Log.w(TAG, "Visual voicemail not available for subscriber.");
// Override default isEnabled setting to false since visual voicemail is unable to
// be accessed for some reason.
- VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(mContext, mPhoneAccount,
+ VisualVoicemailSettingsUtil.setVisualVoicemailEnabled(mContext, phone,
/* isEnabled */ false, /* isUserSet */ true);
}
}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpProvisioningService.java b/src/com/android/phone/vvm/omtp/sms/OmtpProvisioningService.java
new file mode 100644
index 0000000..ced9490
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/sms/OmtpProvisioningService.java
@@ -0,0 +1,70 @@
+/*
+ * 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.phone.vvm.omtp.sms;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.VoicemailContract;
+import android.telecom.PhoneAccountHandle;
+
+import com.android.phone.PhoneUtils;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
+
+/**
+ * Performs visual voicemail provisioning in background thread. Not exported.
+ */
+public class OmtpProvisioningService extends IntentService {
+
+ public OmtpProvisioningService() {
+ super("OmtpProvisioningService");
+ }
+
+ /**
+ * Create an intent to start OmtpProvisioningService from a {@link
+ * VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED} intent.
+ */
+ public static Intent getProvisionIntent(Context context, Intent messageIntent) {
+ Intent serviceIntent = new Intent(context, OmtpProvisioningService.class);
+
+ serviceIntent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID,
+ messageIntent.getExtras().getInt(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID));
+ serviceIntent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS,
+ messageIntent.getExtras().getBundle(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS));
+
+ return serviceIntent;
+ }
+
+ @Override
+ public void onHandleIntent(Intent intent) {
+ int subId = intent.getExtras().getInt(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID);
+ PhoneAccountHandle phone = PhoneAccountHandleConverter.fromSubId(subId);
+
+ Bundle data = intent.getExtras().getBundle(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS);
+
+ StatusMessage message = new StatusMessage(data);
+ startProvisioning(phone, message, data);
+ }
+
+ private void startProvisioning(PhoneAccountHandle phone, StatusMessage message, Bundle data) {
+ OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(this,
+ PhoneUtils.getSubIdForPhoneAccountHandle(phone));
+ helper.startProvisioning(phone, message, data);
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpSmsParser.java b/src/com/android/phone/vvm/omtp/sms/OmtpSmsParser.java
deleted file mode 100644
index 54a2a02..0000000
--- a/src/com/android/phone/vvm/omtp/sms/OmtpSmsParser.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.phone.vvm.omtp.sms;
-
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-
-import java.util.Map;
-
-/**
- * OMTP SMS parser interface, for parsing SYNC and STATUS SMS sent by OMTP visual voicemail server.
- */
-public class OmtpSmsParser {
- private static String TAG = "OmtpSmsParser";
- /**
- * Parses the supplied SMS body and returns back a structured OMTP message.
- * Returns null if unable to parse the SMS body.
- */
- public static WrappedMessageData parse(String smsBody) {
- if (smsBody == null) {
- return null;
- }
-
- WrappedMessageData messageData = null;
- if (smsBody.startsWith(OmtpConstants.SYNC_SMS_PREFIX)) {
- messageData = new WrappedMessageData(OmtpConstants.SYNC_SMS_PREFIX,
- parseSmsBody(smsBody.substring(OmtpConstants.SYNC_SMS_PREFIX.length())));
- // Check for a mandatory field.
- String triggerEvent = messageData.extractString(OmtpConstants.SYNC_TRIGGER_EVENT);
- if (triggerEvent == null) {
- Log.e(TAG, "Missing mandatory field: " + OmtpConstants.SYNC_TRIGGER_EVENT);
- return null;
- }
- } else if (smsBody.startsWith(OmtpConstants.STATUS_SMS_PREFIX)) {
- messageData = new WrappedMessageData(OmtpConstants.STATUS_SMS_PREFIX,
- parseSmsBody(smsBody.substring(OmtpConstants.STATUS_SMS_PREFIX.length())));
- }
-
- return messageData;
- }
-
- /**
- * Converts a String of key/value pairs into a Map object. The WrappedMessageData object
- * contains helper functions to retrieve the values.
- *
- * e.g. "//VVM:STATUS:st=R;rc=0;srv=1;dn=1;ipt=1;spt=0;u=eg@example.com;pw=1"
- * => "WrappedMessageData [mFields={st=R, ipt=1, srv=1, dn=1, u=eg@example.com, pw=1, rc=0}]"
- *
- * @param message The sms string with the prefix removed.
- * @return A WrappedMessageData object containing the map.
- */
- private static Map<String, String> parseSmsBody(String message) {
- Map<String, String> keyValues = new ArrayMap<String, String>();
- String[] entries = message.split(OmtpConstants.SMS_FIELD_SEPARATOR);
- for (String entry : entries) {
- String[] keyValue = entry.split(OmtpConstants.SMS_KEY_VALUE_SEPARATOR);
- if (keyValue.length != 2) {
- continue;
- }
- keyValues.put(keyValue[0].trim(), keyValue[1].trim());
- }
-
- return keyValues;
- }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sms/StatusMessage.java b/src/com/android/phone/vvm/omtp/sms/StatusMessage.java
index 7e4faac..ee1f07d 100644
--- a/src/com/android/phone/vvm/omtp/sms/StatusMessage.java
+++ b/src/com/android/phone/vvm/omtp/sms/StatusMessage.java
@@ -15,6 +15,7 @@
*/
package com.android.phone.vvm.omtp.sms;
+import android.os.Bundle;
import android.telecom.Log;
import com.android.phone.vvm.omtp.OmtpConstants;
@@ -59,20 +60,30 @@
+ ", mSmtpPassword=" + Log.pii(mSmtpPassword) + "]";
}
- public StatusMessage(WrappedMessageData wrappedData) {
- mProvisioningStatus = wrappedData.extractString(OmtpConstants.PROVISIONING_STATUS);
- mStatusReturnCode = wrappedData.extractString(OmtpConstants.RETURN_CODE);
- mSubscriptionUrl = wrappedData.extractString(OmtpConstants.SUBSCRIPTION_URL);
- mServerAddress = wrappedData.extractString(OmtpConstants.SERVER_ADDRESS);
- mTuiAccessNumber = wrappedData.extractString(OmtpConstants.TUI_ACCESS_NUMBER);
- mClientSmsDestinationNumber = wrappedData.extractString(
+ public StatusMessage(Bundle wrappedData) {
+ mProvisioningStatus = unquote(wrappedData.getString(OmtpConstants.PROVISIONING_STATUS));
+ mStatusReturnCode = wrappedData.getString(OmtpConstants.RETURN_CODE);
+ mSubscriptionUrl = wrappedData.getString(OmtpConstants.SUBSCRIPTION_URL);
+ mServerAddress = wrappedData.getString(OmtpConstants.SERVER_ADDRESS);
+ mTuiAccessNumber = wrappedData.getString(OmtpConstants.TUI_ACCESS_NUMBER);
+ mClientSmsDestinationNumber = wrappedData.getString(
OmtpConstants.CLIENT_SMS_DESTINATION_NUMBER);
- mImapPort = wrappedData.extractString(OmtpConstants.IMAP_PORT);
- mImapUserName = wrappedData.extractString(OmtpConstants.IMAP_USER_NAME);
- mImapPassword = wrappedData.extractString(OmtpConstants.IMAP_PASSWORD);
- mSmtpPort = wrappedData.extractString(OmtpConstants.SMTP_PORT);
- mSmtpUserName = wrappedData.extractString(OmtpConstants.SMTP_USER_NAME);
- mSmtpPassword = wrappedData.extractString(OmtpConstants.SMTP_PASSWORD);
+ mImapPort = wrappedData.getString(OmtpConstants.IMAP_PORT);
+ mImapUserName = wrappedData.getString(OmtpConstants.IMAP_USER_NAME);
+ mImapPassword = wrappedData.getString(OmtpConstants.IMAP_PASSWORD);
+ mSmtpPort = wrappedData.getString(OmtpConstants.SMTP_PORT);
+ mSmtpUserName = wrappedData.getString(OmtpConstants.SMTP_USER_NAME);
+ mSmtpPassword = wrappedData.getString(OmtpConstants.SMTP_PASSWORD);
+ }
+
+ private static String unquote(String string) {
+ if (string.length() < 2) {
+ return string;
+ }
+ if (string.startsWith("\"") && string.endsWith("\"")) {
+ return string.substring(1, string.length() - 1);
+ }
+ return string;
}
/**
diff --git a/src/com/android/phone/vvm/omtp/sms/SyncMessage.java b/src/com/android/phone/vvm/omtp/sms/SyncMessage.java
index 6829981..4dddba4 100644
--- a/src/com/android/phone/vvm/omtp/sms/SyncMessage.java
+++ b/src/com/android/phone/vvm/omtp/sms/SyncMessage.java
@@ -15,8 +15,15 @@
*/
package com.android.phone.vvm.omtp.sms;
+import android.annotation.Nullable;
+import android.os.Bundle;
+
import com.android.phone.vvm.omtp.OmtpConstants;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
/**
* Structured data representation of an OMTP SYNC message.
*
@@ -30,6 +37,7 @@
// UID of the new message.
private final String mMessageId;
// Length of the message.
+ @Nullable
private final Integer mMessageLength;
// Content type (voice, video, fax...) of the new message.
private final String mContentType;
@@ -49,16 +57,30 @@
+ ", mMsgTimeMillis=" + mMsgTimeMillis + "]";
}
- public SyncMessage(WrappedMessageData wrappedData) {
- mSyncTriggerEvent = wrappedData.extractString(OmtpConstants.SYNC_TRIGGER_EVENT);
- mMessageId = wrappedData.extractString(OmtpConstants.MESSAGE_UID);
- mMessageLength = wrappedData.extractInteger(OmtpConstants.MESSAGE_LENGTH);
- mContentType = wrappedData.extractString(OmtpConstants.CONTENT_TYPE);
- mSender = wrappedData.extractString(OmtpConstants.SENDER);
- mNewMessageCount = wrappedData.extractInteger(OmtpConstants.NUM_MESSAGE_COUNT);
- mMsgTimeMillis = wrappedData.extractTime(OmtpConstants.TIME);
+ public SyncMessage(Bundle wrappedData) {
+ mSyncTriggerEvent = wrappedData.getString(OmtpConstants.SYNC_TRIGGER_EVENT);
+ mMessageId = wrappedData.getString(OmtpConstants.MESSAGE_UID);
+ if (wrappedData.getString(OmtpConstants.MESSAGE_LENGTH) != null) {
+ mMessageLength = Integer.parseInt(wrappedData.getString(OmtpConstants.MESSAGE_LENGTH));
+ } else {
+ // Optional field
+ mMessageLength = null;
+ }
+ mContentType = wrappedData.getString(OmtpConstants.CONTENT_TYPE);
+ mSender = wrappedData.getString(OmtpConstants.SENDER);
+ mNewMessageCount = Integer.parseInt(wrappedData.getString(OmtpConstants.NUM_MESSAGE_COUNT));
+ mMsgTimeMillis = parseTime(wrappedData.getString(OmtpConstants.TIME));
}
+ static Long parseTime(String value) {
+ try {
+ return new SimpleDateFormat(
+ OmtpConstants.DATE_TIME_FORMAT, Locale.US)
+ .parse(value).getTime();
+ } catch (ParseException e) {
+ return 0L;
+ }
+ }
/**
* @return the event that triggered the sync message. This is a mandatory field and must always
* be set.
diff --git a/src/com/android/phone/vvm/omtp/sms/Vvm3MessageSender.java b/src/com/android/phone/vvm/omtp/sms/Vvm3MessageSender.java
new file mode 100644
index 0000000..dc2ea58
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/sms/Vvm3MessageSender.java
@@ -0,0 +1,55 @@
+/*
+ * 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.phone.vvm.omtp.sms;
+
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.telephony.SmsManager;
+
+public class Vvm3MessageSender extends OmtpMessageSender {
+
+ /**
+ * Creates a new instance of Vvm3MessageSender.
+ *
+ * @param smsManager SMS sending library. There is a different SmsManager for each SIM.
+ * @param applicationPort If set to a value > 0 then a binary sms is sent to this port number.
+ * Otherwise, a standard text SMS is sent.
+ */
+ public Vvm3MessageSender(SmsManager smsManager, short applicationPort,
+ String destinationNumber) {
+ super(smsManager, applicationPort, destinationNumber);
+ }
+
+ @Override
+ public void requestVvmActivation(@Nullable PendingIntent sentIntent) {
+ // Activation not supported for VVM3, send a status request instead.
+ requestVvmStatus(sentIntent);
+ }
+
+ @Override
+ public void requestVvmDeactivation(@Nullable PendingIntent sentIntent) {
+ // Deactivation not supported for VVM3, do nothing
+ }
+
+
+ @Override
+ public void requestVvmStatus(@Nullable PendingIntent sentIntent) {
+ // Status message:
+ // STATUS
+ StringBuilder sb = new StringBuilder().append("STATUS");
+ sendSms(sb.toString(), sentIntent);
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/sms/WrappedMessageData.java b/src/com/android/phone/vvm/omtp/sms/WrappedMessageData.java
deleted file mode 100644
index b4c86d4..0000000
--- a/src/com/android/phone/vvm/omtp/sms/WrappedMessageData.java
+++ /dev/null
@@ -1,128 +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.phone.vvm.omtp.sms;
-
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Class wrapping the raw OMTP message data, internally represented as as map of all key-value pairs
- * found in the SMS body.
- * <p>
- * Provides convenience methods to extract parse fields of different types.
- * <p>
- * All the methods return null if either the field was not present or it could not be parsed.
- */
-public class WrappedMessageData {
- private final String TAG = "WrappedMessageData";
- private final String mPrefix;
- private final Map<String, String> mFields;
-
- @Override
- public String toString() {
- return "WrappedMessageData [mFields=" + mFields + "]";
- }
-
- WrappedMessageData(String prefix, Map<String, String> keyValues) {
- mPrefix = prefix;
- mFields = new ArrayMap<String, String>();
- mFields.putAll(keyValues);
- }
-
- /**
- * @return The String prefix of the message, designating whether this is the message data of a
- * STATUS or SYNC sms.
- */
- String getPrefix() {
- return mPrefix;
- }
-
- /**
- * Extracts the requested field from underlying data and returns the String value as is.
- *
- * @param field The requested field.
- * @return the parsed string value, or null if the field was not present or not valid.
- */
- String extractString(final String field) {
- String value = mFields.get(field);
- if (value == null) {
- return null;
- }
-
- String[] possibleValues = OmtpConstants.possibleValuesMap.get(field);
- if (possibleValues == null) {
- return value;
- }
- for (int i = 0; i < possibleValues.length; i++) {
- if (TextUtils.equals(value, possibleValues[i])) {
- return value;
- }
- }
- Log.e(TAG, "extractString - value \"" + value +
- "\" of field \"" + field + "\" is not allowed.");
- return null;
- }
-
- /**
- * Extracts the requested field from underlying data and parses it as an {@link Integer}.
- *
- * @param field The requested field.
- * @return the parsed integer value, or null if the field was not present.
- */
- Integer extractInteger(final String field) {
- String value = mFields.get(field);
- if (value == null) {
- return null;
- }
-
- try {
- return Integer.decode(value);
- } catch (NumberFormatException e) {
- Log.e(TAG, "extractInteger - could not parse integer: " + value);
- return null;
- }
- }
-
- /**
- * Extracts the requested field from underlying data and parses it as a date/time represented in
- * {@link OmtpConstants#DATE_TIME_FORMAT} format.
- *
- * @param field The requested field.
- * @return the parsed string value, or null if the field was not present.
- */
- Long extractTime(final String field) {
- String value = mFields.get(field);
- if (value == null) {
- return null;
- }
-
- try {
- return new SimpleDateFormat(
- OmtpConstants.DATE_TIME_FORMAT, Locale.US).parse(value).getTime();
- } catch (ParseException e) {
- Log.e(TAG, "extractTime - could not parse time: " + value);
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
index 0520098..1b9e53f 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
@@ -16,7 +16,6 @@
package com.android.phone.vvm.omtp.sync;
import android.content.Context;
-import android.provider.VoicemailContract;
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
@@ -24,7 +23,10 @@
import com.android.internal.telephony.Phone;
import com.android.phone.PhoneUtils;
+import com.android.phone.vvm.omtp.OmtpEvents;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.VvmPhoneStateListener;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
import java.util.Collections;
import java.util.Map;
@@ -105,10 +107,8 @@
}
public void removeSource(PhoneAccountHandle phoneAccount) {
- VoicemailContract.Status.setStatus(mContext, phoneAccount,
- VoicemailContract.Status.CONFIGURATION_STATE_NOT_CONFIGURED,
- VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION,
- VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
+ new OmtpVvmCarrierConfigHelper(mContext, PhoneAccountHandleConverter.toSubId(phoneAccount))
+ .handleEvent(OmtpEvents.OTHER_SOURCE_REMOVED);
removePhoneStateListener(phoneAccount);
mActiveVvmSources.remove(phoneAccount);
OmtpVvmSyncService.cancelAllRetries(mContext, phoneAccount);
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
index e44904b..c0411ec 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
@@ -24,16 +24,16 @@
import android.net.NetworkInfo;
import android.net.Uri;
import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
import android.telecom.PhoneAccountHandle;
import android.telecom.Voicemail;
import android.text.TextUtils;
import android.util.Log;
import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailUtils;
+import com.android.phone.VoicemailStatus;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.vvm.omtp.LocalLogHelper;
+import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.fetch.VoicemailFetchedCallback;
import com.android.phone.vvm.omtp.imap.ImapHelper;
@@ -219,10 +219,7 @@
* finished
* b/26937720
*/
- Status.setStatus(this, phoneAccount,
- Status.CONFIGURATION_STATE_IGNORE,
- Status.DATA_CHANNEL_STATE_IGNORE,
- Status.NOTIFICATION_CHANNEL_STATE_IGNORE);
+ VoicemailStatus.edit(this, phoneAccount).apply();
return;
}
VisualVoicemailSettingsUtil.setVisualVoicemailLastFullSyncTime(
@@ -265,8 +262,8 @@
// Nothing more to do here, just exit.
VisualVoicemailSettingsUtil.resetVisualVoicemailRetryInterval(this,
phoneAccount);
- VoicemailUtils.setDataChannelState(
- this, phoneAccount, Status.DATA_CHANNEL_STATE_OK);
+
+ imapHelper.handleEvent(OmtpEvents.DATA_IMAP_OPERATION_COMPLETED);
return;
}
}
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
index 884bec9..4e09527 100644
--- a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
+++ b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
@@ -23,13 +23,11 @@
import android.net.NetworkRequest;
import android.os.Handler;
import android.os.Looper;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
import android.telecom.PhoneAccountHandle;
import android.util.Log;
import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailUtils;
+import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
/**
@@ -63,6 +61,15 @@
mNetworkRequest = createNetworkRequest();
}
+ public VvmNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
+ PhoneAccountHandle phoneAccount) {
+ mContext = config.getContext();
+ mPhoneAccount = phoneAccount;
+ mSubId = config.getSubId();
+ mCarrierConfigHelper = config;
+ mNetworkRequest = createNetworkRequest();
+ }
+
/**
* @return NetworkRequest for a proper transport type. Use only cellular network if the carrier
* requires it. Otherwise use whatever available.
@@ -147,12 +154,9 @@
public void onFailed(String reason) {
Log.d(TAG, "onFailed: " + reason);
if (mCarrierConfigHelper.isCellularDataRequired()) {
- VoicemailUtils.setDataChannelState(
- mContext, mPhoneAccount,
- Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED);
+ mCarrierConfigHelper.handleEvent(OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
} else {
- VoicemailUtils.setDataChannelState(
- mContext, mPhoneAccount, Status.DATA_CHANNEL_STATE_NO_CONNECTION);
+ mCarrierConfigHelper.handleEvent(OmtpEvents.DATA_NO_CONNECTION);
}
releaseNetwork();
}
diff --git a/src/com/android/phone/vvm/omtp/utils/PhoneAccountHandleConverter.java b/src/com/android/phone/vvm/omtp/utils/PhoneAccountHandleConverter.java
new file mode 100644
index 0000000..0474452
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/utils/PhoneAccountHandleConverter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.phone.vvm.omtp.utils;
+
+import android.telecom.PhoneAccountHandle;
+import android.telephony.SubscriptionManager;
+
+import com.android.phone.PhoneUtils;
+
+/**
+ * Utility to convert between PhoneAccountHandle and subId, which is a common operation in OMTP
+ * client
+ *
+ * TODO(b/28977379): remove dependency on PhoneUtils and use public APIs
+ */
+public class PhoneAccountHandleConverter {
+
+ public static PhoneAccountHandle fromSubId(int subId) {
+ return PhoneUtils.makePstnPhoneAccountHandle(
+ SubscriptionManager.getPhoneId(subId));
+ }
+
+ public static int toSubId(PhoneAccountHandle handle) {
+ return PhoneUtils.getSubIdForPhoneAccountHandle(handle);
+ }
+
+ private PhoneAccountHandleConverter() {
+ }
+}
diff --git a/src/com/android/phone/vvm/omtp/utils/XmlUtils.java b/src/com/android/phone/vvm/omtp/utils/XmlUtils.java
new file mode 100644
index 0000000..4eeb5ce
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/utils/XmlUtils.java
@@ -0,0 +1,245 @@
+/*
+ * 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.phone.vvm.omtp.utils;
+
+import android.util.ArrayMap;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class XmlUtils {
+
+ public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag,
+ String[] name, ReadMapCallback callback)
+ throws XmlPullParserException, java.io.IOException {
+ ArrayMap<String, Object> map = new ArrayMap<>();
+
+ int eventType = parser.getEventType();
+ do {
+ if (eventType == XmlPullParser.START_TAG) {
+ Object val = readThisValueXml(parser, name, callback, true);
+ map.put(name[0], val);
+ } else if (eventType == XmlPullParser.END_TAG) {
+ if (parser.getName().equals(endTag)) {
+ return map;
+ }
+ throw new XmlPullParserException(
+ "Expected " + endTag + " end tag at: " + parser.getName());
+ }
+ eventType = parser.next();
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+
+ throw new XmlPullParserException(
+ "Document ended before " + endTag + " end tag");
+ }
+
+ /**
+ * Read an ArrayList object from an XmlPullParser. The XML data could previously have been
+ * generated by writeListXml(). The XmlPullParser must be positioned <em>after</em> the tag
+ * that begins the list.
+ *
+ * @param parser The XmlPullParser from which to read the list data.
+ * @param endTag Name of the tag that will end the list, usually "list".
+ * @param name An array of one string, used to return the name attribute of the list's tag.
+ * @return HashMap The newly generated list.
+ */
+ public static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+ String[] name, ReadMapCallback callback, boolean arrayMap)
+ throws XmlPullParserException, java.io.IOException {
+ ArrayList list = new ArrayList();
+
+ int eventType = parser.getEventType();
+ do {
+ if (eventType == XmlPullParser.START_TAG) {
+ Object val = readThisValueXml(parser, name, callback, arrayMap);
+ list.add(val);
+ } else if (eventType == XmlPullParser.END_TAG) {
+ if (parser.getName().equals(endTag)) {
+ return list;
+ }
+ throw new XmlPullParserException(
+ "Expected " + endTag + " end tag at: " + parser.getName());
+ }
+ eventType = parser.next();
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+
+ throw new XmlPullParserException(
+ "Document ended before " + endTag + " end tag");
+ }
+
+ /**
+ * Read a String[] object from an XmlPullParser. The XML data could previously have been
+ * generated by writeStringArrayXml(). The XmlPullParser must be positioned <em>after</em> the
+ * tag that begins the list.
+ *
+ * @param parser The XmlPullParser from which to read the list data.
+ * @param endTag Name of the tag that will end the list, usually "string-array".
+ * @param name An array of one string, used to return the name attribute of the list's tag.
+ * @return Returns a newly generated String[].
+ */
+ public static String[] readThisStringArrayXml(XmlPullParser parser, String endTag,
+ String[] name) throws XmlPullParserException, java.io.IOException {
+
+ parser.next();
+
+ List<String> array = new ArrayList<>();
+
+ int eventType = parser.getEventType();
+ do {
+ if (eventType == XmlPullParser.START_TAG) {
+ if (parser.getName().equals("item")) {
+ try {
+ array.add(parser.getAttributeValue(null, "value"));
+ } catch (NullPointerException e) {
+ throw new XmlPullParserException("Need value attribute in item");
+ } catch (NumberFormatException e) {
+ throw new XmlPullParserException("Not a number in value attribute in item");
+ }
+ } else {
+ throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+ }
+ } else if (eventType == XmlPullParser.END_TAG) {
+ if (parser.getName().equals(endTag)) {
+ return array.toArray(new String[0]);
+ } else if (parser.getName().equals("item")) {
+
+ } else {
+ throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+ parser.getName());
+ }
+ }
+ eventType = parser.next();
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+
+ throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+ }
+
+ private static Object readThisValueXml(XmlPullParser parser, String[] name,
+ ReadMapCallback callback, boolean arrayMap)
+ throws XmlPullParserException, java.io.IOException {
+ final String valueName = parser.getAttributeValue(null, "name");
+ final String tagName = parser.getName();
+
+ Object res;
+
+ if (tagName.equals("null")) {
+ res = null;
+ } else if (tagName.equals("string")) {
+ String value = "";
+ int eventType;
+ while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.END_TAG) {
+ if (parser.getName().equals("string")) {
+ name[0] = valueName;
+ return value;
+ }
+ throw new XmlPullParserException(
+ "Unexpected end tag in <string>: " + parser.getName());
+ } else if (eventType == XmlPullParser.TEXT) {
+ value += parser.getText();
+ } else if (eventType == XmlPullParser.START_TAG) {
+ throw new XmlPullParserException(
+ "Unexpected start tag in <string>: " + parser.getName());
+ }
+ }
+ throw new XmlPullParserException(
+ "Unexpected end of document in <string>");
+ } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) {
+ // all work already done by readThisPrimitiveValueXml
+ } else if (tagName.equals("string-array")) {
+ res = readThisStringArrayXml(parser, "string-array", name);
+ name[0] = valueName;
+ return res;
+ } else if (tagName.equals("list")) {
+ parser.next();
+ res = readThisListXml(parser, "list", name, callback, arrayMap);
+ name[0] = valueName;
+ return res;
+ } else if (callback != null) {
+ res = callback.readThisUnknownObjectXml(parser, tagName);
+ name[0] = valueName;
+ return res;
+ } else {
+ throw new XmlPullParserException("Unknown tag: " + tagName);
+ }
+
+ // Skip through to end tag.
+ int eventType;
+ while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.END_TAG) {
+ if (parser.getName().equals(tagName)) {
+ name[0] = valueName;
+ return res;
+ }
+ throw new XmlPullParserException(
+ "Unexpected end tag in <" + tagName + ">: " + parser.getName());
+ } else if (eventType == XmlPullParser.TEXT) {
+ throw new XmlPullParserException(
+ "Unexpected text in <" + tagName + ">: " + parser.getName());
+ } else if (eventType == XmlPullParser.START_TAG) {
+ throw new XmlPullParserException(
+ "Unexpected start tag in <" + tagName + ">: " + parser.getName());
+ }
+ }
+ throw new XmlPullParserException(
+ "Unexpected end of document in <" + tagName + ">");
+ }
+
+ private static final Object readThisPrimitiveValueXml(XmlPullParser parser, String tagName)
+ throws XmlPullParserException, java.io.IOException {
+ try {
+ if (tagName.equals("int")) {
+ return Integer.parseInt(parser.getAttributeValue(null, "value"));
+ } else if (tagName.equals("long")) {
+ return Long.valueOf(parser.getAttributeValue(null, "value"));
+ } else if (tagName.equals("float")) {
+ return Float.valueOf(parser.getAttributeValue(null, "value"));
+ } else if (tagName.equals("double")) {
+ return Double.valueOf(parser.getAttributeValue(null, "value"));
+ } else if (tagName.equals("boolean")) {
+ return Boolean.valueOf(parser.getAttributeValue(null, "value"));
+ } else {
+ return null;
+ }
+ } catch (NullPointerException e) {
+ throw new XmlPullParserException("Need value attribute in <" + tagName + ">");
+ } catch (NumberFormatException e) {
+ throw new XmlPullParserException(
+ "Not a number in value attribute in <" + tagName + ">");
+ }
+ }
+
+ public interface ReadMapCallback {
+
+ /**
+ * Called from readThisMapXml when a START_TAG is not recognized. The input stream is
+ * positioned within the start tag so that attributes can be read using in.getAttribute.
+ *
+ * @param in the XML input stream
+ * @param tag the START_TAG that was not recognized.
+ * @return the Object parsed from the stream which will be put into the map.
+ * @throws XmlPullParserException if the START_TAG is not recognized.
+ * @throws IOException on XmlPullParser serialization errors.
+ */
+ Object readThisUnknownObjectXml(XmlPullParser in, String tag)
+ throws XmlPullParserException, IOException;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index bfb0d23..8020996 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -26,6 +26,7 @@
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import com.android.internal.telephony.Phone;
import com.android.phone.settings.SettingsConstants;
@@ -84,7 +85,9 @@
mAllowMute = allowMute;
mIsOutgoing = isOutgoing;
mIsCallWaiting = connection != null && connection.getState() == Call.State.WAITING;
- if (mIsCallWaiting) {
+ boolean isImsCall = getOriginalConnection() instanceof ImsPhoneConnection;
+ // Start call waiting timer for CDMA waiting call.
+ if (mIsCallWaiting && !isImsCall) {
startCallWaitingTimer();
}
}
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index d7db345..f8fd918 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -137,6 +137,9 @@
case android.telephony.DisconnectCause.NOT_DISCONNECTED:
return DisconnectCause.UNKNOWN;
+ case android.telephony.DisconnectCause.CALL_PULLED:
+ return DisconnectCause.CALL_PULLED;
+
default:
Log.w("DisconnectCauseUtil.toTelecomDisconnectCauseCode",
"Unrecognized Telephony DisconnectCause "
@@ -214,6 +217,9 @@
resourceId = R.string.callFailed_unobtainable_number;
break;
+ case android.telephony.DisconnectCause.CALL_PULLED:
+ resourceId = R.string.callEnded_pulled;
+
default:
break;
}
@@ -329,6 +335,10 @@
resourceId = R.string.callFailed_video_call_tty_enabled;
break;
+ case android.telephony.DisconnectCause.CALL_PULLED:
+ resourceId = R.string.callEnded_pulled;
+ break;
+
case android.telephony.DisconnectCause.OUTGOING_CANCELED:
// We don't want to show any dialog for the canceled case since the call was
// either canceled by the user explicitly (end-call button pushed immediately)
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index b4733dd..47fac6a 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -312,6 +312,17 @@
Connection original = telephonyConnection.getOriginalConnection();
if (original != null && !original.isIncoming()
&& Objects.equals(original.getAddress(), unknown.getAddress())) {
+ // If the new unknown connection is an external connection, don't swap one with an
+ // actual connection. This means a call got pulled away. We want the actual connection
+ // to disconnect.
+ if (unknown instanceof ImsExternalConnection &&
+ !(telephonyConnection
+ .getOriginalConnection() instanceof ImsExternalConnection)) {
+ Log.v(this, "maybeSwapWithUnknownConnection - not swapping regular connection " +
+ "with external connection.");
+ return false;
+ }
+
telephonyConnection.setOriginalConnection(unknown);
return true;
}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 3ed8356..19b1d8a 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -71,6 +71,7 @@
private boolean mIsVideoPresenceSupported;
private boolean mIsVideoPauseSupported;
private boolean mIsMergeCallSupported;
+ private boolean mIsVideoConferencingSupported;
AccountEntry(Phone phone, boolean isEmergency, boolean isDummy) {
mPhone = phone;
@@ -189,6 +190,7 @@
instantLetteringExtras = getPhoneAccountExtras();
}
mIsMergeCallSupported = isCarrierMergeCallSupported();
+ mIsVideoConferencingSupported = isCarrierVideoConferencingSupported();
if (isEmergency && mContext.getResources().getBoolean(
R.bool.config_emergency_account_emergency_calls_only)) {
@@ -244,7 +246,8 @@
// Check if IMS video pause is supported.
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL);
+ return b != null &&
+ b.getBoolean(CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL);
}
/**
@@ -256,7 +259,8 @@
private boolean isCarrierVideoPresenceSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b.getBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL);
+ return b != null &&
+ b.getBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL);
}
/**
@@ -267,7 +271,8 @@
private boolean isCarrierInstantLetteringSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b.getBoolean(CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL);
+ return b != null &&
+ b.getBoolean(CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL);
}
/**
@@ -278,7 +283,8 @@
private boolean isCarrierMergeCallSupported() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b.getBoolean(CarrierConfigManager.KEY_SUPPORT_CONFERENCE_CALL_BOOL);
+ return b != null &&
+ b.getBoolean(CarrierConfigManager.KEY_SUPPORT_CONFERENCE_CALL_BOOL);
}
/**
@@ -289,7 +295,20 @@
private boolean isCarrierEmergencyVideoCallsAllowed() {
PersistableBundle b =
PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
- return b.getBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL);
+ return b != null &&
+ b.getBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL);
+ }
+
+ /**
+ * Determines from carrier config whether video conferencing is supported.
+ *
+ * @return {@code true} if video conferencing is supported, {@code false} otherwise.
+ */
+ private boolean isCarrierVideoConferencingSupported() {
+ PersistableBundle b =
+ PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+ return b != null &&
+ b.getBoolean(CarrierConfigManager.KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL);
}
/**
@@ -339,6 +358,14 @@
public boolean isMergeCallSupported() {
return mIsMergeCallSupported;
}
+
+ /**
+ * Indicates whether this account supports video conferencing.
+ * @return {@code true} if the account supports video conferencing, {@code false} otherwise.
+ */
+ public boolean isVideoConferencingSupported() {
+ return mIsVideoConferencingSupported;
+ }
}
private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
@@ -430,6 +457,22 @@
}
/**
+ * Determines if the {@link AccountEntry} associated with a {@link PhoneAccountHandle} supports
+ * video conferencing.
+ *
+ * @param handle The {@link PhoneAccountHandle}.
+ * @return {@code True} if video conferencing is supported.
+ */
+ boolean isVideoConferencingSupported(PhoneAccountHandle handle) {
+ for (AccountEntry entry : mAccounts) {
+ if (entry.getPhoneAccountHandle().equals(handle)) {
+ return entry.isVideoConferencingSupported();
+ }
+ }
+ return false;
+ }
+
+ /**
* @return Reference to the {@code TelecomAccountRegistry}'s subscription manager.
*/
SubscriptionManager getSubscriptionManager() {
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 21c71d2..e495de5 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -79,6 +79,8 @@
private static final int MSG_CONNECTION_EXTRAS_CHANGED = 12;
private static final int MSG_SET_ORIGNAL_CONNECTION_CAPABILITIES = 13;
private static final int MSG_ON_HOLD_TONE = 14;
+ private static final int MSG_CDMA_VOICE_PRIVACY_ON = 15;
+ private static final int MSG_CDMA_VOICE_PRIVACY_OFF = 16;
private final Handler mHandler = new Handler() {
@Override
@@ -206,6 +208,15 @@
}
}
break;
+
+ case MSG_CDMA_VOICE_PRIVACY_ON:
+ Log.d(this, "MSG_CDMA_VOICE_PRIVACY_ON received");
+ setCdmaVoicePrivacy(true);
+ break;
+ case MSG_CDMA_VOICE_PRIVACY_OFF:
+ Log.d(this, "MSG_CDMA_VOICE_PRIVACY_OFF received");
+ setCdmaVoicePrivacy(false);
+ break;
}
}
};
@@ -388,6 +399,11 @@
private boolean mIsConferenceSupported;
/**
+ * Indicates whether or not this connection has CDMA Enhanced Voice Privacy enabled.
+ */
+ private boolean mIsCdmaVoicePrivacyEnabled;
+
+ /**
* Listeners to our TelephonyConnection specific callbacks
*/
private final Set<TelephonyConnectionListener> mTelephonyListeners = Collections.newSetFromMap(
@@ -662,6 +678,8 @@
newProperties = changeBitmask(newProperties, PROPERTY_WIFI, mIsWifi);
newProperties = changeBitmask(newProperties, PROPERTY_IS_EXTERNAL_CALL,
isExternalConnection());
+ newProperties = changeBitmask(newProperties, PROPERTY_HAS_CDMA_VOICE_PRIVACY,
+ mIsCdmaVoicePrivacyEnabled);
if (getConnectionProperties() != newProperties) {
setConnectionProperties(newProperties);
@@ -712,6 +730,8 @@
getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);
getPhone().registerForSuppServiceNotification(mHandler, MSG_SUPP_SERVICE_NOTIFY, null);
getPhone().registerForOnHoldTone(mHandler, MSG_ON_HOLD_TONE, null);
+ getPhone().registerForInCallVoicePrivacyOn(mHandler, MSG_CDMA_VOICE_PRIVACY_ON, null);
+ getPhone().registerForInCallVoicePrivacyOff(mHandler, MSG_CDMA_VOICE_PRIVACY_OFF, null);
mOriginalConnection.addPostDialListener(mPostDialListener);
mOriginalConnection.addListener(mOriginalConnectionListener);
@@ -780,6 +800,8 @@
getPhone().unregisterForDisconnect(mHandler);
getPhone().unregisterForSuppServiceNotification(mHandler);
getPhone().unregisterForOnHoldTone(mHandler);
+ getPhone().unregisterForInCallVoicePrivacyOn(mHandler);
+ getPhone().unregisterForInCallVoicePrivacyOff(mHandler);
}
mOriginalConnection.removePostDialListener(mPostDialListener);
mOriginalConnection.removeListener(mOriginalConnectionListener);
@@ -1145,6 +1167,16 @@
}
/**
+ * Sets whether or not CDMA enhanced call privacy is enabled for this connection.
+ */
+ private void setCdmaVoicePrivacy(boolean isEnabled) {
+ if(mIsCdmaVoicePrivacyEnabled != isEnabled) {
+ mIsCdmaVoicePrivacyEnabled = isEnabled;
+ updateConnectionProperties();
+ }
+ }
+
+ /**
* Applies capabilities specific to conferences termination to the
* {@code ConnectionCapabilities} bit-mask.
*
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 0af667a..a4434dd 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -296,7 +296,7 @@
final TelephonyConnection connection =
createConnectionFor(phone, null, true /* isOutgoing */, request.getAccountHandle(),
- request.getTelecomCallId(), request.getAddress());
+ request.getTelecomCallId(), request.getAddress(), request.getVideoState());
if (connection == null) {
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
@@ -378,10 +378,15 @@
return Connection.createCanceledConnection();
}
+ // We should rely on the originalConnection to get the video state. The request coming
+ // from Telecom does not know the video state of the incoming call.
+ int videoState = originalConnection != null ? originalConnection.getVideoState() :
+ VideoProfile.STATE_AUDIO_ONLY;
+
Connection connection =
createConnectionFor(phone, originalConnection, false /* isOutgoing */,
request.getAccountHandle(), request.getTelecomCallId(),
- request.getAddress());
+ request.getAddress(), videoState);
if (connection == null) {
return Connection.createCanceledConnection();
} else {
@@ -478,11 +483,16 @@
return Connection.createCanceledConnection();
}
+ // We should rely on the originalConnection to get the video state. The request coming
+ // from Telecom does not know the video state of the unknown call.
+ int videoState = unknownConnection != null ? unknownConnection.getVideoState() :
+ VideoProfile.STATE_AUDIO_ONLY;
+
TelephonyConnection connection =
createConnectionFor(phone, unknownConnection,
!unknownConnection.isIncoming() /* isOutgoing */,
request.getAccountHandle(), request.getTelecomCallId(),
- request.getAddress());
+ request.getAddress(), videoState);
if (connection == null) {
return Connection.createCanceledConnection();
@@ -546,7 +556,8 @@
boolean isOutgoing,
PhoneAccountHandle phoneAccountHandle,
String telecomCallId,
- Uri address) {
+ Uri address,
+ int videoState) {
TelephonyConnection returnConnection = null;
int phoneType = phone.getPhoneType();
if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
@@ -564,9 +575,13 @@
phoneAccountHandle));
boolean isEmergencyCall = (address != null && PhoneNumberUtils.isEmergencyNumber(
address.getSchemeSpecificPart()));
- returnConnection.setConferenceSupported(!isEmergencyCall
- && TelecomAccountRegistry.getInstance(this).isMergeCallSupported(
- phoneAccountHandle));
+ boolean isVideoCall = VideoProfile.isVideo(videoState);
+ boolean isConferencingSupported = TelecomAccountRegistry.getInstance(this)
+ .isMergeCallSupported(phoneAccountHandle);
+ boolean isVideoConferencingSupported = TelecomAccountRegistry.getInstance(this)
+ .isVideoConferencingSupported(phoneAccountHandle);
+ returnConnection.setConferenceSupported(!isEmergencyCall && isConferencingSupported
+ && (!isVideoCall || (isVideoCall && isVideoConferencingSupported)));
}
return returnConnection;
}
diff --git a/tests/src/com/android/phone/common/mail/store/imap/DigestMd5UtilsTest.java b/tests/src/com/android/phone/common/mail/store/imap/DigestMd5UtilsTest.java
new file mode 100644
index 0000000..5534632
--- /dev/null
+++ b/tests/src/com/android/phone/common/mail/store/imap/DigestMd5UtilsTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.phone.common.mail.store.imap;
+
+import junit.framework.TestCase;
+
+public class DigestMd5UtilsTest extends TestCase {
+
+ public void testGetResponse() {
+ // Example data from RFC 2831.4
+ DigestMd5Utils.Data data = new DigestMd5Utils.Data();
+ data.username = "chris";
+ data.password = "secret";
+ data.realm = "elwood.innosoft.com";
+ data.nonce = "OA6MG9tEQGm2hh";
+ data.cnonce = "OA6MHXh6VqTrRk";
+ data.nc = "00000001";
+ data.qop = "auth";
+ data.digestUri = "imap/elwood.innosoft.com";
+ String response = DigestMd5Utils.getResponse(data, false);
+ assertEquals("d388dad90d4bbd760a152321f2143af7", response);
+ }
+
+ public void testGetResponse_ResponseAuth() {
+ // Example data from RFC 2831.4
+ DigestMd5Utils.Data data = new DigestMd5Utils.Data();
+ data.username = "chris";
+ data.password = "secret";
+ data.realm = "elwood.innosoft.com";
+ data.nonce = "OA6MG9tEQGm2hh";
+ data.cnonce = "OA6MHXh6VqTrRk";
+ data.nc = "00000001";
+ data.qop = "auth";
+ data.digestUri = "imap/elwood.innosoft.com";
+ String response = DigestMd5Utils.getResponse(data, true);
+ assertEquals("ea40f60335c427b5527b84dbabcdfffd", response);
+ }
+
+}
diff --git a/tests/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelperTest.java b/tests/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelperTest.java
new file mode 100644
index 0000000..63c7f60
--- /dev/null
+++ b/tests/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelperTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.phone.vvm.omtp;
+
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_CARRIER_VVM_PACKAGE_NAME_STRING;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_DESTINATION_NUMBER_STRING;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_PORT_NUMBER_INT;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_PREFETCH_BOOL;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_SSL_PORT_NUMBER_INT;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_TYPE_STRING;
+
+import android.os.PersistableBundle;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class OmtpVvmCarrierConfigHelperTest extends TestCase {
+
+ private static final String CARRIER_TYPE = "omtp.carrier";
+ private static final String CARRIER_PACKAGE_NAME = "omtp.carrier.package";
+ private static final boolean CARRIER_CELLULAR_REQUIRED = false;
+ private static final boolean CARRIER_PREFETCH = true;
+ private static final String CARRIER_DESTINATION_NUMBER = "123";
+ private static final int CARRIER_APPLICATION_PORT = 456;
+ private static final int DEFAULT_SSL_PORT = 0;
+ private static final Set<String> DEFAULT_DISABLED_CAPABILITIES = null;
+
+ private static final String TELEPHONY_TYPE = "omtp.telephony";
+ private static final String[] TELEPHONY_PACKAGE_NAMES = {"omtp.telephony.package"};
+ private static final boolean TELEPHONY_CELLULAR_REQUIRED = true;
+ private static final boolean TELEPHONY_PREFETCH = false;
+ private static final String TELEPHONY_DESTINATION_NUMBER = "321";
+ private static final int TELEPHONY_APPLICATION_PORT = 654;
+ private static final int TELEPHONY_SSL_PORT = 997;
+ private static final String[] TELEPHONY_DISABLED_CAPABILITIES = {"foo"};
+
+ private OmtpVvmCarrierConfigHelper mHelper;
+
+ public void testCarrierConfig() {
+ mHelper = new OmtpVvmCarrierConfigHelper(createCarrierConfig(), null);
+ verifyCarrierConfig();
+ verifyDefaultExtraConfig();
+ }
+
+ public void testTelephonyConfig() {
+ mHelper = new OmtpVvmCarrierConfigHelper(null, createTelephonyConfig());
+ verifyTelephonyConfig();
+ verifyTelephonyExtraConfig();
+ }
+
+ public void testMixedConfig() {
+ mHelper = new OmtpVvmCarrierConfigHelper(createCarrierConfig(), createTelephonyConfig());
+ verifyCarrierConfig();
+ verifyTelephonyExtraConfig();
+ }
+
+ private PersistableBundle createCarrierConfig() {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(KEY_VVM_TYPE_STRING, CARRIER_TYPE);
+ bundle.putString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING,
+ CARRIER_PACKAGE_NAME);
+ bundle.putBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL,
+ CARRIER_CELLULAR_REQUIRED);
+ bundle.putBoolean(KEY_VVM_PREFETCH_BOOL,
+ CARRIER_PREFETCH);
+ bundle.putString(KEY_VVM_DESTINATION_NUMBER_STRING,
+ CARRIER_DESTINATION_NUMBER);
+ bundle.putInt(KEY_VVM_PORT_NUMBER_INT, CARRIER_APPLICATION_PORT);
+ return bundle;
+ }
+
+ private void verifyCarrierConfig() {
+ assertEquals(CARRIER_TYPE, mHelper.getVvmType());
+ assertEquals(new HashSet<>(Arrays.asList(CARRIER_PACKAGE_NAME)),
+ mHelper.getCarrierVvmPackageNames());
+ assertEquals(CARRIER_CELLULAR_REQUIRED, mHelper.isCellularDataRequired());
+ assertEquals(CARRIER_PREFETCH, mHelper.isPrefetchEnabled());
+ assertEquals(CARRIER_APPLICATION_PORT, mHelper.getApplicationPort());
+ assertEquals(CARRIER_DESTINATION_NUMBER, mHelper.getDestinationNumber());
+ }
+
+
+ private void verifyDefaultExtraConfig() {
+ assertEquals(DEFAULT_SSL_PORT, mHelper.getSslPort());
+ assertEquals(DEFAULT_DISABLED_CAPABILITIES, mHelper.getDisabledCapabilities());
+ }
+
+
+ private PersistableBundle createTelephonyConfig() {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(KEY_VVM_TYPE_STRING, TELEPHONY_TYPE);
+ bundle.putStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY,
+ TELEPHONY_PACKAGE_NAMES);
+ bundle.putBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL,
+ TELEPHONY_CELLULAR_REQUIRED);
+ bundle.putBoolean(KEY_VVM_PREFETCH_BOOL,
+ TELEPHONY_PREFETCH);
+ bundle.putString(KEY_VVM_DESTINATION_NUMBER_STRING,
+ TELEPHONY_DESTINATION_NUMBER);
+ bundle.putInt(KEY_VVM_PORT_NUMBER_INT, TELEPHONY_APPLICATION_PORT);
+ bundle.putInt(KEY_VVM_SSL_PORT_NUMBER_INT, TELEPHONY_SSL_PORT);
+ bundle.putStringArray(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY,
+ TELEPHONY_DISABLED_CAPABILITIES);
+ return bundle;
+ }
+
+ private void verifyTelephonyConfig() {
+ assertEquals(TELEPHONY_TYPE, mHelper.getVvmType());
+ assertEquals(new HashSet<>(Arrays.asList(TELEPHONY_PACKAGE_NAMES)),
+ mHelper.getCarrierVvmPackageNames());
+ assertEquals(TELEPHONY_CELLULAR_REQUIRED, mHelper.isCellularDataRequired());
+ assertEquals(TELEPHONY_PREFETCH, mHelper.isPrefetchEnabled());
+ assertEquals(TELEPHONY_APPLICATION_PORT, mHelper.getApplicationPort());
+ assertEquals(TELEPHONY_DESTINATION_NUMBER, mHelper.getDestinationNumber());
+ }
+
+ private void verifyTelephonyExtraConfig() {
+ assertEquals(TELEPHONY_SSL_PORT, mHelper.getSslPort());
+ assertEquals(new HashSet<>(Arrays.asList(TELEPHONY_DISABLED_CAPABILITIES)),
+ mHelper.getDisabledCapabilities());
+ }
+}
diff --git a/tests/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManagerTest.java b/tests/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManagerTest.java
new file mode 100644
index 0000000..8e7a0da
--- /dev/null
+++ b/tests/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManagerTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.phone.vvm.omtp;
+
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_DESTINATION_NUMBER_STRING;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_PORT_NUMBER_INT;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_PREFETCH_BOOL;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_SSL_PORT_NUMBER_INT;
+import static com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper.KEY_VVM_TYPE_STRING;
+
+import android.os.PersistableBundle;
+
+import junit.framework.TestCase;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.StringReader;
+import java.util.Arrays;
+
+public class TelephonyVvmConfigManagerTest extends TestCase {
+
+ private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<list name=\"carrier_config_list\">\n";
+ private static final String XML_FOOTER = "</list>";
+
+ private static final String CARRIER = " <pbundle_as_map>\n"
+ + " <string-array name=\"mccmnc\">\n"
+ + " <item value=\"12345\"/>\n"
+ + " <item value=\"67890\"/>\n"
+ + " </string-array>\n"
+ + " <int name=\"vvm_port_number_int\" value=\"54321\"/>\n"
+ + " <string name=\"vvm_destination_number_string\">11111</string>\n"
+ + " <string-array name=\"carrier_vvm_package_name_string_array\">\n"
+ + " <item value=\"com.android.phone\"/>\n"
+ + " </string-array>\n"
+ + " <string name=\"vvm_type_string\">vvm_type_omtp</string>\n"
+ + " <boolean name=\"vvm_cellular_data_required\" value=\"true\"/>\n"
+ + " <boolean name=\"vvm_prefetch\" value=\"true\"/>\n"
+ + " <int name=\"vvm_ssl_port_number_int\" value=\"997\"/>\n"
+ + " <string-array name=\"vvm_disabled_capabilities_string_array\">\n"
+ + " <item value =\"foo\"/>\n"
+ + " <item value =\"bar\"/>\n"
+ + " </string-array>\n"
+ + " </pbundle_as_map>\n";
+
+ private static final String CARRIER_EMPTY = "<pbundle_as_map></pbundle_as_map>\n";
+
+
+ public void testLoadConfigFromXml() {
+ TelephonyVvmConfigManager manager = createManager(XML_HEADER + CARRIER + XML_FOOTER);
+ verifyCarrier(manager.getConfig("12345"));
+ verifyCarrier(manager.getConfig("67890"));
+ }
+
+ public void testLoadConfigFromXml_Multiple() {
+ TelephonyVvmConfigManager manager =
+ createManager(XML_HEADER + CARRIER + CARRIER + XML_FOOTER);
+ verifyCarrier(manager.getConfig("12345"));
+ verifyCarrier(manager.getConfig("67890"));
+ }
+
+ public void testLoadConfigFromXml_Empty() {
+ createManager(XML_HEADER + CARRIER_EMPTY + XML_FOOTER);
+ }
+
+
+ private void verifyCarrier(PersistableBundle config) {
+ assertTrue(Arrays.equals(new String[]{"12345", "67890"},
+ config.getStringArray(TelephonyVvmConfigManager.KEY_MCCMNC)));
+ assertEquals(54321, config.getInt(KEY_VVM_PORT_NUMBER_INT));
+ assertEquals("11111", config.getString(KEY_VVM_DESTINATION_NUMBER_STRING));
+ assertTrue(Arrays.equals(new String[]{"com.android.phone"},
+ config.getStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY)));
+ assertEquals("vvm_type_omtp", config.getString(KEY_VVM_TYPE_STRING));
+ assertEquals(true, config.getBoolean(KEY_VVM_PREFETCH_BOOL));
+ assertEquals(true, config.getBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL));
+ assertEquals(997, config.getInt(KEY_VVM_SSL_PORT_NUMBER_INT));
+ assertTrue(Arrays.equals(new String[]{"foo", "bar"},
+ config.getStringArray(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY)));
+ }
+
+ private TelephonyVvmConfigManager createManager(String xml) {
+ try {
+ XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
+ parser.setInput(new StringReader(xml));
+ return new TelephonyVvmConfigManager(parser);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}