Merge "Face and fingerprint unlock strings for private space" into main
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 56b0a41..5bf786e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1240,6 +1240,28 @@
     <string name="private_space_fingerprint_unlock_title">Fingerprint Unlock for private space</string>
     <!-- Title for the Face unlock for private space preference. [CHAR LIMIT=60] -->
     <string name="private_space_face_unlock_title">Face Unlock for private space</string>
+    <!-- Title for the Face and Fingerprint preference for private space. [CHAR LIMIT=60] -->
+    <string name="private_space_biometric_unlock_title">Face &amp; Fingerprint Unlock for private space</string>
+    <!-- Introduction title shown in private space fingerprint enrollment [CHAR LIMIT=90] -->
+    <string name="private_space_fingerprint_enroll_introduction_title">Set up Fingerprint Unlock for private space</string>
+    <!-- Introduction detail message shown in private space fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
+    <string name ="private_space_fingerprint_enroll_introduction_message">Use your fingerprint to unlock your private space or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
+    <!-- Introduction description message shown in private space fingerprint enrollment introduction screen. [CHAR LIMIT=NONE] -->
+    <string name="private_space_fingerprint_enroll_introduction_footer_message">Your private space can be unlocked when you don\u2019t intend to, like if someone holds up your phone to your finger.</string>
+    <!-- Message shown in fingerprint enrollment dialog once enrollment is completed (private space) [CHAR LIMIT=NONE] -->
+    <string name="private_space_fingerprint_enroll_finish_message">Use your fingerprint to unlock your private space or to approve purchases</string>
+    <!-- Introduction title shown in private space face enrollment [CHAR LIMIT=90] -->
+    <string name="private_space_face_enroll_introduction_title">Set up Face Unlock for private space</string>
+    <!-- Introduction detail message shown in private space face enrollment dialog [CHAR LIMIT=NONE]-->
+    <string name ="private_space_face_enroll_introduction_message">Use your face to unlock your private space or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
+    <!-- Message on the face enrollment introduction page for private space that provides information about what could cause the phone to unlock. [CHAR LIMIT=NONE] -->
+    <string name="private_space_face_enroll_introduction_info_looking">Looking at the phone can unlock private space even when you don\u2019t intend to. Your private space can also be unlocked by someone who looks a lot like you, like an identical sibling, or if someone holds the device up to your face.</string>
+    <!-- Message on the face enrollment introduction page for private space that provides information about the relative security of face for unlocking the phone. [CHAR LIMIT=NONE] -->
+    <string name="private_space_face_enroll_introduction_info_less_secure">Using your face to unlock your private space may be less secure than a strong pattern, PIN, or password</string>
+    <!-- Text shown on the details of a toggle which disables/enables face unlock for private space, depending if the user's eyes are open. [CHAR LIMIT=NONE] -->
+    <string name="private_space_face_settings_require_attention_details">To unlock private space, your eyes must be open. For best results, take off sunglasses.</string>
+    <!-- Text shown in face settings in private space explaining what your face can be used for. [CHAR LIMIT=NONE] -->
+    <string name="private_space_face_settings_footer">Use your face to unlock your private space.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour private space can be unlocked by someone else if your device is held up to your face.\n\nYour private space can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
     <!-- Biometric category title - biometric options for unlocking the device. [CHAR LIMIT=50] -->
     <string name="private_space_category_ways_to_unlock">Ways to unlock</string>
     <!-- Summary for one lock when device screen lock is used as private profile lock. [CHAR LIMIT=40] -->
