• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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