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 android.app.Activity; 20 import android.content.Intent; 21 import android.content.res.Resources; 22 import android.os.Bundle; 23 import android.os.UserHandle; 24 import android.os.UserManager; 25 import android.telephony.SubscriptionInfo; 26 import android.telephony.SubscriptionManager; 27 import android.text.TextUtils; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.widget.ArrayAdapter; 32 import android.widget.Button; 33 import android.widget.Spinner; 34 35 import com.android.internal.logging.MetricsProto.MetricsEvent; 36 import com.android.internal.telephony.PhoneConstants; 37 import com.android.settingslib.RestrictedLockUtils; 38 39 import java.util.ArrayList; 40 import java.util.List; 41 42 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 43 44 /** 45 * Confirm and execute a reset of the device's network settings to a clean "just out of the box" 46 * state. Multiple confirmations are required: first, a general "are you sure you want to do this?" 47 * prompt, followed by a keyguard pattern trace if the user has defined one, followed by a final 48 * strongly-worded "THIS WILL RESET EVERYTHING" prompt. If at any time the phone is allowed to go 49 * to sleep, is locked, et cetera, then the confirmation sequence is abandoned. 50 * 51 * This is the initial screen. 52 */ 53 public class ResetNetwork extends OptionsMenuFragment { 54 private static final String TAG = "ResetNetwork"; 55 56 // Arbitrary to avoid conficts 57 private static final int KEYGUARD_REQUEST = 55; 58 59 private List<SubscriptionInfo> mSubscriptions; 60 61 private View mContentView; 62 private Spinner mSubscriptionSpinner; 63 private Button mInitiateButton; 64 65 /** 66 * Keyguard validation is run using the standard {@link ConfirmLockPattern} 67 * component as a subactivity 68 * @param request the request code to be returned once confirmation finishes 69 * @return true if confirmation launched 70 */ 71 private boolean runKeyguardConfirmation(int request) { 72 Resources res = getActivity().getResources(); 73 return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity( 74 request, res.getText(R.string.reset_network_title)); 75 } 76 77 @Override 78 public void onActivityResult(int requestCode, int resultCode, Intent data) { 79 super.onActivityResult(requestCode, resultCode, data); 80 81 if (requestCode != KEYGUARD_REQUEST) { 82 return; 83 } 84 85 // If the user entered a valid keyguard trace, present the final 86 // confirmation prompt; otherwise, go back to the initial state. 87 if (resultCode == Activity.RESULT_OK) { 88 showFinalConfirmation(); 89 } else { 90 establishInitialState(); 91 } 92 } 93 94 private void showFinalConfirmation() { 95 Bundle args = new Bundle(); 96 if (mSubscriptions != null && mSubscriptions.size() > 0) { 97 int selectedIndex = mSubscriptionSpinner.getSelectedItemPosition(); 98 SubscriptionInfo subscription = mSubscriptions.get(selectedIndex); 99 args.putInt(PhoneConstants.SUBSCRIPTION_KEY, subscription.getSubscriptionId()); 100 } 101 ((SettingsActivity) getActivity()).startPreferencePanel(ResetNetworkConfirm.class.getName(), 102 args, R.string.reset_network_confirm_title, null, null, 0); 103 } 104 105 /** 106 * If the user clicks to begin the reset sequence, we next require a 107 * keyguard confirmation if the user has currently enabled one. If there 108 * is no keyguard available, we simply go to the final confirmation prompt. 109 */ 110 private final Button.OnClickListener mInitiateListener = new Button.OnClickListener() { 111 112 @Override 113 public void onClick(View v) { 114 if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) { 115 showFinalConfirmation(); 116 } 117 } 118 }; 119 120 /** 121 * In its initial state, the activity presents a button for the user to 122 * click in order to initiate a confirmation sequence. This method is 123 * called from various other points in the code to reset the activity to 124 * this base state. 125 * 126 * <p>Reinflating views from resources is expensive and prevents us from 127 * caching widget pointers, so we use a single-inflate pattern: we lazy- 128 * inflate each view, caching all of the widget pointers we'll need at the 129 * time, then simply reuse the inflated views directly whenever we need 130 * to change contents. 131 */ 132 private void establishInitialState() { 133 mSubscriptionSpinner = (Spinner) mContentView.findViewById(R.id.reset_network_subscription); 134 135 mSubscriptions = SubscriptionManager.from(getActivity()).getActiveSubscriptionInfoList(); 136 if (mSubscriptions != null && mSubscriptions.size() > 0) { 137 // Get the default subscription in the order of data, voice, sms, first up. 138 int defaultSubscription = SubscriptionManager.getDefaultDataSubscriptionId(); 139 if (!SubscriptionManager.isUsableSubIdValue(defaultSubscription)) { 140 defaultSubscription = SubscriptionManager.getDefaultVoiceSubscriptionId(); 141 } 142 if (!SubscriptionManager.isUsableSubIdValue(defaultSubscription)) { 143 defaultSubscription = SubscriptionManager.getDefaultSmsSubscriptionId(); 144 } 145 if (!SubscriptionManager.isUsableSubIdValue(defaultSubscription)) { 146 defaultSubscription = SubscriptionManager.getDefaultSubscriptionId(); 147 } 148 149 int selectedIndex = 0; 150 int size = mSubscriptions.size(); 151 List<String> subscriptionNames = new ArrayList<>(); 152 for (SubscriptionInfo record : mSubscriptions) { 153 if (record.getSubscriptionId() == defaultSubscription) { 154 // Set the first selected value to the default 155 selectedIndex = subscriptionNames.size(); 156 } 157 String name = record.getDisplayName().toString(); 158 if (TextUtils.isEmpty(name)) { 159 name = record.getNumber(); 160 } 161 if (TextUtils.isEmpty(name)) { 162 name = record.getCarrierName().toString(); 163 } 164 if (TextUtils.isEmpty(name)) { 165 name = String.format("MCC:%s MNC:%s Slot:%s Id:%s", record.getMcc(), 166 record.getMnc(), record.getSimSlotIndex(), record.getSubscriptionId()); 167 } 168 subscriptionNames.add(name); 169 } 170 ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), 171 android.R.layout.simple_spinner_item, subscriptionNames); 172 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 173 mSubscriptionSpinner.setAdapter(adapter); 174 mSubscriptionSpinner.setSelection(selectedIndex); 175 if (mSubscriptions.size() > 1) { 176 mSubscriptionSpinner.setVisibility(View.VISIBLE); 177 } else { 178 mSubscriptionSpinner.setVisibility(View.INVISIBLE); 179 } 180 } else { 181 mSubscriptionSpinner.setVisibility(View.INVISIBLE); 182 } 183 mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_reset_network); 184 mInitiateButton.setOnClickListener(mInitiateListener); 185 } 186 187 @Override 188 public View onCreateView(LayoutInflater inflater, ViewGroup container, 189 Bundle savedInstanceState) { 190 final UserManager um = UserManager.get(getActivity()); 191 final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( 192 getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId()); 193 if (!um.isAdminUser() || RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 194 UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) { 195 return inflater.inflate(R.layout.network_reset_disallowed_screen, null); 196 } else if (admin != null) { 197 View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); 198 ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); 199 view.setVisibility(View.VISIBLE); 200 return view; 201 } 202 203 mContentView = inflater.inflate(R.layout.reset_network, null); 204 205 establishInitialState(); 206 return mContentView; 207 } 208 209 @Override 210 protected int getMetricsCategory() { 211 return MetricsEvent.RESET_NETWORK; 212 } 213 } 214