1/* 2 * Copyright (C) 2008 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 17package com.android.server; 18 19import android.app.ProgressDialog; 20import android.content.BroadcastReceiver; 21import android.content.Context; 22import android.content.Intent; 23import android.os.AsyncTask; 24import android.os.RecoverySystem; 25import android.os.storage.StorageManager; 26import android.util.Log; 27import android.util.Slog; 28import android.view.WindowManager; 29 30import com.android.internal.R; 31 32import java.io.IOException; 33 34public class MasterClearReceiver extends BroadcastReceiver { 35 private static final String TAG = "MasterClear"; 36 37 @Override 38 public void onReceive(final Context context, final Intent intent) { 39 if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) { 40 if (!"google.com".equals(intent.getStringExtra("from"))) { 41 Slog.w(TAG, "Ignoring master clear request -- not from trusted server."); 42 return; 43 } 44 } 45 if (Intent.ACTION_MASTER_CLEAR.equals(intent.getAction())) { 46 Slog.w(TAG, "The request uses the deprecated Intent#ACTION_MASTER_CLEAR, " 47 + "Intent#ACTION_FACTORY_RESET should be used instead."); 48 } 49 if (intent.hasExtra(Intent.EXTRA_FORCE_MASTER_CLEAR)) { 50 Slog.w(TAG, "The request uses the deprecated Intent#EXTRA_FORCE_MASTER_CLEAR, " 51 + "Intent#EXTRA_FORCE_FACTORY_RESET should be used instead."); 52 } 53 54 final boolean shutdown = intent.getBooleanExtra("shutdown", false); 55 final String reason = intent.getStringExtra(Intent.EXTRA_REASON); 56 final boolean wipeExternalStorage = intent.getBooleanExtra( 57 Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false); 58 final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false) 59 || intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false); 60 61 Slog.w(TAG, "!!! FACTORY RESET !!!"); 62 // The reboot call is blocking, so we need to do it on another thread. 63 Thread thr = new Thread("Reboot") { 64 @Override 65 public void run() { 66 try { 67 RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe); 68 Log.wtf(TAG, "Still running after master clear?!"); 69 } catch (IOException e) { 70 Slog.e(TAG, "Can't perform master clear/factory reset", e); 71 } catch (SecurityException e) { 72 Slog.e(TAG, "Can't perform master clear/factory reset", e); 73 } 74 } 75 }; 76 77 if (wipeExternalStorage) { 78 // thr will be started at the end of this task. 79 new WipeAdoptableDisksTask(context, thr).execute(); 80 } else { 81 thr.start(); 82 } 83 } 84 85 private class WipeAdoptableDisksTask extends AsyncTask<Void, Void, Void> { 86 private final Thread mChainedTask; 87 private final Context mContext; 88 private final ProgressDialog mProgressDialog; 89 90 public WipeAdoptableDisksTask(Context context, Thread chainedTask) { 91 mContext = context; 92 mChainedTask = chainedTask; 93 mProgressDialog = new ProgressDialog(context); 94 } 95 96 @Override 97 protected void onPreExecute() { 98 mProgressDialog.setIndeterminate(true); 99 mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 100 mProgressDialog.setMessage(mContext.getText(R.string.progress_erasing)); 101 mProgressDialog.show(); 102 } 103 104 @Override 105 protected Void doInBackground(Void... params) { 106 Slog.w(TAG, "Wiping adoptable disks"); 107 StorageManager sm = (StorageManager) mContext.getSystemService( 108 Context.STORAGE_SERVICE); 109 sm.wipeAdoptableDisks(); 110 return null; 111 } 112 113 @Override 114 protected void onPostExecute(Void result) { 115 mProgressDialog.dismiss(); 116 mChainedTask.start(); 117 } 118 119 } 120} 121