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