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.settingslib.RestrictedLockUtils; 37 38 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 39 40 /** 41 * Confirm and execute a reset of the device to a clean "just out of the box" 42 * state. Multiple confirmations are required: first, a general "are you sure 43 * you want to do this?" prompt, followed by a keyguard pattern trace if the user 44 * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING 45 * ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is 46 * locked, et cetera, then the confirmation sequence is abandoned. 47 * 48 * This is the confirmation screen. 49 */ 50 public class MasterClearConfirm extends OptionsMenuFragment { 51 52 private View mContentView; 53 private boolean mEraseSdCard; 54 private boolean mEraseEsims; 55 56 /** 57 * The user has gone through the multiple confirmation, so now we go ahead 58 * and invoke the Checkin Service to reset the device to its factory-default 59 * state (rebooting in the process). 60 */ 61 private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() { 62 63 public void onClick(View v) { 64 if (Utils.isMonkeyRunning()) { 65 return; 66 } 67 68 final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager) 69 getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 70 final OemLockManager oemLockManager = (OemLockManager) 71 getActivity().getSystemService(Context.OEM_LOCK_SERVICE); 72 73 if (pdbManager != null && !oemLockManager.isOemUnlockAllowed() && 74 Utils.isDeviceProvisioned(getActivity())) { 75 // if OEM unlock is allowed, the persistent data block will be wiped during FR 76 // process. If disabled, it will be wiped here, unless the device is still being 77 // provisioned, in which case the persistent data block will be preserved. 78 new AsyncTask<Void, Void, Void>() { 79 int mOldOrientation; 80 ProgressDialog mProgressDialog; 81 82 @Override 83 protected Void doInBackground(Void... params) { 84 pdbManager.wipe(); 85 return null; 86 } 87 88 @Override 89 protected void onPostExecute(Void aVoid) { 90 mProgressDialog.hide(); 91 if (getActivity() != null) { 92 getActivity().setRequestedOrientation(mOldOrientation); 93 doMasterClear(); 94 } 95 } 96 97 @Override 98 protected void onPreExecute() { 99 mProgressDialog = getProgressDialog(); 100 mProgressDialog.show(); 101 102 // need to prevent orientation changes as we're about to go into 103 // a long IO request, so we won't be able to access inflate resources on flash 104 mOldOrientation = getActivity().getRequestedOrientation(); 105 getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); 106 } 107 }.execute(); 108 } else { 109 doMasterClear(); 110 } 111 } 112 113 private ProgressDialog getProgressDialog() { 114 final ProgressDialog progressDialog = new ProgressDialog(getActivity()); 115 progressDialog.setIndeterminate(true); 116 progressDialog.setCancelable(false); 117 progressDialog.setTitle( 118 getActivity().getString(R.string.master_clear_progress_title)); 119 progressDialog.setMessage( 120 getActivity().getString(R.string.master_clear_progress_text)); 121 return progressDialog; 122 } 123 }; 124 doMasterClear()125 private void doMasterClear() { 126 Intent intent = new Intent(Intent.ACTION_FACTORY_RESET); 127 intent.setPackage("android"); 128 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 129 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm"); 130 intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard); 131 intent.putExtra(Intent.EXTRA_WIPE_ESIMS, mEraseEsims); 132 getActivity().sendBroadcast(intent); 133 // Intent handling is asynchronous -- assume it will happen soon. 134 } 135 136 /** 137 * Configure the UI for the final confirmation interaction 138 */ establishFinalConfirmationState()139 private void establishFinalConfirmationState() { 140 mContentView.findViewById(R.id.execute_master_clear) 141 .setOnClickListener(mFinalClickListener); 142 } 143 144 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)145 public View onCreateView(LayoutInflater inflater, ViewGroup container, 146 Bundle savedInstanceState) { 147 final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( 148 getActivity(), UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId()); 149 if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 150 UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) { 151 return inflater.inflate(R.layout.master_clear_disallowed_screen, null); 152 } else if (admin != null) { 153 View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); 154 ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); 155 view.setVisibility(View.VISIBLE); 156 return view; 157 } 158 mContentView = inflater.inflate(R.layout.master_clear_confirm, null); 159 establishFinalConfirmationState(); 160 setAccessibilityTitle(); 161 return mContentView; 162 } 163 setAccessibilityTitle()164 private void setAccessibilityTitle() { 165 CharSequence currentTitle = getActivity().getTitle(); 166 TextView confirmationMessage = 167 (TextView) mContentView.findViewById(R.id.master_clear_confirm); 168 if (confirmationMessage != null) { 169 String accessibileText = new StringBuilder(currentTitle).append(",").append( 170 confirmationMessage.getText()).toString(); 171 getActivity().setTitle(Utils.createAccessibleSequence(currentTitle, accessibileText)); 172 } 173 } 174 175 @Override onCreate(Bundle savedInstanceState)176 public void onCreate(Bundle savedInstanceState) { 177 super.onCreate(savedInstanceState); 178 179 Bundle args = getArguments(); 180 mEraseSdCard = args != null 181 && args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA); 182 mEraseEsims = args != null 183 && args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA); 184 } 185 186 @Override getMetricsCategory()187 public int getMetricsCategory() { 188 return MetricsEvent.MASTER_CLEAR_CONFIRM; 189 } 190 } 191