Merge "Crash occurs when entering a Bluetooth broadcast password" into main
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index 152446c..191c86d 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -33,7 +33,9 @@
         android:icon="@drawable/ic_nfc"
         android:order="-7"
         settings:searchable="false"
-        settings:controller="com.android.settings.connecteddevice.NfcAndPaymentFragmentController"/>
+        settings:controller="com.android.settings.connecteddevice.NfcAndPaymentFragmentController"
+        settings:userRestriction="no_near_field_communication_radio"
+        settings:useAdminDisabledSummary="true"/>
 
     <Preference
         android:fragment="com.android.settings.wfd.WifiDisplaySettings"
diff --git a/src/com/android/settings/network/apn/ApnEditor.java b/src/com/android/settings/network/apn/ApnEditor.java
index 25d8e84..a66a33f 100644
--- a/src/com/android/settings/network/apn/ApnEditor.java
+++ b/src/com/android/settings/network/apn/ApnEditor.java
@@ -429,15 +429,20 @@
             return false;
         }
 
-        if (hasAllApns(apnTypesArray1) || TextUtils.isEmpty(apnTypes2)) {
+        final String[] apnTypesArray1LowerCase = new String[apnTypesArray1.length];
+        for (int i = 0; i < apnTypesArray1.length; i++) {
+            apnTypesArray1LowerCase[i] = apnTypesArray1[i].toLowerCase();
+        }
+
+        if (hasAllApns(apnTypesArray1LowerCase) || TextUtils.isEmpty(apnTypes2)) {
             return true;
         }
 
-        final List apnTypesList1 = Arrays.asList(apnTypesArray1);
+        final List apnTypesList1 = Arrays.asList(apnTypesArray1LowerCase);
         final String[] apnTypesArray2 = apnTypes2.split(",");
 
         for (String apn : apnTypesArray2) {
-            if (apnTypesList1.contains(apn.trim())) {
+            if (apnTypesList1.contains(apn.trim().toLowerCase())) {
                 Log.d(TAG, "apnTypesMatch: true because match found for " + apn.trim());
                 return true;
             }
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index c0342d1..e1e7047 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -889,7 +889,6 @@
 
         private LockscreenCredential mChosenPattern;
         private LockscreenCredential mCurrentCredential;
-        private boolean mLockVirgin;
 
         public void start(LockPatternUtils utils, boolean credentialRequired,
                 boolean requestGatekeeperPassword, LockscreenCredential chosenPattern,
@@ -901,8 +900,6 @@
             mChosenPattern = chosenPattern;
             mUserId = userId;
 
-            mLockVirgin = !mUtils.isPatternEverChosen(mUserId);
-
             start();
         }
 
@@ -933,14 +930,5 @@
             }
             return Pair.create(success, result);
         }
-
-        @Override
-        protected void finish(Intent resultData) {
-            if (mLockVirgin) {
-                mUtils.setVisiblePatternEnabled(true, mUserId);
-            }
-
-            super.finish(resultData);
-        }
     }
 }
diff --git a/src/com/android/settings/remoteauth/OWNERS b/src/com/android/settings/remoteauth/OWNERS
new file mode 100644
index 0000000..64e7f5c
--- /dev/null
+++ b/src/com/android/settings/remoteauth/OWNERS
@@ -0,0 +1,5 @@
+# People who can approve changes for submission
+dlm@google.com
+jasonsun@google.com
+derekjedral@google.com
+justinmcclain@google.com
diff --git a/src/com/android/settings/security/ShowPasswordPreferenceController.java b/src/com/android/settings/security/ShowPasswordPreferenceController.java
index 696854a..a6e4db6 100644
--- a/src/com/android/settings/security/ShowPasswordPreferenceController.java
+++ b/src/com/android/settings/security/ShowPasswordPreferenceController.java
@@ -17,25 +17,17 @@
 package com.android.settings.security;
 
 import android.content.Context;
-import android.os.UserHandle;
 import android.provider.Settings;
 
-import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
-import com.android.settings.overlay.FeatureFactory;
 
 public class ShowPasswordPreferenceController extends TogglePreferenceController {
 
     private static final String KEY_SHOW_PASSWORD = "show_password";
-    private static final int MY_USER_ID = UserHandle.myUserId();
-    private final LockPatternUtils mLockPatternUtils;
 
     public ShowPasswordPreferenceController(Context context) {
         super(context, KEY_SHOW_PASSWORD);
-        mLockPatternUtils = FeatureFactory.getFactory(context)
-                .getSecurityFeatureProvider()
-                .getLockPatternUtils(context);
     }
 
     @Override
@@ -48,7 +40,6 @@
     public boolean setChecked(boolean isChecked) {
         Settings.System.putInt(mContext.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
                 isChecked ? 1 : 0);
-        mLockPatternUtils.setVisiblePasswordEnabled(isChecked, MY_USER_ID);
         return true;
     }
 
diff --git a/src/com/android/settings/security/screenlock/PinPrivacyPreferenceController.kt b/src/com/android/settings/security/screenlock/PinPrivacyPreferenceController.kt
index 176183e..78656e8 100644
--- a/src/com/android/settings/security/screenlock/PinPrivacyPreferenceController.kt
+++ b/src/com/android/settings/security/screenlock/PinPrivacyPreferenceController.kt
@@ -45,7 +45,7 @@
         return PREF_KEY
     }
 
