Merge "[Safety Labels] Enable safety label change notifications flag by default in Settings code" into udc-dev
diff --git a/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml b/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml
index 700fab3..6b5ffae 100644
--- a/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml
+++ b/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml
@@ -14,12 +14,12 @@
      limitations under the License.
 -->
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/title"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:minHeight="?attr/listPreferredItemHeightSmall"
-    style="?attr/materialAlertDialogBodyTextStyle"
+    style="@style/SettingsLibActionButton"
     android:gravity="center"
     android:paddingTop="?attr/listPreferredItemPaddingStart"
     android:paddingBottom="?attr/listPreferredItemPaddingEnd"
diff --git a/res/layout/supported_links_dialog_item.xml b/res/layout/supported_links_dialog_item.xml
index bbd2857..8a18935 100644
--- a/res/layout/supported_links_dialog_item.xml
+++ b/res/layout/supported_links_dialog_item.xml
@@ -19,6 +19,7 @@
      android:id="@android:id/text1"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
+     android:textDirection="locale"
      android:minHeight="?android:attr/listPreferredItemHeightSmall"
      android:ellipsize="marquee"
      android:gravity="center_vertical"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e02d2a7..a366ac7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9141,13 +9141,13 @@
     <string name="filter_manage_external_storage">Can access all files</string>
 
     <!-- Manage full screen intent permission title [CHAR LIMIT=40] -->
-    <string name="full_screen_intent_title">Manage full screen intents</string>
+    <string name="full_screen_intent_title">Show full screen notifications</string>
 
     <!-- Label for setting that allows apps to send full screen intents. [CHAR LIMIT=NONE] -->
-    <string name="permit_full_screen_intent">Allow apps to send full screen intents</string>
+    <string name="permit_full_screen_intent">Allow app to show full screen notifications when the device is locked</string>
 
     <!-- Description for setting that allows apps to send full screen intents. [CHAR LIMIT=NONE] -->
-    <string name="footer_description_full_screen_intent">Allow this app to send full screen intent notifications that cover the entire screen.</string>
+    <string name="footer_description_full_screen_intent">Allow the app to show notifications that take up the full screen when the device is locked. Apps may use these to highlight alarms, incoming calls, or other urgent notifications.</string>
 
     <!-- Media management apps settings title [CHAR LIMIT=40] -->
     <string name="media_management_apps_title">Media management apps</string>
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index 43c4647..c627df3 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -41,6 +41,8 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
+import com.android.settingslib.utils.ThreadUtils;
+import com.android.internal.content.PackageMonitor;
 import android.util.IconDrawableFactory;
 import android.util.Log;
 
@@ -236,20 +238,11 @@
 
     @OnLifecycleEvent(ON_CREATE)
     void onCreate(LifecycleOwner lifecycleOwner) {
-        if (mCredentialManager == null) {
-            return;
-        }
-
-        setAvailableServices(
-                lifecycleOwner,
-                mCredentialManager.getCredentialProviderServices(
-                        getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY),
-                null);
+        update();
     }
 
     @VisibleForTesting
     void setAvailableServices(
-            LifecycleOwner lifecycleOwner,
             List<CredentialProviderInfo> availableServices,
             String flagOverrideForTest) {
         mFlagOverrideForTest = flagOverrideForTest;
@@ -642,6 +635,40 @@
         void setActivityResult(int resultCode);
     }
 
