From bbcd54dd634b9ae577d3f6f2a5a478f4fe9591c0 Mon Sep 17 00:00:00 2001 From: Jiashen Wang Date: Sun, 9 Aug 2020 20:18:13 -0700 Subject: [PATCH] Adding dialogs to warn users about the potential eSIM erase failure eUICC card could potential in the card error state and all the eSIM operations will fail which could be fixed by a reboot. Thus, we need to pop up a dialog to inform users that their eSIM profiles cannot be erased successfully. Bug: 163078560 Test: Manually tested by mocking the eUICC card error state. Mock: https://docs.google.com/presentation/d/1AVNXxPbieTX1KmoewG4mo3xWPnEZyba_h9rPcwHHcr8/edit#slide=id.p Change-Id: I102fb2de889e08554f525f2cbe1528bb9a37afd7 --- res/values/strings.xml | 14 +++ .../android/settings/MasterClearConfirm.java | 91 +++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 5829cc95cc5..4f0ea10152b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4319,6 +4319,20 @@ result from their use. + + + There is an issue erasing the downloaded SIMs + + Please reboot the device and try again. If you continue factory reset, the downloaded SIMs may remain on the device. + + Reboot + + Continue factory reset? + + Downloaded SIMs will remain on device. + + Factory reset + Your device and personal data are more vulnerable diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java index 3ace43621b6..676789edc8d 100644 --- a/src/com/android/settings/MasterClearConfirm.java +++ b/src/com/android/settings/MasterClearConfirm.java @@ -21,20 +21,26 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.ActionBar; import android.app.Activity; +import android.app.AlertDialog; import android.app.ProgressDialog; import android.app.admin.DevicePolicyManager; import android.app.admin.FactoryResetProtectionPolicy; import android.app.settings.SettingsEnums; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; +import android.os.PowerManager; import android.os.UserHandle; import android.os.UserManager; import android.service.oemlock.OemLockManager; import android.service.persistentdata.PersistentDataBlockManager; +import android.telephony.TelephonyManager; +import android.telephony.UiccSlotInfo; +import android.telephony.euicc.EuiccManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -54,6 +60,8 @@ import com.google.android.setupcompat.template.FooterButton.ButtonType; import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupdesign.GlifLayout; +import java.util.Arrays; + /** * Confirm and execute a reset of the device to a clean "just out of the box" * state. Multiple confirmations are required: first, a general "are you sure @@ -83,6 +91,89 @@ public class MasterClearConfirm extends InstrumentedFragment { return; } + // If the eSIM slot is in an error state, display a dialog to warn users that their eSIM + // profiles may not be fully deleted during FDR. + if (shouldShowEsimEraseFailureDialog()) { + Log.e(TAG, "eUICC card is in an error state. Display a dialog to warn the user."); + showEsimErrorDialog(); + return; + } + + performFactoryReset(); + } + + /** + * Returns true if the user choose to erase eSIM profile but the eUICC card is in an error + * state. + */ + private boolean shouldShowEsimEraseFailureDialog() { + EuiccManager euiccManager = getActivity().getSystemService(EuiccManager.class); + TelephonyManager telephonyManager = + getActivity().getSystemService(TelephonyManager.class); + + if (euiccManager == null || !euiccManager.isEnabled()) { + Log.i( + TAG, + "eSIM manager is disabled. No need to check eSIM slot before FDR."); + return false; + } + if (!mEraseEsims) { + Log.i( + TAG, + "eSIM does not need to be reset. No need to check eSIM slot before FDR."); + return false; + } + UiccSlotInfo[] slotInfos = telephonyManager.getUiccSlotsInfo(); + if (slotInfos == null) { + Log.i(TAG, "Unable to get UICC slots."); + return false; + } + // If getIsEuicc() returns false for an eSIM slot, it means the eSIM is in the error + // state. + return Arrays.stream(slotInfos).anyMatch( + slot -> slot != null && !slot.isRemovable() && !slot.getIsEuicc()); + } + + private void showEsimErrorDialog() { + new AlertDialog.Builder(getActivity()) + .setTitle(R.string.fdr_esim_failure_title) + .setMessage(R.string.fdr_esim_failure_text) + .setNeutralButton(R.string.dlg_cancel, + (DialogInterface.OnClickListener) (dialog, which) -> { + dialog.dismiss(); + }) + .setNegativeButton(R.string.fdr_esim_failure_reboot_btn, + (DialogInterface.OnClickListener) (dialog, which) -> { + dialog.dismiss(); + PowerManager pm = (PowerManager) getActivity() + .getSystemService(Context.POWER_SERVICE); + pm.reboot(null); + }) + .setPositiveButton(R.string.lockpassword_continue_label, + (DialogInterface.OnClickListener) (dialog, which) -> { + dialog.dismiss(); + showContinueFdrDialog(); + }) + .show(); + } + + private void showContinueFdrDialog() { + new AlertDialog.Builder(getActivity()) + .setTitle(R.string.fdr_continue_title) + .setMessage(R.string.fdr_continue_text) + .setNegativeButton(R.string.dlg_cancel, + (DialogInterface.OnClickListener) (dialog, which) -> { + dialog.dismiss(); + }) + .setPositiveButton(R.string.fdr_continue_btn, + (DialogInterface.OnClickListener) (dialog, which) -> { + dialog.dismiss(); + performFactoryReset(); + }) + .show(); + } + + private void performFactoryReset() { final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager) getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);