Merge "PhoneInterfaceManager: Pass a non-null txTimeMs argument to ModemActivityInfo ctor."
diff --git a/ecc/conversion_toolset_v1/proto/Android.bp b/ecc/conversion_toolset_v1/proto/Android.bp
index f633f90..e1e0643 100644
--- a/ecc/conversion_toolset_v1/proto/Android.bp
+++ b/ecc/conversion_toolset_v1/proto/Android.bp
@@ -22,7 +22,7 @@
         ],
     },
     srcs: ["protobuf_ecc_data.proto"],
-    sdk_version: "core_platform",
+    sdk_version: "system_current",
     jarjar_rules: "jarjar-rules.txt",
     java_version: "1.8",
-}
\ No newline at end of file
+}
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 2f6b920..1805e6b 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -183,8 +183,8 @@
     <string name="preferred_network_mode_dialogtitle" msgid="2781447433514459696">"Jenis jaringan yang dipilih"</string>
     <string name="forbidden_network" msgid="5081729819561333023">"(terlarang)"</string>
     <string name="choose_network_title" msgid="5335832663422653082">"Pilih jaringan"</string>
-    <string name="network_disconnected" msgid="8844141106841160825">"Tidak tersambung"</string>
-    <string name="network_connected" msgid="2760235679963580224">"Tersambung"</string>
+    <string name="network_disconnected" msgid="8844141106841160825">"Terputus"</string>
+    <string name="network_connected" msgid="2760235679963580224">"Terhubung"</string>
     <string name="network_connecting" msgid="160901383582774987">"Menyambungkan..."</string>
     <string name="network_could_not_connect" msgid="6547460848093727998">"Tidak dapat tersambung"</string>
   <string-array name="preferred_network_mode_choices">
@@ -823,7 +823,7 @@
     <string name="radioInfo_phone_idle" msgid="2191653783170757819">"Tidak ada aktivitas"</string>
     <string name="radioInfo_phone_ringing" msgid="8100354169567413370">"Berdering"</string>
     <string name="radioInfo_phone_offhook" msgid="7564601639749936170">"Panggilan sedang Berlangsung"</string>
-    <string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Sambungan terputus"</string>
+    <string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Terputus"</string>
     <string name="radioInfo_data_connecting" msgid="925092271092152472">"Menghubungkan"</string>
     <string name="radioInfo_data_connected" msgid="7637335645634239508">"Terhubung"</string>
     <string name="radioInfo_data_suspended" msgid="8695262782642002785">"Ditangguhkan"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 697919b..c9aa805 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -274,7 +274,7 @@
     <string name="data_usage_disable_mobile" msgid="5669109209055988308">"Mobil internet uzilsinmi?"</string>
     <string name="sim_selection_required_pref" msgid="6985901872978341314">"SIM kartani tanlang"</string>
     <string name="sim_change_data_title" msgid="9142726786345906606">"SIM karta o‘zgartirilsinmi?"</string>
-    <string name="sim_change_data_message" msgid="3567358694255933280">"Mobil internet uchun <xliff:g id="OLD_SIM">%2$s</xliff:g> o‘rniga <xliff:g id="NEW_SIM">%1$s</xliff:g> SIM kartasidan foydalanilsinmi?"</string>
+    <string name="sim_change_data_message" msgid="3567358694255933280">"Mobil internet uchun <xliff:g id="OLD_SIM">%2$s</xliff:g> emas, <xliff:g id="NEW_SIM">%1$s</xliff:g> ishlatilsinmi?"</string>
     <string name="wifi_calling_settings_title" msgid="5800018845662016507">"Wi-Fi chaqiruv"</string>
     <string name="video_calling_settings_title" msgid="342829454913266078">"Operator tarmog‘i orqali video suhbatlar"</string>
     <string name="gsm_umts_options" msgid="4968446771519376808">"GSM/UMTS sozlamalari"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index fca8acf..8d84baf 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -15,6 +15,21 @@
 -->
 
 <resources>
+    <!-- Base attributes available to CheckBoxPreference. Copied from frameworks/base/core/res. -->
+    <declare-styleable name="CheckBoxPreference">
+        <!-- The summary for the Preference in a PreferenceActivity screen when the
+             CheckBoxPreference is checked. If separate on/off summaries are not
+             needed, the summary attribute can be used instead. -->
+        <attr name="android:summaryOn" />
+        <!-- The summary for the Preference in a PreferenceActivity screen when the
+             CheckBoxPreference is unchecked. If separate on/off summaries are not
+             needed, the summary attribute can be used instead. -->
+        <attr name="android:summaryOff" />
+        <!-- The state (true for on, or false for off) that causes dependents to be disabled. By default,
+             dependents will be disabled when this is unchecked, so the value of this preference is false. -->
+        <attr name="android:disableDependentsState" />
+    </declare-styleable>
+
     <declare-styleable name="EditPhoneNumberPreference">
         <!-- The enable button text. -->
         <attr name="enableButtonText" format="string" />
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 4bf4204..9841a82 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -55,7 +55,7 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SubscriptionInfoUpdater;
 import com.android.internal.telephony.TelephonyPermissions;