+    /**
+     * Monitor coming and going credman services and calls {@link #update()} when necessary
+     */
+    private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+            ThreadUtils.postOnMainThread(() -> update());
+        }
+
+        @Override
+        public void onPackageModified(String packageName) {
+            ThreadUtils.postOnMainThread(() -> update());
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            ThreadUtils.postOnMainThread(() -> update());
+        }
+    };
+
+    /**
+     * Update the data in this UI.
+     */
+    private void update() {
+        if (mCredentialManager == null) {
+            return;
+        }
+
+        setAvailableServices(
+                mCredentialManager.getCredentialProviderServices(
+                        getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY),
+                null);
+    }
+
     /** Dialog fragment parent class. */
     private abstract static class CredentialManagerDialogFragment extends DialogFragment
             implements DialogInterface.OnClickListener {
diff --git a/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java b/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
index b1ab1cc..cc662aa 100644
--- a/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
+++ b/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
@@ -281,12 +281,18 @@
 
         final List<String> verifiedLinksList = IntentPickerUtils.getLinksList(
                 mDomainVerificationManager, mPackageName, DOMAIN_STATE_VERIFIED);
-        return new AlertDialog.Builder(mContext)
+        AlertDialog dialog = new AlertDialog.Builder(mContext)
                 .setCustomTitle(titleView)
                 .setCancelable(true)
                 .setItems(verifiedLinksList.toArray(new String[0]), /* listener= */ null)
                 .setPositiveButton(R.string.app_launch_dialog_ok, /* listener= */ null)
                 .create();
+        if (dialog.getListView() != null) {
+            dialog.getListView().setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        } else {
+            Log.w(TAG, "createVerifiedLinksDialog: dialog.getListView() is null, please check it.");
+        }
+        return dialog;
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java b/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java
index 9288d52..0716971 100644
--- a/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java
+++ b/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java
@@ -17,6 +17,8 @@
 package com.android.settings.applications.intentpicker;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -29,6 +31,7 @@
 
 /** This adapter is for supported links dialog. */
 public class SupportedLinksAdapter extends BaseAdapter {
+    private static final String TAG = "SupportedLinksAdapter";
     private final Context mContext;
     private final List<SupportedLinkWrapper> mWrapperList;
 
@@ -62,6 +65,14 @@
                     R.layout.supported_links_dialog_item, /* root= */ null);
         }
         final CheckedTextView textView = convertView.findViewById(android.R.id.text1);
+        Drawable[] drawables = textView.getCompoundDrawables();
+        if (mContext.getResources().getConfiguration().getLayoutDirection()
+                == View.LAYOUT_DIRECTION_RTL && drawables[0] != null) {
+            Log.d(TAG, "getView: RTL direction.");
+            // Set a checkbox position. It is same as the android:drawableRight attribute.
+            textView.setCompoundDrawables(/* left= */ null, /* top= */ null, drawables[0],
+                /* bottom= */ null);
+        }
         textView.setText(mWrapperList.get(position).getDisplayTitle(mContext));
         textView.setEnabled(mWrapperList.get(position).isEnabled());
         textView.setChecked(mWrapperList.get(position).isChecked());
diff --git a/src/com/android/settings/biometrics/OWNERS b/src/com/android/settings/biometrics/OWNERS
index 7ea9926..cb0d034 100644
--- a/src/com/android/settings/biometrics/OWNERS
+++ b/src/com/android/settings/biometrics/OWNERS
@@ -4,6 +4,10 @@
 jbolinger@google.com
 jeffpu@google.com
 joshmccloskey@google.com
+diyab@google.com
+austindelgado@google.com
+spdonghao@google.com
+wenhuiy@google.com
 
 firewall@google.com
 jasonsfchang@google.com
diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java
index d84ce61..4a09eb9 100644
--- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java
+++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java
@@ -66,7 +66,6 @@
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentManager;
 import androidx.lifecycle.Observer;
 import androidx.lifecycle.ViewModelProvider;
 import androidx.lifecycle.viewmodel.CreationExtras;
@@ -194,11 +193,13 @@
         // fragment
         setContentView(R.layout.biometric_enrollment_container);
 
+        final Fragment fragment = getSupportFragmentManager().findFragmentById(
+                R.id.fragment_container_view);
         if (DEBUG) {
-            Log.e(TAG, "onCreate() has savedInstance:" + (savedInstanceState != null));
+            Log.d(TAG, "onCreate() has savedInstance:" + (savedInstanceState != null)
+                    + ", fragment:" + fragment);
         }
