• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
20 
21 import android.app.AlertDialog;
22 import android.bluetooth.BluetoothAdapter;
23 import android.bluetooth.BluetoothManager;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.net.ConnectivityManager;
27 import android.net.NetworkPolicyManager;
28 import android.net.Uri;
29 import android.net.wifi.WifiManager;
30 import android.os.AsyncTask;
31 import android.os.Bundle;
32 import android.os.RecoverySystem;
33 import android.os.UserHandle;
34 import android.os.UserManager;
35 import android.provider.Telephony;
36 import android.support.annotation.VisibleForTesting;
37 import android.telephony.SubscriptionManager;
38 import android.telephony.TelephonyManager;
39 import android.util.Log;
40 import android.view.LayoutInflater;
41 import android.view.View;
42 import android.view.ViewGroup;
43 import android.widget.Button;
44 import android.widget.Toast;
45 
46 import com.android.ims.ImsManager;
47 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
48 import com.android.internal.telephony.PhoneConstants;
49 import com.android.settings.core.InstrumentedFragment;
50 import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
51 import com.android.settings.network.ApnSettings;
52 import com.android.settingslib.RestrictedLockUtils;
53 
54 /**
55  * Confirm and execute a reset of the network settings to a clean "just out of the box"
56  * state.  Multiple confirmations are required: first, a general "are you sure
57  * you want to do this?" prompt, followed by a keyguard pattern trace if the user
58  * has defined one, followed by a final strongly-worded "THIS WILL RESET EVERYTHING"
59  * prompt.  If at any time the phone is allowed to go to sleep, is
60  * locked, et cetera, then the confirmation sequence is abandoned.
61  *
62  * This is the confirmation screen.
63  */
64 public class ResetNetworkConfirm extends InstrumentedFragment {
65 
66     private View mContentView;
67     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
68     @VisibleForTesting boolean mEraseEsim;
69     @VisibleForTesting EraseEsimAsyncTask mEraseEsimTask;
70 
71     /**
72      * Async task used to erase all the eSIM profiles from the phone. If error happens during
73      * erasing eSIM profiles or timeout, an error msg is shown.
74      */
75     private static class EraseEsimAsyncTask extends AsyncTask<Void, Void, Boolean> {
76         private final Context mContext;
77         private final String mPackageName;
78 
EraseEsimAsyncTask(Context context, String packageName)79         EraseEsimAsyncTask(Context context, String packageName) {
80             mContext = context;
81             mPackageName = packageName;
82         }
83 
84         @Override
doInBackground(Void... params)85         protected Boolean doInBackground(Void... params) {
86             return RecoverySystem.wipeEuiccData(mContext, mPackageName);
87         }
88 
89         @Override
onPostExecute(Boolean succeeded)90         protected void onPostExecute(Boolean succeeded) {
91             if (succeeded) {
92                 Toast.makeText(mContext, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
93                         .show();
94             } else {
95                 new AlertDialog.Builder(mContext)
96                         .setTitle(R.string.reset_esim_error_title)
97                         .setMessage(R.string.reset_esim_error_msg)
98                         .setPositiveButton(android.R.string.ok, null /* listener */)
99                         .show();
100             }
101         }
102     }
103 
104     /**
105      * The user has gone through the multiple confirmation, so now we go ahead
106      * and reset the network settings to its factory-default state.
107      */
108     private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
109 
110         @Override
111         public void onClick(View v) {
112             if (Utils.isMonkeyRunning()) {
113                 return;
114             }
115             // TODO maybe show a progress screen if this ends up taking a while and won't let user
116             // go back until the tasks finished.
117             Context context = getActivity();
118 
119             ConnectivityManager connectivityManager = (ConnectivityManager)
120                     context.getSystemService(Context.CONNECTIVITY_SERVICE);
121             if (connectivityManager != null) {
122                 connectivityManager.factoryReset();
123             }
124 
125             WifiManager wifiManager = (WifiManager)
126                     context.getSystemService(Context.WIFI_SERVICE);
127             if (wifiManager != null) {
128                 wifiManager.factoryReset();
129             }
130 
131             TelephonyManager telephonyManager = (TelephonyManager)
132                     context.getSystemService(Context.TELEPHONY_SERVICE);
133             if (telephonyManager != null) {
134                 telephonyManager.factoryReset(mSubId);
135             }
136 
137             NetworkPolicyManager policyManager = (NetworkPolicyManager)
138                     context.getSystemService(Context.NETWORK_POLICY_SERVICE);
139             if (policyManager != null) {
140                 String subscriberId = telephonyManager.getSubscriberId(mSubId);
141                 policyManager.factoryReset(subscriberId);
142             }
143 
144             BluetoothManager btManager = (BluetoothManager)
145                     context.getSystemService(Context.BLUETOOTH_SERVICE);
146             if (btManager != null) {
147                 BluetoothAdapter btAdapter = btManager.getAdapter();
148                 if (btAdapter != null) {
149                     btAdapter.factoryReset();
150                 }
151             }
152 
153             ImsManager.factoryReset(context);
154             restoreDefaultApn(context);
155             esimFactoryReset(context, context.getPackageName());
156             // There has been issues when Sms raw table somehow stores orphan
157             // fragments. They lead to garbled message when new fragments come
158             // in and combied with those stale ones. In case this happens again,
159             // user can reset all network settings which will clean up this table.
160             cleanUpSmsRawTable(context);
161         }
162     };
163 
cleanUpSmsRawTable(Context context)164     private void cleanUpSmsRawTable(Context context) {
165         ContentResolver resolver = context.getContentResolver();
166         Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
167         resolver.delete(uri, null, null);
168     }
169 
170     @VisibleForTesting
esimFactoryReset(Context context, String packageName)171     void esimFactoryReset(Context context, String packageName) {
172         if (mEraseEsim) {
173             mEraseEsimTask = new EraseEsimAsyncTask(context, packageName);
174             mEraseEsimTask.execute();
175         } else {
176             Toast.makeText(context, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
177                     .show();
178         }
179     }
180 
181     /**
182      * Restore APN settings to default.
183      */
restoreDefaultApn(Context context)184     private void restoreDefaultApn(Context context) {
185         Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI);
186 
187         if (SubscriptionManager.isUsableSubIdValue(mSubId)) {
188             uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(mSubId));
189         }
190 
191         ContentResolver resolver = context.getContentResolver();
192         resolver.delete(uri, null, null);
193     }
194 
195     /**
196      * Configure the UI for the final confirmation interaction
197      */
establishFinalConfirmationState()198     private void establishFinalConfirmationState() {
199         mContentView.findViewById(R.id.execute_reset_network)
200                 .setOnClickListener(mFinalClickListener);
201     }
202 
203     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)204     public View onCreateView(LayoutInflater inflater, ViewGroup container,
205             Bundle savedInstanceState) {
206         final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
207                 getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
208         if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
209                 UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
210             return inflater.inflate(R.layout.network_reset_disallowed_screen, null);
211         } else if (admin != null) {
212             new ActionDisabledByAdminDialogHelper(getActivity())
213                     .prepareDialogBuilder(UserManager.DISALLOW_NETWORK_RESET, admin)
214                     .setOnDismissListener(__ -> getActivity().finish())
215                     .show();
216             return new View(getContext());
217         }
218         mContentView = inflater.inflate(R.layout.reset_network_confirm, null);
219         establishFinalConfirmationState();
220         return mContentView;
221     }
222 
223     @Override
onCreate(Bundle savedInstanceState)224     public void onCreate(Bundle savedInstanceState) {
225         super.onCreate(savedInstanceState);
226 
227         Bundle args = getArguments();
228         if (args != null) {
229             mSubId = args.getInt(PhoneConstants.SUBSCRIPTION_KEY,
230                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
231             mEraseEsim = args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA);
232         }
233     }
234 
235     @Override
onDestroy()236     public void onDestroy() {
237         if (mEraseEsimTask != null) {
238             mEraseEsimTask.cancel(true /* mayInterruptIfRunning */);
239             mEraseEsimTask = null;
240         }
241         super.onDestroy();
242     }
243 
244     @Override
getMetricsCategory()245     public int getMetricsCategory() {
246         return MetricsEvent.RESET_NETWORK_CONFIRM;
247     }
248 }
249