Merge "Update SFPS enrollment education assets and add light/dark theme colors" into tm-qpr-dev
diff --git a/Android.bp b/Android.bp
index 5bf5514..11a0d18 100644
--- a/Android.bp
+++ b/Android.bp
@@ -83,6 +83,7 @@
         "zxing-core-1.7",
         "android.hardware.dumpstate-V1.0-java",
         "android.hardware.dumpstate-V1.1-java",
+        "android.hardware.dumpstate-V1-java",
         "lottie",
         "WifiTrackerLib",
         "SettingsLibActivityEmbedding",
diff --git a/res/layout/preference_labeled_slider.xml b/res/layout/preference_labeled_slider.xml
index a11d574..ae7027d 100644
--- a/res/layout/preference_labeled_slider.xml
+++ b/res/layout/preference_labeled_slider.xml
@@ -69,6 +69,8 @@
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_gravity="start|top"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorSecondary"
             android:gravity="start"
             android:layout_weight="1"/>
 
@@ -77,6 +79,8 @@
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_gravity="end|top"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorSecondary"
             android:gravity="end"
             android:layout_weight="1"/>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2fef457..12a3439 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -14333,7 +14333,7 @@
     <!-- The title of the toggle which enables/disables overlays on top of the screen saver [CHAR LIMIT=none] -->
     <string name="dream_complications_toggle_title">Show additional information</string>
     <!-- The summary of what overlays this toggle controls [CHAR LIMIT=none] -->
-    <string name="dream_complications_toggle_summary">Display time, date, weather, air quality, and Cast details on the screen saver</string>
+    <string name="dream_complications_toggle_summary">Display things like the time, weather, or other information on the screen saver</string>
     <!-- The title of the category to show for the screensaver miscellaneous settings [CHAR LIMIT=none] -->
     <string name="dream_more_settings_category">More settings</string>
     <!-- The title of the screen saver setup page [CHAR LIMIT=none] -->