-        if (savedInstanceState == null) {
-            Log.d(TAG, "onCreate()"); // Use to differentiate biometrics v2
+        if (fragment == null) {
             checkCredential();
             final EnrollmentRequest request = mViewModel.getRequest();
             if (request.isSkipFindSensor()) {
@@ -209,42 +210,26 @@
                 startIntroFragment();
             }
         } else {
-            final FragmentManager manager = getSupportFragmentManager();
-            String[] tags = new String[] {
-                    FINISH_TAG,
-                    ENROLLING_UDFPS_TAG,
-                    ENROLLING_SFPS_TAG,
-                    ENROLLING_RFPS_TAG,
-                    FIND_UDFPS_TAG,
-                    FIND_SFPS_TAG,
-                    FIND_RFPS_TAG,
-                    INTRO_TAG
-            };
-            for (String tag: tags) {
-                final Fragment fragment = manager.findFragmentByTag(tag);
-                if (fragment == null) {
-                    continue;
-                }
-                if (DEBUG) {
-                    Log.e(TAG, "onCreate() currentFragment:" + tag);
-                }
-                if (tag.equals(INTRO_TAG)) {
-                    attachIntroViewModel();
-                } else if (tag.equals(FIND_UDFPS_TAG) || tag.equals(FIND_SFPS_TAG)
-                        || tag.equals(FIND_RFPS_TAG)) {
-                    attachFindSensorViewModel();
-                    attachIntroViewModel();
-                } else if (tag.equals(ENROLLING_UDFPS_TAG) || tag.equals(ENROLLING_SFPS_TAG)
-                        || tag.equals(ENROLLING_RFPS_TAG)) {
-                    attachEnrollingViewModel();
-                    attachFindSensorViewModel();
-                    attachIntroViewModel();
-                } else { // FINISH_TAG
-                    attachFinishViewModel();
-                    attachFindSensorViewModel();
-                    attachIntroViewModel();
-                }
-                break;
+            final String tag = fragment.getTag();
+            if (INTRO_TAG.equals(tag)) {
+                attachIntroViewModel();
+            } else if (FIND_UDFPS_TAG.equals(tag) || FIND_SFPS_TAG.equals(tag)
+                    || FIND_RFPS_TAG.equals(tag)) {
+                attachFindSensorViewModel();
+                attachIntroViewModel();
+            } else if (ENROLLING_UDFPS_TAG.equals(tag) || ENROLLING_SFPS_TAG.equals(tag)
+                    || ENROLLING_RFPS_TAG.equals(tag)) {
+                attachEnrollingViewModel();
+                attachFindSensorViewModel();
+                attachIntroViewModel();
+            } else if (FINISH_TAG.equals(tag)) {
+                attachFinishViewModel();
+                attachFindSensorViewModel();
+                attachIntroViewModel();
+            } else {
+                Log.e(TAG, "fragment tag " + tag + " not found");
+                finish();
+                return;
             }
         }
 
diff --git a/src/com/android/settings/password/OWNERS b/src/com/android/settings/password/OWNERS
index 3b2013b..aa03c59 100644
--- a/src/com/android/settings/password/OWNERS
+++ b/src/com/android/settings/password/OWNERS
@@ -8,5 +8,9 @@
 kchyn@google.com
 paulcrowley@google.com
 rubinxu@google.com
+diyab@google.com
+austindelgado@google.com
+spdonghao@google.com
+wenhuiy@google.com
 
 # Emergency approvers in case the above are not available
diff --git a/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java b/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java
index ae32651..3cd0009 100644
--- a/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java
+++ b/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java
@@ -56,12 +56,15 @@
     private static final String ACTIVITY_CLASS_NAME =
             "com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity";
     private static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow";
+    private static final String EXTRA_SKIP_INTRO = "skip_intro";
     private static final String EXTRA_SKIP_FIND_SENSOR = "skip_find_sensor";
     private static final String EXTRA_FROM_SETTINGS_SUMMARY = "from_settings_summary";
     private static final String EXTRA_PAGE_TRANSITION_TYPE = "page_transition_type";
     private static final String EXTRA_KEY_GK_PW_HANDLE = "gk_pw_handle";
     private static final String TEST_PIN = "1234";
 
+    private static final String DO_IT_LATER = "Do it later";
+
     private static final String UDFPS_ENROLLING_TITLE = "Touch & hold the fingerprint sensor";
     private static final String SFPS_ENROLLING_TITLE =
             "Lift, then touch. Move your finger slightly each time.";
@@ -120,6 +123,12 @@
         mDevice.pressHome();
     }
 
+    @After
+    public void tearDown() throws Exception {
+        LockScreenUtil.resetLockscreen(TEST_PIN);
+        mDevice.pressHome();
+    }
+
     @Test
     public void testIntroChooseLock() {
         final Intent intent = newActivityIntent();
@@ -165,7 +174,7 @@
         agreeBtn.click();
 
         // FindUdfps page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
         final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
                 "illustration_lottie"));
         assertThat(lottie).isNotNull();
