Add factory reset intent to the settings app.

Bug: 302016478
Test: local
Change-Id: I784395931b32746cb45a447b330ea8d57c17b2fe
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 06e0143..1bd37da 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,6 +16,11 @@
         android:name="com.android.settings.USE_BIOMETRIC_PROVIDER"
         android:protectionLevel="signature|privileged"/>
 
+    <!-- Permissions for acting as the factory reset preparation application. -->
+    <permission
+        android:name="com.android.settings.permissions.PREPARE_FACTORY_RESET"
+        android:protectionLevel="signature|privileged"/>
+
     <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
     <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
diff --git a/src/com/android/settings/MainClear.java b/src/com/android/settings/MainClear.java
index 55d0af9..58fc0d5 100644
--- a/src/com/android/settings/MainClear.java
+++ b/src/com/android/settings/MainClear.java
@@ -94,7 +94,6 @@
     static final int KEYGUARD_REQUEST = 55;
     @VisibleForTesting
     static final int CREDENTIAL_CONFIRM_REQUEST = 56;
-
     private static final String KEY_SHOW_ESIM_RESET_CHECKBOX =
             "masterclear.allow_retain_esim_profiles_after_fdr";
 
diff --git a/src/com/android/settings/system/FactoryResetPreferenceController.java b/src/com/android/settings/system/FactoryResetPreferenceController.java
index 6e010c1..739a0a7 100644
--- a/src/com/android/settings/system/FactoryResetPreferenceController.java
+++ b/src/com/android/settings/system/FactoryResetPreferenceController.java
@@ -17,18 +17,32 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.UserManager;
+import android.util.Log;
 
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
 import androidx.preference.Preference;
 
-import com.android.settings.R;
 import com.android.settings.Settings;
-import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.factory_reset.Flags;
 
 public class FactoryResetPreferenceController extends BasePreferenceController {
 
+    private static final String TAG = "FactoryResetPreference";
+
+    private static final String ACTION_PREPARE_FACTORY_RESET =
+            "com.android.settings.ACTION_PREPARE_FACTORY_RESET";
+
+    private static final String PREPARE_FACTORY_RESET_PERMISSION =
+            "com.android.settings.permissions.PREPARE_FACTORY_RESET";
+
     private final UserManager mUm;
+    private ActivityResultLauncher<Intent> mFactoryResetPreparationLauncher;
 
     public FactoryResetPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
@@ -44,10 +58,73 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (mPreferenceKey.equals(preference.getKey())) {
-            final Intent intent = new Intent(mContext, Settings.FactoryResetActivity.class);
-            mContext.startActivity(intent);
+            if (Flags.enableFactoryResetWizard()) {
+                startFactoryResetPreparationActivity();
+            } else {
+                startFactoryResetActivity();
+            }
             return true;
         }
         return false;
     }
+
+    private void startFactoryResetPreparationActivity() {
+        Intent prepareFactoryResetIntent = getPrepareFactoryResetIntent();
+        if (prepareFactoryResetIntent != null && mFactoryResetPreparationLauncher != null) {
+            mFactoryResetPreparationLauncher.launch(prepareFactoryResetIntent);
+        } else {
+            startFactoryResetActivity();
+        }
+    }
+
+    // We check that the activity that can handle the factory reset preparation action is indeed
+    // a system app with proper permissions.
+    private Intent getPrepareFactoryResetIntent() {
+        final Intent prepareFactoryResetWizardRequest = new Intent(ACTION_PREPARE_FACTORY_RESET);
+        final PackageManager pm = mContext.getPackageManager();
+        final ResolveInfo resolution = pm.resolveActivity(prepareFactoryResetWizardRequest, 0);
+        if (resolution != null
+                && resolution.activityInfo != null) {
+            String packageName = resolution.activityInfo.packageName;
+            PackageInfo factoryResetWizardPackageInfo;
+            try {
+                factoryResetWizardPackageInfo = pm.getPackageInfo(packageName, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.e(TAG, "Unable to resolve a Factory Reset Handler Application");
+                return null;
+            }
+            if (factoryResetWizardPackageInfo.requestedPermissions == null
+                    || factoryResetWizardPackageInfo.requestedPermissions.length == 0) {
+                Log.e(TAG, "Factory Reset Handler has no permissions requested.");
+                return null;
+            }
+            for (int i = 0; i < factoryResetWizardPackageInfo.requestedPermissions.length; i++) {
+                String permission = factoryResetWizardPackageInfo.requestedPermissions[i];
+                boolean isGranted =
+                        (factoryResetWizardPackageInfo.requestedPermissionsFlags[i]
+                                & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
+                if (permission.equals(PREPARE_FACTORY_RESET_PERMISSION) && isGranted) {
+                    return prepareFactoryResetWizardRequest;
+                }
+            }
+            return prepareFactoryResetWizardRequest;
+        }
+        Log.i(TAG, "Unable to resolve a Factory Reset Handler Activity");
+        return null;
+    }
+
+    void setFragment(ResetDashboardFragment fragment) {
+        if (Flags.enableFactoryResetWizard()) {
+            mFactoryResetPreparationLauncher = fragment.registerForActivityResult(
+                    new ActivityResultContracts.StartActivityForResult(),
+                    result -> {
+                        startFactoryResetActivity();
+                    });
+        }
+    }
+
+    private void startFactoryResetActivity() {
+        final Intent intent = new Intent(mContext, Settings.FactoryResetActivity.class);
+        mContext.startActivity(intent);
+    }
 }
diff --git a/src/com/android/settings/system/ResetDashboardFragment.java b/src/com/android/settings/system/ResetDashboardFragment.java
index 662edc5..a8704a5 100644
--- a/src/com/android/settings/system/ResetDashboardFragment.java
+++ b/src/com/android/settings/system/ResetDashboardFragment.java
@@ -65,6 +65,11 @@
         if (SubscriptionUtil.isSimHardwareVisible(context)) {
             use(EraseEuiccDataController.class).setFragment(this);
         }
+        FactoryResetPreferenceController factoryResetPreferenceController =
+                use(FactoryResetPreferenceController.class);
+        if (factoryResetPreferenceController != null) {
+            factoryResetPreferenceController.setFragment(this);
+        }
     }
 
     @Override