diff --git a/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceController.java
index d272a0b..429fd9d 100644
--- a/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceController.java
@@ -102,6 +102,11 @@
     }
 
     private void showQuickSettingsTooltipIfNeeded() {
+        if (mPreference == null) {
+            // Returns if no preference found by slice highlight menu.
+            return;
+        }
+
         final ComponentName tileComponentName = getTileComponentName();
         if (tileComponentName == null) {
             // Returns if no tile service assigned.
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewController.java b/src/com/android/settings/accessibility/TextReadingPreviewController.java
index 1be8c70..98767d9 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewController.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewController.java
@@ -108,6 +108,7 @@
         final PreviewPagerAdapter pagerAdapter = new PreviewPagerAdapter(mContext, isLayoutRtl,
                 PREVIEW_SAMPLE_RES_IDS, createConfig(origConfig));
         mPreviewPreference.setPreviewAdapter(pagerAdapter);
+        mPreviewPreference.setCurrentItem(isLayoutRtl ? PREVIEW_SAMPLE_RES_IDS.length - 1 : 0);
         pagerAdapter.setPreviewLayer(/* newLayerIndex= */ 0,
                 /* currentLayerIndex= */ 0,
                 /* currentFrameIndex= */ 0, /* animate= */ false);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index b1b18ff..64a08d3 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -203,7 +203,9 @@
         // Do NOT cancel enrollment progress after rotating, adding mIsOrientationChanged
         // to judge if the focus changed was triggered by rotation, current WMS has triple callbacks
         // (true > false > true), we need to reset mIsOrientationChanged when !hasFocus callback.
-        if (!mIsOrientationChanged) {
+        // Side fps do not have to synchronize udfpsController overlay state, we should bypass sfps
+        // from onWindowFocusChanged() as long press sfps power key will prompt dialog to users.
+        if (!mIsOrientationChanged && !mCanAssumeSfps) {
             onCancelEnrollment(FINGERPRINT_ERROR_USER_CANCELED);
         } else {
             mIsOrientationChanged = false;
diff --git a/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java b/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java
index e1db74d..051cede 100644
--- a/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java
+++ b/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceController.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.hardware.dumpstate.V1_0.IDumpstateDevice;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -40,8 +41,12 @@
 
     private static final String ENABLE_VERBOSE_VENDOR_LOGGING_KEY = "enable_verbose_vendor_logging";
     private static final int DUMPSTATE_HAL_VERSION_UNKNOWN = -1;
-    private static final int DUMPSTATE_HAL_VERSION_1_0 = 0;
-    private static final int DUMPSTATE_HAL_VERSION_1_1 = 1;
+    private static final int DUMPSTATE_HAL_VERSION_1_0 = 0; // HIDL v1.0
+    private static final int DUMPSTATE_HAL_VERSION_1_1 = 1; // HIDL v1.1
+    private static final int DUMPSTATE_HAL_VERSION_2_0 = 2; // AIDL v1
+
+    private static final String DUMP_STATE_AIDL_SERVICE_NAME =
+            android.hardware.dumpstate.IDumpstateDevice.DESCRIPTOR + "/default";
 
     private int mDumpstateHalVersion;
 
@@ -57,9 +62,8 @@
 
     @Override
     public boolean isAvailable() {
-        // Only show preference when IDumpstateDevice v1.1 is avalaible
-        // This is temperary strategy that may change later.
-        return isIDumpstateDeviceV1_1ServiceAvailable();
+        // Only show preference when IDumpstateDevice AIDL or HIDL v1.1 service is available
+        return isIDumpstateDeviceAidlServiceAvailable() || isIDumpstateDeviceV1_1ServiceAvailable();
     }
 
     @Override
@@ -86,15 +90,31 @@
     boolean isIDumpstateDeviceV1_1ServiceAvailable() {
         IDumpstateDevice service = getDumpstateDeviceService();
         if (service == null) {
-            if (DBG) Log.d(TAG, "IDumpstateDevice service is not available.");
+            if (DBG) Log.d(TAG, "IDumpstateDevice v1.1 service is not available.");
         }
-        return service != null && mDumpstateHalVersion >= DUMPSTATE_HAL_VERSION_1_1;
+        return service != null && mDumpstateHalVersion == DUMPSTATE_HAL_VERSION_1_1;
+    }
+
+    @VisibleForTesting
+    boolean isIDumpstateDeviceAidlServiceAvailable() {
+        android.hardware.dumpstate.IDumpstateDevice aidlService = getDumpstateDeviceAidlService();
+        return aidlService != null;
     }
 
     @VisibleForTesting
     void setVerboseLoggingEnabled(boolean enable) {
-        IDumpstateDevice service = getDumpstateDeviceService();
+        // First check if AIDL service is available
+        android.hardware.dumpstate.IDumpstateDevice aidlService = getDumpstateDeviceAidlService();
+        if (aidlService != null) {
+            try {
+                aidlService.setVerboseLoggingEnabled(enable);
+            } catch (RemoteException re) {
+                if (DBG) Log.e(TAG, "aidlService.setVerboseLoggingEnabled fail: " + re);
+            }
+        }
 
+        // Then check HIDL v1.1 service
+        IDumpstateDevice service = getDumpstateDeviceService();
         if (service == null || mDumpstateHalVersion < DUMPSTATE_HAL_VERSION_1_1) {
             if (DBG) Log.d(TAG, "setVerboseLoggingEnabled not supported.");
             return;
@@ -107,14 +127,24 @@
                 service11.setVerboseLoggingEnabled(enable);
             }
         } catch (RemoteException | RuntimeException e) {
-            if (DBG) Log.e(TAG, "setVerboseLoggingEnabled fail: " + e);
+            if (DBG) Log.e(TAG, "HIDL v1.1 setVerboseLoggingEnabled fail: " + e);
         }
     }
 
     @VisibleForTesting
     boolean getVerboseLoggingEnabled() {
-        IDumpstateDevice service = getDumpstateDeviceService();
+        // First check if AIDL service is available
+        android.hardware.dumpstate.IDumpstateDevice aidlService = getDumpstateDeviceAidlService();
+        if (aidlService != null) {
+            try {
+                return aidlService.getVerboseLoggingEnabled();
+            } catch (RemoteException re) {
+                if (DBG) Log.e(TAG, "aidlService.getVerboseLoggingEnabled fail: " + re);
+            }
+        }
 
+        // Then check HIDL v1.1 service
+        IDumpstateDevice service = getDumpstateDeviceService();
         if (service == null || mDumpstateHalVersion < DUMPSTATE_HAL_VERSION_1_1) {
             if (DBG) Log.d(TAG, "getVerboseLoggingEnabled not supported.");
             return false;
@@ -127,7 +157,7 @@
                 return service11.getVerboseLoggingEnabled();
             }
         } catch (RemoteException | RuntimeException e) {
-            if (DBG) Log.e(TAG, "getVerboseLoggingEnabled fail: " + e);
+            if (DBG) Log.e(TAG, "HIDL v1.1 getVerboseLoggingEnabled fail: " + e);
         }
         return false;
     }
@@ -141,6 +171,7 @@
                     .getService(true /* retry */);
             mDumpstateHalVersion = DUMPSTATE_HAL_VERSION_1_1;
         } catch (NoSuchElementException | RemoteException e) {
+            if (DBG) Log.e(TAG, "Get HIDL v1.1 service fail: " + e);
         }
 
         if (service == null) {
@@ -149,6 +180,7 @@
                         .getService(true /* retry */);
                 mDumpstateHalVersion = DUMPSTATE_HAL_VERSION_1_0;
             } catch (NoSuchElementException | RemoteException e) {
+                if (DBG) Log.e(TAG, "Get HIDL v1.0 service fail: " + e);
             }
         }
 