@@ -193,7 +202,7 @@
         agreeBtn.click();
 
         // FindUdfps page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
         final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
                 "illustration_lottie"));
         assertThat(lottie).isNotNull();
@@ -221,7 +230,7 @@
         agreeBtn.click();
 
         // FindSfps page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
         final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
                 "illustration_lottie"));
         assertThat(lottie).isNotNull();
@@ -244,7 +253,7 @@
         agreeBtn.click();
 
         // FindRfps page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
         final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
                 "illustration_lottie"));
         if (lottie == null) {
@@ -284,15 +293,15 @@
         agreeBtn.click();
 
         // FindSensor page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
-        final UiObject2 doItLaterBtn = mDevice.findObject(By.text("Do it later"));
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
         assertThat(doItLaterBtn).isNotNull();
         assertThat(doItLaterBtn.isClickable()).isTrue();
         doItLaterBtn.click();
 
         // Back to home
         mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
-        assertThat(mDevice.findObject(By.text("Do it later"))).isNull();
+        assertThat(mDevice.findObject(By.text(DO_IT_LATER))).isNull();
     }
 
     @Test
@@ -308,8 +317,8 @@
         agreeBtn.click();
 
         // FindSensor page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
-        final UiObject2 doItLaterBtn = mDevice.findObject(By.text("Do it later"));
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
         assertThat(doItLaterBtn).isNotNull();
         assertThat(doItLaterBtn.isClickable()).isTrue();
         doItLaterBtn.click();
@@ -325,7 +334,7 @@
         // Back to home
         mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
         assertThat(mDevice.findObject(By.text("Skip anyway"))).isNull();
-        assertThat(mDevice.findObject(By.text("Do it later"))).isNull();
+        assertThat(mDevice.findObject(By.text(DO_IT_LATER))).isNull();
     }
 
     @Test
@@ -341,8 +350,8 @@
         agreeBtn.click();
 
         // FindSensor page
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
-        final UiObject2 doItLaterBtn = mDevice.findObject(By.text("Do it later"));
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
         assertThat(doItLaterBtn).isNotNull();
         assertThat(doItLaterBtn.isClickable()).isTrue();
         doItLaterBtn.click();
@@ -356,7 +365,7 @@
         goBackBtn.click();
 
         // FindSensor page again
-        assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
     }
 
     @Test
@@ -447,10 +456,103 @@
         assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
     }
 
