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.pm.ActivityInfo; 22 import android.os.AsyncTask; 23 import android.service.persistentdata.PersistentDataBlockManager; 24 import com.android.internal.os.storage.ExternalStorageFormatter; 25 26 import android.app.Fragment; 27 import android.content.Intent; 28 import android.os.Bundle; 29 import android.os.UserManager; 30 import android.view.LayoutInflater; 31 import android.view.View; 32 import android.view.ViewGroup; 33 import android.widget.Button; 34 35 /** 36 * Confirm and execute a reset of the device to a clean "just out of the box" 37 * state. Multiple confirmations are required: first, a general "are you sure 38 * you want to do this?" prompt, followed by a keyguard pattern trace if the user 39 * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING 40 * ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is 41 * locked, et cetera, then the confirmation sequence is abandoned. 42 * 43 * This is the confirmation screen. 44 */ 45 public class MasterClearConfirm extends Fragment { 46 47 private View mContentView; 48 private boolean mEraseSdCard; 49 50 /** 51 * The user has gone through the multiple confirmation, so now we go ahead 52 * and invoke the Checkin Service to reset the device to its factory-default 53 * state (rebooting in the process). 54 */ 55 private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() { 56 57 public void onClick(View v) { 58 if (Utils.isMonkeyRunning()) { 59 return; 60 } 61 62 final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager) 63 getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 64 65 if (pdbManager != null && !pdbManager.getOemUnlockEnabled()) { 66 // if OEM unlock is enabled, this will be wiped during FR process. 67 final ProgressDialog progressDialog = getProgressDialog(); 68 progressDialog.show(); 69 70 // need to prevent orientation changes as we're about to go into 71 // a long IO request, so we won't be able to access inflate resources on flash 72 final int oldOrientation = getActivity().getRequestedOrientation(); 73 getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); 74 new AsyncTask<Void, Void, Void>() { 75 @Override 76 protected Void doInBackground(Void... params) { 77 pdbManager.wipe(); 78 return null; 79 } 80 81 @Override 82 protected void onPostExecute(Void aVoid) { 83 progressDialog.hide(); 84 getActivity().setRequestedOrientation(oldOrientation); 85 doMasterClear(); 86 } 87 }.execute(); 88 } else { 89 doMasterClear(); 90 } 91 } 92 93 private ProgressDialog getProgressDialog() { 94 final ProgressDialog progressDialog = new ProgressDialog(getActivity()); 95 progressDialog.setIndeterminate(true); 96 progressDialog.setCancelable(false); 97 progressDialog.setTitle( 98 getActivity().getString(R.string.master_clear_progress_title)); 99 progressDialog.setMessage( 100 getActivity().getString(R.string.master_clear_progress_text)); 101 return progressDialog; 102 } 103 }; 104 doMasterClear()105 private void doMasterClear() { 106 if (mEraseSdCard) { 107 Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET); 108 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm"); 109 intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); 110 getActivity().startService(intent); 111 } else { 112 Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); 113 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 114 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm"); 115 getActivity().sendBroadcast(intent); 116 // Intent handling is asynchronous -- assume it will happen soon. 117 } 118 } 119 120 /** 121 * Configure the UI for the final confirmation interaction 122 */ establishFinalConfirmationState()123 private void establishFinalConfirmationState() { 124 mContentView.findViewById(R.id.execute_master_clear) 125 .setOnClickListener(mFinalClickListener); 126 } 127 128 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)129 public View onCreateView(LayoutInflater inflater, ViewGroup container, 130 Bundle savedInstanceState) { 131 if (UserManager.get(getActivity()).hasUserRestriction( 132 UserManager.DISALLOW_FACTORY_RESET)) { 133 return inflater.inflate(R.layout.master_clear_disallowed_screen, null); 134 } 135 mContentView = inflater.inflate(R.layout.master_clear_confirm, null); 136 establishFinalConfirmationState(); 137 return mContentView; 138 } 139 140 @Override onCreate(Bundle savedInstanceState)141 public void onCreate(Bundle savedInstanceState) { 142 super.onCreate(savedInstanceState); 143 144 Bundle args = getArguments(); 145 mEraseSdCard = args != null && args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA); 146 } 147 } 148