diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java
deleted file mode 100644
index 76c9e95..0000000
--- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.biometrics2.ui.view;
-
-import static androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult;
-import static androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
-import static androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY;
-
-import static com.android.settings.biometrics2.factory.BiometricsViewModelFactory.CHALLENGE_GENERATOR_KEY;
-import static com.android.settings.biometrics2.factory.BiometricsViewModelFactory.ENROLLMENT_REQUEST_KEY;
-import static com.android.settings.biometrics2.factory.BiometricsViewModelFactory.USER_ID_KEY;
-import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK;
-import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK;
-import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE;
-import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingAction;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintErrorDialogAction;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FingerprintEnrollFindSensorAction;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FingerprintEnrollFinishAction;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL;
-import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FingerprintEnrollIntroAction;
-
-import android.annotation.StyleRes;
-import android.app.Application;
-import android.content.Intent;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.Log;
-
-import androidx.activity.result.ActivityResult;
-import androidx.activity.result.ActivityResultCallback;
-import androidx.activity.result.ActivityResultLauncher;
-import androidx.annotation.ColorInt;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.lifecycle.Observer;
-import androidx.lifecycle.ViewModelProvider;
-import androidx.lifecycle.viewmodel.CreationExtras;
-import androidx.lifecycle.viewmodel.MutableCreationExtras;
-
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.biometrics.BiometricEnrollBase;
-import com.android.settings.biometrics2.data.repository.FingerprintRepository;
-import com.android.settings.biometrics2.factory.BiometricsViewModelFactory;
-import com.android.settings.biometrics2.ui.model.CredentialModel;
-import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
-import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.FingerprintChallengeGenerator;
-import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel;
-import com.android.settings.overlay.FeatureFactory;
-
-import com.google.android.setupdesign.util.ThemeHelper;
-
-/**
- * Fingerprint enrollment activity implementation
- */
-public class FingerprintEnrollmentActivity extends FragmentActivity {
-
-    /**
-     * Setupwizard activity
-     */
-    public static class SetupActivity extends FingerprintEnrollmentActivity {}
-
-    /**
-     * Internal activity for FingerprintSettings
-     */
-    public static class InternalActivity extends FingerprintEnrollmentActivity {}
-
-    private static final boolean DEBUG = false;
-    private static final String TAG = "FingerprintEnrollmentActivity";
-
-    private static final String INTRO_TAG = "intro";
-    private static final String FIND_SENSOR_TAG = "find-sensor";
-    private static final String ENROLLING_TAG = "enrolling";
-    private static final String FINISH_TAG = "finish";
-    private static final String SKIP_SETUP_FIND_FPS_DIALOG_TAG = "skip-setup-dialog";
-    private static final String ENROLLING_ERROR_DIALOG_TAG = "enrolling-error-dialog";
-
-    protected static final int LAUNCH_CONFIRM_LOCK_ACTIVITY = 1;
-
-    // This flag is used for addBackStack(), we do not save it in ViewModel because it is just used
-    // during FragmentManager calls
-    private boolean mIsFirstFragmentAdded = false;
-
-    private ViewModelProvider mViewModelProvider;
-    private FingerprintEnrollmentViewModel mViewModel;
-    private AutoCredentialViewModel mAutoCredentialViewModel;
-    private final Observer<Integer> mIntroActionObserver = action -> {
-        if (DEBUG) {
-            Log.d(TAG, "mIntroActionObserver(" + action + ")");
-        }
-        if (action != null) {
-            onIntroAction(action);
-        }
-    };
-    private final Observer<Integer> mFindSensorActionObserver = action -> {
-        if (DEBUG) {
-            Log.d(TAG, "mFindSensorActionObserver(" + action + ")");
-        }
-        if (action != null) {
-            onFindSensorAction(action);
-        }
-    };
-    private final Observer<Integer> mEnrollingActionObserver = action -> {
-        if (DEBUG) {
-            Log.d(TAG, "mEnrollingActionObserver(" + action + ")");
-        }
-        if (action != null) {
-            onEnrollingAction(action);
-        }
-    };
-    private final Observer<ErrorDialogData> mEnrollingErrorDialogObserver = data -> {
-        if (DEBUG) {
-            Log.d(TAG, "mEnrollingErrorDialogObserver(" + data + ")");
-        }
-        if (data != null) {
-            new FingerprintEnrollEnrollingErrorDialog().show(getSupportFragmentManager(),
-                    ENROLLING_ERROR_DIALOG_TAG);
-        }
-    };
-    private final Observer<Integer> mEnrollingErrorDialogActionObserver = action -> {
-        if (DEBUG) {
-            Log.d(TAG, "mEnrollingErrorDialogActionObserver(" + action + ")");
-        }
-        if (action != null) {
-            onEnrollingErrorDialogAction(action);
-        }
-    };
-    private final Observer<Integer> mFinishActionObserver = action -> {
-        if (DEBUG) {
-            Log.d(TAG, "mFinishActionObserver(" + action + ")");
-        }
-        if (action != null) {
-            onFinishAction(action);
-        }
-    };
-    private final ActivityResultCallback<ActivityResult> mChooseLockResultCallback =
-            result -> onChooseOrConfirmLockResult(true /* isChooseLock */, result);
-    private final ActivityResultLauncher<Intent> mChooseLockLauncher =
-            registerForActivityResult(new StartActivityForResult(), mChooseLockResultCallback);
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mViewModelProvider = new ViewModelProvider(this);
-
-        mViewModel = mViewModelProvider.get(FingerprintEnrollmentViewModel.class);
-        mViewModel.setSavedInstanceState(savedInstanceState);
-
-        mAutoCredentialViewModel = mViewModelProvider.get(AutoCredentialViewModel.class);
-        mAutoCredentialViewModel.setCredentialModel(savedInstanceState, getIntent());
-
-        // Theme
-        setTheme(mViewModel.getRequest().getTheme());
-        ThemeHelper.trySetDynamicColor(this);
-        getWindow().setStatusBarColor(android.graphics.Color.TRANSPARENT);
-
-        // fragment
-        setContentView(R.layout.biometric_enrollment_container);
-
-        final Fragment fragment = getSupportFragmentManager().findFragmentById(
-                R.id.fragment_container_view);
-        if (DEBUG) {
-            Log.d(TAG, "onCreate() has savedInstance:" + (savedInstanceState != null)
-                    + ", fragment:" + fragment);
-        }
-        if (fragment == null) {
-            checkCredential();
-            final EnrollmentRequest request = mViewModel.getRequest();
-            if (request.isSkipFindSensor()) {
-                startEnrollingFragment();
-            } else if (request.isSkipIntro()) {
-                startFindSensorFragment();
-            } else {
-                startIntroFragment();
-            }
-        } else {
-            final String tag = fragment.getTag();
-            if (INTRO_TAG.equals(tag)) {
-                attachIntroViewModel();
-            } else if (FIND_SENSOR_TAG.equals(tag)) {
-                attachFindSensorViewModel();
-                attachIntroViewModel();
-            } else if (ENROLLING_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;
-            }
-        }
-
-        // observe LiveData
-        mViewModel.getSetResultLiveData().observe(this, this::onSetActivityResult);
-
-        mAutoCredentialViewModel.getGenerateChallengeFailedLiveData().observe(this,
-                this::onGenerateChallengeFailed);
-    }
-
-    private void startFragment(@NonNull Class<? extends Fragment> fragmentClass,
-            @NonNull String tag) {
-        if (!mIsFirstFragmentAdded) {
-            getSupportFragmentManager().beginTransaction()
-                    .setReorderingAllowed(true)
-                    .replace(R.id.fragment_container_view, fragmentClass, null, tag)
-                    .commit();
-            mIsFirstFragmentAdded = true;
-        } else {
-            getSupportFragmentManager().beginTransaction()
-                    .setReorderingAllowed(true)
-                    .setCustomAnimations(R.anim.shared_x_axis_activity_open_enter_dynamic_color,
-                            R.anim.shared_x_axis_activity_open_exit,
-                            R.anim.shared_x_axis_activity_close_enter_dynamic_color,
-                            R.anim.shared_x_axis_activity_close_exit)
-                    .replace(R.id.fragment_container_view, fragmentClass, null, tag)
-                    .addToBackStack(tag)
-                    .commit();
-        }
-    }
-
-    private void startIntroFragment() {
-        attachIntroViewModel();
-        startFragment(FingerprintEnrollIntroFragment.class, INTRO_TAG);
-    }
-
-    private void attachIntroViewModel() {
-        final EnrollmentRequest request = mViewModel.getRequest();
-        if (request.isSkipIntro() || request.isSkipFindSensor()) {
-            return;
-        }
-
-        final FingerprintEnrollIntroViewModel introViewModel =
-                mViewModelProvider.get(FingerprintEnrollIntroViewModel.class);
-
-        // Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
-        // recreate, like press 'Agree' then press 'back' in FingerprintEnrollFindSensor activity.
-        introViewModel.clearActionLiveData();
-        introViewModel.getActionLiveData().observe(this, mIntroActionObserver);
-    }
-
-    // We need to make sure token is valid before entering find sensor page
-    private void startFindSensorFragment() {
-        // Always setToken into progressViewModel even it is not necessary action for UDFPS
-        mViewModelProvider.get(FingerprintEnrollProgressViewModel.class)
-                .setToken(mAutoCredentialViewModel.getToken());
-
-        attachFindSensorViewModel();
-
-        final Class<? extends Fragment> fragmentClass;
-        if (mViewModel.canAssumeUdfps()) {
-            fragmentClass = FingerprintEnrollFindUdfpsFragment.class;
-        } else if (mViewModel.canAssumeSfps()) {
-            fragmentClass = FingerprintEnrollFindSfpsFragment.class;
-        } else {
-            fragmentClass = FingerprintEnrollFindRfpsFragment.class;
-        }
-        startFragment(fragmentClass, FIND_SENSOR_TAG);
-    }
-
-    private void attachFindSensorViewModel() {
-        if (mViewModel.getRequest().isSkipFindSensor()) {
-            return;
-        }
-
-        final FingerprintEnrollFindSensorViewModel findSensorViewModel =
-                mViewModelProvider.get(FingerprintEnrollFindSensorViewModel.class);
-
-        // Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
-        // recreate, like press 'Start' then press 'back' in FingerprintEnrollEnrolling activity.
-        findSensorViewModel.clearActionLiveData();
-        findSensorViewModel.getActionLiveData().observe(this, mFindSensorActionObserver);
-    }
-
-    private void startEnrollingFragment() {
-        // Always setToken into progressViewModel even it is not necessary action for SFPS or RFPS
-        mViewModelProvider.get(FingerprintEnrollProgressViewModel.class)
-                .setToken(mAutoCredentialViewModel.getToken());
-
-        attachEnrollingViewModel();
-
-        final Class<? extends Fragment> fragmentClass;
-        if (mViewModel.canAssumeUdfps()) {
-            fragmentClass = FingerprintEnrollEnrollingUdfpsFragment.class;
-        } else if (mViewModel.canAssumeSfps()) {
-            fragmentClass = FingerprintEnrollEnrollingSfpsFragment.class;
-        } else {
-            fragmentClass = FingerprintEnrollEnrollingRfpsFragment.class;
-        }
-        startFragment(fragmentClass, ENROLLING_TAG);
-    }
-
-    private void attachEnrollingViewModel() {
-        final FingerprintEnrollEnrollingViewModel enrollingViewModel =
-                mViewModelProvider.get(FingerprintEnrollEnrollingViewModel.class);
-        enrollingViewModel.clearActionLiveData();
-        enrollingViewModel.getActionLiveData().observe(this, mEnrollingActionObserver);
-        enrollingViewModel.getErrorDialogLiveData().observe(this, mEnrollingErrorDialogObserver);
-        enrollingViewModel.getErrorDialogActionLiveData().observe(this,
-                mEnrollingErrorDialogActionObserver);
-    }
-
-    private void startFinishFragment() {
-        mViewModel.setIsNewFingerprintAdded();
-        attachFinishViewModel();
-
-        if (mViewModel.getRequest().isSkipFindSensor()) {
-            // Set page to Finish
-            getSupportFragmentManager().beginTransaction()
-                    .setReorderingAllowed(true)
-                    .setCustomAnimations(R.anim.shared_x_axis_activity_open_enter_dynamic_color,
-                            R.anim.shared_x_axis_activity_open_exit,
-                            R.anim.shared_x_axis_activity_close_enter_dynamic_color,
-                            R.anim.shared_x_axis_activity_close_exit)
-                    .replace(R.id.fragment_container_view, FingerprintEnrollFinishFragment.class,
-                            null, FINISH_TAG)
-                    .commit();
-        } else {
-            // Remove Enrolling page
-            getSupportFragmentManager().popBackStack();
-
-            // Remove old Finish page if any
-            if (getSupportFragmentManager().findFragmentByTag(FINISH_TAG) != null) {
-                getSupportFragmentManager().popBackStack(FINISH_TAG, POP_BACK_STACK_INCLUSIVE);
-            }
-
-            // Remove FindSensor page if maxEnrolled
-            if (mViewModel.isMaxEnrolledReached(mAutoCredentialViewModel.getUserId())
-                    && getSupportFragmentManager().findFragmentByTag(FIND_SENSOR_TAG) != null) {
-                getSupportFragmentManager().popBackStack(FIND_SENSOR_TAG, POP_BACK_STACK_INCLUSIVE);
-            }
-
-            // Add Finish page
-            getSupportFragmentManager().beginTransaction()
-                    .setReorderingAllowed(true)
-                    .setCustomAnimations(R.anim.shared_x_axis_activity_open_enter_dynamic_color,
-                            R.anim.shared_x_axis_activity_open_exit,
-                            R.anim.shared_x_axis_activity_close_enter_dynamic_color,
-                            R.anim.shared_x_axis_activity_close_exit)
-                    .replace(R.id.fragment_container_view, FingerprintEnrollFinishFragment.class,
-                            null, FINISH_TAG)
-                    .addToBackStack(FINISH_TAG)
-                    .commit();
-        }
-    }
-
-    private void attachFinishViewModel() {
-        final FingerprintEnrollFinishViewModel viewModel =
-                mViewModelProvider.get(FingerprintEnrollFinishViewModel.class);
-        viewModel.clearActionLiveData();
-        viewModel.getActionLiveData().observe(this, mFinishActionObserver);
-    }
-
-    private void onGenerateChallengeFailed(@NonNull Boolean ignoredBoolean) {
-        onSetActivityResult(new ActivityResult(RESULT_CANCELED, null));
-    }
-
-    private void onSetActivityResult(@NonNull ActivityResult result) {
-        final Bundle challengeExtras = mAutoCredentialViewModel.createGeneratingChallengeExtras();
-        final ActivityResult overrideResult = mViewModel.getOverrideActivityResult(
-                result, challengeExtras);
-        if (DEBUG) {
-            Log.d(TAG, "onSetActivityResult(" + result + "), override:" + overrideResult
-                    + ") challengeExtras:" + challengeExtras);
-        }
-        setResult(overrideResult.getResultCode(), overrideResult.getData());
-        finish();
-    }
-
-    private void checkCredential() {
-        switch (mAutoCredentialViewModel.checkCredential()) {
-            case CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK: {
-                final Intent intent = mAutoCredentialViewModel.createChooseLockIntent(this,
-                        mViewModel.getRequest().isSuw(), mViewModel.getRequest().getSuwExtras());
-                if (!mViewModel.isWaitingActivityResult().compareAndSet(false, true)) {
-                    Log.w(TAG, "chooseLock, fail to set isWaiting flag to true");
-                }
-                mChooseLockLauncher.launch(intent);
-                return;
-            }
-            case CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK: {
-                final boolean launched = mAutoCredentialViewModel.createConfirmLockLauncher(
-                        this,
-                        LAUNCH_CONFIRM_LOCK_ACTIVITY,
-                        getString(R.string.security_settings_fingerprint_preference_title)
-                ).launch();
-                if (!launched) {
-                    // This shouldn't happen, as we should only end up at this step if a lock thingy
-                    // is already set.
-                    Log.e(TAG, "confirmLock, launched is true");
-                    finish();
-                } else if (!mViewModel.isWaitingActivityResult().compareAndSet(false, true)) {
-                    Log.w(TAG, "confirmLock, fail to set isWaiting flag to true");
-                }
-                return;
-            }
-            case CREDENTIAL_VALID:
-            case CREDENTIAL_IS_GENERATING_CHALLENGE: {
-                // Do nothing
-            }
-        }
-    }
-
-    private void onChooseOrConfirmLockResult(boolean isChooseLock,
-            @NonNull ActivityResult activityResult) {
-        if (!mViewModel.isWaitingActivityResult().compareAndSet(true, false)) {
-            Log.w(TAG, "isChooseLock:" + isChooseLock + ", fail to unset waiting flag");
-        }
-        if (mAutoCredentialViewModel.checkNewCredentialFromActivityResult(
-                isChooseLock, activityResult)) {
-            overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out);
-        } else {
-            onSetActivityResult(activityResult);
-        }
-    }
-
-    private void onIntroAction(@FingerprintEnrollIntroAction int action) {
-        switch (action) {
-            case FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH: {
-                onSetActivityResult(
-                        new ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null));
-                return;
-            }
-            case FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL: {
-                onSetActivityResult(
-                        new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null));
-                return;
-            }
-            case FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL: {
-                startFindSensorFragment();
-            }
-        }
-    }
-
-    private void onFindSensorAction(@FingerprintEnrollFindSensorAction int action) {
-        switch (action) {
-            case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP: {
-                onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null));
-                return;
-            }
-            case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG: {
-                new SkipSetupFindFpsDialog().show(getSupportFragmentManager(),
-                        SKIP_SETUP_FIND_FPS_DIALOG_TAG);
-                return;
-            }
-            case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START: {
-                startEnrollingFragment();
-            }
-        }
-    }
-
-    private void onEnrollingAction(@FingerprintEnrollEnrollingAction int action) {
-        switch (action) {
-            case FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE: {
-                startFinishFragment();
-                break;
-            }
-            case FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP: {
-                onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null));
-                break;
-            }
-            case FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG: {
-                new FingerprintEnrollEnrollingIconTouchDialog().show(getSupportFragmentManager(),
-                        SKIP_SETUP_FIND_FPS_DIALOG_TAG);
-                break;
-            }
-            case FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED: {
-                if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
-                    getSupportFragmentManager().popBackStack();
-                } else {
-                    onSetActivityResult(new ActivityResult(RESULT_CANCELED, null));
-                }
-                break;
-            }
-        }
-    }
-
-    private void onEnrollingErrorDialogAction(@FingerprintErrorDialogAction int action) {
-        switch (action) {
-            case FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH:
-                onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null));
-                break;
-            case FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT:
-                onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null));
-                break;
-        }
-    }
-
-    private void onFinishAction(@FingerprintEnrollFinishAction int action) {
-        switch (action) {
-            case FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK: {
-                startEnrollingFragment();
-                break;
-            }
-            case FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK: {
-                final Intent data;
-                if (mViewModel.getRequest().isSuw()) {
-                    data = new Intent();
-                    data.putExtras(mViewModel.getSuwFingerprintCountExtra(
-                            mAutoCredentialViewModel.getUserId()));
-                } else {
-                    data = null;
-                }
-                onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_FINISHED, data));
-                break;
-            }
-        }
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mViewModel.checkFinishActivityDuringOnPause(isFinishing(), isChangingConfigurations());
-    }
-
-    @Override
-    protected void onDestroy() {
-        mViewModel.updateFingerprintSuggestionEnableState(mAutoCredentialViewModel.getUserId());
-        super.onDestroy();
-    }
-
-    @Override
-    protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid, boolean first) {
-        theme.applyStyle(R.style.SetupWizardPartnerResource, true);
-        super.onApplyThemeResource(theme, resid, first);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
-        if (requestCode == LAUNCH_CONFIRM_LOCK_ACTIVITY) {
-            onChooseOrConfirmLockResult(false, new ActivityResult(resultCode, data));
-            return;
-        }
-        super.onActivityResult(requestCode, resultCode, data);
-    }
-
-    @NonNull
-    @Override
-    public CreationExtras getDefaultViewModelCreationExtras() {
-        final Application application =
-                super.getDefaultViewModelCreationExtras().get(APPLICATION_KEY);
-        final MutableCreationExtras ret = new MutableCreationExtras();
-        ret.set(APPLICATION_KEY, application);
-
-        final FingerprintRepository repository = FeatureFactory.getFactory(application)
-                .getBiometricsRepositoryProvider().getFingerprintRepository(application);
-        ret.set(CHALLENGE_GENERATOR_KEY, new FingerprintChallengeGenerator(repository));
-
-        ret.set(ENROLLMENT_REQUEST_KEY, new EnrollmentRequest(getIntent(), getApplicationContext(),
-                this instanceof SetupActivity));
-
-        Bundle extras = getIntent().getExtras();
-        final CredentialModel credentialModel = new CredentialModel(extras,
-                SystemClock.elapsedRealtimeClock());
-        ret.set(USER_ID_KEY, credentialModel.getUserId());
-
-        return ret;
-    }
-
-    @NonNull
-    @Override
-    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
-        return new BiometricsViewModelFactory();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        getWindow().setStatusBarColor(getBackgroundColor());
-    }
-
-    @ColorInt
-    private int getBackgroundColor() {
-        final ColorStateList stateList = Utils.getColorAttr(this, android.R.attr.windowBackground);
-        return stateList != null ? stateList.getDefaultColor() : Color.TRANSPARENT;
-    }
-
-    @Override
-    public void onConfigurationChanged(@NonNull Configuration newConfig) {
-        mViewModelProvider.get(DeviceFoldedViewModel.class).onConfigurationChanged(newConfig);
-        super.onConfigurationChanged(newConfig);
-    }
-
-    @Override
-    protected void onSaveInstanceState(@NonNull Bundle outState) {
-        super.onSaveInstanceState(outState);
-        mViewModel.onSaveInstanceState(outState);
-        mAutoCredentialViewModel.onSaveInstanceState(outState);
-    }
-}
diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.kt b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.kt
new file mode 100644
index 0000000..e3a6078
--- /dev/null
+++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.kt
@@ -0,0 +1,644 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.biometrics2.ui.view
+
+import android.annotation.StyleRes
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.content.res.Configuration
+import android.content.res.Resources.Theme
+import android.graphics.Color
+import android.os.Bundle
+import android.os.SystemClock
+import android.util.Log
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.ActivityResultCallback
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
+import androidx.annotation.ColorInt
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE
+import androidx.lifecycle.Observer
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.CreationExtras
+import androidx.lifecycle.viewmodel.MutableCreationExtras
+import com.android.settings.R
+import com.android.settings.Utils
+import com.android.settings.biometrics.BiometricEnrollBase
+import com.android.settings.biometrics2.data.repository.FingerprintRepository
+import com.android.settings.biometrics2.factory.BiometricsViewModelFactory
+import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.CHALLENGE_GENERATOR_KEY
+import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.ENROLLMENT_REQUEST_KEY
+import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.USER_ID_KEY
+import com.android.settings.biometrics2.ui.model.CredentialModel
+import com.android.settings.biometrics2.ui.model.EnrollmentRequest
+import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel
+import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK
+import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK
+import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE
+import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID
+import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.FingerprintChallengeGenerator
+import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingAction
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintErrorDialogAction
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FingerprintEnrollFindSensorAction
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FingerprintEnrollFinishAction
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FingerprintEnrollIntroAction
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel
+import com.android.settings.overlay.FeatureFactory
+import com.google.android.setupdesign.util.ThemeHelper
+
+/**
+ * Fingerprint enrollment activity implementation
+ */
+open class FingerprintEnrollmentActivity : FragmentActivity() {
+    /** SetupWizard activity*/
+    class SetupActivity : FingerprintEnrollmentActivity()
+
+    /** Internal activity for FingerprintSettings */
+    class InternalActivity : FingerprintEnrollmentActivity()
+
+    /**
+     * This flag is used for addBackStack(), we do not save it in ViewModel because it is just used
+     * during FragmentManager calls
+     */
+    private var isFirstFragmentAdded = false
+
+    private val viewModelProvider: ViewModelProvider by lazy {
+        ViewModelProvider(this)
+    }
+
+    private val viewModel: FingerprintEnrollmentViewModel by lazy {
+        viewModelProvider[FingerprintEnrollmentViewModel::class.java]
+    }
+
+    private val autoCredentialViewModel: AutoCredentialViewModel by lazy {
+        viewModelProvider[AutoCredentialViewModel::class.java]
+    }
+
+    private val introActionObserver: Observer<Int> = Observer<Int> { action ->
+        if (DEBUG) {
+            Log.d(TAG, "introActionObserver($action)")
+        }
+        action?.let { onIntroAction(it) }
+    }
+
+    private val findSensorActionObserver: Observer<Int> = Observer<Int> { action ->
+        if (DEBUG) {
+            Log.d(TAG, "findSensorActionObserver($action)")
+        }
+        action?.let { onFindSensorAction(it) }
+    }
+
+    private val enrollingActionObserver: Observer<Int> = Observer<Int> { action ->
+        if (DEBUG) {
+            Log.d(TAG, "enrollingActionObserver($action)")
+        }
+        action?.let { onEnrollingAction(it) }
+    }
+
+    private val enrollingErrorDialogObserver: Observer<ErrorDialogData> =
+        Observer<ErrorDialogData> { data ->
+            if (DEBUG) {
+                Log.d(TAG, "enrollingErrorDialogObserver($data)")
+            }
+            data?.let {
+                FingerprintEnrollEnrollingErrorDialog().show(
+                    supportFragmentManager,
+                    ENROLLING_ERROR_DIALOG_TAG
+                )
+            }
+        }
+
+    private val enrollingErrorDialogActionObserver: Observer<Int> = Observer<Int> { action ->
+        if (DEBUG) {
+            Log.d(TAG, "enrollingErrorDialogActionObserver($action)")
+        }
+        action?.let { onEnrollingErrorDialogAction(it) }
+    }
+
+    private val finishActionObserver: Observer<Int> = Observer<Int> { action ->
+        if (DEBUG) {
+            Log.d(TAG, "finishActionObserver($action)")
+        }
+        action?.let { onFinishAction(it) }
+    }
+
+    private val chooseLockResultCallback: ActivityResultCallback<ActivityResult> =
+        ActivityResultCallback { result ->
+            onChooseOrConfirmLockResult(true /* isChooseLock */, result)
+        }
+
+    private val chooseLockLauncher: ActivityResultLauncher<Intent> =
+        registerForActivityResult(StartActivityForResult(), chooseLockResultCallback)
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        viewModel.setSavedInstanceState(savedInstanceState)
+        autoCredentialViewModel.setCredentialModel(savedInstanceState, intent)
+
+        // Theme
+        setTheme(viewModel.request.theme)
+        ThemeHelper.trySetDynamicColor(this)
+        window.statusBarColor = Color.TRANSPARENT
+
+        // fragment
+        setContentView(R.layout.biometric_enrollment_container)
+        val fragment: Fragment? = supportFragmentManager.findFragmentById(
+            R.id.fragment_container_view
+        )
+        if (DEBUG) {
+            Log.d(
+                TAG, "onCreate() has savedInstance:" + (savedInstanceState != null)
+                        + ", fragment:" + fragment
+            )
+        }
+        if (fragment == null) {
+            checkCredential()
+            val request: EnrollmentRequest = viewModel.getRequest()
+            if (request.isSkipFindSensor) {
+                startEnrollingFragment()
+            } else if (request.isSkipIntro) {
+                startFindSensorFragment()
+            } else {
+                startIntroFragment()
+            }
+        } else {
+            val tag: String? = fragment.tag
+            if (INTRO_TAG == tag) {
+                attachIntroViewModel()
+            } else if (FIND_SENSOR_TAG == tag) {
+                attachFindSensorViewModel()
+                attachIntroViewModel()
+            } else if (ENROLLING_TAG == tag) {
+                attachEnrollingViewModel()
+                attachFindSensorViewModel()
+                attachIntroViewModel()
+            } else if (FINISH_TAG == tag) {
+                attachFinishViewModel()
+                attachFindSensorViewModel()
+                attachIntroViewModel()
+            } else {
+                Log.e(TAG, "fragment tag $tag not found")
+                finish()
+                return
+            }
+        }
+
+        // observe LiveData
+        viewModel.setResultLiveData.observe(this) {
+            result: ActivityResult -> onSetActivityResult(result)
+        }
+        autoCredentialViewModel.generateChallengeFailedLiveData.observe(this) {
+            _: Boolean -> onGenerateChallengeFailed()
+        }
+    }
+
+    private fun startFragment(fragmentClass: Class<out Fragment>, tag: String) {
+        if (!isFirstFragmentAdded) {
+            supportFragmentManager.beginTransaction()
+                .setReorderingAllowed(true)
+                .replace(R.id.fragment_container_view, fragmentClass, null, tag)
+                .commit()
+            isFirstFragmentAdded = true
+        } else {
+            supportFragmentManager.beginTransaction()
+                .setReorderingAllowed(true)
+                .setCustomAnimations(
+                    R.anim.shared_x_axis_activity_open_enter_dynamic_color,
+                    R.anim.shared_x_axis_activity_open_exit,
+                    R.anim.shared_x_axis_activity_close_enter_dynamic_color,
+                    R.anim.shared_x_axis_activity_close_exit
+                )
+                .replace(R.id.fragment_container_view, fragmentClass, null, tag)
+                .addToBackStack(tag)
+                .commit()
+        }
+    }
+
+    private fun startIntroFragment() {
+        attachIntroViewModel()
+        startFragment(FingerprintEnrollIntroFragment::class.java, INTRO_TAG)
+    }
+
+    private fun attachIntroViewModel() {
+        val request: EnrollmentRequest = viewModel.request
+        if (request.isSkipIntro || request.isSkipFindSensor) {
+            return
+        }
+        viewModelProvider[FingerprintEnrollIntroViewModel::class.java].let {
+            // Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
+            // recreate, like press 'Agree' then press 'back' in FingerprintEnrollFindSensor
+            // activity.
+            it.clearActionLiveData()
+            it.actionLiveData.observe(this, introActionObserver)
+        }
+    }
+
+    // We need to make sure token is valid before entering find sensor page
+    private fun startFindSensorFragment() {
+        // Always setToken into progressViewModel even it is not necessary action for UDFPS
+        viewModelProvider[FingerprintEnrollProgressViewModel::class.java]
+            .setToken(autoCredentialViewModel.token)
+        attachFindSensorViewModel()
+        val fragmentClass: Class<out Fragment> = if (viewModel.canAssumeUdfps()) {
+            FingerprintEnrollFindUdfpsFragment::class.java
+        } else if (viewModel.canAssumeSfps()) {
+            FingerprintEnrollFindSfpsFragment::class.java
+        } else {
+            FingerprintEnrollFindRfpsFragment::class.java
+        }
+        startFragment(fragmentClass, FIND_SENSOR_TAG)
+    }
+
+    private fun attachFindSensorViewModel() {
+        if (viewModel.request.isSkipFindSensor) {
+            return
+        }
+        viewModelProvider[FingerprintEnrollFindSensorViewModel::class.java].let {
+            // Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
+            // recreate, like press 'Start' then press 'back' in FingerprintEnrollEnrolling
+            // activity.
+            it.clearActionLiveData()
+            it.actionLiveData.observe(this, findSensorActionObserver)
+        }
+    }
+
+    private fun startEnrollingFragment() {
+        // Always setToken into progressViewModel even it is not necessary action for SFPS or RFPS
+        viewModelProvider[FingerprintEnrollProgressViewModel::class.java]
+            .setToken(autoCredentialViewModel.token)
+        attachEnrollingViewModel()
+        val fragmentClass: Class<out Fragment> = if (viewModel.canAssumeUdfps()) {
+            FingerprintEnrollEnrollingUdfpsFragment::class.java
+        } else if (viewModel.canAssumeSfps()) {
+            FingerprintEnrollEnrollingSfpsFragment::class.java
+        } else {
+            FingerprintEnrollEnrollingRfpsFragment::class.java
+        }
+        startFragment(fragmentClass, ENROLLING_TAG)
+    }
+
+    private fun attachEnrollingViewModel() {
+        viewModelProvider[FingerprintEnrollEnrollingViewModel::class.java].let {
+            it.clearActionLiveData()
+            it.actionLiveData.observe(this, enrollingActionObserver)
+            it.errorDialogLiveData.observe(this, enrollingErrorDialogObserver)
+            it.errorDialogActionLiveData.observe(
+                this,
+                enrollingErrorDialogActionObserver
+            )
+        }
+    }
+
+    private fun startFinishFragment() {
+        viewModel.setIsNewFingerprintAdded()
+        attachFinishViewModel()
+        if (viewModel.request.isSkipFindSensor) {
+            // Set page to Finish
+            supportFragmentManager.beginTransaction()
+                .setReorderingAllowed(true)
+                .setCustomAnimations(
+                    R.anim.shared_x_axis_activity_open_enter_dynamic_color,
+                    R.anim.shared_x_axis_activity_open_exit,
+                    R.anim.shared_x_axis_activity_close_enter_dynamic_color,
+                    R.anim.shared_x_axis_activity_close_exit
+                )
+                .replace(
+                    R.id.fragment_container_view,
+                    FingerprintEnrollFinishFragment::class.java,
+                    null,
+                    FINISH_TAG
+                )
+                .commit()
+        } else {
+            // Remove Enrolling page
+            supportFragmentManager.popBackStack()
+
+            // Remove old Finish page if any
+            if (supportFragmentManager.findFragmentByTag(FINISH_TAG) != null) {
+                supportFragmentManager.popBackStack(FINISH_TAG, POP_BACK_STACK_INCLUSIVE)
+            }
+
+            // Remove FindSensor page if maxEnrolled
+            if (viewModel.isMaxEnrolledReached(autoCredentialViewModel.userId)
+                && supportFragmentManager.findFragmentByTag(FIND_SENSOR_TAG) != null
+            ) {
+                supportFragmentManager.popBackStack(FIND_SENSOR_TAG, POP_BACK_STACK_INCLUSIVE)
+            }
+
+            // Add Finish page
+            supportFragmentManager.beginTransaction()
+                .setReorderingAllowed(true)
+                .setCustomAnimations(
+                    R.anim.shared_x_axis_activity_open_enter_dynamic_color,
+                    R.anim.shared_x_axis_activity_open_exit,
+                    R.anim.shared_x_axis_activity_close_enter_dynamic_color,
+                    R.anim.shared_x_axis_activity_close_exit
+                )
+                .replace(
+                    R.id.fragment_container_view,
+                    FingerprintEnrollFinishFragment::class.java,
+                    null,
+                    FINISH_TAG
+                )
+                .addToBackStack(FINISH_TAG)
+                .commit()
+        }
+    }
+
+    private fun attachFinishViewModel() {
+        viewModelProvider[FingerprintEnrollFinishViewModel::class.java].let {
+            it.clearActionLiveData()
+            it.actionLiveData.observe(this, finishActionObserver)
+        }
+    }
+
+    private fun onGenerateChallengeFailed() {
+        onSetActivityResult(ActivityResult(RESULT_CANCELED, null))
+    }
+
+    private fun onSetActivityResult(result: ActivityResult) {
+        val challengeExtras: Bundle? = autoCredentialViewModel.createGeneratingChallengeExtras()
+        val overrideResult: ActivityResult = viewModel.getOverrideActivityResult(
+            result, challengeExtras
+        )
+        if (DEBUG) {
+            Log.d(
+                TAG, "onSetActivityResult(" + result + "), override:" + overrideResult
+                        + ") challengeExtras:" + challengeExtras
+            )
+        }
+        setResult(overrideResult.resultCode, overrideResult.data)
+        finish()
+    }
+
+    private fun checkCredential() {
+        when (autoCredentialViewModel.checkCredential()) {
+            CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK -> {
+                val intent: Intent = autoCredentialViewModel.createChooseLockIntent(
+                    this,
+                    viewModel.request.isSuw,
+                    viewModel.request.suwExtras
+                )
+                if (!viewModel.isWaitingActivityResult().compareAndSet(false, true)) {
+                    Log.w(TAG, "chooseLock, fail to set isWaiting flag to true")
+                }
+                chooseLockLauncher.launch(intent)
+                return
+            }
+
+            CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK -> {
+                val launched: Boolean = autoCredentialViewModel.createConfirmLockLauncher(
+                    this,
+                    LAUNCH_CONFIRM_LOCK_ACTIVITY,
+                    getString(R.string.security_settings_fingerprint_preference_title)
+                ).launch()
+                if (!launched) {
+                    // This shouldn't happen, as we should only end up at this step if a lock thingy
+                    // is already set.
+                    Log.e(TAG, "confirmLock, launched is true")
+                    finish()
+                } else if (!viewModel.isWaitingActivityResult().compareAndSet(false, true)) {
+                    Log.w(TAG, "confirmLock, fail to set isWaiting flag to true")
+                }
+                return
+            }
+
+            CREDENTIAL_VALID,
+            CREDENTIAL_IS_GENERATING_CHALLENGE -> {}
+        }
+    }
+
+    private fun onChooseOrConfirmLockResult(isChooseLock: Boolean, activityResult: ActivityResult) {
+        if (!viewModel.isWaitingActivityResult().compareAndSet(true, false)) {
+            Log.w(TAG, "isChooseLock:$isChooseLock, fail to unset waiting flag")
+        }
+        if (autoCredentialViewModel.checkNewCredentialFromActivityResult(
+                isChooseLock, activityResult
+            )
+        ) {
+            overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out)
+        } else {
+            onSetActivityResult(activityResult)
+        }
+    }
+
+    private fun onIntroAction(@FingerprintEnrollIntroAction action: Int) {
+        when (action) {
+            FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH -> {
+                onSetActivityResult(
+                    ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null)
+                )
+                return
+            }
+
+            FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL -> {
+                onSetActivityResult(
+                    ActivityResult(BiometricEnrollBase.RESULT_SKIP, null)
+                )
+                return
+            }
+
+            FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL -> {
+                startFindSensorFragment()
+            }
+        }
+    }
+
+    private fun onFindSensorAction(@FingerprintEnrollFindSensorAction action: Int) {
+        when (action) {
+            FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP -> {
+                onSetActivityResult(ActivityResult(BiometricEnrollBase.RESULT_SKIP, null))
+                return
+            }
+
+            FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG -> {
+                SkipSetupFindFpsDialog().show(
+                    supportFragmentManager,
+                    SKIP_SETUP_FIND_FPS_DIALOG_TAG
+                )
+                return
+            }
+
+            FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START -> {
+                startEnrollingFragment()
+            }
+        }
+    }
+
+    private fun onEnrollingAction(@FingerprintEnrollEnrollingAction action: Int) {
+        when (action) {
+            FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE -> {
+                startFinishFragment()
+            }
+
+            FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP -> {
+                onSetActivityResult(ActivityResult(BiometricEnrollBase.RESULT_SKIP, null))
+            }
+
+            FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG -> {
+                FingerprintEnrollEnrollingIconTouchDialog().show(
+                    supportFragmentManager,
+                    SKIP_SETUP_FIND_FPS_DIALOG_TAG
+                )
+            }
+
+            FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED -> {
+                if (supportFragmentManager.backStackEntryCount > 0) {
+                    supportFragmentManager.popBackStack()
+                } else {
+                    onSetActivityResult(ActivityResult(RESULT_CANCELED, null))
+                }
+            }
+        }
+    }
+
+    private fun onEnrollingErrorDialogAction(@FingerprintErrorDialogAction action: Int) {
+        when (action) {
+            FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH -> onSetActivityResult(
+                ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null)
+            )
+
+            FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT -> onSetActivityResult(
+                ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null)
+            )
+        }
+    }
+
+    private fun onFinishAction(@FingerprintEnrollFinishAction action: Int) {
+        when (action) {
+            FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK -> {
+                startEnrollingFragment()
+            }
+
+            FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK -> {
+                val data: Intent? = if (viewModel.request.isSuw) {
+                    Intent().also {
+                        it.putExtras(
+                            viewModel.getSuwFingerprintCountExtra(
+                                autoCredentialViewModel.userId
+                            )
+                        )
+                    }
+                } else {
+                    null
+                }
+                onSetActivityResult(ActivityResult(BiometricEnrollBase.RESULT_FINISHED, data))
+            }
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+        viewModel.checkFinishActivityDuringOnPause(isFinishing, isChangingConfigurations)
+    }
+
+    override fun onDestroy() {
+        viewModel.updateFingerprintSuggestionEnableState(autoCredentialViewModel.userId)
+        super.onDestroy()
+    }
+
+    override fun onApplyThemeResource(theme: Theme, @StyleRes resid: Int, first: Boolean) {
+        theme.applyStyle(R.style.SetupWizardPartnerResource, true)
+        super.onApplyThemeResource(theme, resid, first)
+    }
+
+    @Deprecated("Deprecated in Java")
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (requestCode == LAUNCH_CONFIRM_LOCK_ACTIVITY) {
+            onChooseOrConfirmLockResult(false, ActivityResult(resultCode, data))
+            return
+        }
+        super.onActivityResult(requestCode, resultCode, data)
+    }
+
+    override val defaultViewModelCreationExtras: CreationExtras
+        get() {
+            val fingerprintRepository = FeatureFactory
+                .getFactory(application)
+                .biometricsRepositoryProvider
+                .getFingerprintRepository(application)!!
+            val credentialModel = CredentialModel(intent.extras, SystemClock.elapsedRealtimeClock())
+
+            return MutableCreationExtras(super.defaultViewModelCreationExtras).also {
+                it[CHALLENGE_GENERATOR_KEY] = FingerprintChallengeGenerator(fingerprintRepository)
+                it[ENROLLMENT_REQUEST_KEY] =
+                    EnrollmentRequest(intent, applicationContext, this is SetupActivity)
+                it[USER_ID_KEY] = credentialModel.userId
+            }
+        }
+
+    override val defaultViewModelProviderFactory: ViewModelProvider.Factory
+        get() = BiometricsViewModelFactory()
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+        window.statusBarColor = backgroundColor
+    }
+
+    @get:ColorInt
+    private val backgroundColor: Int
+        get() {
+            val stateList: ColorStateList? =
+                Utils.getColorAttr(this, android.R.attr.windowBackground)
+            return stateList?.defaultColor ?: Color.TRANSPARENT
+        }
+
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        viewModelProvider[DeviceFoldedViewModel::class.java].onConfigurationChanged(newConfig)
+        super.onConfigurationChanged(newConfig)
+    }
+
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+        viewModel.onSaveInstanceState(outState)
+        autoCredentialViewModel.onSaveInstanceState(outState)
+    }
+
+    companion object {
+        private const val DEBUG = false
+        private const val TAG = "FingerprintEnrollmentActivity"
+        private const val INTRO_TAG = "intro"
+        private const val FIND_SENSOR_TAG = "find-sensor"
+        private const val ENROLLING_TAG = "enrolling"
+        private const val FINISH_TAG = "finish"
+        private const val SKIP_SETUP_FIND_FPS_DIALOG_TAG = "skip-setup-dialog"
+        private const val ENROLLING_ERROR_DIALOG_TAG = "enrolling-error-dialog"
+        protected const val LAUNCH_CONFIRM_LOCK_ACTIVITY = 1
+    }
+}
diff --git a/tests/uitests/Android.bp b/tests/uitests/Android.bp
index d4f09a3..407b5ec 100644
--- a/tests/uitests/Android.bp
+++ b/tests/uitests/Android.bp
@@ -26,7 +26,10 @@
     platform_apis: true,
     certificate: "platform",
     test_suites: ["device-tests"],
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
 
     libs: [
         "android.test.runner",
@@ -34,6 +37,7 @@
     ],
 
     static_libs: [
+        "androidx.test.ext.junit",
         "androidx.test.rules",
         "androidx.test.uiautomator_uiautomator",
         "app-helpers-core",
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
deleted file mode 100644
index 0a84c15..0000000
--- a/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.java
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.biometrics2.ui.view;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
-import android.os.UserHandle;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.widget.LockPatternChecker;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockscreenCredential;
-import com.android.settings.biometrics2.utils.LockScreenUtil;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class FingerprintEnrollmentActivityTest {
-
-    private static final String TAG = "FingerprintEnrollmentActivityTest";
-
-    private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
-    private static final String ACTIVITY_CLASS_NAME =
-            "com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity";
-    private static final String SUW_ACTIVITY_CLASS_NAME = ACTIVITY_CLASS_NAME + "$SetupActivity";
-    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_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.";
-    private static final String RFPS_ENROLLING_TITLE = "Lift, then touch again";
-
-    private UiDevice mDevice;
-    private byte[] mToken = new byte[]{};
-    private Context mContext;
-    private boolean mFingerprintPropCallbackLaunched;
-    private boolean mCanAssumeUdfps;
-    private boolean mCanAssumeSfps;
-    private String mEnrollingTitle;
-
-    private static final int IDLE_TIMEOUT = 10000;
-
-    @Before
-    public void setUp() throws InterruptedException {
-        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mContext = InstrumentationRegistry.getContext();
-
-        // Stop every test if it is not a fingerprint device
-        assumeTrue(mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_FINGERPRINT));
-
-        final FingerprintManager fingerprintManager = mContext.getSystemService(
-                FingerprintManager.class);
-        mFingerprintPropCallbackLaunched = false;
-        fingerprintManager.addAuthenticatorsRegisteredCallback(
-                new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
-                    @Override
-                    public void onAllAuthenticatorsRegistered(
-                            List<FingerprintSensorPropertiesInternal> list) {
-                        mFingerprintPropCallbackLaunched = true;
-
-                        assertThat(list).isNotNull();
-                        assertThat(list).isNotEmpty();
-                        final FingerprintSensorPropertiesInternal prop = list.get(0);
-                        mCanAssumeUdfps = prop.isAnyUdfpsType();
-                        mCanAssumeSfps = prop.isAnySidefpsType();
-                        if (mCanAssumeUdfps) {
-                            mEnrollingTitle = UDFPS_ENROLLING_TITLE;
-                        } else if (mCanAssumeSfps) {
-                            mEnrollingTitle = SFPS_ENROLLING_TITLE;
-                        } else {
-                            mEnrollingTitle = RFPS_ENROLLING_TITLE;
-                        }
-                    }
-                });
-
-        for (long i = 0; i < IDLE_TIMEOUT && !mFingerprintPropCallbackLaunched; i += 100L) {
-            Thread.sleep(100L);
-        }
-        assertThat(mFingerprintPropCallbackLaunched).isTrue();
-
-        mDevice.pressHome();
-
-        // Stop settings before performing test
-        try {
-            mDevice.executeShellCommand("am force-stop " + SETTINGS_PACKAGE_NAME);
-        } catch (IOException e) {
-            Log.e(TAG, "Fail to stop settings app", e);
-        }
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        LockScreenUtil.resetLockscreen(TEST_PIN);
-        mDevice.pressHome();
-    }
-
-    @Test
-    public void testIntroChooseLock() {
-        final Intent intent = newActivityIntent(false);
-        mContext.startActivity(intent);
-        assertThat(mDevice.wait(Until.hasObject(By.text("Choose your backup screen lock method")),
-                IDLE_TIMEOUT)).isTrue();
-    }
-
-    private void verifyIntroPage() {
-        mDevice.waitForIdle();
-        for (long i = 0; i < IDLE_TIMEOUT; i += 100L) {
-            if (mDevice.wait(Until.hasObject(By.text("More")), 50L)) {
-                break;
-            } else if (mDevice.wait(Until.hasObject(By.text("I agree")), 50L)) {
-                break;
-            }
-        }
-
-        // Click more btn at most twice and the introduction should stay in the last page
-        UiObject2 moreBtn;
-        for (int i = 0; i < 2 && (moreBtn = mDevice.findObject(By.text("More"))) != null; ++i) {
-            moreBtn.click();
-            mDevice.waitForIdle();
-            mDevice.wait(Until.hasObject(By.text("More")), IDLE_TIMEOUT);
-        }
-
-        assertThat(mDevice.wait(Until.hasObject(By.text("No thanks")), IDLE_TIMEOUT)).isTrue();
-        assertThat(mDevice.wait(Until.hasObject(By.text("I agree")), IDLE_TIMEOUT)).isTrue();
-    }
-
-    @Test
-    public void testIntroWithGkPwHandle_withUdfps_clickStart() {
-        assumeTrue(mCanAssumeUdfps);
-
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(false);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        agreeBtn.click();
-
-        // 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 testIntroWithGkPwHandle_withUdfps_clickLottie() {
-        assumeTrue(mCanAssumeUdfps);
-
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(false);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        agreeBtn.click();
-
-        // 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 testIntroWithGkPwHandle_withSfps() {
-        assumeTrue(mCanAssumeSfps);
-
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(false);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        agreeBtn.click();
-
-        // 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 testIntroWithGkPwHandle_withRfps() {
-        assumeFalse(mCanAssumeUdfps || mCanAssumeSfps);
-
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(false);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        agreeBtn.click();
-
-        // 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 testIntroWithGkPwHandle_clickNoThanksInIntroPage() {
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(false);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 noThanksBtn = mDevice.findObject(By.text("No thanks"));
-        assertThat(noThanksBtn).isNotNull();
-        noThanksBtn.click();
-
-        // Back to home
-        mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
-        assertThat(mDevice.findObject(By.text("No thanks"))).isNull();
-    }
-
-    @Test
-    public void testIntroWithGkPwHandle_clickSkipInFindSensor() {
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(false);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        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(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();
-    }
-
-    @Test
-    public void testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw() {
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(true);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        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(doItLaterBtn).isNotNull();
-        assertThat(doItLaterBtn.isClickable()).isTrue();
-        doItLaterBtn.click();
-
-        // SkipSetupFindFpsDialog
-        assertThat(mDevice.wait(Until.hasObject(By.text("Skip fingerprint?")),
-                IDLE_TIMEOUT)).isTrue();
-        final UiObject2 skipAnywayBtn = mDevice.findObject(By.text("Skip anyway"));
-        assertThat(skipAnywayBtn).isNotNull();
-        assertThat(skipAnywayBtn.isClickable()).isTrue();
-        skipAnywayBtn.click();
-
-        // 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();
-    }
-
-    @Test
-    public void testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw() {
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchIntroWithGkPwHandle(true);
-
-        // Intro page
-        verifyIntroPage();
-        final UiObject2 agreeBtn = mDevice.findObject(By.text("I agree"));
-        assertThat(agreeBtn).isNotNull();
-        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(doItLaterBtn).isNotNull();
-        assertThat(doItLaterBtn.isClickable()).isTrue();
-        doItLaterBtn.click();
-
-        // SkipSetupFindFpsDialog
-        assertThat(mDevice.wait(Until.hasObject(By.text("Skip fingerprint?")), IDLE_TIMEOUT))
-                .isTrue();
-        final UiObject2 goBackBtn = mDevice.findObject(By.text("Go back"));
-        assertThat(goBackBtn).isNotNull();
-        assertThat(goBackBtn.isClickable()).isTrue();
-        goBackBtn.click();
-
-        // FindSensor page again
-        assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
-    }
-
-    @Test
-    public void testIntroCheckPin() {
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-        final Intent intent = newActivityIntent(false);
-        mContext.startActivity(intent);
-        assertThat(mDevice.wait(Until.hasObject(By.text("Enter your device PIN to continue")),
-                IDLE_TIMEOUT)).isTrue();
-    }
-
-    @Test
-    public void testEnrollingWithGkPwHandle() {
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchEnrollingWithGkPwHandle();
-
-        // Enrolling screen
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
-    }
-
-    @Test
-    public void testEnrollingIconTouchDialog_withSfps() {
-        assumeTrue(mCanAssumeSfps);
-
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchEnrollingWithGkPwHandle();
-
-        // Enrolling screen
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
-
-        final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
-                "illustration_lottie"));
-        assertThat(lottie).isNotNull();
-
-        lottie.click();
-        lottie.click();
-        lottie.click();
-
-        // IconTouchDialog
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text("Touch the sensor instead")), IDLE_TIMEOUT))
-                .isTrue();
-        final UiObject2 okButton = mDevice.findObject(By.text("OK"));
-        assertThat(okButton).isNotNull();
-
-        okButton.click();
-
-        // Enrolling screen again
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
-    }
-
-    @Test
-    public void testEnrollingIconTouchDialog_withRfps() {
-        assumeFalse(mCanAssumeUdfps || mCanAssumeSfps);
-
-        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
-
-        launchEnrollingWithGkPwHandle();
-
-        // Enrolling screen
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
-
-        final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
-                "fingerprint_progress_bar"));
-        assertThat(lottie).isNotNull();
-
-        lottie.click();
-        lottie.click();
-        lottie.click();
-
-        // IconTouchDialog
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text("Whoops, that\u2019s not the sensor")),
-                IDLE_TIMEOUT)).isTrue();
-        final UiObject2 okButton = mDevice.findObject(By.text("OK"));
-        assertThat(okButton).isNotNull();
-
-        okButton.click();
-
-        // Enrolling screen again
-        mDevice.waitForIdle();
-        assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
-    }
-
-    @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.wait(Until.gone(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
-    }
-
-    private void launchIntroWithGkPwHandle(boolean isSuw) {
-        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(isSuw);
-            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 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(false);
-            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);
-        final int userId = UserHandle.myUserId();
-        final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> {
-            final Intent intent = newActivityIntent(false);
-            intent.putExtra(EXTRA_SKIP_FIND_SENSOR, 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);
-    }
-
-    @NonNull
-    private Intent newActivityIntent(boolean isSuw) {
-        Intent intent = new Intent();
-        intent.setClassName(SETTINGS_PACKAGE_NAME,
-                isSuw ? SUW_ACTIVITY_CLASS_NAME : ACTIVITY_CLASS_NAME);
-        if (isSuw) {
-            intent.putExtra(EXTRA_IS_SETUP_FLOW, true);
-        }
-        intent.putExtra(EXTRA_PAGE_TRANSITION_TYPE, 1);
-        intent.putExtra(Intent.EXTRA_USER_ID, mContext.getUserId());
-        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-}
diff --git a/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.kt b/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.kt
new file mode 100644
index 0000000..49c5ac9
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivityTest.kt
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.biometrics2.ui.view
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager.FEATURE_FINGERPRINT
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
+import android.os.UserHandle
+import android.support.test.uiautomator.By
+import android.support.test.uiautomator.UiDevice
+import android.support.test.uiautomator.UiObject2
+import android.support.test.uiautomator.Until
+import android.util.Log
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.internal.widget.LockPatternChecker
+import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockscreenCredential
+import com.android.internal.widget.VerifyCredentialResponse
+import com.android.settings.biometrics2.utils.LockScreenUtil
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.io.IOException
+
+@RunWith(AndroidJUnit4::class)
+class FingerprintEnrollmentActivityTest {
+
+    private val context: Context by lazy {
+        InstrumentationRegistry.getInstrumentation().context
+    }
+
+    private val fingerprintManager: FingerprintManager by lazy {
+        context.getSystemService(FingerprintManager::class.java)!!
+    }
+
+    private var fingerprintPropCallbackLaunched = false
+    private var canAssumeUdfps = false
+    private var canAssumeSfps = false
+    private var enrollingPageTitle: String = ""
+
+    private val device: UiDevice by lazy {
+        UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+    }
+
+    @Before
+    @Throws(InterruptedException::class)
+    fun setUp() {
+        // Stop every test if it is not a fingerprint device
+        Assume.assumeTrue(context.packageManager.hasSystemFeature(FEATURE_FINGERPRINT))
+
+        fingerprintPropCallbackLaunched = false
+        fingerprintManager.addAuthenticatorsRegisteredCallback(
+            object : IFingerprintAuthenticatorsRegisteredCallback.Stub() {
+                override fun onAllAuthenticatorsRegistered(
+                    list: List<FingerprintSensorPropertiesInternal>
+                ) {
+                    fingerprintPropCallbackLaunched = true
+                    assertThat(list).isNotNull()
+                    assertThat(list).isNotEmpty()
+                    val prop = list[0]
+                    canAssumeUdfps = prop.isAnyUdfpsType
+                    canAssumeSfps = prop.isAnySidefpsType
+                    enrollingPageTitle = if (canAssumeUdfps) {
+                        UDFPS_ENROLLING_TITLE
+                    } else if (canAssumeSfps) {
+                        SFPS_ENROLLING_TITLE
+                    } else {
+                        RFPS_ENROLLING_TITLE
+                    }
+                }
+            })
+        var i: Long = 0
+        while (i < IDLE_TIMEOUT && !fingerprintPropCallbackLaunched) {
+            Thread.sleep(100L)
+            i += 100L
+        }
+        assertThat(fingerprintPropCallbackLaunched).isTrue()
+        device.pressHome()
+
+        // Stop settings before performing test
+        try {
+            device.executeShellCommand("am force-stop $SETTINGS_PACKAGE_NAME")
+        } catch (e: IOException) {
+            Log.e(TAG, "Fail to stop settings app", e)
+        }
+    }
+
+    @After
+    @Throws(Exception::class)
+    fun tearDown() {
+        LockScreenUtil.resetLockscreen(TEST_PIN)
+        device.pressHome()
+    }
+
+    @Test
+    fun testIntroChooseLock() {
+        val intent = newActivityIntent(false)
+        context.startActivity(intent)
+        assertThat(
+            device.wait(
+                Until.hasObject(By.text("Choose your backup screen lock method")),
+                IDLE_TIMEOUT
+            )
+        ).isTrue()
+    }
+
+    private fun verifyIntroPage() {
+        device.waitForIdle()
+        run {
+            var i: Long = 0
+            while (i < IDLE_TIMEOUT) {
+                if (device.wait(Until.hasObject(By.text("More")), 50L)) {
+                    break
+                } else if (device.wait(Until.hasObject(By.text("I agree")), 50L)) {
+                    break
+                }
+                i += 100L
+            }
+        }
+
+        // Click more btn at most twice and the introduction should stay in the last page
+        var moreBtn: UiObject2? = null
+        var i = 0
+        while (i < 2 && device.findObject(By.text("More")).also { moreBtn = it } != null) {
+            moreBtn!!.click()
+            device.waitForIdle()
+            device.wait(Until.hasObject(By.text("More")), IDLE_TIMEOUT)
+            ++i
+        }
+        assertThat(device.wait(Until.hasObject(By.text("No thanks")), IDLE_TIMEOUT)).isTrue()
+        assertThat(device.wait(Until.hasObject(By.text("I agree")), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_withUdfps_clickStart() {
+        Assume.assumeTrue(canAssumeUdfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(false)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindUdfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(SETTINGS_PACKAGE_NAME, "illustration_lottie")
+        )
+        assertThat(lottie).isNotNull()
+        assertThat(lottie.isClickable).isTrue()
+        val startBtn = device.findObject(By.text("Start"))
+        assertThat(startBtn.isClickable).isTrue()
+        startBtn.click()
+
+        // Enrolling page
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_withUdfps_clickLottie() {
+        Assume.assumeTrue(canAssumeUdfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(false)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindUdfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(By.res(SETTINGS_PACKAGE_NAME, "illustration_lottie"))
+        assertThat(lottie).isNotNull()
+        assertThat(lottie.isClickable).isTrue()
+        val startBtn = device.findObject(By.text("Start"))
+        assertThat(startBtn.isClickable).isTrue()
+        lottie.click()
+
+        // Enrolling page
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_withSfps() {
+        Assume.assumeTrue(canAssumeSfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(false)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindSfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.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
+    fun testIntroWithGkPwHandle_withRfps() {
+        Assume.assumeFalse(canAssumeUdfps || canAssumeSfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(false)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindRfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(SETTINGS_PACKAGE_NAME, "illustration_lottie")
+        )
+        if (lottie == null) {
+            // FindSfps page shall have an animation view if no lottie view
+            assertThat(
+                device.findObject(
+                    By.res(SETTINGS_PACKAGE_NAME, "fingerprint_sensor_location_animation")
+                )
+            ).isNotNull()
+        }
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_clickNoThanksInIntroPage() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(false)
+
+        // Intro page
+        verifyIntroPage()
+        val noThanksBtn = device.findObject(By.text("No thanks"))
+        assertThat(noThanksBtn).isNotNull()
+        noThanksBtn.click()
+
+        // Back to home
+        device.waitForWindowUpdate(SETTINGS_PACKAGE_NAME, IDLE_TIMEOUT)
+        assertThat(device.findObject(By.text("No thanks"))).isNull()
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_clickSkipInFindSensor() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(false)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindSensor page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val doItLaterBtn = device.findObject(By.text(DO_IT_LATER))
+        assertThat(doItLaterBtn).isNotNull()
+        assertThat(doItLaterBtn.isClickable).isTrue()
+        doItLaterBtn.click()
+
+        // Back to home
+        device.waitForWindowUpdate(SETTINGS_PACKAGE_NAME, IDLE_TIMEOUT)
+        assertThat(device.findObject(By.text(DO_IT_LATER))).isNull()
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(true)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindSensor page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val doItLaterBtn = device.findObject(By.text(DO_IT_LATER))
+        assertThat(doItLaterBtn).isNotNull()
+        assertThat(doItLaterBtn.isClickable).isTrue()
+        doItLaterBtn.click()
+
+        // SkipSetupFindFpsDialog
+        assertThat(device.wait(Until.hasObject(By.text("Skip fingerprint?")), IDLE_TIMEOUT)).isTrue()
+        val skipAnywayBtn = device.findObject(By.text("Skip anyway"))
+        assertThat(skipAnywayBtn).isNotNull()
+        assertThat(skipAnywayBtn.isClickable).isTrue()
+        skipAnywayBtn.click()
+
+        // Back to home
+        device.waitForWindowUpdate(SETTINGS_PACKAGE_NAME, IDLE_TIMEOUT)
+        assertThat(device.findObject(By.text("Skip anyway"))).isNull()
+        assertThat(device.findObject(By.text(DO_IT_LATER))).isNull()
+    }
+
+    @Test
+    fun testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchIntroWithGkPwHandle(true)
+
+        // Intro page
+        verifyIntroPage()
+        val agreeBtn = device.findObject(By.text("I agree"))
+        assertThat(agreeBtn).isNotNull()
+        agreeBtn.click()
+
+        // FindSensor page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val doItLaterBtn = device.findObject(By.text(DO_IT_LATER))
+        assertThat(doItLaterBtn).isNotNull()
+        assertThat(doItLaterBtn.isClickable).isTrue()
+        doItLaterBtn.click()
+
+        // SkipSetupFindFpsDialog
+        assertThat(device.wait(Until.hasObject(By.text("Skip fingerprint?")), IDLE_TIMEOUT)).isTrue()
+        val goBackBtn = device.findObject(By.text("Go back"))
+        assertThat(goBackBtn).isNotNull()
+        assertThat(goBackBtn.isClickable).isTrue()
+        goBackBtn.click()
+
+        // FindSensor page again
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testIntroCheckPin() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        val intent = newActivityIntent(false)
+        context.startActivity(intent)
+        assertThat(
+            device.wait(
+                Until.hasObject(By.text("Enter your device PIN to continue")),
+                IDLE_TIMEOUT
+            )
+        ).isTrue()
+    }
+
+    @Test
+    fun testEnrollingWithGkPwHandle() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchEnrollingWithGkPwHandle()
+
+        // Enrolling screen
+        device.waitForIdle()
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testEnrollingIconTouchDialog_withSfps() {
+        Assume.assumeTrue(canAssumeSfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchEnrollingWithGkPwHandle()
+
+        // Enrolling screen
+        device.waitForIdle()
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(SETTINGS_PACKAGE_NAME, "illustration_lottie")
+        )
+        assertThat(lottie).isNotNull()
+        lottie.click()
+        lottie.click()
+        lottie.click()
+
+        // IconTouchDialog
+        device.waitForIdle()
+        assertThat(
+            device.wait(
+                Until.hasObject(By.text("Touch the sensor instead")),
+                IDLE_TIMEOUT
+            )
+        )
+            .isTrue()
+        val okButton = device.findObject(By.text("OK"))
+        assertThat(okButton).isNotNull()
+        okButton.click()
+
+        // Enrolling screen again
+        device.waitForIdle()
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testEnrollingIconTouchDialog_withRfps() {
+        Assume.assumeFalse(canAssumeUdfps || canAssumeSfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchEnrollingWithGkPwHandle()
+
+        // Enrolling screen
+        device.waitForIdle()
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(SETTINGS_PACKAGE_NAME, "fingerprint_progress_bar")
+        )
+        assertThat(lottie).isNotNull()
+        lottie.click()
+        lottie.click()
+        lottie.click()
+
+        // IconTouchDialog
+        device.waitForIdle()
+        assertThat(
+            device.wait(
+                Until.hasObject(By.text("Whoops, that\u2019s not the sensor")),
+                IDLE_TIMEOUT
+            )
+        ).isTrue()
+        val okButton = device.findObject(By.text("OK"))
+        assertThat(okButton).isNotNull()
+        okButton.click()
+
+        // Enrolling screen again
+        device.waitForIdle()
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testFindUdfpsWithGkPwHandle_clickStart() {
+        Assume.assumeTrue(canAssumeUdfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchFindSensorWithGkPwHandle()
+
+        // FindUdfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(SETTINGS_PACKAGE_NAME, "illustration_lottie")
+        )
+        assertThat(lottie).isNotNull()
+        assertThat(lottie.isClickable).isTrue()
+        val startBtn = device.findObject(By.text("Start"))
+        assertThat(startBtn.isClickable).isTrue()
+        startBtn.click()
+
+        // Enrolling page
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testFindUdfpsWithGkPwHandle_clickLottie() {
+        Assume.assumeTrue(canAssumeUdfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchFindSensorWithGkPwHandle()
+
+        // FindUdfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(SETTINGS_PACKAGE_NAME, "illustration_lottie")
+        )
+        assertThat(lottie).isNotNull()
+        assertThat(lottie.isClickable).isTrue()
+        val startBtn = device.findObject(By.text("Start"))
+        assertThat(startBtn.isClickable).isTrue()
+        lottie.click()
+
+        // Enrolling page
+        assertThat(device.wait(Until.hasObject(By.text(enrollingPageTitle)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    @Test
+    fun testFindSfpsWithGkPwHandle() {
+        Assume.assumeTrue(canAssumeSfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchFindSensorWithGkPwHandle()
+
+        // FindSfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.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
+    fun testFindRfpsWithGkPwHandle() {
+        Assume.assumeFalse(canAssumeUdfps || canAssumeSfps)
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchFindSensorWithGkPwHandle()
+
+        // FindRfps page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val lottie = device.findObject(
+            By.res(
+                SETTINGS_PACKAGE_NAME,
+                "illustration_lottie"
+            )
+        )
+        if (lottie == null) {
+            // FindSfps page shall have an animation view if no lottie view
+            assertThat(
+                device.findObject(
+                    By.res(
+                        SETTINGS_PACKAGE_NAME,
+                        "fingerprint_sensor_location_animation"
+                    )
+                )
+            ).isNotNull()
+        }
+    }
+
+    @Test
+    fun testFindSensorWithGkPwHandle_clickSkipInFindSensor() {
+        LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true)
+        launchFindSensorWithGkPwHandle()
+
+        // FindSensor page
+        assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+        val doItLaterBtn = device.findObject(By.text(DO_IT_LATER))
+        assertThat(doItLaterBtn).isNotNull()
+        assertThat(doItLaterBtn.isClickable).isTrue()
+        doItLaterBtn.click()
+
+        // Back to home
+        device.waitForWindowUpdate(SETTINGS_PACKAGE_NAME, IDLE_TIMEOUT)
+        assertThat(device.wait(Until.gone(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
+    }
+
+    private fun launchIntroWithGkPwHandle(isSuw: Boolean) {
+        val lockPatternUtils = LockPatternUtils(context)
+        val lockscreenCredential = LockscreenCredential.createPin(TEST_PIN)
+        val userId = UserHandle.myUserId()
+        val onVerifyCallback =
+            LockPatternChecker.OnVerifyCallback { response: VerifyCredentialResponse, _: Int ->
+                val intent = newActivityIntent(isSuw)
+                intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.gatekeeperPasswordHandle)
+                context.startActivity(intent)
+            }
+        LockPatternChecker.verifyCredential(
+            lockPatternUtils, lockscreenCredential,
+            userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback
+        )
+    }
+
+    private fun launchFindSensorWithGkPwHandle() {
+        val lockPatternUtils = LockPatternUtils(context)
+        val lockscreenCredential = LockscreenCredential.createPin(TEST_PIN)
+        val userId = UserHandle.myUserId()
+        val onVerifyCallback =
+            LockPatternChecker.OnVerifyCallback { response: VerifyCredentialResponse, _: Int ->
+                val intent = newActivityIntent(false)
+                intent.putExtra(EXTRA_SKIP_INTRO, true)
+                intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.gatekeeperPasswordHandle)
+                context.startActivity(intent)
+            }
+        LockPatternChecker.verifyCredential(
+            lockPatternUtils, lockscreenCredential,
+            userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback
+        )
+    }
+
+    private fun launchEnrollingWithGkPwHandle() {
+        val lockPatternUtils = LockPatternUtils(context)
+        val lockscreenCredential = LockscreenCredential.createPin(TEST_PIN)
+        val userId = UserHandle.myUserId()
+        val onVerifyCallback =
+            LockPatternChecker.OnVerifyCallback { response: VerifyCredentialResponse, _: Int ->
+                val intent = newActivityIntent(false)
+                intent.putExtra(EXTRA_SKIP_FIND_SENSOR, true)
+                intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.gatekeeperPasswordHandle)
+                context.startActivity(intent)
+            }
+        LockPatternChecker.verifyCredential(
+            lockPatternUtils, lockscreenCredential,
+            userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback
+        )
+    }
+
+    private fun newActivityIntent(isSuw: Boolean): Intent {
+        val intent = Intent()
+        intent.setClassName(
+            SETTINGS_PACKAGE_NAME,
+            if (isSuw) SUW_ACTIVITY_CLASS_NAME else ACTIVITY_CLASS_NAME
+        )
+        if (isSuw) {
+            intent.putExtra(EXTRA_IS_SETUP_FLOW, true)
+        }
+        intent.putExtra(EXTRA_PAGE_TRANSITION_TYPE, 1)
+        intent.putExtra(Intent.EXTRA_USER_ID, context.userId)
+        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+        return intent
+    }
+
+    companion object {
+        private const val TAG = "FingerprintEnrollmentActivityTest"
+        const val SETTINGS_PACKAGE_NAME = "com.android.settings"
+        private const val ACTIVITY_CLASS_NAME =
+            "com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity"
+        private const val SUW_ACTIVITY_CLASS_NAME = "$ACTIVITY_CLASS_NAME\$SetupActivity"
+        private const val EXTRA_IS_SETUP_FLOW = "isSetupFlow"
+        private const val EXTRA_SKIP_INTRO = "skip_intro"
+        private const val EXTRA_SKIP_FIND_SENSOR = "skip_find_sensor"
+        private const val EXTRA_PAGE_TRANSITION_TYPE = "page_transition_type"
+        private const val EXTRA_KEY_GK_PW_HANDLE = "gk_pw_handle"
+        private const val TEST_PIN = "1234"
+        private const val DO_IT_LATER = "Do it later"
+        private const val UDFPS_ENROLLING_TITLE = "Touch & hold the fingerprint sensor"
+        private const val SFPS_ENROLLING_TITLE =
+            "Lift, then touch. Move your finger slightly each time."
+        private const val RFPS_ENROLLING_TITLE = "Lift, then touch again"
+        private const val IDLE_TIMEOUT = 10000L
+    }
+}
