Add checkbox to let user wipe eSIM data together with FDR

This CL add a check box for eSIM enabled devices to reset eSIM data
during factory reset of the phone.

Bug: 67500470
Test: make RunSettingsRoboTests
Change-Id: I5a81d43f23ae55f8549a5b807fdf41f36c9d3acd
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index f81c7e8..d328478 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -115,6 +115,10 @@
                         android:text="@string/erase_external_storage_description" />
                 </LinearLayout>
             </LinearLayout>
+            <include layout="@layout/reset_esim_checkbox"
+                 android:id="@+id/erase_esim_container"
+                 android:layout_width="match_parent"
+                 android:layout_height="wrap_content" />
         </LinearLayout>
     </ScrollView>
     <Button
diff --git a/res/layout/reset_esim_checkbox.xml b/res/layout/reset_esim_checkbox.xml
index e76ced0..d830bf4 100644
--- a/res/layout/reset_esim_checkbox.xml
+++ b/res/layout/reset_esim_checkbox.xml
@@ -13,7 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
@@ -21,7 +22,8 @@
     android:clickable="true"
     android:visibility="gone">
 
-    <CheckBox android:id="@+id/erase_esim"
+    <CheckBox
+        android:id="@+id/erase_esim"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
@@ -30,12 +32,14 @@
         android:clickable="false"
         android:duplicateParentState="true" />
 
-    <LinearLayout android:layout_width="match_parent"
+    <LinearLayout
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:orientation="vertical">
 
-        <TextView android:id="@+id/erase_esim_title"
+        <TextView
+            android:id="@+id/erase_esim_title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:paddingTop="@dimen/reset_checkbox_title_padding_top"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 164f6d5..c41b24f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3248,7 +3248,7 @@
     <!-- SD card & phone storage settings screen, list of items in user data storage (USB storage or SD card) that will be erased during this operation [CHAR LIMIT=NONE] -->
     <string name="master_clear_desc_also_erases_external">"<li>Music</li>\n<li>Photos</li>\n<li>Other user data</li>"</string>
     <!-- SD card & phone storage settings screen, list of items on an eSIM (embedded SIM) that will be erased during this operation [CHAR LIMIT=NONE] -->
-    <string name="master_clear_desc_also_erases_esim">"<li>Carriers on eSIM</li>"</string>
+    <string name="master_clear_desc_also_erases_esim">"<li>eSIMs</li>"</string>
     <!-- SD card & phone storage settings screen, notification if there are eSIM (embedded SIM) profiles present that the user's mobile service plan will not be canceled [CHAR LIMIT=NONE] -->
     <string name="master_clear_desc_no_cancel_mobile_plan">"\n\nThis will not cancel your mobile service plan.</string>
     <!-- SD card & phone storage settings screen, instructions about whether to also erase the external storage (SD card) when erasing the internal storage [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 3cc722b..a6006f8 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -78,6 +78,9 @@
     private static final int KEYGUARD_REQUEST = 55;
     private static final int CREDENTIAL_CONFIRM_REQUEST = 56;
 
+    private static final String KEY_SHOW_ESIM_RESET_CHECKBOX
+            = "masterclear.allow_retain_esim_profiles_after_fdr";
+
     static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
     static final String ERASE_ESIMS_EXTRA = "erase_esim";
 
@@ -85,6 +88,8 @@
     private Button mInitiateButton;
     private View mExternalStorageContainer;
     @VisibleForTesting CheckBox mExternalStorage;
+    private View mEsimStorageContainer;
+    @VisibleForTesting CheckBox mEsimStorage;
     private ScrollView mScrollView;
 
     private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
@@ -134,8 +139,7 @@
     void showFinalConfirmation() {
         Bundle args = new Bundle();
         args.putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked());
-        // TODO: Offer the user a choice to wipe eSIMs when it is technically feasible to do so.
-        args.putBoolean(ERASE_ESIMS_EXTRA, true);
+        args.putBoolean(ERASE_ESIMS_EXTRA, mEsimStorage.isChecked());
         ((SettingsActivity) getActivity()).startPreferencePanel(
                 this, MasterClearConfirm.class.getName(),
                 args, R.string.master_clear_confirm_title, null, null, 0);
@@ -214,6 +218,8 @@
         mInitiateButton.setOnClickListener(mInitiateListener);
         mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
         mExternalStorage = (CheckBox) mContentView.findViewById(R.id.erase_external);
+        mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
+        mEsimStorage = (CheckBox) mContentView.findViewById(R.id.erase_esim);
         mScrollView = (ScrollView) mContentView.findViewById(R.id.master_clear_scrollview);
 
         /*
@@ -248,11 +254,25 @@
         }
 
         if (showWipeEuicc()) {
-            final View esimAlsoErased = mContentView.findViewById(R.id.also_erases_esim);
-            esimAlsoErased.setVisibility(View.VISIBLE);
+            if (showWipeEuiccCheckbox()) {
+                TextView title = mContentView.findViewById(R.id.erase_esim_title);
+                title.setText(R.string.erase_esim_storage);
+                mEsimStorageContainer.setVisibility(View.VISIBLE);
+                mEsimStorageContainer.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        mEsimStorage.toggle();
+                    }
+                });
+            } else {
+                final View esimAlsoErased = mContentView.findViewById(R.id.also_erases_esim);
+                esimAlsoErased.setVisibility(View.VISIBLE);
 
-            final View noCancelMobilePlan = mContentView.findViewById(R.id.no_cancel_mobile_plan);
-            noCancelMobilePlan.setVisibility(View.VISIBLE);
+                final View noCancelMobilePlan = mContentView.findViewById(
+                        R.id.no_cancel_mobile_plan);
+                noCancelMobilePlan.setVisibility(View.VISIBLE);
+                mEsimStorage.setChecked(true /* checked */);
+            }
         }
 
         final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