@@ -157,4 +189,24 @@
         }
         return service;
     }
+
+    /**
+     * Return a {@link android.hardware.dumpstate.IDumpstateDevice} instance or null if service is
+     * not available.
+     */
+    @VisibleForTesting
+    @Nullable android.hardware.dumpstate.IDumpstateDevice getDumpstateDeviceAidlService() {
+        android.hardware.dumpstate.IDumpstateDevice service = null;
+        try {
+            service = android.hardware.dumpstate.IDumpstateDevice.Stub.asInterface(
+                    ServiceManager.waitForDeclaredService(DUMP_STATE_AIDL_SERVICE_NAME));
+        } catch (NoSuchElementException e) {
+            if (DBG) Log.e(TAG, "Get AIDL service fail: " + e);
+        }
+
+        if (service != null) {
+            mDumpstateHalVersion = DUMPSTATE_HAL_VERSION_2_0;
+        }
+        return service;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java
index 89c9120..deab745 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java
@@ -118,18 +118,29 @@
         mController = new TestAccessibilityQuickSettingsPrimarySwitchPreferenceController(mContext,
                 TEST_KEY);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
-        mController.displayPreference(mScreen);
     }
 
     @Test
     public void setChecked_showTooltipView() {
+        mController.displayPreference(mScreen);
+
         mController.setChecked(true);
 
         assertThat(getLatestPopupWindow().isShowing()).isTrue();
     }
 
     @Test
+    public void setChecked_notCallDisplayPreference_notShowTooltipView() {
+        // Simulates the slice highlight menu that does not call {@link #displayPreference} before
+        // {@link #setChecked} called.
+        mController.setChecked(true);
+
+        assertThat(getLatestPopupWindow()).isNull();
+    }
+
+    @Test
     public void setChecked_tooltipViewShown_notShowTooltipView() {
+        mController.displayPreference(mScreen);
         mController.setChecked(true);
         getLatestPopupWindow().dismiss();
         mController.setChecked(false);
@@ -142,6 +153,7 @@
     @Test
     @Config(shadows = ShadowFragment.class)
     public void restoreValueFromSavedInstanceState_showTooltipView() {
+        mController.displayPreference(mScreen);
         mController.setChecked(true);
         final Bundle savedInstanceState = new Bundle();
         savedInstanceState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
index ef31c39..2c864d6 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
@@ -222,6 +222,16 @@
         );
     }
 
