Merge "Implement SFPS guided enrollment for T6" into tm-qpr-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b2e5f2d..1eaf28f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6827,9 +6827,17 @@
     <!-- [CHAR_LIMIT=NONE] Battery usage item for background usage time -->
     <string name="battery_usage_for_background_time">Background: <xliff:g id="time">%s</xliff:g></string>
     <!-- [CHAR_LIMIT=NONE] Battery usage main screen footer content -->
-    <string name="battery_usage_screen_footer">Battery usage data is approximate and doesn\'t measure usage when phone is charging</string>
+    <string name="battery_usage_screen_footer" product="default">Battery usage data is approximate and doesn\'t measure usage when phone is charging</string>
+    <!-- [CHAR_LIMIT=NONE] Battery usage main screen footer content -->
+    <string name="battery_usage_screen_footer" product="tablet">Battery usage data is approximate and doesn\'t measure usage when tablet is charging</string>
+    <!-- [CHAR_LIMIT=NONE] Battery usage main screen footer content -->
+    <string name="battery_usage_screen_footer" product="device">Battery usage data is approximate and doesn\'t measure usage when device is charging</string>
     <!-- [CHAR_LIMIT=NONE] Battery usage main screen footer for empty content -->
-    <string name="battery_usage_screen_footer_empty">Battery usage data will be available after you use your phone for a few hours</string>
+    <string name="battery_usage_screen_footer_empty" product="default">Battery usage data will be available after you use your phone for a few hours</string>
+    <!-- [CHAR_LIMIT=NONE] Battery usage main screen footer for empty content -->
+    <string name="battery_usage_screen_footer_empty" product="tablet">Battery usage data will be available after you use your tablet for a few hours</string>
+    <!-- [CHAR_LIMIT=NONE] Battery usage main screen footer for empty content -->
+    <string name="battery_usage_screen_footer_empty" product="device">Battery usage data will be available after you use your device for a few hours</string>
     <!-- [CHAR_LIMIT=NONE] Accessibility content description for battery chart view. -->
     <string name="battery_usage_chart">Battery usage chart</string>
     <!-- [CHAR_LIMIT=NONE] Accessibility content description for daily battery chart view. -->
diff --git a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
index 1485500..0668c62 100644
--- a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
@@ -64,8 +64,7 @@
 
     @Override
     public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        getPreferenceManager().setPreferenceComparisonCallback(null);
+        // Initialize the parameters since displayTile() will be called in super.onCreate().
         Bundle args = getArguments();
         final Activity activity = getActivity();
         mUserHandle = Utils.getSecureTargetUser(activity.getActivityToken(),
@@ -82,6 +81,9 @@
                 mAccountType = args.getString(KEY_ACCOUNT_TYPE);
             }
         }
+
+        super.onCreate(icicle);
+        getPreferenceManager().setPreferenceComparisonCallback(null);
         mAccountSynController.init(mAccount, mUserHandle);
         mRemoveAccountController.init(mAccount, mUserHandle);
     }
diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java b/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java
index 978fb0d..50eb43d 100644
--- a/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java
@@ -35,7 +35,7 @@
  */
 public class CombinedBiometricStatusPreferenceController extends
         BiometricStatusPreferenceController implements LifecycleObserver {
-    private static final String KEY_BIOMETRIC_SETTINGS = "biometric_settings";
+    public static final String KEY_BIOMETRIC_SETTINGS = "biometric_settings";
 
     @VisibleForTesting
     RestrictedPreference mPreference;
@@ -122,4 +122,8 @@
     protected String getSettingsClassName() {
         return mCombinedBiometricStatusUtils.getSettingsClassName();
     }
+
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        mPreferenceScreen = preferenceScreen;
+    }
 }
diff --git a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
index 7c41957..f18a74f 100644
--- a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
@@ -38,6 +38,7 @@
     public static final String KEY_FACE_SETTINGS = "face_settings";
 
     protected final FaceManager mFaceManager;