@@ -294,6 +314,12 @@
     }
 
     @VisibleForTesting
+    boolean showWipeEuiccCheckbox() {
+        return SystemProperties
+                .getBoolean(KEY_SHOW_ESIM_RESET_CHECKBOX, false /* def */);
+    }
+
+    @VisibleForTesting
     protected boolean isEuiccEnabled(Context context) {
         EuiccManager euiccManager = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
         return euiccManager.isEnabled();
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index 53d9386..bc0fa77 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -81,8 +81,7 @@
 
         @Override
         protected Boolean doInBackground(Void... params) {
-            return mRecoverySystem.wipeEuiccData(
-                    mContext, true /* isWipeEuicc */, mPackageName);
+            return mRecoverySystem.wipeEuiccData(mContext, mPackageName);
         }
 
         @Override
diff --git a/src/com/android/settings/wrapper/RecoverySystemWrapper.java b/src/com/android/settings/wrapper/RecoverySystemWrapper.java
index 8a36969..c7ce244 100644
--- a/src/com/android/settings/wrapper/RecoverySystemWrapper.java
+++ b/src/com/android/settings/wrapper/RecoverySystemWrapper.java
@@ -29,11 +29,10 @@
     /**
      * Returns whether wipe Euicc data successfully or not.
      *
-     * @param isWipeEuicc whether we want to wipe Euicc data or not
      * @param packageName the package name of the caller app.
      */
     public boolean wipeEuiccData(
-            Context context, final boolean isWipeEuicc, final String packageName) {
-        return RecoverySystem.wipeEuiccData(context, isWipeEuicc, packageName);
+            Context context, final String packageName) {
+        return RecoverySystem.wipeEuiccData(context, packageName);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 361bc8f..ccc148c 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -33,6 +33,7 @@
 import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.CheckBox;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 
@@ -94,6 +95,32 @@
     }
 
     @Test
+    public void testShowFinalConfirmation_eraseEsimChecked() {
+        ActivityForTest testActivity = new ActivityForTest();
+        when(mMasterClear.getActivity()).thenReturn(testActivity);
+
+        mMasterClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
+        mMasterClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
+        mMasterClear.mEsimStorage.setChecked(true);
+        mMasterClear.showFinalConfirmation();
+        assertThat(testActivity.getArgs().getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
+                .isTrue();
+    }
+
+    @Test
+    public void testShowFinalConfirmation_eraseEsimUnchecked() {
+        ActivityForTest testActivity = new ActivityForTest();
+        when(mMasterClear.getActivity()).thenReturn(testActivity);
+
+        mMasterClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
+        mMasterClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
+        mMasterClear.mEsimStorage.setChecked(false);
+        mMasterClear.showFinalConfirmation();
+        assertThat(testActivity.getArgs().getBoolean(MasterClear.ERASE_ESIMS_EXTRA, true))
+                .isFalse();
+    }
+
+    @Test
     public void testShowWipeEuicc_euiccDisabled() {
         prepareEuiccState(
                 false /* isEuiccEnabled */, true /* isEuiccProvisioned */);
diff --git a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
index 354cacf..f4b5f4c 100644
--- a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
+++ b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
@@ -66,7 +66,7 @@
     public void testResetNetworkData_resetEsim() {
         mResetNetworkConfirm.mEraseEsim = true;
         doReturn(true)
-                .when(mRecoverySystem).wipeEuiccData(any(Context.class), anyBoolean(), anyString());
+                .when(mRecoverySystem).wipeEuiccData(any(Context.class), anyString());
 
         mResetNetworkConfirm.esimFactoryReset(mActivity, "" /* packageName */);
         try {
@@ -77,7 +77,7 @@
         }
 
         Assert.assertNotNull(mResetNetworkConfirm.mEraseEsimTask);
-        verify(mRecoverySystem).wipeEuiccData(any(Context.class), anyBoolean(), anyString());
+        verify(mRecoverySystem).wipeEuiccData(any(Context.class), anyString());
     }
 
     @Test
@@ -88,6 +88,6 @@
 
         Assert.assertNull(mResetNetworkConfirm.mEraseEsimTask);
         verify(mRecoverySystem, never())
-                .wipeEuiccData(any(Context.class), anyBoolean(), anyString());
+                .wipeEuiccData(any(Context.class), anyString());
     }
 }