Merge "Support showing battery level chart first immediately after the battery level data is ready." into tm-qpr-dev
diff --git a/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java b/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java
index 3a61d5e..2a1d049 100644
--- a/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java
@@ -24,8 +24,6 @@
 import com.android.settings.R;
 import com.android.settings.password.ChooseLockSettingsHelper;
 
-import com.google.android.setupcompat.util.WizardManagerHelper;
-
 /**
  * Abstract base activity which handles the actual enrolling for biometrics.
  */
@@ -62,30 +60,18 @@
 
     @Override
     protected void onStop() {
-        super.onStop();
-
         if (mSidecar != null) {
             mSidecar.setListener(null);
         }
-
         if (!isChangingConfigurations()) {
             if (mSidecar != null) {
                 mSidecar.cancelEnrollment();
                 getSupportFragmentManager()
                         .beginTransaction().remove(mSidecar).commitAllowingStateLoss();
             }
-            if (!WizardManagerHelper.isAnySetupWizard(getIntent())
-                    && !BiometricUtils.isAnyMultiBiometricFlow(this)) {
-                setResult(RESULT_TIMEOUT);
-            }
-            finish();
         }
-    }
 
-    @Override
-    protected boolean shouldFinishWhenBackgrounded() {
-        // Prevent super.onStop() from finishing, since we handle this in our onStop().
-        return false;
+        super.onStop();
     }
 
     @Override
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
index bf4a1d4..68fbe38 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
@@ -31,11 +31,13 @@
 import com.android.settings.biometrics.BiometricEnrollBase;
 import com.android.settings.biometrics.BiometricEnrollSidecar;
 import com.android.settings.biometrics.BiometricErrorDialog;
+import com.android.settings.biometrics.BiometricUtils;
 import com.android.settings.biometrics.BiometricsEnrollEnrolling;
 import com.android.settings.slices.CustomSliceRegistry;
 
 import com.google.android.setupcompat.template.FooterBarMixin;
 import com.google.android.setupcompat.template.FooterButton;
+import com.google.android.setupcompat.util.WizardManagerHelper;
 
 import java.util.ArrayList;
 
@@ -113,6 +115,25 @@
     }
 
     @Override
+    protected void onStop() {
+        if (!isChangingConfigurations()) {
+            if (!WizardManagerHelper.isAnySetupWizard(getIntent())
+                    && !BiometricUtils.isAnyMultiBiometricFlow(this)) {
+                setResult(RESULT_TIMEOUT);
+            }
+            finish();
+        }
+
+        super.onStop();
+    }
+
+    @Override
+    protected boolean shouldFinishWhenBackgrounded() {
+        // Prevent super.onStop() from finishing, since we handle this in our onStop().
+        return false;
+    }
+
+    @Override
     public void startEnrollment() {
         super.startEnrollment();
         mPreviewFragment = (FaceEnrollPreviewFragment) getSupportFragmentManager()
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 5f9a74f..bad1bbd 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -339,8 +339,23 @@
 
     @Override
     protected void onStop() {
-        super.onStop();
+        if (!isChangingConfigurations()) {
+            if (!WizardManagerHelper.isAnySetupWizard(getIntent())
+                    && !BiometricUtils.isAnyMultiBiometricFlow(this)
+                    && !mFromSettingsSummary) {
+                setResult(RESULT_TIMEOUT);
+            }
+            finish();
+        }
         stopIconAnimation();
+
+        super.onStop();
+    }
+
+    @Override
+    protected boolean shouldFinishWhenBackgrounded() {
+        // Prevent super.onStop() from finishing, since we handle this in our onStop().
+        return false;
     }
 
     @Override
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
index 627a514..9abf38d 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
@@ -49,8 +49,8 @@
 public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
         BiometricEnrollSidecar.Listener {
 
-
     private static final String TAG = "FingerprintEnrollFindSensor";
+    private static final String SAVED_STATE_IS_NEXT_CLICKED = "is_next_clicked";
 
     @Nullable
     private FingerprintFindSensorAnimation mAnimation;
@@ -67,7 +67,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
+        final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(this);
         final List<FingerprintSensorPropertiesInternal> props =
                 fingerprintManager.getSensorPropertiesInternal();
         mCanAssumeUdfps = props != null && props.size() == 1 && props.get(0).isAnyUdfpsType();
@@ -134,12 +134,14 @@
             setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
             setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message);
         }
