Merge "Add set/get call composer status methods in PhoneInterfaceMangaer"
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 3d397d0..4945012 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -614,7 +614,7 @@
     <string name="ota_skip_activation_dialog_title" msgid="7666611236789203797">"לדלג על ההפעלה?"</string>
     <string name="ota_skip_activation_dialog_message" msgid="6691722887019708713">"‏אם מדלגים על ההפעלה, אי אפשר להתקשר או להתחבר לרשתות נתונים לנייד (אך אפשר להתחבר לרשתות Wi-Fi). עד להפעלת הטלפון תופיע הודעה שמבקשת לבצע את ההפעלה בכל פעם שמדליקים את הטלפון."</string>
     <string name="ota_skip_activation_dialog_skip_label" msgid="5908029466817825633">"דילוג"</string>
-    <string name="ota_activate" msgid="7939695753665438357">"הפעל"</string>
+    <string name="ota_activate" msgid="7939695753665438357">"הפעלה"</string>
     <string name="ota_title_activate_success" msgid="1272135024761004889">"הטלפון מופעל."</string>
     <string name="ota_title_problem_with_activation" msgid="7019745985413368726">"בעיה בהפעלה"</string>
     <string name="ota_listen" msgid="2772252405488894280">"בצע את ההוראות הנאמרות עד שתשמע שההפעלה הושלמה."</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 1aa482d..c287440 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -167,7 +167,7 @@
     <string name="vm_change_pin_progress_message" msgid="626015184502739044">"براہ کرم انتظار کریں۔"</string>
     <string name="vm_change_pin_error_too_short" msgid="1789139338449945483">"‏نیا PIN بہت ہی مختصر ہے۔"</string>
     <string name="vm_change_pin_error_too_long" msgid="3634907034310018954">"‏نیا PIN بہت ہی طویل ہے۔"</string>
-    <string name="vm_change_pin_error_too_weak" msgid="8581892952627885719">"‏نیا PIN بہت ہی کمزور ہے۔ مضبوط پاسورڈ میں مسلسل ترتیب یا دہرے عدد نہیں ہونے چاہئیں۔"</string>
+    <string name="vm_change_pin_error_too_weak" msgid="8581892952627885719">"‏نیا PIN بہت ہی کمزور ہے۔ مضبوط پاس ورڈ میں مسلسل ترتیب یا دہرے عدد نہیں ہونے چاہئیں۔"</string>
     <string name="vm_change_pin_error_mismatch" msgid="5364847280026257331">"‏پرانا PIN مماثل نہیں ہے۔"</string>
     <string name="vm_change_pin_error_invalid" msgid="5230002671175580674">"‏نئے PIN میں غلط کریکٹرز شامل ہیں۔"</string>
     <string name="vm_change_pin_error_system_error" msgid="9116483527909681791">"‏PIN تبدیل کرنے سے قاصر"</string>
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 1002127..a831e94 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -9704,4 +9704,19 @@
         enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
         return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
     }
