Add erase eSIMs choice into factory reset

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

Bug: 37255419
Test: Included
Change-Id: Ic98974726a515b0a350b73a33093460a63c1fb8a
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 662b7db..4423e10 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -102,6 +102,38 @@
                         android:text="@string/erase_external_storage_description" />
                 </LinearLayout>
             </LinearLayout>
+            <LinearLayout android:id="@+id/erase_esim_container"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:focusable="true"
+                    android:clickable="true">
+                <CheckBox android:id="@+id/erase_esim"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center_vertical"
+                        android:paddingEnd="8dp"
+                        android:focusable="false"
+                        android:clickable="false"
+                        android:duplicateParentState="true" />
+                <LinearLayout android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center_vertical"
+                        android:orientation="vertical">
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:paddingTop="12dp"
+                        android:textSize="18sp"
+                        android:text="@string/erase_esim_storage" />
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:paddingTop="4sp"
+                        android:textSize="14sp"
+                        android:text="@string/erase_esim_storage_description" />
+                </LinearLayout>
+            </LinearLayout>
         </LinearLayout>
     </ScrollView>
     <Button
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aa85c35..fe50515 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3033,6 +3033,12 @@
     <string name="erase_external_storage_description" product="nosdcard">Erase all the data on the internal USB storage, such as music or photos</string>
     <!-- SD card & phone storage settings screen, description for check box to erase USB storage [CHAR LIMIT=NONE] -->
     <string name="erase_external_storage_description" product="default">Erase all the data on the SD card, such as music or photos</string>
+    <!-- SD card & phone storage settings screen, label for check box to erase all the carriers information on the embedded SIM card [CHAR LIMIT=30] -->
+    <string name="erase_esim_storage">Erase eSIMs</string>
+    <!-- SD card & phone storage settings screen, description for check box to erase eSIMs for default devices [CHAR LIMIT=NONE] -->
+    <string name="erase_esim_storage_description" product="default">Erase all eSIMs on the phone. This will not unsubscribe you from any of your carriers.</string>
+    <!-- SD card & phone storage settings screen, description for check box to erase eSIMs for tablets [CHAR LIMIT=NONE] -->
+    <string name="erase_esim_storage_description" product="tablet">Erase all eSIMs on the tablet. This will not unsubscribe you from any of your carriers.</string>
     <!-- SD card & phone storage settings screen, button on screen after user selects Factory data reset -->
     <string name="master_clear_button_text" product="tablet">Reset tablet</string>
     <!-- SD card & phone storage settings screen, button on screen after user selects Factory data reset -->
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index fa9410d..8b09fe3 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -33,6 +33,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.support.annotation.VisibleForTesting;
+import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -71,11 +72,14 @@
     private static final int KEYGUARD_REQUEST = 55;
 
     static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
+    static final String ERASE_ESIMS_EXTRA = "erase_esim";
 
     private View mContentView;
     private Button mInitiateButton;
     private View mExternalStorageContainer;
-    private CheckBox mExternalStorage;
+    @VisibleForTesting CheckBox mExternalStorage;
+    private View mEsimStorageContainer;
+    @VisibleForTesting CheckBox mEsimStorage;
     private ScrollView mScrollView;
 
     private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
@@ -115,9 +119,11 @@
         }
     }
 
-    private void showFinalConfirmation() {
+    @VisibleForTesting
+    void showFinalConfirmation() {
         Bundle args = new Bundle();
         args.putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked());
+        args.putBoolean(ERASE_ESIMS_EXTRA, mEsimStorage.isChecked());
         ((SettingsActivity) getActivity()).startPreferencePanel(
                 this, MasterClearConfirm.class.getName(),
                 args, R.string.master_clear_confirm_title, null, null, 0);
@@ -165,6 +171,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);
 
         /*
@@ -198,6 +206,20 @@
             });
         }
 
+        EuiccManager euiccManager =
+                        (EuiccManager) getActivity().getSystemService(Context.EUICC_SERVICE);
+        if (euiccManager.isEnabled()) {
+            mEsimStorageContainer.setOnClickListener(new View.OnClickListener() {
+
+                @Override
+                public void onClick(View v) {
+                    mEsimStorage.toggle();
+                }
+            });
+        } else {
+            mEsimStorageContainer.setVisibility(View.GONE);
+        }
+
         final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
         loadAccountList(um);
         StringBuffer contentDescription = new StringBuffer();
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index 218ebbb..153a1aa 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -51,6 +51,7 @@
 
     private View mContentView;
     private boolean mEraseSdCard;
+    private boolean mEraseEsims;
 
     /**
      * The user has gone through the multiple confirmation, so now we go ahead
@@ -125,6 +126,7 @@
         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
         intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard);
+        intent.putExtra(Intent.EXTRA_WIPE_ESIMS, mEraseEsims);
         getActivity().sendBroadcast(intent);
         // Intent handling is asynchronous -- assume it will happen soon.
     }
@@ -175,6 +177,8 @@
         Bundle args = getArguments();
         mEraseSdCard = args != null
                 && args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA);
+        mEraseEsims = args != null
+                && args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA);
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 721d0e0..98b33d3 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -17,30 +17,65 @@
 package com.android.settings;
 
 import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
 
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowActivity;
+
+
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class MasterClearTest {
+
+    @Mock
     private MasterClear mMasterClear;
     @Mock
     private ScrollView mScrollView;
     @Mock
     private LinearLayout mLinearLayout;
+    private ShadowActivity mShadowActivity;
+    private Activity mActivity;
+    private View mContentView;
+
+    private class ActivityForTest extends SettingsActivity {
+        private Bundle mArgs;
+
+        @Override
+        public void startPreferencePanel(Fragment caller, String fragmentClass, Bundle args,
+            int titleRes, CharSequence titleText, Fragment resultTo, int resultRequestCode) {
+            mArgs = args;
+        }
+
+        public Bundle getArgs() {
+            return mArgs;
+        }
+    }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mMasterClear = new MasterClear();
+        mMasterClear = spy(new MasterClear());
+        mActivity = Robolectric.setupActivity(Activity.class);
+        mShadowActivity = shadowOf(mActivity);
+        mContentView = LayoutInflater.from(mActivity).inflate(R.layout.master_clear, null);
 
         // Make scrollView only have one child
         when(mScrollView.getChildAt(0)).thenReturn(mLinearLayout);
@@ -48,6 +83,32 @@
     }
 
     @Test
+    public void testShowFinalConfirmation_EraseEsimChecked() {
+        ActivityForTest testActivity = new ActivityForTest();
+        when(mMasterClear.getActivity()).thenReturn(testActivity);
+
+        mMasterClear.mEsimStorage = (CheckBox) mContentView.findViewById(R.id.erase_esim);
+        mMasterClear.mExternalStorage = (CheckBox) 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 = (CheckBox) mContentView.findViewById(R.id.erase_esim);
+        mMasterClear.mExternalStorage = (CheckBox) 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 testHasReachedBottom_NotScrollDown_returnFalse() {
         initScrollView(100, 0, 200);