Home | History | Annotate | Download | only in settings
      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 
    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      */
    139     private void establishFinalConfirmationState() {
    140         mContentView.findViewById(R.id.execute_master_clear)
    141                 .setOnClickListener(mFinalClickListener);
    142     }
    143 
    144     @Override
    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 
    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
    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
    187     public int getMetricsCategory() {
    188         return MetricsEvent.MASTER_CLEAR_CONFIRM;
    189     }
    190 }
    191