blob: 733d7febbf18486f01ea3eb8ae87106db9890204 [file] [log] [blame]
Stuart Scottbe903412014-07-24 19:22:06 -07001/*
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
17package com.android.settings;
18
Doris Linged4685f2017-10-25 14:08:57 -070019import android.annotation.Nullable;
Stuart Scottbe903412014-07-24 19:22:06 -070020import android.app.Activity;
Fan Zhang31b21002019-01-16 13:49:47 -080021import android.app.settings.SettingsEnums;
Qingxi Li0caad2f2018-01-05 10:52:42 -080022import android.content.ContentResolver;
23import android.content.Context;
Stuart Scottbe903412014-07-24 19:22:06 -070024import android.content.Intent;
Stuart Scottbe903412014-07-24 19:22:06 -070025import android.content.res.Resources;
Stuart Scottbe903412014-07-24 19:22:06 -070026import android.os.Bundle;
Sudheer Shanka7dbbe132016-02-16 14:19:32 +000027import android.os.UserHandle;
Stuart Scottbe903412014-07-24 19:22:06 -070028import android.os.UserManager;
Qingxi Li0caad2f2018-01-05 10:52:42 -080029import android.provider.Settings;
30import android.provider.Settings.Global;
Stuart Scottbe903412014-07-24 19:22:06 -070031import android.telephony.SubscriptionInfo;
32import android.telephony.SubscriptionManager;
Qingxi Li0caad2f2018-01-05 10:52:42 -080033import android.telephony.euicc.EuiccManager;
Stuart Scottbe903412014-07-24 19:22:06 -070034import android.text.TextUtils;
Stuart Scottbe903412014-07-24 19:22:06 -070035import android.view.LayoutInflater;
36import android.view.View;
Qingxi Li0caad2f2018-01-05 10:52:42 -080037import android.view.View.OnClickListener;
Stuart Scottbe903412014-07-24 19:22:06 -070038import android.view.ViewGroup;
39import android.widget.ArrayAdapter;
40import android.widget.Button;
Qingxi Li0caad2f2018-01-05 10:52:42 -080041import android.widget.CheckBox;
Stuart Scottbe903412014-07-24 19:22:06 -070042import android.widget.Spinner;
Stuart Scottbe903412014-07-24 19:22:06 -070043
Andrew Sapperstein88930e32019-03-07 14:18:15 -080044import androidx.annotation.VisibleForTesting;
45
Doris Ling72489722017-11-16 11:03:40 -080046import com.android.settings.core.InstrumentedFragment;
Fan Zhang7cf99f52018-02-16 10:37:37 -080047import com.android.settings.core.SubSettingLauncher;
arangelov93081542017-10-27 13:51:28 +010048import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
Maurice Lam2eb170c2017-04-28 16:18:47 -070049import com.android.settings.password.ChooseLockSettingsHelper;
50import com.android.settings.password.ConfirmLockPattern;
Maurice Lam2eb170c2017-04-28 16:18:47 -070051import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
Philip P. Moltmanne3f72112018-08-28 15:01:43 -070052import com.android.settingslib.RestrictedLockUtilsInternal;
Taesu Lee39e4fbb2019-07-22 19:20:05 +090053import com.android.settingslib.development.DevelopmentSettingsEnabler;
Stuart Scottbe903412014-07-24 19:22:06 -070054
55import java.util.ArrayList;
56import java.util.List;
57
58/**
59 * Confirm and execute a reset of the device's network settings to a clean "just out of the box"
60 * state. Multiple confirmations are required: first, a general "are you sure you want to do this?"
61 * prompt, followed by a keyguard pattern trace if the user has defined one, followed by a final
62 * strongly-worded "THIS WILL RESET EVERYTHING" prompt. If at any time the phone is allowed to go
63 * to sleep, is locked, et cetera, then the confirmation sequence is abandoned.
64 *
65 * This is the initial screen.
66 */
Doris Ling72489722017-11-16 11:03:40 -080067public class ResetNetwork extends InstrumentedFragment {
Stuart Scottbe903412014-07-24 19:22:06 -070068 private static final String TAG = "ResetNetwork";
69
70 // Arbitrary to avoid conficts
71 private static final int KEYGUARD_REQUEST = 55;
72
73 private List<SubscriptionInfo> mSubscriptions;
74
75 private View mContentView;
76 private Spinner mSubscriptionSpinner;
77 private Button mInitiateButton;
Andrew Sapperstein88930e32019-03-07 14:18:15 -080078 @VisibleForTesting View mEsimContainer;
79 @VisibleForTesting CheckBox mEsimCheckbox;
Stuart Scottbe903412014-07-24 19:22:06 -070080
Doris Ling03a3b512017-10-18 14:25:01 -070081 @Override
Doris Linged4685f2017-10-25 14:08:57 -070082 public void onCreate(@Nullable Bundle savedInstanceState) {
83 super.onCreate(savedInstanceState);
Doris Ling4a012832017-11-13 17:58:13 -080084 getActivity().setTitle(R.string.reset_network_title);
Doris Ling03a3b512017-10-18 14:25:01 -070085 }
86
Stuart Scottbe903412014-07-24 19:22:06 -070087 /**
88 * Keyguard validation is run using the standard {@link ConfirmLockPattern}
89 * component as a subactivity
90 * @param request the request code to be returned once confirmation finishes
91 * @return true if confirmation launched
92 */
93 private boolean runKeyguardConfirmation(int request) {
94 Resources res = getActivity().getResources();
Jorim Jaggi8a09b612015-04-06 17:47:18 -070095 return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
96 request, res.getText(R.string.reset_network_title));
Stuart Scottbe903412014-07-24 19:22:06 -070097 }
98
99 @Override
100 public void onActivityResult(int requestCode, int resultCode, Intent data) {
101 super.onActivityResult(requestCode, resultCode, data);
102
103 if (requestCode != KEYGUARD_REQUEST) {
104 return;
105 }
106
107 // If the user entered a valid keyguard trace, present the final
108 // confirmation prompt; otherwise, go back to the initial state.
109 if (resultCode == Activity.RESULT_OK) {
110 showFinalConfirmation();
111 } else {
112 establishInitialState();
113 }
114 }
115
Andrew Sapperstein88930e32019-03-07 14:18:15 -0800116 @VisibleForTesting
117 void showFinalConfirmation() {
Stuart Scottbe903412014-07-24 19:22:06 -0700118 Bundle args = new Bundle();
Stuart Scott754b5662015-03-19 16:02:09 -0700119 if (mSubscriptions != null && mSubscriptions.size() > 0) {
Stuart Scottbe903412014-07-24 19:22:06 -0700120 int selectedIndex = mSubscriptionSpinner.getSelectedItemPosition();
121 SubscriptionInfo subscription = mSubscriptions.get(selectedIndex);
tom hsua3811962020-01-14 14:46:09 +0800122 args.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
123 subscription.getSubscriptionId());
Stuart Scottbe903412014-07-24 19:22:06 -0700124 }
Andrew Sapperstein88930e32019-03-07 14:18:15 -0800125 args.putBoolean(MasterClear.ERASE_ESIMS_EXTRA,
tom hsua3811962020-01-14 14:46:09 +0800126 mEsimContainer.getVisibility() == View.VISIBLE && mEsimCheckbox.isChecked());
Fan Zhang7cf99f52018-02-16 10:37:37 -0800127 new SubSettingLauncher(getContext())
128 .setDestination(ResetNetworkConfirm.class.getName())
129 .setArguments(args)
hjchangliaoe86eec02018-05-02 13:01:07 +0800130 .setTitleRes(R.string.reset_network_confirm_title)
Fan Zhang7cf99f52018-02-16 10:37:37 -0800131 .setSourceMetricsCategory(getMetricsCategory())
132 .launch();
Stuart Scottbe903412014-07-24 19:22:06 -0700133 }
134
135 /**
136 * If the user clicks to begin the reset sequence, we next require a
137 * keyguard confirmation if the user has currently enabled one. If there
138 * is no keyguard available, we simply go to the final confirmation prompt.
139 */
140 private final Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
141
142 @Override
143 public void onClick(View v) {
144 if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
145 showFinalConfirmation();
146 }
147 }
148 };
149
150 /**
151 * In its initial state, the activity presents a button for the user to
152 * click in order to initiate a confirmation sequence. This method is
153 * called from various other points in the code to reset the activity to
154 * this base state.
155 *
156 * <p>Reinflating views from resources is expensive and prevents us from
157 * caching widget pointers, so we use a single-inflate pattern: we lazy-
158 * inflate each view, caching all of the widget pointers we'll need at the
159 * time, then simply reuse the inflated views directly whenever we need
160 * to change contents.
161 */
162 private void establishInitialState() {
163 mSubscriptionSpinner = (Spinner) mContentView.findViewById(R.id.reset_network_subscription);
Qingxi Li0caad2f2018-01-05 10:52:42 -0800164 mEsimContainer = mContentView.findViewById(R.id.erase_esim_container);
165 mEsimCheckbox = mContentView.findViewById(R.id.erase_esim);
Stuart Scottbe903412014-07-24 19:22:06 -0700166
Malcolm Chen14dde502019-01-14 15:13:10 -0800167 mSubscriptions = SubscriptionManager.from(getActivity())
Bonian Chen12477712019-12-16 13:55:54 +0800168 .getActiveSubscriptionInfoList();
Stuart Scott93028302015-03-19 14:48:37 -0700169 if (mSubscriptions != null && mSubscriptions.size() > 0) {
Stuart Scottbe903412014-07-24 19:22:06 -0700170 // Get the default subscription in the order of data, voice, sms, first up.
Shishir Agrawald2b0fc02016-01-25 14:05:32 -0800171 int defaultSubscription = SubscriptionManager.getDefaultDataSubscriptionId();
changbettyebe36cf2020-01-08 22:06:26 +0800172 if (!SubscriptionManager.isUsableSubscriptionId(defaultSubscription)) {
Shishir Agrawald2b0fc02016-01-25 14:05:32 -0800173 defaultSubscription = SubscriptionManager.getDefaultVoiceSubscriptionId();
Stuart Scottbe903412014-07-24 19:22:06 -0700174 }
changbettyebe36cf2020-01-08 22:06:26 +0800175 if (!SubscriptionManager.isUsableSubscriptionId(defaultSubscription)) {
Shishir Agrawald2b0fc02016-01-25 14:05:32 -0800176 defaultSubscription = SubscriptionManager.getDefaultSmsSubscriptionId();
Stuart Scottbe903412014-07-24 19:22:06 -0700177 }
changbettyebe36cf2020-01-08 22:06:26 +0800178 if (!SubscriptionManager.isUsableSubscriptionId(defaultSubscription)) {
Shishir Agrawald2b0fc02016-01-25 14:05:32 -0800179 defaultSubscription = SubscriptionManager.getDefaultSubscriptionId();
Stuart Scottbe903412014-07-24 19:22:06 -0700180 }
181
182 int selectedIndex = 0;
183 int size = mSubscriptions.size();
184 List<String> subscriptionNames = new ArrayList<>();
185 for (SubscriptionInfo record : mSubscriptions) {
186 if (record.getSubscriptionId() == defaultSubscription) {
187 // Set the first selected value to the default
188 selectedIndex = subscriptionNames.size();
189 }
190 String name = record.getDisplayName().toString();
191 if (TextUtils.isEmpty(name)) {
192 name = record.getNumber();
193 }
194 if (TextUtils.isEmpty(name)) {
195 name = record.getCarrierName().toString();
196 }
197 if (TextUtils.isEmpty(name)) {
198 name = String.format("MCC:%s MNC:%s Slot:%s Id:%s", record.getMcc(),
199 record.getMnc(), record.getSimSlotIndex(), record.getSubscriptionId());
200 }
201 subscriptionNames.add(name);
202 }
203 ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
204 android.R.layout.simple_spinner_item, subscriptionNames);
205 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
206 mSubscriptionSpinner.setAdapter(adapter);
207 mSubscriptionSpinner.setSelection(selectedIndex);
Meng Wangdfba9232016-08-01 10:19:15 -0700208 if (mSubscriptions.size() > 1) {
209 mSubscriptionSpinner.setVisibility(View.VISIBLE);
210 } else {
211 mSubscriptionSpinner.setVisibility(View.INVISIBLE);
212 }
Stuart Scottbe903412014-07-24 19:22:06 -0700213 } else {
214 mSubscriptionSpinner.setVisibility(View.INVISIBLE);
215 }
216 mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_reset_network);
217 mInitiateButton.setOnClickListener(mInitiateListener);
Qingxi Li0caad2f2018-01-05 10:52:42 -0800218 if (showEuiccSettings(getContext())) {
219 mEsimContainer.setVisibility(View.VISIBLE);
Qingxi Li0caad2f2018-01-05 10:52:42 -0800220 mEsimContainer.setOnClickListener(new OnClickListener() {
221 @Override
222 public void onClick(View v) {
223 mEsimCheckbox.toggle();
224 }
225 });
226 } else {
227 mEsimCheckbox.setChecked(false /* checked */);
228 }
229 }
230
231 private boolean showEuiccSettings(Context context) {
232 EuiccManager euiccManager =
233 (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
234 if (!euiccManager.isEnabled()) {
235 return false;
236 }
237 ContentResolver resolver = context.getContentResolver();
238 return Settings.Global.getInt(resolver, Global.EUICC_PROVISIONED, 0) != 0
Taesu Lee39e4fbb2019-07-22 19:20:05 +0900239 || DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(context);
Stuart Scottbe903412014-07-24 19:22:06 -0700240 }
241
242 @Override
243 public View onCreateView(LayoutInflater inflater, ViewGroup container,
244 Bundle savedInstanceState) {
Xiaohui Chen44879a32015-07-22 13:53:22 -0700245 final UserManager um = UserManager.get(getActivity());
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700246 final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000247 getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700248 if (!um.isAdminUser() || RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000249 UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
Stuart Scott176f5122015-04-20 11:05:43 -0700250 return inflater.inflate(R.layout.network_reset_disallowed_screen, null);
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000251 } else if (admin != null) {
arangelov93081542017-10-27 13:51:28 +0100252 new ActionDisabledByAdminDialogHelper(getActivity())
253 .prepareDialogBuilder(UserManager.DISALLOW_NETWORK_RESET, admin)
254 .setOnDismissListener(__ -> getActivity().finish())
255 .show();
256 return new View(getContext());
Stuart Scott176f5122015-04-20 11:05:43 -0700257 }
258
Stuart Scottbe903412014-07-24 19:22:06 -0700259 mContentView = inflater.inflate(R.layout.reset_network, null);
260
261 establishInitialState();
262 return mContentView;
263 }
Chris Wren8a963ba2015-03-20 10:29:14 -0400264
265 @Override
Fan Zhang65076132016-08-08 10:25:13 -0700266 public int getMetricsCategory() {
Fan Zhang31b21002019-01-16 13:49:47 -0800267 return SettingsEnums.RESET_NETWORK;
Chris Wren8a963ba2015-03-20 10:29:14 -0400268 }
Stuart Scottbe903412014-07-24 19:22:06 -0700269}