Move eSIM factory reset implementation to RecoverySystem

This CL reverts the implementation of eSIM factory reset in
MasterClearReceiver and uses RecoverySystem#rebootWipeUserData to erase
eSIM data. Besides this, when the eSIM data isn't erased, we should call
EuiccManager#retainSubscriptionsForFactoryReset to let the fastboot know
that.

Bug: 62957212
Test: TreeHugger
Change-Id: I08ab9d53ec4fc73a65e8e7d0c39ac95b2d44d012
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 6f458e0..2c6c7f9 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -87,19 +87,19 @@
     /** Send progress to listeners no more often than this (in ms). */
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
-    private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s
+    private static final long DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 30000L; // 30 s
 
-    private static final long MIN_EUICC_WIPING_TIMEOUT_MILLIS = 5000L; // 5 s
+    private static final long MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 5000L; // 5 s
 
-    private static final long MAX_EUICC_WIPING_TIMEOUT_MILLIS = 60000L; // 60 s
+    private static final long MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 60000L; // 60 s
 
     /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static final File RECOVERY_DIR = new File("/cache/recovery");
     private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
     private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install");
     private static final String LAST_PREFIX = "last_";
-    private static final String ACTION_WIPE_EUICC_DATA =
-            "com.android.internal.action.WIPE_EUICC_DATA";
+    private static final String ACTION_EUICC_FACTORY_RESET =
+            "com.android.internal.action.EUICC_FACTORY_RESET";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -751,9 +751,7 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
-        if (wipeEuicc) {
-            wipeEuiccData(context);
-        }
+        wipeEuiccData(context, wipeEuicc);
 
         String shutdownArg = null;
         if (shutdown) {
@@ -769,7 +767,7 @@
         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
     }
 
-    private static void wipeEuiccData(Context context) {
+    private static void wipeEuiccData(Context context, final boolean isWipeEuicc) {
         EuiccManager euiccManager = (EuiccManager) context.getSystemService(
                 Context.EUICC_SERVICE);
         if (euiccManager != null && euiccManager.isEnabled()) {
@@ -778,48 +776,69 @@
             BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
-                    if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) {
+                    if (ACTION_EUICC_FACTORY_RESET.equals(intent.getAction())) {
                         if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
                             int detailedCode = intent.getIntExtra(
                                     EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
-                            Log.e(TAG, "Error wiping euicc data, Detailed code = "
-                                    + detailedCode);
+                            if (isWipeEuicc) {
+                                Log.e(TAG, "Error wiping euicc data, Detailed code = "
+                                        + detailedCode);
+                            } else {
+                                Log.e(TAG, "Error retaining euicc data, Detailed code = "
+                                        + detailedCode);
+                            }
                         } else {
-                            Log.d(TAG, "Successfully wiped euicc data.");
+                            if (isWipeEuicc) {
+                                Log.d(TAG, "Successfully wiped euicc data.");
+                            } else {
+                                Log.d(TAG, "Successfully retained euicc data.");
+                            }
                         }
                         euiccFactoryResetLatch.countDown();
                     }
                 }
             };
 
-            Intent intent = new Intent(ACTION_WIPE_EUICC_DATA);
+            Intent intent = new Intent(ACTION_EUICC_FACTORY_RESET);
             intent.setPackage("android");
             PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
                     context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
             IntentFilter filterConsent = new IntentFilter();
-            filterConsent.addAction(ACTION_WIPE_EUICC_DATA);
+            filterConsent.addAction(ACTION_EUICC_FACTORY_RESET);
             HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread");
             euiccHandlerThread.start();
             Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
             context.registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler);
