Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f23151e authored by qingxi's avatar qingxi
Browse files

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
parent 06815d60
Loading
Loading
Loading
Loading
+43 −24
Original line number Diff line number Diff line
@@ -87,19 +87,19 @@ public class RecoverySystem {
    /** 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 @@ public class RecoverySystem {
        // 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 @@ public class RecoverySystem {
        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 @@ public class RecoverySystem {
            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);
                            if (isWipeEuicc) {
                                Log.e(TAG, "Error wiping euicc data, Detailed code = "
                                        + detailedCode);
                            } else {
                                Log.e(TAG, "Error retaining euicc data, Detailed code = "
                                        + detailedCode);
                            }
                        } else {
                            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);
            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)) {
                    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();
                if (isWipeEuicc) {
                    Log.e(TAG, "Wiping eUICC data interrupted", e);
                } else {
                    Log.e(TAG, "Retaining eUICC data interrupted", e);
                }
            }
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -10190,8 +10190,8 @@ public final class Settings {
         *
         * @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
+1 −1
Original line number Diff line number Diff line
@@ -200,7 +200,7 @@ public class SettingsBackupTest {
                    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,
+2 −40
Original line number Diff line number Diff line
@@ -38,24 +38,11 @@ import java.util.concurrent.TimeUnit;

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 @@ public class MasterClearReceiver extends BroadcastReceiver {
            @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 @@ public class MasterClearReceiver extends BroadcastReceiver {
                        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;
        }