-    @After
-    public void tearDown() throws Exception {
-        LockScreenUtil.resetLockscreen(TEST_PIN);
-        mDevice.pressHome();
+    @Test
+    public void testFindUdfpsWithGkPwHandle_clickStart() {
+        assumeTrue(mCanAssumeUdfps);
+
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
+
+        launchFindSensorWithGkPwHandle();
+
+        // FindUdfps page
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
+                "illustration_lottie"));
+        assertThat(lottie).isNotNull();
+        assertThat(lottie.isClickable()).isTrue();
+        final UiObject2 startBtn = mDevice.findObject(By.text("Start"));
+        assertThat(startBtn.isClickable()).isTrue();
+        startBtn.click();
+
+        // Enrolling page
+        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
+    }
+
+    @Test
+    public void testFindUdfpsWithGkPwHandle_clickLottie() {
+        assumeTrue(mCanAssumeUdfps);
+
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
+
+        launchFindSensorWithGkPwHandle();
+
+        // FindUdfps page
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
+                "illustration_lottie"));
+        assertThat(lottie).isNotNull();
+        assertThat(lottie.isClickable()).isTrue();
+        final UiObject2 startBtn = mDevice.findObject(By.text("Start"));
+        assertThat(startBtn.isClickable()).isTrue();
+        lottie.click();
+
+        // Enrolling page
+        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
+    }
+
+    @Test
+    public void testFindSfpsWithGkPwHandle() {
+        assumeTrue(mCanAssumeSfps);
+
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
+
+        launchFindSensorWithGkPwHandle();
+
+        // FindSfps page
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
+                "illustration_lottie"));
+        assertThat(lottie).isNotNull();
+
+        // We don't have view which can be clicked to run to next page, stop at here.
+    }
+
+    @Test
+    public void testFindRfpsWithGkPwHandle() {
+        assumeFalse(mCanAssumeUdfps || mCanAssumeSfps);
+
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
+
+        launchFindSensorWithGkPwHandle();
+
+        // FindRfps page
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
+                "illustration_lottie"));
+        if (lottie == null) {
+            // FindSfps page shall have an animation view if no lottie view
+            assertThat(mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
+                    "fingerprint_sensor_location_animation"))).isNotNull();
+        }
+    }
+
+
+    @Test
+    public void testFindSensorWithGkPwHandle_clickSkipInFindSensor() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
+
+        launchFindSensorWithGkPwHandle();
+
+        // FindSensor page
+        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
+        final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
+        assertThat(doItLaterBtn).isNotNull();
+        assertThat(doItLaterBtn.isClickable()).isTrue();
+        doItLaterBtn.click();
+
+        // Back to home
+        mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
+        assertThat(mDevice.findObject(By.text(DO_IT_LATER))).isNull();
     }
 
     private void launchIntroWithGkPwHandle(boolean isSuw) {
@@ -469,6 +571,20 @@
                 userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback);
     }
 
+    private void launchFindSensorWithGkPwHandle() {
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
+        final LockscreenCredential lockscreenCredential = LockscreenCredential.createPin(TEST_PIN);
+        final int userId = UserHandle.myUserId();
+        final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> {
+            final Intent intent = newActivityIntent();
+            intent.putExtra(EXTRA_SKIP_INTRO, true);
+            intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.getGatekeeperPasswordHandle());
+            mContext.startActivity(intent);
+        };
+        LockPatternChecker.verifyCredential(lockPatternUtils, lockscreenCredential,
+                userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback);
+    }
+
     private void launchEnrollingWithGkPwHandle() {
         LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
         final LockscreenCredential lockscreenCredential = LockscreenCredential.createPin(TEST_PIN);
diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
index b02cf1c..2a2aaee 100644
--- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
@@ -484,7 +484,7 @@
         CredentialManagerPreferenceController controller =
                 new CredentialManagerPreferenceController(
                         mContext, mCredentialsPreferenceCategory.getKey());
-        controller.setAvailableServices(() -> mock(Lifecycle.class), availableServices, addServiceOverride);
+        controller.setAvailableServices(availableServices, addServiceOverride);
         controller.setDelegate(mDelegate);
         return controller;
     }