+
     @VisibleForTesting
     RestrictedPreference mPreference;
     private PreferenceScreen mPreferenceScreen;
@@ -111,4 +112,8 @@
     protected String getSettingsClassName() {
         return mFaceStatusUtils.getSettingsClassName();
     }
+
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        mPreferenceScreen = preferenceScreen;
+    }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java
index 1ed0688..347fec7 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java
@@ -35,7 +35,7 @@
 public class FingerprintStatusPreferenceController extends BiometricStatusPreferenceController
         implements LifecycleObserver {
 
-    private static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings";
+    public static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings";
 
     protected final FingerprintManager mFingerprintManager;
     @VisibleForTesting
@@ -112,4 +112,8 @@
             mPreference.setDisabledByAdmin(enforcedAdmin);
         }
     }
+
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        mPreferenceScreen = preferenceScreen;
+    }
 }
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index 6aadee6..b30b54d 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -40,7 +40,7 @@
 public class SecuritySettings extends DashboardFragment {
 
     private static final String TAG = "SecuritySettings";
-    private static final String SECURITY_CATEGORY = "security_category";
+    protected static final String SECURITY_CATEGORY = "security_category";
 
     public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
     public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
@@ -132,4 +132,9 @@
                             && !SafetyCenterManagerWrapper.get().isEnabled(context);
                 }
             };
+
+    @Override
+    public Lifecycle getSettingsLifecycle() {
+        return super.getSettingsLifecycle();
+    }
 }
diff --git a/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java b/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java
index 272c840..c517884 100644
--- a/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java
+++ b/tests/unit/src/com/android/settings/security/SecuritySettingsTest.java
@@ -40,6 +40,10 @@
 import android.os.Looper;
 import android.provider.SearchIndexableResource;
 
+import androidx.lifecycle.Lifecycle;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -51,6 +55,7 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.security.trustagent.TrustAgentManager;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 import org.junit.Before;
@@ -62,13 +67,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 @RunWith(AndroidJUnit4.class)
 public class SecuritySettingsTest {
-
     private Context mContext;
     private SecuritySettingsFeatureProvider mSecuritySettingsFeatureProvider;
     private SecuritySettings mSecuritySettings;
+    private Preference mPreference;
+    private RestrictedPreference mPreferenceFace;
+    private RestrictedPreference mPreferenceFingerprint;
+    private RestrictedPreference mPreferenceCombined;
 
     @Mock
     private TrustAgentManager mTrustAgentManager;
@@ -79,6 +86,8 @@
     @Mock
     private PackageManager mPackageManager;
 
+    private PreferenceScreen mScreen;
+
     @Before
     @UiThreadTest
     public void setup() {
@@ -96,10 +105,30 @@
         FakeFeatureFactory mFeatureFactory = FakeFeatureFactory.setupForTest();
         SecurityFeatureProvider mSecurityFeatureProvider =
                 mFeatureFactory.getSecurityFeatureProvider();
-
         when(mSecurityFeatureProvider.getTrustAgentManager()).thenReturn(mTrustAgentManager);
         mSecuritySettingsFeatureProvider = mFeatureFactory.getSecuritySettingsFeatureProvider();
         mSecuritySettings = new SecuritySettings();
+
+        PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        mScreen = preferenceManager.createPreferenceScreen(mContext);
+        mPreference = new Preference(mContext);
+        mPreference.setKey(SecuritySettings.SECURITY_CATEGORY);
+
+        mPreferenceFace = new RestrictedPreference(mContext);
+        mPreferenceFingerprint = new RestrictedPreference(mContext);
+        mPreferenceCombined = new RestrictedPreference(mContext);
+
+        mPreferenceFace.setKey(FaceStatusPreferenceController
+                .KEY_FACE_SETTINGS);
+        mPreferenceFingerprint.setKey(FingerprintStatusPreferenceController
+                .KEY_FINGERPRINT_SETTINGS);
+        mPreferenceCombined.setKey(CombinedBiometricStatusPreferenceController
+                .KEY_BIOMETRIC_SETTINGS);
+
+        mScreen.addPreference(mPreference);
+        mScreen.addPreference(mPreferenceFace);
+        mScreen.addPreference(mPreferenceFingerprint);
+        mScreen.addPreference(mPreferenceCombined);
     }
 
     @Test
@@ -167,6 +196,150 @@
         assertThat(isCombinedPrefAvailable(controllers)).isTrue();
     }
 
