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.provider.Settings; 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.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 55 /** 56 * The user has gone through the multiple confirmation, so now we go ahead 57 * and invoke the Checkin Service to reset the device to its factory-default 58 * state (rebooting in the process). 59 */ 60 private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() { 61 62 public void onClick(View v) { 63 if (Utils.isMonkeyRunning()) { 64 return; 65 } 66 67 final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager) 68 getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 69 70 if (pdbManager != null && !pdbManager.getOemUnlockEnabled() && 71 Utils.isDeviceProvisioned(getActivity())) { 72 // if OEM unlock is enabled, this will be wiped during FR process. If disabled, it 73 // will be wiped here, unless the device is still being provisioned, in which case 74 // the persistent data block will be preserved. 75 new AsyncTask<Void, Void, Void>() { 76 int mOldOrientation; 77 ProgressDialog mProgressDialog; 78 79 @Override 80 protected Void doInBackground(Void... params) { 81 pdbManager.wipe(); 82 return null; 83 } 84 85 @Override 86 protected void onPostExecute(Void aVoid) { 87 mProgressDialog.hide(); 88 if (getActivity() != null) { 89 getActivity().setRequestedOrientation(mOldOrientation); 90 doMasterClear(); 91 } 92 } 93 94 @Override 95 protected void onPreExecute() { 96 mProgressDialog = getProgressDialog(); 97 mProgressDialog.show(); 98 99 // need to prevent orientation changes as we're about to go into 100 // a long IO request, so we won't be able to access inflate resources on flash 101 mOldOrientation = getActivity().getRequestedOrientation(); 102 getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); 103 } 104 }.execute(); 105 } else { 106 doMasterClear(); 107 } 108 } 109 110 private ProgressDialog getProgressDialog() { 111 final ProgressDialog progressDialog = new ProgressDialog(getActivity()); 112 progressDialog.setIndeterminate(true); 113 progressDialog.setCancelable(false); 114 progressDialog.setTitle( 115 getActivity().getString(R.string.master_clear_progress_title)); 116 progressDialog.setMessage( 117 getActivity().getString(R.string.master_clear_progress_text)); 118 return progressDialog; 119 } 120 }; 121 122 private void doMasterClear() { 123 Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); 124 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 125 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm"); 126 intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard); 127 getActivity().sendBroadcast(intent); 128 // Intent handling is asynchronous -- assume it will happen soon. 129 } 130 131 /** 132 * Configure the UI for the final confirmation interaction 133 */ 134 private void establishFinalConfirmationState() { 135 mContentView.findViewById(R.id.execute_master_clear) 136 .setOnClickListener(mFinalClickListener); 137 } 138 139 @Override 140 public View onCreateView(LayoutInflater inflater, ViewGroup container, 141 Bundle savedInstanceState) { 142 final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( 143 getActivity(), UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId()); 144 if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 145 UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) { 146 return inflater.inflate(R.layout.master_clear_disallowed_screen, null); 147 } else if (admin != null) { 148 View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); 149 ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); 150 view.setVisibility(View.VISIBLE); 151 return view; 152 } 153 mContentView = inflater.inflate(R.layout.master_clear_confirm, null); 154 establishFinalConfirmationState(); 155 setAccessibilityTitle(); 156 return mContentView; 157 } 158 159 private void setAccessibilityTitle() { 160 CharSequence currentTitle = getActivity().getTitle(); 161 TextView confirmationMessage = 162 (TextView) mContentView.findViewById(R.id.master_clear_confirm); 163 if (confirmationMessage != null) { 164 String accessibileText = new StringBuilder(currentTitle).append(",").append( 165 confirmationMessage.getText()).toString(); 166 getActivity().setTitle(Utils.createAccessibleSequence(currentTitle, accessibileText)); 167 } 168 } 169 170 @Override 171 public void onCreate(Bundle savedInstanceState) { 172 super.onCreate(savedInstanceState); 173 174 Bundle args = getArguments(); 175 mEraseSdCard = args != null 176 && args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA); 177 } 178 179 @Override 180 protected int getMetricsCategory() { 181 return MetricsEvent.MASTER_CLEAR_CONFIRM; 182 } 183 } 184