Adding dialogs to warn users about the potential eSIM erase failure am: bbcd54dd63

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/12379093

Change-Id: I987fd968ff755e88942bd69409b59996a08c972a
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 629394a..2ad35e0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4321,6 +4321,20 @@
         result from their use.
     </string>
 
+    <!-- eSIM erase warning dialog. -->
+    <!-- Factory data reset erase eSIM failure title [CHAR LIMIT=50] -->
+    <string name="fdr_esim_failure_title" >There is an issue erasing the downloaded SIMs</string>
+    <!-- Factory data reset erase eSIM failure text [CHAR LIMIT=none] -->
+    <string name="fdr_esim_failure_text">Please reboot the device and try again. If you continue factory reset, the downloaded SIMs may remain on the device.</string>
+    <!-- Factory data reset erase eSIM failure reboot button text [CHAR LIMIT=none] -->
+    <string name="fdr_esim_failure_reboot_btn">Reboot</string>
+    <!-- Factory data reset continue factory data reset title [CHAR LIMIT=35] -->
+    <string name="fdr_continue_title" >Continue factory reset?</string>
+    <!-- Factory data reset continue factory data reset text [CHAR LIMIT=none] -->
+    <string name="fdr_continue_text">Downloaded SIMs will remain on device.</string>
+    <!-- Factory data reset continue factory data reset button text [CHAR LIMIT=none] -->
+    <string name="fdr_continue_btn">Factory reset</string>
+
     <!-- Warning that appears below the unknown sources switch in settings -->
     <string name="install_all_warning" product="device">
         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 3ace436..676789e 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -21,20 +21,26 @@
 
 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.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 @@
                 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);