Merge "Fixed unicorn multi-enrollment flow." into tm-d1-dev
diff --git a/src/com/android/settings/display/ScreenResolutionFragment.java b/src/com/android/settings/display/ScreenResolutionFragment.java
index a827e92..bc82514 100644
--- a/src/com/android/settings/display/ScreenResolutionFragment.java
+++ b/src/com/android/settings/display/ScreenResolutionFragment.java
@@ -46,6 +46,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /** Preference fragment used for switch screen resolution */
 @SearchIndexable
@@ -61,7 +62,7 @@
     private String[] mScreenResolutionSummaries;
 
     private IllustrationPreference mImagePreference;
-    private DensityRestorer mDensityRestorer;
+    private DisplayObserver mDisplayObserver;
 
     @Override
     public void onAttach(Context context) {
@@ -76,7 +77,7 @@
                 mResources.getStringArray(R.array.config_screen_resolution_summaries_strings);
         mResolutions = getAllSupportedResolution();
         mImagePreference = new IllustrationPreference(context);
-        mDensityRestorer = new DensityRestorer(context);
+        mDisplayObserver = new DisplayObserver(context);
     }
 
     @Override
@@ -155,11 +156,7 @@
     /** Using display manager to set the display mode. */
     @VisibleForTesting
     public void setDisplayMode(final int width) {
-        if (width == getDisplayMode().getPhysicalWidth()) {
-            return;
-        }
-
-        mDensityRestorer.startObserve();
+        mDisplayObserver.startObserve();
         mDefaultDisplay.setUserPreferredDisplayMode(getPreferMode(width));
     }
 
@@ -171,6 +168,13 @@
                 : width == QHD_WIDTH ? mScreenResolutionOptions[QHD_INDEX] : null;
     }
 
+    /** Get the width corresponding to the resolution key. */
+    int getWidthForResoluitonKey(String key) {
+        return mScreenResolutionOptions[FHD_INDEX].equals(key)
+                ? FHD_WIDTH
+                : mScreenResolutionOptions[QHD_INDEX].equals(key) ? QHD_WIDTH : -1;
+    }
+
     @Override
     protected String getDefaultKey() {
         int physicalWidth = getDisplayMode().getPhysicalWidth();
@@ -180,17 +184,28 @@
 
     @Override
     protected boolean setDefaultKey(final String key) {
-        if (mScreenResolutionOptions[FHD_INDEX].equals(key)) {
-            setDisplayMode(FHD_WIDTH);
-
-        } else if (mScreenResolutionOptions[QHD_INDEX].equals(key)) {
-            setDisplayMode(QHD_WIDTH);
+        int width = getWidthForResoluitonKey(key);
+        if (width < 0) {
+          return false;
         }
 
+        setDisplayMode(width);
         updateIllustrationImage(mImagePreference);
+
         return true;
     }
 
+    @Override
+    public void onRadioButtonClicked(SelectorWithWidgetPreference selected) {
+        String selectedKey = selected.getKey();
+        int selectedWidth = getWidthForResoluitonKey(selectedKey);
+        if (!mDisplayObserver.setPendingResolutionChange(selectedWidth)) {
+          return;
+        }
+
+        super.onRadioButtonClicked(selected);
+    }
+
     /** Update the resolution image according display mode. */
     private void updateIllustrationImage(IllustrationPreference preference) {
         String key = getDefaultKey();
@@ -252,12 +267,13 @@
                 }
             };
 
-    private static final class DensityRestorer implements DisplayManager.DisplayListener {
+    private static final class DisplayObserver implements DisplayManager.DisplayListener {
         private final @Nullable Context mContext;
         private int mDefaultDensity;
         private int mCurrentIndex;
+        private AtomicInteger mPreviousWidth = new AtomicInteger(-1);
 
-        DensityRestorer(Context context) {
+        DisplayObserver(Context context) {
             mContext = context;
         }
 
@@ -301,26 +317,59 @@
                 return;
             }
 
+            if (!isDensityChanged() || !isResolutionChangeApplied()) {
+              return;
+            }
+
             restoreDensity();
+            stopObserve();
         }
 
         private void restoreDensity() {
-            if (mContext == null) {
-                return;
-            }
-
             final DisplayDensityUtils density = new DisplayDensityUtils(mContext);
-            if (density.getDefaultDensity() == mDefaultDensity) {
-                return;
-            }
-
             if (density.getValues()[mCurrentIndex] != density.getDefaultDensity()) {
                 DisplayDensityUtils.setForcedDisplayDensity(
                         Display.DEFAULT_DISPLAY, density.getValues()[mCurrentIndex]);
             }
 
             mDefaultDensity = density.getDefaultDensity();
-            stopObserve();
+        }
+
+        private boolean isDensityChanged() {
+            final DisplayDensityUtils density = new DisplayDensityUtils(mContext);
+            if (density.getDefaultDensity() == mDefaultDensity) {
+                return false;
+            }
+
+            return true;
+        }
+
+        private int getCurrentWidth() {
+            final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
+            return dm.getDisplay(Display.DEFAULT_DISPLAY).getMode().getPhysicalWidth();
+        }
+
+        private boolean setPendingResolutionChange(int selectedWidth) {
+            int currentWidth = getCurrentWidth();
+
+            if (selectedWidth == currentWidth) {
+              return false;
+            }
+            if (mPreviousWidth.get() != -1 && !isResolutionChangeApplied()) {
+              return false;
+            }
+
+            mPreviousWidth.set(currentWidth);
+
+            return true;
+        }
+
+        private boolean isResolutionChangeApplied() {
+            if (mPreviousWidth.get() == getCurrentWidth()) {
+              return false;
+            }
+
+            return true;
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java
index cbd4390..2d5a0e9 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java
@@ -46,8 +46,10 @@
 import androidx.slice.widget.SliceLiveData;
 
 import com.android.settings.R;
+import com.android.settings.bluetooth.Utils;
 import com.android.settings.testutils.SliceTester;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowCachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 import org.junit.After;
@@ -67,7 +69,7 @@
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowBluetoothAdapter.class)
+@Config(shadows = {ShadowBluetoothAdapter.class, ShadowCachedBluetoothDeviceManager.class})
 public class BluetoothDevicesSliceTest {
 
     private static final String BLUETOOTH_MOCK_ADDRESS = "00:11:00:11:00:11";
@@ -111,6 +113,9 @@
             mShadowBluetoothAdapter.setEnabled(true);
             mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON);
         }
+        final ShadowCachedBluetoothDeviceManager shadowCachedBluetoothDeviceManager =
+                Shadow.extract(Utils.getLocalBtManager(mContext).getCachedDeviceManager());
+        shadowCachedBluetoothDeviceManager.setCachedDevicesCopy(mBluetoothDeviceList);
     }
 
     @After