-            euiccManager.eraseSubscriptions(callbackIntent);
+            if (isWipeEuicc) {
+                euiccManager.eraseSubscriptions(callbackIntent);
+            } else {
+                euiccManager.retainSubscriptionsForFactoryReset(callbackIntent);
+            }
             try {
                 long waitingTimeMillis = Settings.Global.getLong(
                         context.getContentResolver(),
-                        Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
-                        DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS);
-                if (waitingTimeMillis < MIN_EUICC_WIPING_TIMEOUT_MILLIS) {
-                    waitingTimeMillis = MIN_EUICC_WIPING_TIMEOUT_MILLIS;
-                } else if (waitingTimeMillis > MAX_EUICC_WIPING_TIMEOUT_MILLIS) {
-                    waitingTimeMillis = MAX_EUICC_WIPING_TIMEOUT_MILLIS;
+                        Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
+                        DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS);
+                if (waitingTimeMillis < MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS;
+                } else if (waitingTimeMillis > MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS;
                 }
                 if (!euiccFactoryResetLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
-                    Log.e(TAG, "Timeout wiping eUICC data.");
+                    if (isWipeEuicc) {
+                        Log.e(TAG, "Timeout wiping eUICC data.");
+                    } else {
+                        Log.e(TAG, "Timeout retaining eUICC data.");
+                    }
                 }
                 context.unregisterReceiver(euiccWipeFinishReceiver);
             } catch (InterruptedException e) {
                 Thread.currentThread().interrupt();
-                Log.e(TAG, "Wiping eUICC data interrupted", e);
+                if (isWipeEuicc) {
+                    Log.e(TAG, "Wiping eUICC data interrupted", e);
+                } else {
+                    Log.e(TAG, "Retaining eUICC data interrupted", e);
+                }
             }
         }
     }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6f54e36..8e3e378 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10190,8 +10190,8 @@
          *
          * @hide
          */
-        public static final String EUICC_WIPING_TIMEOUT_MILLIS =
-                "euicc_wiping_timeout_millis";
+        public static final String EUICC_FACTORY_RESET_TIMEOUT_MILLIS =
+                "euicc_factory_reset_timeout_millis";
 
         /**
          * Settings to backup. This is here so that it's in the same place as the settings
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 2f064c9f..5af2396 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -200,7 +200,7 @@
                     Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
                     Settings.Global.ERROR_LOGCAT_PREFIX,
                     Settings.Global.EUICC_PROVISIONED,
-                    Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
+                    Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
                     Settings.Global.FANCY_IME_ANIMATIONS,
                     Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
                     Settings.Global.FSTRIM_MANDATORY_INTERVAL,
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 516f8f6..06c46b9 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -38,24 +38,11 @@
 
 public class MasterClearReceiver extends BroadcastReceiver {
     private static final String TAG = "MasterClear";
-    private static final String ACTION_WIPE_EUICC_DATA =
-            "com.android.internal.action.wipe_euicc_data";
-    private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s
     private boolean mWipeExternalStorage;
     private boolean mWipeEsims;
-    private static CountDownLatch mEuiccFactoryResetLatch;
 
     @Override
     public void onReceive(final Context context, final Intent intent) {
-        if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) {
-            if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
-                int detailedCode = intent.getIntExtra(
-                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
-                Slog.e(TAG, "Error wiping euicc data, Detailed code = " + detailedCode);
-            }
-            mEuiccFactoryResetLatch.countDown();
-            return;
-        }
         if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
             if (!"google.com".equals(intent.getStringExtra("from"))) {
                 Slog.w(TAG, "Ignoring master clear request -- not from trusted server.");
@@ -84,7 +71,8 @@
             @Override
             public void run() {
                 try {
-                    RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe);
+                    RecoverySystem
+                            .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims);
                     Log.wtf(TAG, "Still running after master clear?!");
                 } catch (IOException e) {
                     Slog.e(TAG, "Can't perform master clear/factory reset", e);
@@ -129,32 +117,6 @@
                         Context.STORAGE_SERVICE);
                 sm.wipeAdoptableDisks();
             }
-            if (mWipeEsims) {
-                EuiccManager euiccManager = (EuiccManager) mContext.getSystemService(
-                        Context.EUICC_SERVICE);
-                Intent intent = new Intent(mContext, MasterClearReceiver.class);
-                intent.setAction(ACTION_WIPE_EUICC_DATA);
-                PendingIntent callbackIntent = PendingIntent.getBroadcast(
-                        mContext,
-                        0 /* requestCode */,
-                        intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT);
-                mEuiccFactoryResetLatch = new CountDownLatch(1);
-                euiccManager.eraseSubscriptions(callbackIntent);
-                try {
-                    long waitingTime = Settings.Global.getLong(
-                            mContext.getContentResolver(),
-                            Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
-                            DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS);
-
-                    if (!mEuiccFactoryResetLatch.await(waitingTime, TimeUnit.MILLISECONDS)) {
-                        Slog.e(TAG, "Timeout wiping eUICC data.");
-                    }
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    Slog.e(TAG, "Wiping eUICC data interrupted", e);
-                }
-            }
             return null;
         }