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