1 /* 2 * Copyright (C) 2006 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.phone; 18 19 import android.app.ProgressDialog; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.AsyncResult; 23 import android.os.Handler; 24 import android.os.Message; 25 import android.preference.Preference; 26 import android.preference.PreferenceCategory; 27 import android.preference.TwoStatePreference; 28 import android.telephony.ServiceState; 29 import android.telephony.SubscriptionManager; 30 import android.telephony.TelephonyManager; 31 import android.util.AttributeSet; 32 import android.util.Log; 33 34 import com.android.internal.logging.MetricsLogger; 35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 36 import com.android.internal.telephony.CommandException; 37 import com.android.internal.telephony.Phone; 38 import com.android.internal.telephony.PhoneFactory; 39 40 /** 41 * "Networks" settings UI for the Phone app. 42 */ 43 public class NetworkOperators extends PreferenceCategory 44 implements Preference.OnPreferenceChangeListener { 45 46 private static final String LOG_TAG = "NetworkOperators"; 47 private static final boolean DBG = true; 48 49 private static final int EVENT_AUTO_SELECT_DONE = 100; 50 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 200; 51 52 //String keys for preference lookup 53 public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key"; 54 public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key"; 55 public static final String BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key"; 56 public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key"; 57 58 int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; 59 private static final int ALREADY_IN_AUTO_SELECTION = 1; 60 61 //preference objects 62 private NetworkSelectListPreference mNetworkSelect; 63 private TwoStatePreference mAutoSelect; 64 private Preference mChooseNetwork; 65 66 private int mSubId; 67 private ProgressDialog mProgressDialog; 68 69 // There's two sets of Auto-Select UI in this class. 70 // If {@code com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI} set as true 71 // {@link mChooseNetwork} will be used, otherwise {@link mNetworkSelect} will be used. 72 boolean mEnableNewManualSelectNetworkUI; 73 74 public NetworkOperators(Context context, AttributeSet attrs) { 75 super(context, attrs); 76 } 77 78 public NetworkOperators(Context context) { 79 super(context); 80 } 81 82 /** 83 * Initialize NetworkOperators instance. 84 */ 85 public void initialize() { 86 mEnableNewManualSelectNetworkUI = getContext().getResources().getBoolean( 87 com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI); 88 mAutoSelect = (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY); 89 mChooseNetwork = findPreference(BUTTON_CHOOSE_NETWORK_KEY); 90 mNetworkSelect = (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY); 91 if (mEnableNewManualSelectNetworkUI) { 92 removePreference(mNetworkSelect); 93 } else { 94 removePreference(mChooseNetwork); 95 } 96 mProgressDialog = new ProgressDialog(getContext()); 97 } 98 99 /** 100 * Update NetworkOperators instance if like subId or queryService are updated. 101 * 102 * @param subId Corresponding subscription ID of this network. 103 * @param queryService The service to do network queries. 104 */ 105 protected void update(final int subId, INetworkQueryService queryService) { 106 mSubId = subId; 107 mPhoneId = SubscriptionManager.getPhoneId(mSubId); 108 109 if (mAutoSelect != null) { 110 mAutoSelect.setOnPreferenceChangeListener(this); 111 } 112 113 if (mEnableNewManualSelectNetworkUI) { 114 if (mChooseNetwork != null) { 115 TelephonyManager telephonyManager = (TelephonyManager) 116 getContext().getSystemService(Context.TELEPHONY_SERVICE); 117 if (DBG) logd("data connection status " + telephonyManager.getDataState()); 118 if (telephonyManager.getDataState() == telephonyManager.DATA_CONNECTED) { 119 mChooseNetwork.setSummary(telephonyManager.getNetworkOperatorName()); 120 } else { 121 mChooseNetwork.setSummary(R.string.network_disconnected); 122 } 123 } 124 } else { 125 if (mNetworkSelect != null) { 126 mNetworkSelect.initialize(mSubId, queryService, this, mProgressDialog); 127 } 128 } 129 getNetworkSelectionMode(); 130 } 131 132 /** 133 * Implemented to support onPreferenceChangeListener to look for preference 134 * changes specifically on auto select button. 135 * 136 * @param preference is the preference to be changed, should be auto select button. 137 * @param newValue should be the value of whether autoSelect is checked. 138 */ 139 @Override 140 public boolean onPreferenceChange(Preference preference, Object newValue) { 141 if (preference == mAutoSelect) { 142 boolean autoSelect = (Boolean) newValue; 143 if (DBG) logd("onPreferenceChange autoSelect: " + String.valueOf(autoSelect)); 144 selectNetworkAutomatic(autoSelect); 145 MetricsLogger.action(getContext(), 146 MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE, autoSelect); 147 return true; 148 } 149 return false; 150 } 151 152 private final Handler mHandler = new Handler() { 153 @Override 154 public void handleMessage(Message msg) { 155 AsyncResult ar; 156 switch (msg.what) { 157 case EVENT_AUTO_SELECT_DONE: 158 mAutoSelect.setEnabled(true); 159 dismissProgressBar(); 160 161 ar = (AsyncResult) msg.obj; 162 if (ar.exception != null) { 163 if (DBG) logd("automatic network selection: failed!"); 164 displayNetworkSelectionFailed(ar.exception); 165 } else { 166 if (DBG) logd("automatic network selection: succeeded!"); 167 displayNetworkSelectionSucceeded(msg.arg1); 168 } 169 170 break; 171 case EVENT_GET_NETWORK_SELECTION_MODE_DONE: 172 ar = (AsyncResult) msg.obj; 173 if (ar.exception != null) { 174 if (DBG) logd("get network selection mode: failed!"); 175 } else if (ar.result != null) { 176 try { 177 int[] modes = (int[]) ar.result; 178 boolean autoSelect = (modes[0] == 0); 179 if (DBG) { 180 logd("get network selection mode: " 181 + (autoSelect ? "auto" : "manual") + " selection"); 182 } 183 if (mAutoSelect != null) { 184 mAutoSelect.setChecked(autoSelect); 185 } 186 if (mEnableNewManualSelectNetworkUI) { 187 if (mChooseNetwork != null) { 188 mChooseNetwork.setEnabled(!autoSelect); 189 } 190 } else { 191 if (mNetworkSelect != null) { 192 mNetworkSelect.setEnabled(!autoSelect); 193 } 194 } 195 } catch (Exception e) { 196 if (DBG) loge("get network selection mode: unable to parse result."); 197 } 198 } 199 } 200 return; 201 } 202 }; 203 204 // Used by both mAutoSelect and mNetworkSelect buttons. 205 protected void displayNetworkSelectionFailed(Throwable ex) { 206 String status; 207 if ((ex != null && ex instanceof CommandException) 208 && ((CommandException) ex).getCommandError() 209 == CommandException.Error.ILLEGAL_SIM_OR_ME) { 210 status = getContext().getResources().getString(R.string.not_allowed); 211 } else { 212 status = getContext().getResources().getString(R.string.connect_later); 213 } 214 215 final PhoneGlobals app = PhoneGlobals.getInstance(); 216 app.notificationMgr.postTransientNotification( 217 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status); 218 219 TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE); 220 Phone phone = PhoneFactory.getPhone(mPhoneId); 221 if (phone != null) { 222 ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId()); 223 if (ss != null) { 224 app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId()); 225 } 226 } 227 } 228 229 // Used by both mAutoSelect and mNetworkSelect buttons. 230 protected void displayNetworkSelectionSucceeded(int msgArg1) { 231 String status = null; 232 if (msgArg1 == ALREADY_IN_AUTO_SELECTION) { 233 status = getContext().getResources().getString(R.string.already_auto); 234 } else { 235 status = getContext().getResources().getString(R.string.registration_done); 236 } 237 238 final PhoneGlobals app = PhoneGlobals.getInstance(); 239 app.notificationMgr.postTransientNotification( 240 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status); 241 } 242 243 private void selectNetworkAutomatic(boolean autoSelect) { 244 if (DBG) logd("selectNetworkAutomatic: " + String.valueOf(autoSelect)); 245 246 if (autoSelect) { 247 if (mEnableNewManualSelectNetworkUI) { 248 if (mChooseNetwork != null) { 249 mChooseNetwork.setEnabled(!autoSelect); 250 } 251 } else { 252 if (mNetworkSelect != null) { 253 mNetworkSelect.setEnabled(!autoSelect); 254 } 255 } 256 if (DBG) logd("select network automatically..."); 257 showAutoSelectProgressBar(); 258 mAutoSelect.setEnabled(false); 259 Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE); 260 Phone phone = PhoneFactory.getPhone(mPhoneId); 261 if (phone != null) { 262 phone.setNetworkSelectionModeAutomatic(msg); 263 } 264 } else { 265 if (mEnableNewManualSelectNetworkUI) { 266 if (mChooseNetwork != null) { 267 // Open the choose Network page automatically when user turn off the auto-select 268 openChooseNetworkPage(); 269 } 270 } else { 271 if (mNetworkSelect != null) { 272 mNetworkSelect.onClick(); 273 } 274 } 275 } 276 } 277 278 protected void getNetworkSelectionMode() { 279 if (DBG) logd("getting network selection mode..."); 280 Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE); 281 Phone phone = PhoneFactory.getPhone(mPhoneId); 282 if (phone != null) { 283 phone.getNetworkSelectionMode(msg); 284 } 285 } 286 287 private void dismissProgressBar() { 288 if (mProgressDialog != null && mProgressDialog.isShowing()) { 289 mProgressDialog.dismiss(); 290 } 291 } 292 293 private void showAutoSelectProgressBar() { 294 mProgressDialog.setMessage( 295 getContext().getResources().getString(R.string.register_automatically)); 296 mProgressDialog.setCanceledOnTouchOutside(false); 297 mProgressDialog.setCancelable(false); 298 mProgressDialog.setIndeterminate(true); 299 mProgressDialog.show(); 300 } 301 302 /** 303 * Open the Choose netwotk page via {@alink NetworkSelectSettingActivity} 304 */ 305 public void openChooseNetworkPage() { 306 Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mPhoneId); 307 getContext().startActivity(intent); 308 } 309 310 protected boolean preferenceTreeClick(Preference preference) { 311 if (mEnableNewManualSelectNetworkUI) { 312 if (DBG) logd("enable New AutoSelectNetwork UI"); 313 if (preference == mChooseNetwork) { 314 openChooseNetworkPage(); 315 } 316 return (preference == mAutoSelect || preference == mChooseNetwork); 317 } else { 318 return (preference == mAutoSelect || preference == mNetworkSelect); 319 } 320 } 321 322 private void logd(String msg) { 323 Log.d(LOG_TAG, "[NetworksList] " + msg); 324 } 325 326 private void loge(String msg) { 327 Log.e(LOG_TAG, "[NetworksList] " + msg); 328 } 329 }