-    override fun onPreferenceChange(preference: Preference?, value: Any?): Boolean {
+    override fun onPreferenceChange(preference: Preference, value: Any): Boolean {
         lockPatternUtils.setPinEnhancedPrivacyEnabled((value as Boolean), userId)
         return true
     }
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index d2daa00..b8db351 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -223,7 +223,7 @@
     private final WifiManager mWifiManager;
     private boolean mIsTrustOnFirstUseSupported;
 
-    private final List<SubscriptionInfo> mActiveSubscriptionInfos = new ArrayList<>();
+    private final ArrayMap<Integer, SubscriptionInfo> mActiveSubscriptionInfos = new ArrayMap<>();
 
     public WifiConfigController2(WifiConfigUiBase2 parent, View view, WifiEntry wifiEntry,
             int mode) {
@@ -703,7 +703,7 @@
                 if (config.enterpriseConfig.isAuthenticationSimBased()
                         && mActiveSubscriptionInfos.size() > 0) {
                     config.carrierId = mActiveSubscriptionInfos
-                            .get(mEapSimSpinner.getSelectedItemPosition()).getCarrierId();
+                            .valueAt(mEapSimSpinner.getSelectedItemPosition()).getCarrierId();
                 }
 
                 String caCert = (String) mEapCaCertSpinner.getSelectedItem();
@@ -1114,11 +1114,9 @@
             }
 
             if (enterpriseConfig.isAuthenticationSimBased()) {
-                for (int i = 0; i < mActiveSubscriptionInfos.size(); i++) {
-                    if (wifiConfig.carrierId == mActiveSubscriptionInfos.get(i).getCarrierId()) {
-                        mEapSimSpinner.setSelection(i);
-                        break;
-                    }
+                int index = mActiveSubscriptionInfos.indexOfKey(wifiConfig.carrierId);
+                if (index > -1) {
+                    mEapSimSpinner.setSelection(index);
                 }
             }
 
@@ -1476,18 +1474,8 @@
         }
         mActiveSubscriptionInfos.clear();
 
-        // De-duplicates active subscriptions and caches in mActiveSubscriptionInfos.
-        for (SubscriptionInfo newInfo : activeSubscriptionInfos) {
-            for (SubscriptionInfo cachedInfo : mActiveSubscriptionInfos) {
-                if (newInfo.getCarrierId() == cachedInfo.getCarrierId()) {
-                    continue;
-                }
-            }
-            mActiveSubscriptionInfos.add(newInfo);
-        }
-
         // Shows disabled 'No SIM' when there is no active subscription.
-        if (mActiveSubscriptionInfos.size() == 0) {
+        if (activeSubscriptionInfos.isEmpty()) {
             final String[] noSim = new String[]{mContext.getString(R.string.wifi_no_sim_card)};
             mEapSimSpinner.setAdapter(getSpinnerAdapter(noSim));
             mEapSimSpinner.setSelection(0 /* position */);
@@ -1498,7 +1486,7 @@
         // Shows display name of each active subscription.
         ArrayMap<Integer, CharSequence> displayNames = new ArrayMap<>();
         int defaultDataSubscriptionId = SubscriptionManager.getDefaultDataSubscriptionId();
-        for (SubscriptionInfo activeSubInfo : mActiveSubscriptionInfos) {
+        for (SubscriptionInfo activeSubInfo : activeSubscriptionInfos) {
             // If multiple SIMs have the same carrier id, only the first or default data SIM is
             // displayed.
             if (displayNames.containsKey(activeSubInfo.getCarrierId())
@@ -1507,6 +1495,7 @@
             }
             displayNames.put(activeSubInfo.getCarrierId(),
                     SubscriptionUtil.getUniqueSubscriptionDisplayName(activeSubInfo, mContext));
+            mActiveSubscriptionInfos.put(activeSubInfo.getCarrierId(), activeSubInfo);
         }
         mEapSimSpinner.setAdapter(
                 getSpinnerAdapter(displayNames.values().toArray(new String[displayNames.size()])));
diff --git a/tests/robotests/src/com/android/settings/remoteauth/OWNERS b/tests/robotests/src/com/android/settings/remoteauth/OWNERS
new file mode 100644
index 0000000..ed486d7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/remoteauth/OWNERS
@@ -0,0 +1 @@
+include /src/com/android/settings/remoteauth/OWNERS
diff --git a/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java
index 5e3c27a..206dee1 100644
--- a/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/ShowPasswordPreferenceControllerTest.java
@@ -18,20 +18,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.os.UserHandle;
 import android.provider.Settings;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.testutils.FakeFeatureFactory;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -45,11 +40,8 @@
 public class ShowPasswordPreferenceControllerTest {
 
     @Mock
-    private LockPatternUtils mLockPatternUtils;
-    @Mock
     private PreferenceScreen mScreen;
 
-    private FakeFeatureFactory mFeatureFactory;
     private Context mContext;
     private ShowPasswordPreferenceController mController;
     private Preference mPreference;
@@ -58,9 +50,6 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
-        when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
-                .thenReturn(mLockPatternUtils);
         mController = new ShowPasswordPreferenceController(mContext);
         mPreference = new Preference(mContext);
         mPreference.setKey(mController.getPreferenceKey());
@@ -98,7 +87,6 @@
         mController.onPreferenceChange(mPreference, true);
 
         assertThat(mController.isChecked()).isTrue();
-        verify(mLockPatternUtils).setVisiblePasswordEnabled(true, UserHandle.myUserId());
     }
 
     @Test
@@ -106,6 +94,5 @@
         mController.onPreferenceChange(mPreference, false);
 
         assertThat(mController.isChecked()).isFalse();
-        verify(mLockPatternUtils).setVisiblePasswordEnabled(false, UserHandle.myUserId());
     }
 }