+        if (savedInstanceState != null) {
+            mNextClicked = savedInstanceState.getBoolean(SAVED_STATE_IS_NEXT_CLICKED, mNextClicked);
+        }
 
         // This is an entry point for SetNewPasswordController, e.g.
         // adb shell am start -a android.app.action.SET_NEW_PASSWORD
         if (mToken == null && BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) {
-            final FingerprintManager fpm = getSystemService(FingerprintManager.class);
-            fpm.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
+            fingerprintManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
                 mChallenge = challenge;
                 mSensorId = sensorId;
                 mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge);
@@ -149,11 +151,19 @@
                 // it passed in.
                 getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
 
-                startLookingForFingerprint();
+                // Do not start looking for fingerprint if this activity is re-created because it is
+                // waiting for activity result from enrolling activity.
+                if (!mNextClicked) {
+                    startLookingForFingerprint();
+                }
             });
         } else if (mToken != null) {
-            // HAT passed in from somewhere else, such as FingerprintEnrollIntroduction
-            startLookingForFingerprint();
+            // Do not start looking for fingerprint if this activity is re-created because it is
+            // waiting for activity result from enrolling activity.
+            if (!mNextClicked) {
+                // HAT passed in from somewhere else, such as FingerprintEnrollIntroduction
+                startLookingForFingerprint();
+            }
         } else {
             // There's something wrong with the enrollment flow, this should never happen.
             throw new IllegalStateException("HAT and GkPwHandle both missing...");
@@ -177,6 +187,12 @@
     }
 
     @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(SAVED_STATE_IS_NEXT_CLICKED, mNextClicked);
+    }
+
+    @Override
     public void onBackPressed() {
         stopLookingForFingerprint();
         super.onBackPressed();
@@ -240,7 +256,6 @@
     @Override
     public void onEnrollmentError(int errMsgId, CharSequence errString) {
         if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
-            mNextClicked = false;
             proceedToEnrolling(false /* cancelEnrollment */);
         } else {
             FingerprintErrorDialog.showErrorDialog(this, errMsgId);
@@ -270,6 +285,7 @@
     }
 
     private void onStartButtonClick(View view) {
+        mNextClicked = true;
         startActivityForResult(getFingerprintEnrollingIntent(), ENROLL_REQUEST);
     }
 
@@ -289,6 +305,7 @@
                     return;
                 }
             }
+            mSidecar.setListener(null);
             getSupportFragmentManager().beginTransaction().remove(mSidecar).
                     commitAllowingStateLoss();
             mSidecar = null;
@@ -341,6 +358,7 @@
                         finish();
                     } else {
                         // We came back from enrolling but it wasn't completed, start again.
+                        mNextClicked = false;
                         startLookingForFingerprint();
                     }
                     break;
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
index 16773d3..c24e9f0 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
@@ -32,7 +32,6 @@
 import com.android.settings.Utils;
 import com.android.settings.biometrics.BiometricEnrollBase;
 import com.android.settings.biometrics.BiometricUtils;
-import com.android.settings.password.ChooseLockSettingsHelper;
 
 import com.google.android.setupcompat.template.FooterBarMixin;
 import com.google.android.setupcompat.template.FooterButton;
@@ -51,6 +50,8 @@
     static final String FINGERPRINT_SUGGESTION_ACTIVITY =
             "com.android.settings.SetupFingerprintSuggestionActivity";
 
+    private boolean mIsAddAnotherOrFinish;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -109,14 +110,25 @@
     }
 
     @Override
+    protected void onStart() {
+        super.onStart();
+
+        // Reset it to false every time activity back to fg because this flag is stateless between
+        // different life cycle.
+        mIsAddAnotherOrFinish = false;
+    }
+
+    @Override
     protected void onNextButtonClick(View view) {
         updateFingerprintSuggestionEnableState();
+        finishAndToNext();
+    }
+
+    private void finishAndToNext() {
+        mIsAddAnotherOrFinish = true;
         setResult(RESULT_FINISHED);
         if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
             postEnroll();
-        } else if (mFromSettingsSummary) {
-            // Only launch fingerprint settings if enrollment was triggered through settings summary
-            launchFingerprintSettings();
         }
         finish();
     }