-import com.android.internal.util.ArrayUtils;
+import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
 
diff --git a/src/com/android/phone/EditPhoneNumberPreference.java b/src/com/android/phone/EditPhoneNumberPreference.java
index 74b8a45..35af20d 100644
--- a/src/com/android/phone/EditPhoneNumberPreference.java
+++ b/src/com/android/phone/EditPhoneNumberPreference.java
@@ -136,9 +136,9 @@
         a.recycle();
 
         //get the summary settings, use CheckBoxPreference as the standard.
-        a = context.obtainStyledAttributes(attrs, android.R.styleable.CheckBoxPreference, 0, 0);
-        mSummaryOn = a.getString(android.R.styleable.CheckBoxPreference_summaryOn);
-        mSummaryOff = a.getString(android.R.styleable.CheckBoxPreference_summaryOff);
+        a = context.obtainStyledAttributes(attrs, R.styleable.CheckBoxPreference, 0, 0);
+        mSummaryOn = a.getString(R.styleable.CheckBoxPreference_summaryOn);
+        mSummaryOff = a.getString(R.styleable.CheckBoxPreference_summaryOff);
         a.recycle();
     }
 
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 2ea0b66..8e88c7b 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2456,6 +2456,11 @@
         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
     }
 
+    private void enforceActiveEmergencySessionPermission() {
+        mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
+    }
+
     /**
      * Make sure the caller has the CALL_PHONE permission.
      *
@@ -7271,6 +7276,57 @@
     }
 
     @Override
+    public int getEmergencyNumberDbVersion(int subId) {
+        enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final Phone phone = getPhone(subId);
+            if (phone == null) {
+                loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
+                return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
+            }
+            return phone.getEmergencyNumberDbVersion();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void notifyOtaEmergencyNumberDbInstalled() {
+        enforceModifyPermission();
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            for (Phone phone: PhoneFactory.getPhones()) {
+                EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+                if (tracker != null) {
+                    tracker.updateOtaEmergencyNumberDatabase();
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void updateTestOtaEmergencyNumberDbFilePath(String otaFilePath) {
+        enforceActiveEmergencySessionPermission();
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            for (Phone phone: PhoneFactory.getPhones()) {
+                EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+                if (tracker != null) {
+                    tracker.updateTestOtaEmergencyNumberDbFilePath(otaFilePath);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
         Phone phone = getPhone(subId);
diff --git a/src/com/android/phone/ShortcutViewUtils.java b/src/com/android/phone/ShortcutViewUtils.java
index 47ca5ee..e3c5b64 100644
--- a/src/com/android/phone/ShortcutViewUtils.java
+++ b/src/com/android/phone/ShortcutViewUtils.java
@@ -33,7 +33,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.internal.util.ArrayUtils;
+import com.android.internal.telephony.util.ArrayUtils;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/tests/src/com/android/phone/CallFeaturesSettingTest.java b/tests/src/com/android/phone/CallFeaturesSettingTest.java
index 15d48ba..0666c56 100644
--- a/tests/src/com/android/phone/CallFeaturesSettingTest.java
+++ b/tests/src/com/android/phone/CallFeaturesSettingTest.java
@@ -24,10 +24,10 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.when;
 
+import android.app.KeyguardManager;
 import android.content.Context;
 
 import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
 import androidx.test.rule.ActivityTestRule;
 
 import com.android.internal.telephony.IccCard;
@@ -49,18 +49,18 @@
     IccCard mMockIccCard;
     @Rule
     public ActivityTestRule<CallFeaturesSetting> mRule =
-            new ActivityTestRule<>(CallFeaturesSetting.class);
+            new ActivityTestRule<>(CallFeaturesSetting.class, false, true);
     private CallFeaturesSetting mActivity;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Throwable {
         MockitoAnnotations.initMocks(this);
         mActivity = mRule.getActivity();
         Context targetContext = InstrumentationRegistry.getTargetContext();
         doReturn(targetContext).when(mMockPhone).getContext();
+        keepScreenOn(mRule, mActivity);
     }
 
-    @FlakyTest
     @Test
     public void onResume_fdnIsAvailable_shouldShowFdnMenu() throws NoSuchFieldException,
             IllegalAccessException {
@@ -69,13 +69,12 @@
         when(mMockIccCard.getIccFdnAvailable()).thenReturn(true);
         getField("mPhone").set(mActivity, mMockPhone);
 
-        mActivity.onResume();
+        mActivity.runOnUiThread(() -> mActivity.onResume());
 
         // Check the FDN menu is displayed.
         onView(withText(R.string.fdn)).check(matches(isDisplayed()));
     }
 
-    @FlakyTest
     @Test
     public void onResume_iccCardIsNull_shouldNotShowFdnMenu() throws NoSuchFieldException,
             IllegalAccessException {
@@ -83,13 +82,12 @@
         when(mMockPhone.getIccCard()).thenReturn(null);
         getField("mPhone").set(mActivity, mMockPhone);
 
-        mActivity.onResume();
+        mActivity.runOnUiThread(() -> mActivity.onResume());
 
         // Check the FDN menu is not displayed.
         onView(withText(R.string.fdn)).check(doesNotExist());
     }
 
-    @FlakyTest
     @Test
     public void onResume_fdnIsNotAvailable_shouldNotShowFdnMenu() throws NoSuchFieldException,
             IllegalAccessException {
@@ -98,7 +96,7 @@
         when(mMockIccCard.getIccFdnAvailable()).thenReturn(false);
         getField("mPhone").set(mActivity, mMockPhone);
 
-        mActivity.onResume();
+        mActivity.runOnUiThread(() -> mActivity.onResume());
 
         // Check the FDN menu is not displayed.
         onView(withText(R.string.fdn)).check(doesNotExist());
@@ -109,4 +107,19 @@
         field.setAccessible(true);
         return field;
     }
+
+    /**
+     * Automatically wake up device to perform tests.
+     */
+    private static void keepScreenOn(ActivityTestRule activityTestRule,
+            final CallFeaturesSetting activity) throws Throwable {
+        activityTestRule.runOnUiThread(() -> {
+            activity.setTurnScreenOn(true);
+            activity.setShowWhenLocked(true);
+            KeyguardManager keyguardManager =
+                    activity.getSystemService(KeyguardManager.class);
+            keyguardManager.requestDismissKeyguard(activity, null);
+        });
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
 }