+
+    /**
+     * Get the mobile provisioning url that is used to launch a browser to allow users to manage
+     * their mobile plan.
+     */
+    @Override
+    public String getMobileProvisioningUrl() {
+        enforceReadPrivilegedPermission("getMobileProvisioningUrl");
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return getDefaultPhone().getMobileProvisioningUrl();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }
diff --git a/src/com/android/phone/RcsProvisioningMonitor.java b/src/com/android/phone/RcsProvisioningMonitor.java
index 8e4d35e..98003bd 100644
--- a/src/com/android/phone/RcsProvisioningMonitor.java
+++ b/src/com/android/phone/RcsProvisioningMonitor.java
@@ -333,6 +333,7 @@
             mConfigs.forEach((k, v) -> {
                 if (isAcsUsed(k)) {
                     logv("acs used, trigger to re-configure.");
+                    mConfigs.put(k, null);
                     notifyRcsAutoConfigurationRemoved(k);
                     triggerRcsReconfiguration(k);
                 } else {
@@ -345,6 +346,11 @@
 
     private void notifyRcsAutoConfigurationReceived(int subId, byte[] config,
             boolean isCompressed) {
+        if (config == null) {
+            logd("Rcs config is null for sub : " + subId);
+            return;
+        }
+
         IImsConfig imsConfig = getIImsConfig(subId, ImsFeature.FEATURE_RCS);
         if (imsConfig != null) {
             try {
@@ -358,6 +364,7 @@
     }
 
     private void notifyRcsAutoConfigurationRemoved(int subId) {
+        RcsConfig.updateConfigForSub(mPhone, subId, null, true);
         IImsConfig imsConfig = getIImsConfig(subId, ImsFeature.FEATURE_RCS);
         if (imsConfig != null) {
             try {
@@ -461,8 +468,7 @@
 
     private void onReconfigRequest(int subId) {
         logv("onReconfigRequest, subId:" + subId);
-        mConfigs.remove(subId);
-        RcsConfig.updateConfigForSub(mPhone, subId, null, true);
+        mConfigs.put(subId, null);
         notifyRcsAutoConfigurationRemoved(subId);
         triggerRcsReconfiguration(subId);
     }
diff --git a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
index 7ef9768..5035284 100644
--- a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
+++ b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -156,6 +157,7 @@
 
     private class SimInfoContentProvider extends MockContentProvider {
         private Cursor mCursor;
+        private ContentValues mValues;
 
         SimInfoContentProvider(Context context) {
             super(context);
@@ -174,8 +176,13 @@
         @Override
         public int update(Uri uri, ContentValues values,
                 String selection, String[] selectionArgs) {
+            mValues = values;
             return 1;
         }
+
+        ContentValues getContentValues() {
+            return mValues;
+        }
     }
 
     @Before
@@ -272,7 +279,7 @@
 
     @Test
     @SmallTest
-    public void testInit() throws Exception {
+    public void testInitWithSavedConfig() throws Exception {
         createMonitor(3);
         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
         for (int i = 0; i < 3; i++) {
@@ -291,6 +298,21 @@
 
     @Test
     @SmallTest
+    public void testInitWithoutSavedConfig() throws Exception {
+        when(mCursor.getBlob(anyInt())).thenReturn(null);
+        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
+        createMonitor(3);
+
+        verify(mPhone, times(3)).sendBroadcast(captorIntent.capture());
+        Intent capturedIntent = captorIntent.getAllValues().get(1);
+        assertEquals(ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE,
+                capturedIntent.getAction());
+        //Should not notify null config
+        verify(mIImsConfig, never()).notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
     public void testSubInfoChanged() throws Exception {
         createMonitor(3);
         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
@@ -318,17 +340,37 @@
 
     @Test
     @SmallTest
-    public void testDefaultMessagingApplicationChanged() throws Exception {
+    public void testDefaultMessagingApplicationChangedWithAcs() throws Exception {
+        createMonitor(1);
+        updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
+        processAllMessages();
+        byte[] configCached = mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE);
+
+        assertNull(configCached);
+        assertNull(mProvider.getContentValues().get(SimInfo.COLUMN_RCS_CONFIG));
+        verify(mIImsConfig, atLeastOnce()).notifyRcsAutoConfigurationRemoved();
+        verify(mIImsConfig, atLeastOnce()).triggerRcsReconfiguration();
+        // The api should only be called when monitor is initilized.
+        verify(mIImsConfig, times(1))
+                .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
+    public void testDefaultMessagingApplicationChangedWithoutAcs() throws Exception {
         createMonitor(1);
         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
         mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, false);
         processAllMessages();
-        verify(mIImsConfig, atLeastOnce())
+        byte[] configCached = mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE);
+
+        assertTrue(Arrays.equals(SAMPLE_CONFIG.getBytes(), configCached));
+        verify(mIImsConfig, never()).notifyRcsAutoConfigurationRemoved();
+        // The api should be called 2 times, one happens when monitor is initilized,
+        // Another happens when DMS is changed.
+        verify(mIImsConfig, times(2))
                 .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
-        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
-        updateDefaultMessageApplication(DEFAULT_MESSAGING_APP1);
-        processAllMessages();
-        verify(mIImsConfig, atLeastOnce()).triggerRcsReconfiguration();
     }
 
     @Test
@@ -452,7 +494,6 @@
         } catch (Exception e) {
             logd("Unable to create looper from handler.");
         }
-        processAllMessages();
     }
 
     private void broadcastCarrierConfigChange(int subId) {
@@ -494,7 +535,6 @@
         ((Map<String, IBinder>) field.get(null)).put(serviceName, binder);
     }
 
-
     private void processAllMessages() {
         while (!mLooper.getLooper().getQueue().isIdle()) {
             mLooper.processAllMessages();
diff --git a/tests/src/com/android/services/telephony/TelephonyManagerTest.java b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
index e9cdc98..2202bc7 100644
--- a/tests/src/com/android/services/telephony/TelephonyManagerTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
@@ -100,6 +100,44 @@
     }
 
     @Test
+    public void testFilterEmergencyNumbersByCategories() throws Exception {
+        Map<Integer, List<EmergencyNumber>> emergencyNumberLists = new HashMap<>();
+        List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
+        EmergencyNumber number_police = new EmergencyNumber(
+                "911",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        EmergencyNumber number_fire = new EmergencyNumber(
+                "912",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        emergencyNumberList.add(number_police);
+        emergencyNumberList.add(number_fire);
+        final int test_sub_id = 1;
+        emergencyNumberLists.put(test_sub_id, emergencyNumberList);
+
+        Map<Integer, List<EmergencyNumber>> returnedEmergencyNumberLists =
+                mTelephonyManager.filterEmergencyNumbersByCategories(emergencyNumberLists,
+                        EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
+
+        // Verify the returned number list contains only the police number(s)
+        List<EmergencyNumber> returnedEmergencyNumberList = returnedEmergencyNumberLists.get(
+                test_sub_id);
+        for (EmergencyNumber num : returnedEmergencyNumberList) {
+            assertTrue(num.isInEmergencyServiceCategories(
+                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
+        }
+    }
+
+    @Test
     public void testGetEmergencyNumberListForCategories() throws Exception {
         Map<Integer, List<EmergencyNumber>> emergencyNumberLists = new HashMap<>();
         List<EmergencyNumber> emergencyNumberList = new ArrayList<>();