@@ -148,27 +160,22 @@
         }
     }
 
-    private void launchFingerprintSettings() {
-        final Intent intent = new Intent(ACTION_FINGERPRINT_SETTINGS);
-        intent.setPackage(Utils.SETTINGS_PACKAGE_NAME);
-        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
-        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
-        intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mChallenge);
-        startActivity(intent);
-        overridePendingTransition(R.anim.sud_slide_back_in, R.anim.sud_slide_back_out);
+    private void onAddAnotherButtonClick(View view) {
+        mIsAddAnotherOrFinish = true;
+        startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER);
     }
 
-    private void onAddAnotherButtonClick(View view) {
-        startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER);
+    @Override
+    protected boolean shouldFinishWhenBackgrounded() {
+        return !mIsAddAnotherOrFinish && super.shouldFinishWhenBackgrounded();
     }
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         updateFingerprintSuggestionEnableState();
         if (requestCode == BiometricUtils.REQUEST_ADD_ANOTHER && resultCode != RESULT_CANCELED) {
-            setResult(resultCode, data);
-            finish();
+            // If user cancel during "Add another", just use similar flow on "Next" button
+            finishAndToNext();
         } else {
             super.onActivityResult(requestCode, resultCode, data);
         }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index 46ea7f4..bf18ed5 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -22,6 +22,7 @@
 import static android.app.admin.DevicePolicyResources.UNDEFINED;
 
 import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
+import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY;
 
 import android.app.Activity;
 import android.app.Dialog;
@@ -62,6 +63,7 @@
 import com.android.settings.Utils;
 import com.android.settings.biometrics.BiometricEnrollBase;
 import com.android.settings.biometrics.BiometricUtils;
+import com.android.settings.core.SettingsBaseActivity;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.password.ChooseLockGeneric;
 import com.android.settings.password.ChooseLockSettingsHelper;
@@ -69,6 +71,7 @@
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.transition.SettingsTransitionHelper;
 import com.android.settingslib.widget.FooterPreference;
 import com.android.settingslib.widget.TwoTargetPreference;
 
@@ -129,6 +132,8 @@
         private static final String KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE =
                 "fingerprint_enable_keyguard_toggle";
         private static final String KEY_LAUNCHED_CONFIRM = "launched_confirm";
+        private static final String KEY_HAS_FIRST_ENROLLED = "has_first_enrolled";
+        private static final String KEY_IS_ENROLLING = "is_enrolled";
 
         private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000;
         private static final int MSG_FINGER_AUTH_SUCCESS = 1001;
@@ -140,6 +145,7 @@
         private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
 
         private static final int ADD_FINGERPRINT_REQUEST = 10;
+        private static final int AUTO_ADD_FIRST_FINGERPRINT_REQUEST = 11;
 
         protected static final boolean DEBUG = false;
 
@@ -149,10 +155,11 @@
         private boolean mInFingerprintLockout;
         private byte[] mToken;
         private boolean mLaunchedConfirm;
+        private boolean mHasFirstEnrolled = true;
         private Drawable mHighlightDrawable;
         private int mUserId;
         private final List<FooterColumn> mFooterColumns = new ArrayList<>();
-        private boolean mEnrollClicked;
+        private boolean mIsEnrolling;
 
         private long mChallenge;
 
@@ -341,6 +348,9 @@
             }
 
             mFingerprintsRenaming = new HashMap<Integer, String>();
+            mUserId = getActivity().getIntent().getIntExtra(
+                    Intent.EXTRA_USER_ID, UserHandle.myUserId());
+            mHasFirstEnrolled = mFingerprintManager.hasEnrolledFingerprints(mUserId);
 
             if (savedInstanceState != null) {
                 mFingerprintsRenaming = (HashMap<Integer, String>)
@@ -349,14 +359,21 @@
                         ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
                 mLaunchedConfirm = savedInstanceState.getBoolean(
                         KEY_LAUNCHED_CONFIRM, false);
+                mIsEnrolling = savedInstanceState.getBoolean(KEY_IS_ENROLLING, mIsEnrolling);
+                mHasFirstEnrolled = savedInstanceState.getBoolean(KEY_HAS_FIRST_ENROLLED,
+                        mHasFirstEnrolled);
             }