diff --git a/res/xml/private_space_biometric_settings.xml b/res/xml/private_space_biometric_settings.xml
index 6135b5f..38ec09a 100644
--- a/res/xml/private_space_biometric_settings.xml
+++ b/res/xml/private_space_biometric_settings.xml
@@ -17,7 +17,7 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
-    android:title="@string/private_space_biometric_title"
+    android:title="@string/private_space_biometric_unlock_title"
     settings:searchable="false">
 
     <com.android.settingslib.widget.TopIntroPreference
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index f76ea27..145f3a4 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -1401,6 +1401,16 @@
     }
 
     /**
+     * Returns true if the userId is a private profile, false otherwise.
+     */
+    public static boolean isPrivateProfile(int userId, @NonNull Context context) {
+        final UserManager userManager = context.getSystemService(UserManager.class);
+        UserInfo userInfo = userManager.getUserInfo(userId);
+        return Flags.allowPrivateProfile() && android.multiuser.Flags.enablePrivateSpaceFeatures()
+                && userInfo.isPrivateProfile();
+    }
+
+    /**
      * Enable new edge to edge feature.
      *
      * @param activity the Activity need to setup the edge to edge feature.
diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricStatusUtils.java b/src/com/android/settings/biometrics/combination/CombinedBiometricStatusUtils.java
index 2cd239e..92b6d60 100644
--- a/src/com/android/settings/biometrics/combination/CombinedBiometricStatusUtils.java
+++ b/src/com/android/settings/biometrics/combination/CombinedBiometricStatusUtils.java
@@ -93,7 +93,10 @@
     public String getTitle() {
         UserManager userManager = mContext.getSystemService(UserManager.class);
         if (userManager != null && userManager.isProfile()) {
-            return mContext.getString(R.string.security_settings_work_biometric_preference_title);
+            return mContext.getString(
+                    Utils.isPrivateProfile(mUserId, mContext)
+                            ? R.string.private_space_biometric_unlock_title
+                            : R.string.security_settings_work_biometric_preference_title);
         } else {
             return mContext.getString(R.string.security_settings_biometric_preference_title);
         }
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index 414c545..4888388 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -365,7 +365,9 @@
 
     @StringRes
     protected int getInfoMessageLooking() {
-        return R.string.security_settings_face_enroll_introduction_info_looking;
+        return isPrivateProfile()
+                ? R.string.private_space_face_enroll_introduction_info_looking
+                : R.string.security_settings_face_enroll_introduction_info_looking;
     }
 
     @StringRes
@@ -390,7 +392,10 @@
 
     @StringRes
     protected int getLessSecureMessage() {
-        return R.string.security_settings_face_enroll_introduction_info_less_secure;
+        return isPrivateProfile()
+                ? R.string.private_space_face_enroll_introduction_info_less_secure
+                : R.string.security_settings_face_enroll_introduction_info_less_secure;
+
     }
 
     @Override
@@ -411,6 +416,9 @@
 
     @Override
     protected int getHeaderResDefault() {
+        if (isPrivateProfile()) {
+            return R.string.private_space_face_enroll_introduction_title;
+        }
         return R.string.security_settings_face_enroll_introduction_title;
     }
 
@@ -577,7 +585,10 @@
 
     @Override
     protected void updateDescriptionText() {
-        if (mIsFaceStrong) {
+        if (isPrivateProfile()) {
+            setDescriptionText(getString(
+                    R.string.private_space_face_enroll_introduction_message));
+        } else if (mIsFaceStrong) {
             setDescriptionText(getString(
                     R.string.security_settings_face_enroll_introduction_message_class3));
         }
@@ -608,4 +619,8 @@
         }
         updateDescriptionText();
     }
+
+    private boolean isPrivateProfile() {
+        return Utils.isPrivateProfile(mUserId, getApplicationContext());
+    }
 }
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index 24df51f..061487a 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -211,6 +211,8 @@
                 ((FaceSettingsPreferenceController) controller).setUserId(mUserId);
             } else if (controller instanceof FaceSettingsEnrollButtonPreferenceController) {
                 ((FaceSettingsEnrollButtonPreferenceController) controller).setUserId(mUserId);
+            } else if (controller instanceof FaceSettingsFooterPreferenceController) {
+                ((FaceSettingsFooterPreferenceController) controller).setUserId(mUserId);
             }
         }
         mRemoveController.setUserId(mUserId);
@@ -367,6 +369,7 @@
         controllers.add(new FaceSettingsRemoveButtonPreferenceController(context));
         controllers.add(new FaceSettingsConfirmPreferenceController(context));
         controllers.add(new FaceSettingsEnrollButtonPreferenceController(context));
+        controllers.add(new FaceSettingsFooterPreferenceController(context));
         return controllers;
     }
 
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
index 77a160d..71c4678 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
@@ -24,10 +24,12 @@
 import android.hardware.face.FaceManager.SetFeatureCallback;
 import android.provider.Settings;
 
+import androidx.annotation.Nullable;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 import androidx.preference.TwoStatePreference;
 
+import com.android.settings.R;
 import com.android.settings.Utils;
 
 /**
@@ -99,6 +101,18 @@
     }
 
     @Override
+    public void updateState(@Nullable Preference preference) {
+        if (preference == null) {
+            return;
+        }
+        super.updateState(preference);
+        if (Utils.isPrivateProfile(getUserId(), mContext)) {
+            preference.setSummary(mContext.getString(
+                    R.string.private_space_face_settings_require_attention_details));
+        }
+    }
+
+    @Override
     public boolean isChecked() {
         if (!FaceSettings.isFaceHardwareDetected(mContext)) {
             return true;
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
index e2123f0..d56c9b3 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
@@ -30,6 +30,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.utils.AnnotationSpan;
@@ -41,12 +42,17 @@
  * Footer for face settings showing the help text and help link.
  */
 public class FaceSettingsFooterPreferenceController extends BasePreferenceController {
+    private static final String KEY = "security_face_footer";
     private static final String TAG = "FaceSettingsFooterPreferenceController";
     private static final String ANNOTATION_URL = "url";
     private final FaceFeatureProvider mProvider;
     private Preference mPreference;
     private boolean mIsFaceStrong;
+    private int mUserId;
 
+    public FaceSettingsFooterPreferenceController(@NonNull Context context) {
+        this(context, KEY);
+    }
     public FaceSettingsFooterPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mProvider = FeatureFactory.getFeatureFactory().getFaceFeatureProvider();
@@ -79,7 +85,9 @@
 
         int footerRes;
         boolean isAttentionSupported = mProvider.isAttentionSupported(mContext);
-        if (mIsFaceStrong) {
+        if (Utils.isPrivateProfile(mUserId, mContext)) {
+            footerRes = R.string.private_space_face_settings_footer;
+        } else if (mIsFaceStrong) {
             footerRes = isAttentionSupported
                     ? R.string.security_settings_face_settings_footer_class3
                     : R.string.security_settings_face_settings_footer_attention_not_supported;
@@ -92,6 +100,10 @@
                 mContext.getText(footerRes), linkInfo));
     }
 
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
     private void addAuthenticatorsRegisteredCallback(Context context) {
         final FaceManager faceManager = context.getSystemService(FaceManager.class);
         faceManager.addAuthenticatorsRegisteredCallback(
diff --git a/src/com/android/settings/biometrics/face/FaceStatusUtils.java b/src/com/android/settings/biometrics/face/FaceStatusUtils.java
index d02e115..5af0a8a 100644
--- a/src/com/android/settings/biometrics/face/FaceStatusUtils.java
+++ b/src/com/android/settings/biometrics/face/FaceStatusUtils.java
@@ -67,7 +67,10 @@
     public String getTitle() {
         UserManager userManager = mContext.getSystemService(UserManager.class);
         if (userManager != null && userManager.isProfile()) {
-            return mContext.getString(R.string.security_settings_face_profile_preference_title);
+            return mContext.getString(
+                    Utils.isPrivateProfile(mUserId, mContext)
+                            ? R.string.private_space_face_unlock_title
+                            : R.string.security_settings_face_profile_preference_title);
         } else {
             return mContext.getString(R.string.security_settings_face_preference_title);
         }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
index 9c89f24..013e3d7 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
@@ -78,7 +78,10 @@
             setContentView(R.layout.fingerprint_enroll_finish);
         }
         setHeaderText(R.string.security_settings_fingerprint_enroll_finish_title);
-        setDescriptionText(R.string.security_settings_fingerprint_enroll_finish_v2_message);
+        setDescriptionText(Utils.isPrivateProfile(mUserId, getApplicationContext())
+                ? R.string.private_space_fingerprint_enroll_finish_message
+                : R.string.security_settings_fingerprint_enroll_finish_v2_message);
+
         final String sfpsDescription = mSfpsRestToUnlockFeature != null
                 ? mSfpsRestToUnlockFeature.getDescriptionForSfps(this)
                 : null;
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
index a1f4eff..f6626b2 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
@@ -176,7 +176,9 @@
     @Override
     protected void initViews() {
         setDescriptionText(getString(
-                R.string.security_settings_fingerprint_enroll_introduction_v3_message,
+                isPrivateProfile()
+                        ? R.string.private_space_fingerprint_enroll_introduction_message
+                        : R.string.security_settings_fingerprint_enroll_introduction_v3_message,
                 DeviceHelper.getDeviceName(this)));
 
         super.initViews();
@@ -261,6 +263,9 @@
 
     @StringRes
     protected int getFooterMessage5() {
+        if (isPrivateProfile()) {
+            return R.string.private_space_fingerprint_enroll_introduction_footer_message;
+        }
         return R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_5;
     }
 
@@ -292,6 +297,9 @@
 
     @Override
     protected int getHeaderResDefault() {
+        if (isPrivateProfile()) {
+            return R.string.private_space_fingerprint_enroll_introduction_title;
+        }
         return R.string.security_settings_fingerprint_enroll_introduction_title;
     }
 
@@ -477,4 +485,8 @@
         data.putExtra(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, true);
         return data;
     }
+
+    private boolean isPrivateProfile() {
+        return Utils.isPrivateProfile(mUserId, getApplicationContext());
+    }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index 63499a5..7651176 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -510,8 +510,9 @@
                 mFooterColumns.add(column2);
             } else {
                 final FooterColumn column = new FooterColumn();
-                column.mTitle = getString(
-                        R.string.security_settings_fingerprint_enroll_introduction_v3_message,
+                column.mTitle = getString(isPrivateProfile()
+                        ? R.string.private_space_fingerprint_enroll_introduction_message
+                        : R.string.security_settings_fingerprint_enroll_introduction_v3_message,
                         DeviceHelper.getDeviceName(getActivity()));
                 column.mLearnMoreClickListener = learnMoreClickListener;
                 column.mLearnMoreOverrideText = getText(
@@ -1130,6 +1131,10 @@
             }
         };
 
+        private boolean isPrivateProfile() {
+            return Utils.isPrivateProfile(mUserId, getContext());
+        }
+
         public static class DeleteFingerprintDialog extends InstrumentedDialogFragment
                 implements DialogInterface.OnClickListener {
 
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java
index d6e6498..a7c9e9d 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java
@@ -68,7 +68,10 @@
     public String getTitle() {
         UserManager userManager = mContext.getSystemService(UserManager.class);
         if (userManager != null && userManager.isProfile()) {
-            return mContext.getString(R.string.security_settings_work_fingerprint_preference_title);
+            return mContext.getString(
+                    Utils.isPrivateProfile(mUserId, mContext)
+                            ? R.string.private_space_fingerprint_unlock_title
+                            : R.string.security_settings_work_fingerprint_preference_title);
         } else {
             return mContext.getString(R.string.security_settings_fingerprint_preference_title);
         }
diff --git a/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowUtils.java
index 5f8c434..ed03bcc 100644
--- a/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -50,6 +50,7 @@
     private static ArraySet<String> sResultLinks = new ArraySet<>();
     private static boolean sIsBatteryPresent;
     private static boolean sIsMultipleBiometricsSupported;
+    private static boolean sIsPrivateProfile;
 
     @Implementation
     protected static int enforceSameOwner(Context context, int userId) {
@@ -82,6 +83,7 @@
         sResultLinks = new ArraySet<>();
         sIsBatteryPresent = true;
         sIsMultipleBiometricsSupported = false;
+        sIsPrivateProfile = false;
     }
 
     public static void setIsDemoUser(boolean isDemoUser) {
@@ -188,4 +190,13 @@
     public static void setIsMultipleBiometricsSupported(boolean isMultipleBiometricsSupported) {
         sIsMultipleBiometricsSupported = isMultipleBiometricsSupported;
     }
+
+    @Implementation
+    protected static boolean isPrivateProfile(int userId, Context context) {
+        return sIsPrivateProfile;
+    }
+
+    public static void setIsPrivateProfile(boolean isPrivateProfile) {
+        sIsPrivateProfile = isPrivateProfile;
+    }
 }