+    @Test
+    public void fingerprintSfpsEnrollment_loseFocus_shouldNotCancel() {
+        initializeActivityFor(FingerprintSensorProperties.TYPE_POWER_BUTTON);
+
+        mActivity.onEnrollmentProgressChange(1, 1);
+        mActivity.onWindowFocusChanged(true);
+
+        verify(mActivity, never()).onCancelEnrollment(anyInt());
+    }
+
     private void initializeActivityFor(int sensorType) {
         final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
         final FingerprintSensorPropertiesInternal prop =
diff --git a/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java
index 6145939..8e62521 100644
--- a/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/EnableVerboseVendorLoggingPreferenceControllerTest.java
@@ -47,6 +47,8 @@
     private PreferenceScreen mPreferenceScreen;
     @Mock
     IDumpstateDevice mIDumpstateDevice;
+    @Mock
+    android.hardware.dumpstate.IDumpstateDevice mIDumpstateDeviceAidl;
 
     private Context mContext;
     private EnableVerboseVendorLoggingPreferenceController mController;
@@ -57,6 +59,7 @@
         mContext = RuntimeEnvironment.application;
         mController = spy(new EnableVerboseVendorLoggingPreferenceController(mContext));
         doReturn(mIDumpstateDevice).when(mController).getDumpstateDeviceService();
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
 
         // mock with Dumpstate HAL v1.1
         Field f = EnableVerboseVendorLoggingPreferenceController.class
@@ -70,7 +73,9 @@
     }
 
     @Test
-    public void onPreferenceChange_settingEnable_enableVendorLoggingShouldBeOn() throws Exception {
+    public void onPreferenceChange_settingEnableByHidl_enableVendorLoggingShouldBeOn()
+            throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(true).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.onPreferenceChange(mPreference, true /* new value */);
@@ -80,8 +85,21 @@
     }
 
     @Test
-    public void onPreferenceChange_settingDisable_enableVendorLoggingShouldBeOff()
+    public void onPreferenceChange_settingEnableByAidl_enableVendorLoggingShouldBeOn()
             throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(true).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.onPreferenceChange(mPreference, true /* new value */);
+
+        final boolean enabled = mController.getVerboseLoggingEnabled();
+        assertTrue(enabled);
+    }
+
+    @Test
+    public void onPreferenceChange_settingDisableByHidl_enableVendorLoggingShouldBeOff()
+            throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(false).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.onPreferenceChange(mPreference,  false /* new value */);
@@ -91,7 +109,20 @@
     }
 
     @Test
-    public void updateState_settingDisabled_preferenceShouldNotBeChecked() throws Exception {
+    public void onPreferenceChange_settingDisableByAidl_enableVendorLoggingShouldBeOff()
+            throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(false).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.onPreferenceChange(mPreference,  false /* new value */);
+
+        final boolean enabled = mController.getVerboseLoggingEnabled();
+        assertFalse(enabled);
+    }
+
+    @Test
+    public void updateState_settingDisabledByHidl_preferenceShouldNotBeChecked() throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(false).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.setVerboseLoggingEnabled(false);
@@ -101,7 +132,19 @@
     }
 
     @Test
-    public void updateState_settingEnabled_preferenceShouldBeChecked() throws Exception {
+    public void updateState_settingDisabledByAidl_preferenceShouldNotBeChecked() throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(false).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.setVerboseLoggingEnabled(false);
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(false);
+    }
+
+    @Test
+    public void updateState_settingEnabledByHidl_preferenceShouldBeChecked() throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(true).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.setVerboseLoggingEnabled(true);
@@ -111,7 +154,19 @@
     }
 
     @Test
-    public void onDeveloperOptionDisabled_shouldDisablePreference() throws Exception {
+    public void updateState_settingEnabledByAidl_preferenceShouldBeChecked() throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(true).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.setVerboseLoggingEnabled(true);
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(true);
+    }
+
+    @Test
+    public void onDeveloperOptionDisabled_byHidl_shouldDisablePreference() throws Exception {
+        doReturn(null).when(mController).getDumpstateDeviceAidlService();
         doReturn(false).when(mIDumpstateDevice).getVerboseLoggingEnabled();
 
         mController.onDeveloperOptionsSwitchDisabled();
@@ -121,4 +176,17 @@
         verify(mPreference).setChecked(false);
         verify(mPreference).setEnabled(false);
     }
+
+    @Test
+    public void onDeveloperOptionDisabled_byAidl_shouldDisablePreference() throws Exception {
+        doReturn(mIDumpstateDeviceAidl).when(mController).getDumpstateDeviceAidlService();
+        doReturn(false).when(mIDumpstateDeviceAidl).getVerboseLoggingEnabled();
+
+        mController.onDeveloperOptionsSwitchDisabled();
+
+        final boolean enabled = mController.getVerboseLoggingEnabled();
+        assertFalse(enabled);
+        verify(mPreference).setChecked(false);
+        verify(mPreference).setEnabled(false);
+    }
 }