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.nano.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( 102 this, ResetNetworkConfirm.class.getName(), 103 args, R.string.reset_network_confirm_title, null, null, 0); 104 } 105 106 /** 107 * If the user clicks to begin the reset sequence, we next require a 108 * keyguard confirmation if the user has currently enabled one. If there 109 * is no keyguard available, we simply go to the final confirmation prompt. 110 */ 111 private final Button.OnClickListener mInitiateListener = new Button.OnClickListener() { 112 113 @Override 114 public void onClick(View v) { 115 if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) { 116 showFinalConfirmation(); 117 } 118 } 119 }; 120 121 /** 122 * In its initial state, the activity presents a button for the user to 123 * click in order to initiate a confirmation sequence. This method is 124 * called from various other points in the code to reset the activity to 125 * this base state. 126 * 127 * <p>Reinflating views from resources is expensive and prevents us from 128 * caching widget pointers, so we use a single-inflate pattern: we lazy- 129 * inflate each view, caching all of the widget pointers we'll need at the 130 * time, then simply reuse the inflated views directly whenever we need 131 * to change contents. 132 */ 133 private void establishInitialState() { 134 mSubscriptionSpinner = (Spinner) mContentView.findViewById(R.id.reset_network_subscription); 135 136 mSubscriptions = SubscriptionManager.from(getActivity()).getActiveSubscriptionInfoList(); 137 if (mSubscriptions != null && mSubscriptions.size() > 0) { 138 // Get the default subscription in the order of data, voice, sms, first up. 139 int defaultSubscription = SubscriptionManager.getDefaultDataSubscriptionId(); 140 if (!SubscriptionManager.isUsableSubIdValue(defaultSubscription)) { 141 defaultSubscription = SubscriptionManager.getDefaultVoiceSubscriptionId(); 142 } 143 if (!SubscriptionManager.isUsableSubIdValue(defaultSubscription)) { 144 defaultSubscription = SubscriptionManager.getDefaultSmsSubscriptionId(); 145 } 146 if (!SubscriptionManager.isUsableSubIdValue(defaultSubscription)) { 147 defaultSubscription = SubscriptionManager.getDefaultSubscriptionId(); 148 } 149 150 int selectedIndex = 0; 151 int size = mSubscriptions.size(); 152 List<String> subscriptionNames = new ArrayList<>(); 153 for (SubscriptionInfo record : mSubscriptions) { 154 if (record.getSubscriptionId() == defaultSubscription) { 155 // Set the first selected value to the default 156 selectedIndex = subscriptionNames.size(); 157 } 158 String name = record.getDisplayName().toString(); 159 if (TextUtils.isEmpty(name)) { 160 name = record.getNumber(); 161 } 162 if (TextUtils.isEmpty(name)) { 163 name = record.getCarrierName().toString(); 164 } 165 if (TextUtils.isEmpty(name)) { 166 name = String.format("MCC:%s MNC:%s Slot:%s Id:%s", record.getMcc(), 167 record.getMnc(), record.getSimSlotIndex(), record.getSubscriptionId()); 168 } 169 subscriptionNames.add(name); 170 } 171 ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), 172 android.R.layout.simple_spinner_item, subscriptionNames); 173 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 174 mSubscriptionSpinner.setAdapter(adapter); 175 mSubscriptionSpinner.setSelection(selectedIndex); 176 if (mSubscriptions.size() > 1) { 177 mSubscriptionSpinner.setVisibility(View.VISIBLE); 178 } else { 179 mSubscriptionSpinner.setVisibility(View.INVISIBLE); 180 } 181 } else { 182 mSubscriptionSpinner.setVisibility(View.INVISIBLE); 183 } 184 mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_reset_network); 185 mInitiateButton.setOnClickListener(mInitiateListener); 186 } 187 188 @Override 189 public View onCreateView(LayoutInflater inflater, ViewGroup container, 190 Bundle savedInstanceState) { 191 final UserManager um = UserManager.get(getActivity()); 192 final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( 193 getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId()); 194 if (!um.isAdminUser() || RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 195 UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) { 196 return inflater.inflate(R.layout.network_reset_disallowed_screen, null); 197 } else if (admin != null) { 198 View view = inflater.inflate(R.layout.admin_support_details_empty_view, null); 199 ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(), view, admin, false); 200 view.setVisibility(View.VISIBLE); 201 return view; 202 } 203 204 mContentView = inflater.inflate(R.layout.reset_network, null); 205 206 establishInitialState(); 207 return mContentView; 208 } 209 210 @Override 211 public int getMetricsCategory() { 212 return MetricsEvent.RESET_NETWORK; 213 } 214 } 215