+    @Test
+    @UiThreadTest
+    public void preferenceLifecycle_faceShowsThenCombined() {
+        when(mFaceManager.isHardwareDetected()).thenReturn(true);
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
+        final List<AbstractPreferenceController> controllers =
+                mSecuritySettings.createPreferenceControllers(mContext);
+
+        FaceStatusPreferenceController mFaceStatusPreferenceController =
+                getFaceStatusPreferenceController(controllers);
+
+        FingerprintStatusPreferenceController mFingerprintStatusPreferenceController =
+                getFingerprintStatusPreferenceController(controllers);
+
+        CombinedBiometricStatusPreferenceController mCombinedStatusPreferenceController =
+                getCombinedBiometricStatusPreferenceController(controllers);
+
+        mFaceStatusPreferenceController.setPreferenceScreen(mScreen);
+        mFingerprintStatusPreferenceController.setPreferenceScreen(mScreen);
+        mCombinedStatusPreferenceController.setPreferenceScreen(mScreen);
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isTrue();
+        assertThat(mPreferenceFingerprint.isVisible()).isFalse();
+        assertThat(mPreferenceCombined.isVisible()).isFalse();
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isFalse();
+        assertThat(mPreferenceFingerprint.isVisible()).isFalse();
+        assertThat(mPreferenceCombined.isVisible()).isTrue();
+    }
+
+    @Test
+    @UiThreadTest
+    public void preferenceLifecycle_fingerprintShowsThenCombined() {
+        when(mFaceManager.isHardwareDetected()).thenReturn(false);
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+        final List<AbstractPreferenceController> controllers =
+                mSecuritySettings.createPreferenceControllers(mContext);
+
+        FaceStatusPreferenceController mFaceStatusPreferenceController =
+                getFaceStatusPreferenceController(controllers);
+
+        FingerprintStatusPreferenceController mFingerprintStatusPreferenceController =
+                getFingerprintStatusPreferenceController(controllers);
+
+        CombinedBiometricStatusPreferenceController mCombinedStatusPreferenceController =
+                getCombinedBiometricStatusPreferenceController(controllers);
+
+        mFaceStatusPreferenceController.setPreferenceScreen(mScreen);
+        mFingerprintStatusPreferenceController.setPreferenceScreen(mScreen);
+        mCombinedStatusPreferenceController.setPreferenceScreen(mScreen);
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isFalse();
+        assertThat(mPreferenceFingerprint.isVisible()).isTrue();
+        assertThat(mPreferenceCombined.isVisible()).isFalse();
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
+        when(mFaceManager.isHardwareDetected()).thenReturn(true);
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isFalse();
+        assertThat(mPreferenceFingerprint.isVisible()).isFalse();
+        assertThat(mPreferenceCombined.isVisible()).isTrue();
+    }
+
+    @Test
+    @UiThreadTest
+    public void preferenceLifecycle_combinedShowsThenFace() {
+        when(mFaceManager.isHardwareDetected()).thenReturn(true);
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+        final List<AbstractPreferenceController> controllers =
+                mSecuritySettings.createPreferenceControllers(mContext);
+
+        FaceStatusPreferenceController mFaceStatusPreferenceController =
+                getFaceStatusPreferenceController(controllers);
+
+        FingerprintStatusPreferenceController mFingerprintStatusPreferenceController =
+                getFingerprintStatusPreferenceController(controllers);
+
+        CombinedBiometricStatusPreferenceController mCombinedStatusPreferenceController =
+                getCombinedBiometricStatusPreferenceController(controllers);
+
+        mFaceStatusPreferenceController.setPreferenceScreen(mScreen);
+        mFingerprintStatusPreferenceController.setPreferenceScreen(mScreen);
+        mCombinedStatusPreferenceController.setPreferenceScreen(mScreen);
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isFalse();
+        assertThat(mPreferenceFingerprint.isVisible()).isFalse();
+        assertThat(mPreferenceCombined.isVisible()).isTrue();
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isTrue();
+        assertThat(mPreferenceFingerprint.isVisible()).isFalse();
+        assertThat(mPreferenceCombined.isVisible()).isFalse();
+    }
+
+    @Test
+    @UiThreadTest
+    public void preferenceLifecycle_combinedShowsThenFingerprint() {
+        when(mFaceManager.isHardwareDetected()).thenReturn(true);
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+        final List<AbstractPreferenceController> controllers =
+                mSecuritySettings.createPreferenceControllers(mContext);
+
+        FaceStatusPreferenceController mFaceStatusPreferenceController =
+                getFaceStatusPreferenceController(controllers);
+
+        FingerprintStatusPreferenceController mFingerprintStatusPreferenceController =
+                getFingerprintStatusPreferenceController(controllers);
+
+        CombinedBiometricStatusPreferenceController mCombinedStatusPreferenceController =
+                getCombinedBiometricStatusPreferenceController(controllers);
+
+        mFaceStatusPreferenceController.setPreferenceScreen(mScreen);
+        mFingerprintStatusPreferenceController.setPreferenceScreen(mScreen);
+        mCombinedStatusPreferenceController.setPreferenceScreen(mScreen);
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isFalse();
+        assertThat(mPreferenceFingerprint.isVisible()).isFalse();
+        assertThat(mPreferenceCombined.isVisible()).isTrue();
+
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
+        when(mFaceManager.isHardwareDetected()).thenReturn(false);
+        mSecuritySettings.getSettingsLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
+
+        assertThat(mPreferenceFace.isVisible()).isFalse();
+        assertThat(mPreferenceFingerprint.isVisible()).isTrue();
+        assertThat(mPreferenceCombined.isVisible()).isFalse();
+    }
+
     private List<String> getAllXmlKeys(BaseSearchIndexProvider indexProvider) throws Exception {
         final List<SearchIndexableResource> resources = indexProvider.getXmlResourcesToIndex(
                 mContext, true /* not used*/);
@@ -207,4 +380,35 @@
                 controller -> controller instanceof CombinedBiometricStatusPreferenceController
                         && controller.isAvailable()).count() == 1;
     }