-            mUserId = getActivity().getIntent().getIntExtra(
-                    Intent.EXTRA_USER_ID, UserHandle.myUserId());
 
-            // Need to authenticate a session token if none
-            if (mToken == null && mLaunchedConfirm == false) {
-                mLaunchedConfirm = true;
-                launchChooseOrConfirmLock();
+            // (mLaunchedConfirm or mIsEnrolling) means that we are waiting an activity result.
+            if (!mLaunchedConfirm && !mIsEnrolling) {
+                // Need to authenticate a session token if none
+                if (mToken == null) {
+                    mLaunchedConfirm = true;
+                    launchChooseOrConfirmLock();
+                } else if (!mHasFirstEnrolled) {
+                    mIsEnrolling = true;
+                    addFirstFingerprint();
+                }
             }
             updateFooterColumns(activity);
         }
@@ -546,7 +563,7 @@
         @Override
         public void onStop() {
             super.onStop();
-            if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mEnrollClicked) {
+            if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mIsEnrolling) {
                 getActivity().finish();
             }
         }
@@ -557,13 +574,15 @@
                     mToken);
             outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm);
             outState.putSerializable("mFingerprintsRenaming", mFingerprintsRenaming);
+            outState.putBoolean(KEY_IS_ENROLLING, mIsEnrolling);
+            outState.putBoolean(KEY_HAS_FIRST_ENROLLED, mHasFirstEnrolled);
         }
 
         @Override
         public boolean onPreferenceTreeClick(Preference pref) {
             final String key = pref.getKey();
             if (KEY_FINGERPRINT_ADD.equals(key)) {
-                mEnrollClicked = true;
+                mIsEnrolling = true;
                 Intent intent = new Intent();
                 intent.setClassName(SETTINGS_PACKAGE_NAME,
                         FingerprintEnrollEnrolling.class.getName());
@@ -659,6 +678,10 @@
                                     BiometricUtils.removeGatekeeperPasswordHandle(getActivity(),
                                             data);
                                     updateAddPreference();
+                                    if (!mHasFirstEnrolled && !mIsEnrolling) {
+                                        mIsEnrolling = true;
+                                        addFirstFingerprint();
+                                    }
                         });
                     } else {
                         Log.d(TAG, "Data null or GK PW missing");
@@ -669,12 +692,19 @@
                     finish();
                 }
             } else if (requestCode == ADD_FINGERPRINT_REQUEST) {
-                mEnrollClicked = false;
+                mIsEnrolling = false;
                 if (resultCode == RESULT_TIMEOUT) {
                     Activity activity = getActivity();
                     activity.setResult(resultCode);
                     activity.finish();
                 }
+            } else if (requestCode == AUTO_ADD_FIRST_FINGERPRINT_REQUEST) {
+                mIsEnrolling = false;
+                mHasFirstEnrolled = true;
+                if (resultCode != RESULT_FINISHED) {
+                    Log.d(TAG, "Add first fingerprint fail, result:" + resultCode);
+                    finish();
+                }
             }
         }
 
@@ -746,6 +776,20 @@
             }
         }
 