diff --git a/tests/src/com/android/phone/LocationAccessPolicyTest.java b/tests/src/com/android/phone/LocationAccessPolicyTest.java
index 6939108..2061f38 100644
--- a/tests/src/com/android/phone/LocationAccessPolicyTest.java
+++ b/tests/src/com/android/phone/LocationAccessPolicyTest.java
@@ -188,10 +188,10 @@
                 anyInt(), anyInt())).thenReturn(s.appHasCoarseManifest
                 ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
 
-        when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_FINE_LOCATION),
+        when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OPSTR_FINE_LOCATION),
                 anyInt(), anyString(), nullable(String.class), nullable(String.class)))
                 .thenReturn(s.fineAppOp);
-        when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_COARSE_LOCATION),
+        when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OPSTR_COARSE_LOCATION),
                 anyInt(), anyString(), nullable(String.class), nullable(String.class)))
                 .thenReturn(s.coarseAppOp);
 
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index c00764b..bcc4fd3 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -283,6 +283,37 @@
 
     /**
      * Prerequisites:
+     * - MSIM Device, only slot 1 inserted and PUK locked
+     * - slot 1 has higher capabilities
+     *
+     * Result: getFirstPhoneForEmergencyCall returns the slot 1 phone because it is the only one
+     * with a SIM inserted (even if it is PUK locked)
+     */
+    @Test
+    @SmallTest
+    public void testSlot1PinLockedAndSlot0Absent() {
+        Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
+                false /*isEmergencyOnly*/);
+        Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
+                false /*isEmergencyOnly*/);
+        setDefaultPhone(slot0Phone);
+        setupDeviceConfig(slot0Phone, slot1Phone, SLOT_0_PHONE_ID);
+        setPhoneSlotState(SLOT_0_PHONE_ID, TelephonyManager.SIM_STATE_ABSENT);
+        setPhoneSlotState(SLOT_1_PHONE_ID, TelephonyManager.SIM_STATE_PIN_REQUIRED);
+        // Slot 1 has more capabilities
+        setPhoneRadioAccessFamily(slot0Phone, RadioAccessFamily.RAF_GSM);
+        setPhoneRadioAccessFamily(slot1Phone, RadioAccessFamily.RAF_LTE);
+        // Slot 1 has SIM inserted.
+        setSlotHasIccCard(SLOT_0_PHONE_ID, false /*isInserted*/);
+        setSlotHasIccCard(SLOT_1_PHONE_ID, true /*isInserted*/);
+
+        Phone resultPhone = mTestConnectionService.getFirstPhoneForEmergencyCall();
+
+        assertEquals(slot1Phone, resultPhone);
+    }
+
+    /**
+     * Prerequisites:
      * - MSIM Device, two slots with SIMs inserted
      * - Slot 1 is LTE capable, Slot 0 is GSM capable
      *