• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server;
18 
19 import android.app.ProgressDialog;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.AsyncTask;
24 import android.os.RecoverySystem;
25 import android.os.storage.StorageManager;
26 import android.util.Log;
27 import android.util.Slog;
28 import android.view.WindowManager;
29 
30 import com.android.internal.R;
31 
32 import java.io.IOException;
33 
34 public class MasterClearReceiver extends BroadcastReceiver {
35     private static final String TAG = "MasterClear";
36 
37     @Override
onReceive(final Context context, final Intent intent)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 
WipeAdoptableDisksTask(Context context, Thread chainedTask)90         public WipeAdoptableDisksTask(Context context, Thread chainedTask) {
91             mContext = context;
92             mChainedTask = chainedTask;
93             mProgressDialog = new ProgressDialog(context);
94         }
95 
96         @Override
onPreExecute()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
doInBackground(Void... params)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
onPostExecute(Void result)114         protected void onPostExecute(Void result) {
115             mProgressDialog.dismiss();
116             mChainedTask.start();
117         }
118 
119     }
120 }
121