+        private void addFirstFingerprint() {
+            Intent intent = new Intent();
+            intent.setClassName(SETTINGS_PACKAGE_NAME,
+                    FingerprintEnrollIntroductionInternal.class.getName());
+
+            intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true);
+            intent.putExtra(SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE,
+                    SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE);
+
+            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+            intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
+            startActivityForResult(intent, AUTO_ADD_FIRST_FINGERPRINT_REQUEST);
+        }
+
         @VisibleForTesting
         void deleteFingerPrint(Fingerprint fingerPrint) {
             mRemovalSidecar.startRemove(fingerPrint, mUserId);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java
index 82ceed6..71cdcf7 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtils.java
@@ -78,8 +78,7 @@
      * Returns the class name of the Settings page corresponding to fingerprint settings.
      */
     public String getSettingsClassName() {
-        return hasEnrolled() ? FingerprintSettings.class.getName()
-                : FingerprintEnrollIntroductionInternal.class.getName();
+        return FingerprintSettings.class.getName();
     }
 
     /**
diff --git a/src/com/android/settings/dream/DreamPickerController.java b/src/com/android/settings/dream/DreamPickerController.java
index 261db6c..f1a018f 100644
--- a/src/com/android/settings/dream/DreamPickerController.java
+++ b/src/com/android/settings/dream/DreamPickerController.java
@@ -132,7 +132,7 @@
             mActiveDream = mDreamInfo;
             mBackend.setActiveDream(mDreamInfo.componentName);
             mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
-                    SettingsEnums.ACTION_DREAM_SELECT_TYPE, SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_DREAM_SELECT_TYPE, SettingsEnums.DREAM,
                     mDreamInfo.componentName.flattenToString(), 1);
         }
 
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index cfdd851..c1cffc8 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -515,7 +515,7 @@
 
     private boolean hasOverlap(
             final Rect[] displayAreas, final int leftIndex, final int rightIndex) {
-        return displayAreas[leftIndex].right + mTextPadding * 2f > displayAreas[rightIndex].left;
+        return displayAreas[leftIndex].right + mTextPadding * 2.3f > displayAreas[rightIndex].left;
     }
 
     private void drawAxisLabelText(
diff --git a/src/com/android/settings/panel/PanelFeatureProviderImpl.java b/src/com/android/settings/panel/PanelFeatureProviderImpl.java
index a73881b..57a1ab0 100644
--- a/src/com/android/settings/panel/PanelFeatureProviderImpl.java
+++ b/src/com/android/settings/panel/PanelFeatureProviderImpl.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.util.FeatureFlagUtils;
 
 public class PanelFeatureProviderImpl implements PanelFeatureProvider {
 
@@ -49,9 +50,19 @@
             case Settings.Panel.ACTION_WIFI:
                 return WifiPanel.create(context);
             case Settings.Panel.ACTION_VOLUME:
-                return VolumePanel.create(context);
+                if (FeatureFlagUtils.isEnabled(context,
+                        FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI)) {
+                    // Redirect to the volume panel in SystemUI.
+                    Intent volumeIntent = new Intent(Settings.Panel.ACTION_VOLUME);
+                    volumeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND).setPackage(
+                            SYSTEMUI_PACKAGE_NAME);
+                    context.sendBroadcast(volumeIntent);
+                    return null;
+                } else {
+                    return VolumePanel.create(context);
+                }
         }
 
-        throw new IllegalStateException("No matching panel for: "  + panelType);
+        throw new IllegalStateException("No matching panel for: " + panelType);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java
index 55f0210..fad3abf 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensorTest.java
@@ -16,21 +16,39 @@
 
 package com.android.settings.biometrics.fingerprint;
 
+import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
+import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
+
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED;
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_SKIP;
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT;
+import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.TAG_SIDECAR;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
 import static org.robolectric.RuntimeEnvironment.application;
 
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.hardware.biometrics.ComponentInfoInternal;
+import android.hardware.biometrics.SensorProperties;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
+import android.hardware.fingerprint.FingerprintSensorProperties;
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
+import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.view.View;
+
+import androidx.fragment.app.Fragment;
 
 import com.android.settings.R;
 import com.android.settings.biometrics.BiometricEnrollBase;
@@ -40,6 +58,8 @@
 
 import com.google.android.setupcompat.PartnerCustomizationLayout;
 import com.google.android.setupcompat.template.FooterBarMixin;
+import com.google.android.setupcompat.template.FooterButton;
+import com.google.android.setupdesign.GlifLayout;
 
 import org.junit.After;
 import org.junit.Before;
@@ -51,31 +71,69 @@
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.Shadows;
+import org.robolectric.android.controller.ActivityController;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowActivity;
 import org.robolectric.shadows.ShadowActivity.IntentForResult;
 
+import java.util.ArrayList;
+
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = ShadowUtils.class)
 public class FingerprintEnrollFindSensorTest {
 
+    private static final int DEFAULT_ACTIVITY_RESULT = Activity.RESULT_CANCELED;
+
     @Mock
     private FingerprintManager mFingerprintManager;
 
+    private ActivityController<FingerprintEnrollFindSensor> mActivityController;
+
     private FingerprintEnrollFindSensor mActivity;
 
+    private void buildActivity() {
+        mActivityController = Robolectric.buildActivity(
+                FingerprintEnrollFindSensor.class,
+                new Intent()
+                        // Set the challenge token so the confirm screen will not be shown
+                        .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0])
+        );
+        mActivity = mActivityController.get();
+    }
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
         FakeFeatureFactory.setupForTest();
+        buildActivity();
+    }
 
-        mActivity = Robolectric.buildActivity(
-                FingerprintEnrollFindSensor.class,
-                new Intent()
-                        // Set the challenge token so the confirm screen will not be shown
-                        .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]))
-                .setup().get();
+    private void setupActivity_onRearDevice() {
+        final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+        props.add(newFingerprintSensorPropertiesInternal(TYPE_REAR));
+        doReturn(props).when(mFingerprintManager).getSensorPropertiesInternal();
+
+        mActivityController.setup();
+    }
+
+    private void setupActivity_onUdfpsDevice() {
+        final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+        props.add(newFingerprintSensorPropertiesInternal(TYPE_UDFPS_OPTICAL));
+        doReturn(props).when(mFingerprintManager).getSensorPropertiesInternal();
+
+        mActivityController.setup();
+    }
+
+    private FingerprintSensorPropertiesInternal newFingerprintSensorPropertiesInternal(
+            @FingerprintSensorProperties.SensorType int sensorType) {
+        return new FingerprintSensorPropertiesInternal(
+                0 /* sensorId */,
+                SensorProperties.STRENGTH_STRONG,
+                1 /* maxEnrollmentsPerUser */,
+                new ArrayList<ComponentInfoInternal>(),
+                sensorType,
+                true /* resetLockoutRequiresHardwareAuthToken */);
     }
 
     @After
