1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings; 18 19 import android.app.ProgressDialog; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.ActivityInfo; 23 import android.os.AsyncTask; 24 import android.os.Bundle; 25 import android.os.UserHandle; 26 import android.os.UserManager; 27 import android.service.oemlock.OemLockManager; 28 import android.service.persistentdata.PersistentDataBlockManager; 29 import android.view.LayoutInflater; 30 import android.view.View; 31 import android.view.ViewGroup; 32 import android.widget.Button; 33 import android.widget.TextView; 34 35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 36 import com.android.settings.core.InstrumentedFragment; 37 import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper; 38 import com.android.settingslib.RestrictedLockUtils; 39 40 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 41 42 /** 43 * Confirm and execute a reset of the device to a clean "just out of the box" 44 * state. Multiple confirmations are required: first, a general "are you sure 45 * you want to do this?" prompt, followed by a keyguard pattern trace if the user 46 * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING 47 * ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is 48 * locked, et cetera, then the confirmation sequence is abandoned. 49 * 50 * This is the confirmation screen. 51 */ 52 public class MasterClearConfirm extends InstrumentedFragment { 53 54 private View mContentView; 55 private boolean mEraseSdCard; 56 private boolean mEraseEsims; 57 58 /** 59 * The user has gone through the multiple confirmation, so now we go ahead 60 * and invoke the Checkin Service to reset the device to its factory-default 61 * state (rebooting in the process). 62 */ 63 private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() { 64 65 public void onClick(View v) { 66 if (Utils.isMonkeyRunning()) { 67 return; 68 } 69 70 final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager) 71 getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 72 final OemLockManager oemLockManager = (OemLockManager) 73 getActivity().getSystemService(Context.OEM_LOCK_SERVICE); 74 75 if (pdbManager != null && !oemLockManager.isOemUnlockAllowed() && 76 Utils.isDeviceProvisioned(getActivity())) { 77 // if OEM unlock is allowed, the persistent data block will be wiped during FR 78 // process. If disabled, it will be wiped here, unless the device is still being 79 // provisioned, in which case the persistent data block will be preserved. 80 new AsyncTask<Void, Void, Void>() { 81 int mOldOrientation; 82 ProgressDialog mProgressDialog; 83 84 @Override 85 protected Void doInBackground(Void... params) { 86 pdbManager.wipe(); 87 return null; 88 } 89 90 @Override 91 protected void onPostExecute(Void aVoid) { 92 mProgressDialog.hide(); 93 if (getActivity() != null) { 94 getActivity().setRequestedOrientation(mOldOrientation); 95 doMasterClear(); 96 } 97 } 98 99 @Override 100 protected void onPreExecute() { 101 mProgressDialog = getProgressDialog(); 102 mProgressDialog.show(); 103 104 // need to prevent orientation changes as we're about to go into 105 // a long IO request, so we won't be able to access inflate resources on flash 106 mOldOrientation = getActivity().getRequestedOrientation(); 107 getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); 108 } 109 }.execute(); 110 } else { 111 doMasterClear(); 112 } 113 } 114 115 private ProgressDialog getProgressDialog() { 116 final ProgressDialog progressDialog = new ProgressDialog(getActivity()); 117 progressDialog.setIndeterminate(true); 118 progressDialog.setCancelable(false); 119 progressDialog.setTitle( 120 getActivity().getString(R.string.master_clear_progress_title)); 121 progressDialog.setMessage( 122 getActivity().getString(R.string.master_clear_progress_text)); 123 return progressDialog; 124 } 125 }; 126 doMasterClear()127 private void doMasterClear() { 128 Intent intent = new Intent(Intent.ACTION_FACTORY_RESET); 129 intent.setPackage("android"); 130 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 131 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm"); 132 intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard); 133 intent.putExtra(Intent.EXTRA_WIPE_ESIMS, mEraseEsims); 134 getActivity().sendBroadcast(intent); 135 // Intent handling is asynchronous -- assume it will happen soon. 136 } 137 138 /** 139 * Configure the UI for the final confirmation interaction 140 */ establishFinalConfirmationState()141 private void establishFinalConfirmationState() { 142 mContentView.findViewById(R.id.execute_master_clear) 143 .setOnClickListener(mFinalClickListener); 144 } 145 146 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)147 public View onCreateView(LayoutInflater inflater, ViewGroup container, 148 Bundle savedInstanceState) { 149 final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( 150 getActivity(), UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId()); 151 if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 152 UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) { 153 return inflater.inflate(R.layout.master_clear_disallowed_screen, null); 154 } else if (admin != null) { 155 new ActionDisabledByAdminDialogHelper(getActivity()) 156 .prepareDialogBuilder(UserManager.DISALLOW_FACTORY_RESET, admin) 157 .setOnDismissListener(__ -> getActivity().finish()) 158 .show(); 159 return new View(getActivity()); 160 } 161 mContentView = inflater.inflate(R.layout.master_clear_confirm, null); 162 establishFinalConfirmationState(); 163 setAccessibilityTitle(); 164 return mContentView; 165 } 166 setAccessibilityTitle()167 private void setAccessibilityTitle() { 168 CharSequence currentTitle = getActivity().getTitle(); 169 TextView confirmationMessage = 170 (TextView) mContentView.findViewById(R.id.master_clear_confirm); 171 if (confirmationMessage != null) { 172 String accessibleText = new StringBuilder(currentTitle).append(",").append( 173 confirmationMessage.getText()).toString(); 174 getActivity().setTitle(Utils.createAccessibleSequence(currentTitle, accessibleText)); 175 } 176 } 177 178 @Override onCreate(Bundle savedInstanceState)179 public void onCreate(Bundle savedInstanceState) { 180 super.onCreate(savedInstanceState); 181 182 Bundle args = getArguments(); 183 mEraseSdCard = args != null 184 && args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA); 185 mEraseEsims = args != null 186 && args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA); 187 } 188 189 @Override getMetricsCategory()190 public int getMetricsCategory() { 191 return MetricsEvent.MASTER_CLEAR_CONFIRM; 192 } 193 } 194