+
+    FaceStatusPreferenceController getFaceStatusPreferenceController(
+            List<AbstractPreferenceController> controllers) {
+        for (AbstractPreferenceController abstractPreferenceController: controllers) {
+            if (abstractPreferenceController instanceof FaceStatusPreferenceController) {
+                return (FaceStatusPreferenceController) abstractPreferenceController;
+            }
+        }
+        return null;
+    }
+
+    FingerprintStatusPreferenceController getFingerprintStatusPreferenceController(
+            List<AbstractPreferenceController> controllers) {
+        for (AbstractPreferenceController abstractPreferenceController: controllers) {
+            if (abstractPreferenceController instanceof FingerprintStatusPreferenceController) {
+                return (FingerprintStatusPreferenceController) abstractPreferenceController;
+            }
+        }
+        return null;
+    }
+
+    CombinedBiometricStatusPreferenceController getCombinedBiometricStatusPreferenceController(
+            List<AbstractPreferenceController> controllers) {
+        for (AbstractPreferenceController abstractPreferenceController: controllers) {
+            if (abstractPreferenceController
+                    instanceof CombinedBiometricStatusPreferenceController) {
+                return (CombinedBiometricStatusPreferenceController) abstractPreferenceController;
+            }
+        }
+        return null;
+    }
 }