@@ -83,13 +141,7 @@
         ShadowUtils.reset();
     }
 
-    @Test
-    public void enrollFingerprint_shouldProceed() {
-        EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
-
-        enrollmentCallback.onEnrollmentProgress(123);
-        enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
-
+    private void verifyStartEnrollingActivity() {
         ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
         IntentForResult startedActivity =
                 shadowActivity.getNextStartedActivityForResult();
@@ -100,6 +152,7 @@
 
     @Test
     public void enrollFingerprintTwice_shouldStartOneEnrolling() {
+        setupActivity_onRearDevice();
         EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
 
         enrollmentCallback.onEnrollmentProgress(123);
@@ -123,6 +176,8 @@
     @Config(qualifiers = "mcc999")
     @Test
     public void layoutWithoutAnimation_shouldNotCrash() {
+        setupActivity_onRearDevice();
+
         EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
         enrollmentCallback.onEnrollmentProgress(123);
         enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
@@ -137,12 +192,14 @@
 
     @Test
     public void clickSkip_shouldReturnResultSkip() {
+        setupActivity_onRearDevice();
+
         PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
         layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().performClick();
 
         ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
         assertWithMessage("result code").that(shadowActivity.getResultCode())
-                .isEqualTo(BiometricEnrollBase.RESULT_SKIP);
+                .isEqualTo(RESULT_SKIP);
     }
 
     private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
@@ -160,9 +217,404 @@
 
     @Test
     public void onActivityResult_withNullIntentShouldNotCrash() {
+        setupActivity_onRearDevice();
+
         // this should not crash
         mActivity.onActivityResult(BiometricEnrollBase.CONFIRM_REQUEST, Activity.RESULT_OK,
             null);
         assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(Activity.RESULT_CANCELED);
     }
+
+    @Test
+    public void resultFinishShallForward_onRearDevice() {
+        setupActivity_onRearDevice();
+        triggerEnrollProgressAndError_onRearDevice();
+        verifyStartEnrollingActivity();
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
+    }
+
+    @Test
+    public void resultFinishShallForward_onRearDevice_recreate() {
+        setupActivity_onRearDevice();
+        triggerEnrollProgressAndError_onRearDevice();
+        verifyStartEnrollingActivity();
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
+    }
+
+    @Test
+    public void resultSkipShallForward_onRearDevice() {
+        setupActivity_onRearDevice();
+        verifySidecar_onRearOrSfpsDevice();
+
+        triggerEnrollProgressAndError_onRearDevice();
+        verifyStartEnrollingActivity();
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
+    }
+
+    @Test
+    public void resultSkipShallForward_onRearDevice_recreate() {
+        setupActivity_onRearDevice();
+        verifySidecar_onRearOrSfpsDevice();
+
+        triggerEnrollProgressAndError_onRearDevice();
+        verifyStartEnrollingActivity();
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_SKIP, bundle);
+    }
+
+    @Test
+    public void resultTimeoutShallForward_onRearDevice() {
+        setupActivity_onRearDevice();
+        verifySidecar_onRearOrSfpsDevice();
+
+        triggerEnrollProgressAndError_onRearDevice();
+        verifyStartEnrollingActivity();
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_TIMEOUT);
+    }
+
+    @Test
+    public void resultTimeoutShallForward_onRearDevice_recreate() {
+        setupActivity_onRearDevice();
+        verifySidecar_onRearOrSfpsDevice();
+
+        triggerEnrollProgressAndError_onRearDevice();
+        verifyStartEnrollingActivity();
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_TIMEOUT, bundle);
+    }
+
+    @Test
+    public void clickLottieResultFinishShallForward_onUdfpsDevice() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickLottieView_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
+    }
+
+    @Test
+    public void clickLottieResultFinishShallForward_onUdfpsDevice_ifActivityRecycled() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickLottieView_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
+    }
+
+    @Test
+    public void clickLottieResultSkipShallForward_onUdfpsDevice() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickLottieView_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
+    }
+
+    @Test
+    public void clickLottieResultSkipShallForward_onUdfpsDevice_ifActivityRecycled() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickLottieView_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_SKIP, bundle);
+    }
+
+    @Test
+    public void clickLottieResultTimeoutShallForward_onUdfpsDevice() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickLottieView_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_TIMEOUT);
+    }
+
+    @Test
+    public void clickLottieResultTimeoutShallForward_onUdfpsDevice_ifActivityRecycled() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickLottieView_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_TIMEOUT, bundle);
+    }
+
+    @Test
+    public void clickPrimiaryButtonResultFinishShallForward_onUdfpsDevice() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickPrimaryButton_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
+    }
+
+    @Test
+    public void clickPrimiaryButtonResultFinishShallForward_onUdfpsDevice_ifActivityRecycled() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickPrimaryButton_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
+    }
+
+    @Test
+    public void clickPrimiaryButtonResultSkipShallForward_onUdfpsDevice() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickPrimaryButton_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
+    }
+
+    @Test
+    public void clickPrimaryButtonResultSkipShallForward_onUdfpsDevice_ifActivityRecycled() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickPrimaryButton_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_SKIP, bundle);
+    }
+
+    @Test
+    public void clickPrimaryButtonResultTimeoutShallForward_onUdfpsDevice() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickPrimaryButton_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+
+        // pause activity
+        mActivityController.pause().stop();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_TIMEOUT);
+    }
+
+    @Test
+    public void clickPrimaryButtonResultTimeoutShallForward_onUdfpsDevice_ifActivityRecycled() {
+        setupActivity_onUdfpsDevice();
+        verifyNoSidecar();
+
+        clickPrimaryButton_onUdfpsDevice();
+        verifyStartEnrollingActivity();
+
+        // recycle activity
+        final Bundle bundle = new Bundle();
+        mActivityController.pause().stop().saveInstanceState(bundle).destroy();
+
+        // onStop shall not change default activity result
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
+
+        gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_TIMEOUT, bundle);
+    }
+
+    private void triggerEnrollProgressAndError_onRearDevice() {
+        EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
+        enrollmentCallback.onEnrollmentProgress(123);
+        enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
+    }
+
+    private void clickPrimaryButton_onUdfpsDevice() {
+        final FooterBarMixin footerBarMixin =
+                ((GlifLayout) mActivity.findViewById(R.id.setup_wizard_layout))
+                        .getMixin(FooterBarMixin.class);
+        final FooterButton primaryButton = footerBarMixin.getPrimaryButton();
+        assertThat(primaryButton).isNotNull();
+        assertThat(primaryButton.getVisibility()).isEqualTo(View.VISIBLE);
+        primaryButton.onClick(null);
+    }
+
+    private void clickLottieView_onUdfpsDevice() {
+        final View lottieView = mActivity.findViewById(R.id.illustration_lottie);
+        assertThat(lottieView).isNotNull();
+        lottieView.performClick();
+    }
+
+    private void gotEnrollingResult_resumeActivityAndVerifyResultThenForward(
+            int testActivityResult) {
+        // resume activity
+        mActivityController.start().resume().visible();
+        verifyNoSidecar();
+
+        // onActivityResult from Enrolling activity shall be forward back
+        Shadows.shadowOf(mActivity).receiveResult(
+                new Intent(mActivity, FingerprintEnrollEnrolling.class),
+                testActivityResult,
+                null);
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
+        assertThat(mActivity.isFinishing()).isEqualTo(true);
+
+        // onStop shall not change last activity result
+        mActivityController.pause().stop().destroy();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
+    }
+
+    private void gotEnrollingResult_recreateActivityAndVerifyResultThenForward(
+            int testActivityResult, @NonNull Bundle savedInstance) {
+        // Rebuild activity and use savedInstance to restore.
+        buildActivity();
+        mActivityController.setup(savedInstance);
+        verifyNoSidecar();
+
+        // onActivityResult from Enrolling activity shall be forward back
+        Shadows.shadowOf(mActivity).receiveResult(
+                new Intent(mActivity, FingerprintEnrollEnrolling.class),
+                testActivityResult,
+                null);
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
+        assertThat(mActivity.isFinishing()).isEqualTo(true);
+
+        // onStop shall not change last activity result
+        mActivityController.pause().stop().destroy();
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
+    }
+
+    private void verifySidecar_onRearOrSfpsDevice() {
+        final Fragment sidecar = mActivity.getSupportFragmentManager().findFragmentByTag(
+                TAG_SIDECAR);
+        assertThat(sidecar).isNotNull();
+        assertThat(sidecar.isAdded()).isTrue();
+    }
+
+    private void verifyNoSidecar() {
+        final Fragment sidecar = mActivity.getSupportFragmentManager().findFragmentByTag(
+                TAG_SIDECAR);
+        if (sidecar != null) {
+            assertThat(sidecar.isAdded()).isFalse();
+        }
+    }
 }
diff --git a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java
index 6faf801..69e5e2f 100644
--- a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java
+++ b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintStatusUtilsTest.java
@@ -179,11 +179,11 @@
     }
 
     @Test
-    public void getSettingsClassName_whenNotEnrolled_returnsFingerprintEnrollInduction() {
+    public void getSettingsClassName_whenNotEnrolled_returnsFingerprintSettings() {
         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
 
         assertThat(mFingerprintStatusUtils.getSettingsClassName())
-                .isEqualTo(FingerprintEnrollIntroductionInternal.class.getName());
+                .isEqualTo(FingerprintSettings.class.getName());
     }
 
     @Test
diff --git a/tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java b/tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java
index a02c054..4b08ef8 100644
--- a/tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java
+++ b/tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java
@@ -28,6 +28,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.util.FeatureFlagUtils;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -35,6 +36,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 @RunWith(AndroidJUnit4.class)
 public class PanelFeatureProviderImplTest {
@@ -66,11 +68,27 @@
     }
 
     @Test
-    public void getPanel_volume_returnsCorrectPanel() {
+    public void getPanel_volumePanel_returnsCorrectPanel() {
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI,
+                false);
         mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, Settings.Panel.ACTION_VOLUME);
 
         final PanelContent panel = mProvider.getPanel(mContext, mBundle);
 
         assertThat(panel).isInstanceOf(VolumePanel.class);
     }
+
+    @Test
+    public void getPanel_volumePanelFlagEnabled_sendRedirectIntent() {
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI,
+                true);
+        mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, Settings.Panel.ACTION_VOLUME);
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        mProvider.getPanel(mContext, mBundle);
+
+        verify(mContext).sendBroadcast(intentCaptor.capture());
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(Settings.Panel.ACTION_VOLUME);
+        assertThat(intentCaptor.getValue().getPackage()).isEqualTo(SYSTEMUI_PACKAGE_NAME);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java b/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
index 7ff407d..07c1571 100644
--- a/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
+++ b/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
@@ -47,7 +47,6 @@
 
 import com.android.settings.Settings;
 import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal;
-import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroductionInternal;
 import com.android.settings.biometrics.fingerprint.FingerprintSettings;
 import com.android.settings.testutils.ResourcesUtils;
 
@@ -186,7 +185,7 @@
         assertSafetySourceEnabledDataSetWithSingularSummary(
                 "security_settings_fingerprint_preference_title",
                 "security_settings_fingerprint_preference_summary_none",
-                FingerprintEnrollIntroductionInternal.class.getName());
+                FingerprintSettings.class.getName());
     }
 
     @Test