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.settings; 18 19 import android.app.AlertDialog; 20 import android.app.Dialog; 21 import android.content.ContentUris; 22 import android.content.ContentValues; 23 import android.content.Intent; 24 import android.content.SharedPreferences; 25 import android.content.res.Resources; 26 import android.database.Cursor; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.preference.EditTextPreference; 30 import android.preference.ListPreference; 31 import android.preference.MultiSelectListPreference; 32 import android.preference.Preference; 33 import android.preference.PreferenceActivity; 34 import android.preference.SwitchPreference; 35 import android.provider.Telephony; 36 import android.telephony.ServiceState; 37 import android.telephony.SubscriptionManager; 38 import android.telephony.TelephonyManager; 39 import android.text.TextUtils; 40 import android.util.Log; 41 import android.view.KeyEvent; 42 import android.view.Menu; 43 import android.view.MenuItem; 44 import com.android.internal.logging.MetricsLogger; 45 46 import java.util.HashSet; 47 import java.util.Set; 48 49 public class ApnEditor extends InstrumentedPreferenceActivity 50 implements SharedPreferences.OnSharedPreferenceChangeListener, 51 Preference.OnPreferenceChangeListener { 52 53 private final static String TAG = ApnEditor.class.getSimpleName(); 54 55 private final static String SAVED_POS = "pos"; 56 private final static String KEY_AUTH_TYPE = "auth_type"; 57 private final static String KEY_PROTOCOL = "apn_protocol"; 58 private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol"; 59 private final static String KEY_CARRIER_ENABLED = "carrier_enabled"; 60 private final static String KEY_BEARER_MULTI = "bearer_multi"; 61 private final static String KEY_MVNO_TYPE = "mvno_type"; 62 63 private static final int MENU_DELETE = Menu.FIRST; 64 private static final int MENU_SAVE = Menu.FIRST + 1; 65 private static final int MENU_CANCEL = Menu.FIRST + 2; 66 private static final int ERROR_DIALOG_ID = 0; 67 68 private static String sNotSet; 69 private EditTextPreference mName; 70 private EditTextPreference mApn; 71 private EditTextPreference mProxy; 72 private EditTextPreference mPort; 73 private EditTextPreference mUser; 74 private EditTextPreference mServer; 75 private EditTextPreference mPassword; 76 private EditTextPreference mMmsc; 77 private EditTextPreference mMcc; 78 private EditTextPreference mMnc; 79 private EditTextPreference mMmsProxy; 80 private EditTextPreference mMmsPort; 81 private ListPreference mAuthType; 82 private EditTextPreference mApnType; 83 private ListPreference mProtocol; 84 private ListPreference mRoamingProtocol; 85 private SwitchPreference mCarrierEnabled; 86 private MultiSelectListPreference mBearerMulti; 87 private ListPreference mMvnoType; 88 private EditTextPreference mMvnoMatchData; 89 90 private String mCurMnc; 91 private String mCurMcc; 92 93 private Uri mUri; 94 private Cursor mCursor; 95 private boolean mNewApn; 96 private boolean mFirstTime; 97 private int mSubId; 98 private Resources mRes; 99 private TelephonyManager mTelephonyManager; 100 private int mBearerInitialVal = 0; 101 private String mMvnoTypeStr; 102 private String mMvnoMatchDataStr; 103 104 /** 105 * Standard projection for the interesting columns of a normal note. 106 */ 107 private static final String[] sProjection = new String[] { 108 Telephony.Carriers._ID, // 0 109 Telephony.Carriers.NAME, // 1 110 Telephony.Carriers.APN, // 2 111 Telephony.Carriers.PROXY, // 3 112 Telephony.Carriers.PORT, // 4 113 Telephony.Carriers.USER, // 5 114 Telephony.Carriers.SERVER, // 6 115 Telephony.Carriers.PASSWORD, // 7 116 Telephony.Carriers.MMSC, // 8 117 Telephony.Carriers.MCC, // 9 118 Telephony.Carriers.MNC, // 10 119 Telephony.Carriers.NUMERIC, // 11 120 Telephony.Carriers.MMSPROXY,// 12 121 Telephony.Carriers.MMSPORT, // 13 122 Telephony.Carriers.AUTH_TYPE, // 14 123 Telephony.Carriers.TYPE, // 15 124 Telephony.Carriers.PROTOCOL, // 16 125 Telephony.Carriers.CARRIER_ENABLED, // 17 126 Telephony.Carriers.BEARER, // 18 127 Telephony.Carriers.BEARER_BITMASK, // 19 128 Telephony.Carriers.ROAMING_PROTOCOL, // 20 129 Telephony.Carriers.MVNO_TYPE, // 21 130 Telephony.Carriers.MVNO_MATCH_DATA // 22 131 }; 132 133 private static final int ID_INDEX = 0; 134 private static final int NAME_INDEX = 1; 135 private static final int APN_INDEX = 2; 136 private static final int PROXY_INDEX = 3; 137 private static final int PORT_INDEX = 4; 138 private static final int USER_INDEX = 5; 139 private static final int SERVER_INDEX = 6; 140 private static final int PASSWORD_INDEX = 7; 141 private static final int MMSC_INDEX = 8; 142 private static final int MCC_INDEX = 9; 143 private static final int MNC_INDEX = 10; 144 private static final int MMSPROXY_INDEX = 12; 145 private static final int MMSPORT_INDEX = 13; 146 private static final int AUTH_TYPE_INDEX = 14; 147 private static final int TYPE_INDEX = 15; 148 private static final int PROTOCOL_INDEX = 16; 149 private static final int CARRIER_ENABLED_INDEX = 17; 150 private static final int BEARER_INDEX = 18; 151 private static final int BEARER_BITMASK_INDEX = 19; 152 private static final int ROAMING_PROTOCOL_INDEX = 20; 153 private static final int MVNO_TYPE_INDEX = 21; 154 private static final int MVNO_MATCH_DATA_INDEX = 22; 155 156 157 @Override onCreate(Bundle icicle)158 protected void onCreate(Bundle icicle) { 159 super.onCreate(icicle); 160 161 addPreferencesFromResource(R.xml.apn_editor); 162 163 sNotSet = getResources().getString(R.string.apn_not_set); 164 mName = (EditTextPreference) findPreference("apn_name"); 165 mApn = (EditTextPreference) findPreference("apn_apn"); 166 mProxy = (EditTextPreference) findPreference("apn_http_proxy"); 167 mPort = (EditTextPreference) findPreference("apn_http_port"); 168 mUser = (EditTextPreference) findPreference("apn_user"); 169 mServer = (EditTextPreference) findPreference("apn_server"); 170 mPassword = (EditTextPreference) findPreference("apn_password"); 171 mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy"); 172 mMmsPort = (EditTextPreference) findPreference("apn_mms_port"); 173 mMmsc = (EditTextPreference) findPreference("apn_mmsc"); 174 mMcc = (EditTextPreference) findPreference("apn_mcc"); 175 mMnc = (EditTextPreference) findPreference("apn_mnc"); 176 mApnType = (EditTextPreference) findPreference("apn_type"); 177 178 mAuthType = (ListPreference) findPreference(KEY_AUTH_TYPE); 179 mAuthType.setOnPreferenceChangeListener(this); 180 181 mProtocol = (ListPreference) findPreference(KEY_PROTOCOL); 182 mProtocol.setOnPreferenceChangeListener(this); 183 184 mRoamingProtocol = (ListPreference) findPreference(KEY_ROAMING_PROTOCOL); 185 mRoamingProtocol.setOnPreferenceChangeListener(this); 186 187 mCarrierEnabled = (SwitchPreference) findPreference(KEY_CARRIER_ENABLED); 188 189 mBearerMulti = (MultiSelectListPreference) findPreference(KEY_BEARER_MULTI); 190 mBearerMulti.setOnPreferenceChangeListener(this); 191 192 mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE); 193 mMvnoType.setOnPreferenceChangeListener(this); 194 mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data"); 195 196 mRes = getResources(); 197 198 final Intent intent = getIntent(); 199 final String action = intent.getAction(); 200 mSubId = intent.getIntExtra(ApnSettings.SUB_ID, 201 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 202 203 mFirstTime = icicle == null; 204 205 if (action.equals(Intent.ACTION_EDIT)) { 206 mUri = intent.getData(); 207 } else if (action.equals(Intent.ACTION_INSERT)) { 208 if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { 209 mUri = getContentResolver().insert(intent.getData(), new ContentValues()); 210 } else { 211 mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, 212 icicle.getInt(SAVED_POS)); 213 } 214 mNewApn = true; 215 mMvnoTypeStr = intent.getStringExtra(ApnSettings.MVNO_TYPE); 216 mMvnoMatchDataStr = intent.getStringExtra(ApnSettings.MVNO_MATCH_DATA); 217 // If we were unable to create a new note, then just finish 218 // this activity. A RESULT_CANCELED will be sent back to the 219 // original activity if they requested a result. 220 if (mUri == null) { 221 Log.w(TAG, "Failed to insert new telephony provider into " 222 + getIntent().getData()); 223 finish(); 224 return; 225 } 226 227 // The new entry was created, so assume all will end well and 228 // set the result to be returned. 229 setResult(RESULT_OK, (new Intent()).setAction(mUri.toString())); 230 231 } else { 232 finish(); 233 return; 234 } 235 236 mCursor = managedQuery(mUri, sProjection, null, null); 237 mCursor.moveToFirst(); 238 239 mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 240 241 fillUi(); 242 } 243 244 @Override getMetricsCategory()245 protected int getMetricsCategory() { 246 return MetricsLogger.APN_EDITOR; 247 } 248 249 @Override onResume()250 public void onResume() { 251 super.onResume(); 252 getPreferenceScreen().getSharedPreferences() 253 .registerOnSharedPreferenceChangeListener(this); 254 } 255 256 @Override onPause()257 public void onPause() { 258 getPreferenceScreen().getSharedPreferences() 259 .unregisterOnSharedPreferenceChangeListener(this); 260 super.onPause(); 261 } 262 fillUi()263 private void fillUi() { 264 if (mFirstTime) { 265 mFirstTime = false; 266 // Fill in all the values from the db in both text editor and summary 267 mName.setText(mCursor.getString(NAME_INDEX)); 268 mApn.setText(mCursor.getString(APN_INDEX)); 269 mProxy.setText(mCursor.getString(PROXY_INDEX)); 270 mPort.setText(mCursor.getString(PORT_INDEX)); 271 mUser.setText(mCursor.getString(USER_INDEX)); 272 mServer.setText(mCursor.getString(SERVER_INDEX)); 273 mPassword.setText(mCursor.getString(PASSWORD_INDEX)); 274 mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX)); 275 mMmsPort.setText(mCursor.getString(MMSPORT_INDEX)); 276 mMmsc.setText(mCursor.getString(MMSC_INDEX)); 277 mMcc.setText(mCursor.getString(MCC_INDEX)); 278 mMnc.setText(mCursor.getString(MNC_INDEX)); 279 mApnType.setText(mCursor.getString(TYPE_INDEX)); 280 if (mNewApn) { 281 String numeric = mTelephonyManager.getSimOperator(mSubId); 282 // MCC is first 3 chars and then in 2 - 3 chars of MNC 283 if (numeric != null && numeric.length() > 4) { 284 // Country code 285 String mcc = numeric.substring(0, 3); 286 // Network code 287 String mnc = numeric.substring(3); 288 // Auto populate MNC and MCC for new entries, based on what SIM reports 289 mMcc.setText(mcc); 290 mMnc.setText(mnc); 291 mCurMnc = mnc; 292 mCurMcc = mcc; 293 } 294 } 295 int authVal = mCursor.getInt(AUTH_TYPE_INDEX); 296 if (authVal != -1) { 297 mAuthType.setValueIndex(authVal); 298 } else { 299 mAuthType.setValue(null); 300 } 301 302 mProtocol.setValue(mCursor.getString(PROTOCOL_INDEX)); 303 mRoamingProtocol.setValue(mCursor.getString(ROAMING_PROTOCOL_INDEX)); 304 mCarrierEnabled.setChecked(mCursor.getInt(CARRIER_ENABLED_INDEX)==1); 305 mBearerInitialVal = mCursor.getInt(BEARER_INDEX); 306 307 HashSet<String> bearers = new HashSet<String>(); 308 int bearerBitmask = mCursor.getInt(BEARER_BITMASK_INDEX); 309 if (bearerBitmask == 0) { 310 if (mBearerInitialVal == 0) { 311 bearers.add("" + 0); 312 } 313 } else { 314 int i = 1; 315 while (bearerBitmask != 0) { 316 if ((bearerBitmask & 1) == 1) { 317 bearers.add("" + i); 318 } 319 bearerBitmask >>= 1; 320 i++; 321 } 322 } 323 324 if (mBearerInitialVal != 0 && bearers.contains("" + mBearerInitialVal) == false) { 325 // add mBearerInitialVal to bearers 326 bearers.add("" + mBearerInitialVal); 327 } 328 mBearerMulti.setValues(bearers); 329 330 mMvnoType.setValue(mCursor.getString(MVNO_TYPE_INDEX)); 331 mMvnoMatchData.setEnabled(false); 332 mMvnoMatchData.setText(mCursor.getString(MVNO_MATCH_DATA_INDEX)); 333 if (mNewApn && mMvnoTypeStr != null && mMvnoMatchDataStr != null) { 334 mMvnoType.setValue(mMvnoTypeStr); 335 mMvnoMatchData.setText(mMvnoMatchDataStr); 336 } 337 } 338 339 mName.setSummary(checkNull(mName.getText())); 340 mApn.setSummary(checkNull(mApn.getText())); 341 mProxy.setSummary(checkNull(mProxy.getText())); 342 mPort.setSummary(checkNull(mPort.getText())); 343 mUser.setSummary(checkNull(mUser.getText())); 344 mServer.setSummary(checkNull(mServer.getText())); 345 mPassword.setSummary(starify(mPassword.getText())); 346 mMmsProxy.setSummary(checkNull(mMmsProxy.getText())); 347 mMmsPort.setSummary(checkNull(mMmsPort.getText())); 348 mMmsc.setSummary(checkNull(mMmsc.getText())); 349 mMcc.setSummary(checkNull(mMcc.getText())); 350 mMnc.setSummary(checkNull(mMnc.getText())); 351 mApnType.setSummary(checkNull(mApnType.getText())); 352 353 String authVal = mAuthType.getValue(); 354 if (authVal != null) { 355 int authValIndex = Integer.parseInt(authVal); 356 mAuthType.setValueIndex(authValIndex); 357 358 String []values = mRes.getStringArray(R.array.apn_auth_entries); 359 mAuthType.setSummary(values[authValIndex]); 360 } else { 361 mAuthType.setSummary(sNotSet); 362 } 363 364 mProtocol.setSummary( 365 checkNull(protocolDescription(mProtocol.getValue(), mProtocol))); 366 mRoamingProtocol.setSummary( 367 checkNull(protocolDescription(mRoamingProtocol.getValue(), mRoamingProtocol))); 368 mBearerMulti.setSummary( 369 checkNull(bearerMultiDescription(mBearerMulti.getValues()))); 370 mMvnoType.setSummary( 371 checkNull(mvnoDescription(mMvnoType.getValue()))); 372 mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText())); 373 // allow user to edit carrier_enabled for some APN 374 boolean ceEditable = getResources().getBoolean(R.bool.config_allow_edit_carrier_enabled); 375 if (ceEditable) { 376 mCarrierEnabled.setEnabled(true); 377 } else { 378 mCarrierEnabled.setEnabled(false); 379 } 380 } 381 382 /** 383 * Returns the UI choice (e.g., "IPv4/IPv6") corresponding to the given 384 * raw value of the protocol preference (e.g., "IPV4V6"). If unknown, 385 * return null. 386 */ protocolDescription(String raw, ListPreference protocol)387 private String protocolDescription(String raw, ListPreference protocol) { 388 int protocolIndex = protocol.findIndexOfValue(raw); 389 if (protocolIndex == -1) { 390 return null; 391 } else { 392 String[] values = mRes.getStringArray(R.array.apn_protocol_entries); 393 try { 394 return values[protocolIndex]; 395 } catch (ArrayIndexOutOfBoundsException e) { 396 return null; 397 } 398 } 399 } 400 bearerDescription(String raw)401 private String bearerDescription(String raw) { 402 int mBearerIndex = mBearerMulti.findIndexOfValue(raw); 403 if (mBearerIndex == -1) { 404 return null; 405 } else { 406 String[] values = mRes.getStringArray(R.array.bearer_entries); 407 try { 408 return values[mBearerIndex]; 409 } catch (ArrayIndexOutOfBoundsException e) { 410 return null; 411 } 412 } 413 } 414 bearerMultiDescription(Set<String> raw)415 private String bearerMultiDescription(Set<String> raw) { 416 String[] values = mRes.getStringArray(R.array.bearer_entries); 417 StringBuilder retVal = new StringBuilder(); 418 boolean first = true; 419 for (String bearer : raw) { 420 int bearerIndex = mBearerMulti.findIndexOfValue(bearer); 421 try { 422 if (first) { 423 retVal.append(values[bearerIndex]); 424 first = false; 425 } else { 426 retVal.append(", " + values[bearerIndex]); 427 } 428 } catch (ArrayIndexOutOfBoundsException e) { 429 // ignore 430 } 431 } 432 String val = retVal.toString(); 433 if (!TextUtils.isEmpty(val)) { 434 return val; 435 } 436 return null; 437 } 438 mvnoDescription(String newValue)439 private String mvnoDescription(String newValue) { 440 int mvnoIndex = mMvnoType.findIndexOfValue(newValue); 441 String oldValue = mMvnoType.getValue(); 442 443 if (mvnoIndex == -1) { 444 return null; 445 } else { 446 String[] values = mRes.getStringArray(R.array.mvno_type_entries); 447 if (values[mvnoIndex].equals("None")) { 448 mMvnoMatchData.setEnabled(false); 449 } else { 450 mMvnoMatchData.setEnabled(true); 451 } 452 if (newValue != null && newValue.equals(oldValue) == false) { 453 if (values[mvnoIndex].equals("SPN")) { 454 mMvnoMatchData.setText(mTelephonyManager.getSimOperatorName()); 455 } else if (values[mvnoIndex].equals("IMSI")) { 456 String numeric = mTelephonyManager.getSimOperator(mSubId); 457 mMvnoMatchData.setText(numeric + "x"); 458 } else if (values[mvnoIndex].equals("GID")) { 459 mMvnoMatchData.setText(mTelephonyManager.getGroupIdLevel1()); 460 } 461 } 462 463 try { 464 return values[mvnoIndex]; 465 } catch (ArrayIndexOutOfBoundsException e) { 466 return null; 467 } 468 } 469 } 470 onPreferenceChange(Preference preference, Object newValue)471 public boolean onPreferenceChange(Preference preference, Object newValue) { 472 String key = preference.getKey(); 473 if (KEY_AUTH_TYPE.equals(key)) { 474 try { 475 int index = Integer.parseInt((String) newValue); 476 mAuthType.setValueIndex(index); 477 478 String []values = mRes.getStringArray(R.array.apn_auth_entries); 479 mAuthType.setSummary(values[index]); 480 } catch (NumberFormatException e) { 481 return false; 482 } 483 } else if (KEY_PROTOCOL.equals(key)) { 484 String protocol = protocolDescription((String) newValue, mProtocol); 485 if (protocol == null) { 486 return false; 487 } 488 mProtocol.setSummary(protocol); 489 mProtocol.setValue((String) newValue); 490 } else if (KEY_ROAMING_PROTOCOL.equals(key)) { 491 String protocol = protocolDescription((String) newValue, mRoamingProtocol); 492 if (protocol == null) { 493 return false; 494 } 495 mRoamingProtocol.setSummary(protocol); 496 mRoamingProtocol.setValue((String) newValue); 497 } else if (KEY_BEARER_MULTI.equals(key)) { 498 String bearer = bearerMultiDescription((Set<String>) newValue); 499 if (bearer == null) { 500 return false; 501 } 502 mBearerMulti.setValues((Set<String>) newValue); 503 mBearerMulti.setSummary(bearer); 504 } else if (KEY_MVNO_TYPE.equals(key)) { 505 String mvno = mvnoDescription((String) newValue); 506 if (mvno == null) { 507 return false; 508 } 509 mMvnoType.setValue((String) newValue); 510 mMvnoType.setSummary(mvno); 511 } 512 513 return true; 514 } 515 516 @Override onCreateOptionsMenu(Menu menu)517 public boolean onCreateOptionsMenu(Menu menu) { 518 super.onCreateOptionsMenu(menu); 519 // If it's a new APN, then cancel will delete the new entry in onPause 520 if (!mNewApn) { 521 menu.add(0, MENU_DELETE, 0, R.string.menu_delete) 522 .setIcon(R.drawable.ic_menu_delete); 523 } 524 menu.add(0, MENU_SAVE, 0, R.string.menu_save) 525 .setIcon(android.R.drawable.ic_menu_save); 526 menu.add(0, MENU_CANCEL, 0, R.string.menu_cancel) 527 .setIcon(android.R.drawable.ic_menu_close_clear_cancel); 528 return true; 529 } 530 531 @Override onOptionsItemSelected(MenuItem item)532 public boolean onOptionsItemSelected(MenuItem item) { 533 switch (item.getItemId()) { 534 case MENU_DELETE: 535 deleteApn(); 536 return true; 537 case MENU_SAVE: 538 if (validateAndSave(false)) { 539 finish(); 540 } 541 return true; 542 case MENU_CANCEL: 543 if (mNewApn) { 544 getContentResolver().delete(mUri, null, null); 545 } 546 finish(); 547 return true; 548 } 549 return super.onOptionsItemSelected(item); 550 } 551 552 @Override onKeyDown(int keyCode, KeyEvent event)553 public boolean onKeyDown(int keyCode, KeyEvent event) { 554 switch (keyCode) { 555 case KeyEvent.KEYCODE_BACK: { 556 if (validateAndSave(false)) { 557 finish(); 558 } 559 return true; 560 } 561 } 562 return super.onKeyDown(keyCode, event); 563 } 564 565 @Override onSaveInstanceState(Bundle icicle)566 protected void onSaveInstanceState(Bundle icicle) { 567 super.onSaveInstanceState(icicle); 568 if (validateAndSave(true)) { 569 icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX)); 570 } 571 } 572 573 /** 574 * Check the key fields' validity and save if valid. 575 * @param force save even if the fields are not valid, if the app is 576 * being suspended 577 * @return true if the data was saved 578 */ validateAndSave(boolean force)579 private boolean validateAndSave(boolean force) { 580 String name = checkNotSet(mName.getText()); 581 String apn = checkNotSet(mApn.getText()); 582 String mcc = checkNotSet(mMcc.getText()); 583 String mnc = checkNotSet(mMnc.getText()); 584 585 if (getErrorMsg() != null && !force) { 586 showDialog(ERROR_DIALOG_ID); 587 return false; 588 } 589 590 if (!mCursor.moveToFirst()) { 591 Log.w(TAG, 592 "Could not go to the first row in the Cursor when saving data."); 593 return false; 594 } 595 596 // If it's a new APN and a name or apn haven't been entered, then erase the entry 597 if (force && mNewApn && name.length() < 1 && apn.length() < 1) { 598 getContentResolver().delete(mUri, null, null); 599 return false; 600 } 601 602 ContentValues values = new ContentValues(); 603 604 // Add a dummy name "Untitled", if the user exits the screen without adding a name but 605 // entered other information worth keeping. 606 values.put(Telephony.Carriers.NAME, 607 name.length() < 1 ? getResources().getString(R.string.untitled_apn) : name); 608 values.put(Telephony.Carriers.APN, apn); 609 values.put(Telephony.Carriers.PROXY, checkNotSet(mProxy.getText())); 610 values.put(Telephony.Carriers.PORT, checkNotSet(mPort.getText())); 611 values.put(Telephony.Carriers.MMSPROXY, checkNotSet(mMmsProxy.getText())); 612 values.put(Telephony.Carriers.MMSPORT, checkNotSet(mMmsPort.getText())); 613 values.put(Telephony.Carriers.USER, checkNotSet(mUser.getText())); 614 values.put(Telephony.Carriers.SERVER, checkNotSet(mServer.getText())); 615 values.put(Telephony.Carriers.PASSWORD, checkNotSet(mPassword.getText())); 616 values.put(Telephony.Carriers.MMSC, checkNotSet(mMmsc.getText())); 617 618 String authVal = mAuthType.getValue(); 619 if (authVal != null) { 620 values.put(Telephony.Carriers.AUTH_TYPE, Integer.parseInt(authVal)); 621 } 622 623 values.put(Telephony.Carriers.PROTOCOL, checkNotSet(mProtocol.getValue())); 624 values.put(Telephony.Carriers.ROAMING_PROTOCOL, checkNotSet(mRoamingProtocol.getValue())); 625 626 values.put(Telephony.Carriers.TYPE, checkNotSet(mApnType.getText())); 627 628 values.put(Telephony.Carriers.MCC, mcc); 629 values.put(Telephony.Carriers.MNC, mnc); 630 631 values.put(Telephony.Carriers.NUMERIC, mcc + mnc); 632 633 if (mCurMnc != null && mCurMcc != null) { 634 if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) { 635 values.put(Telephony.Carriers.CURRENT, 1); 636 } 637 } 638 639 Set<String> bearerSet = mBearerMulti.getValues(); 640 int bearerBitmask = 0; 641 for (String bearer : bearerSet) { 642 if (Integer.parseInt(bearer) == 0) { 643 bearerBitmask = 0; 644 break; 645 } else { 646 bearerBitmask |= ServiceState.getBitmaskForTech(Integer.parseInt(bearer)); 647 } 648 } 649 values.put(Telephony.Carriers.BEARER_BITMASK, bearerBitmask); 650 651 int bearerVal; 652 if (bearerBitmask == 0 || mBearerInitialVal == 0) { 653 bearerVal = 0; 654 } else if (ServiceState.bitmaskHasTech(bearerBitmask, mBearerInitialVal)) { 655 bearerVal = mBearerInitialVal; 656 } else { 657 // bearer field was being used but bitmask has changed now and does not include the 658 // initial bearer value -- setting bearer to 0 but maybe better behavior is to choose a 659 // random tech from the new bitmask?? 660 bearerVal = 0; 661 } 662 values.put(Telephony.Carriers.BEARER, bearerVal); 663 664 values.put(Telephony.Carriers.MVNO_TYPE, checkNotSet(mMvnoType.getValue())); 665 values.put(Telephony.Carriers.MVNO_MATCH_DATA, checkNotSet(mMvnoMatchData.getText())); 666 667 values.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled.isChecked() ? 1 : 0); 668 getContentResolver().update(mUri, values, null, null); 669 670 return true; 671 } 672 getErrorMsg()673 private String getErrorMsg() { 674 String errorMsg = null; 675 676 String name = checkNotSet(mName.getText()); 677 String apn = checkNotSet(mApn.getText()); 678 String mcc = checkNotSet(mMcc.getText()); 679 String mnc = checkNotSet(mMnc.getText()); 680 681 if (name.length() < 1) { 682 errorMsg = mRes.getString(R.string.error_name_empty); 683 } else if (apn.length() < 1) { 684 errorMsg = mRes.getString(R.string.error_apn_empty); 685 } else if (mcc.length() != 3) { 686 errorMsg = mRes.getString(R.string.error_mcc_not3); 687 } else if ((mnc.length() & 0xFFFE) != 2) { 688 errorMsg = mRes.getString(R.string.error_mnc_not23); 689 } 690 691 return errorMsg; 692 } 693 694 @Override onCreateDialog(int id)695 protected Dialog onCreateDialog(int id) { 696 697 if (id == ERROR_DIALOG_ID) { 698 String msg = getErrorMsg(); 699 700 return new AlertDialog.Builder(this) 701 .setTitle(R.string.error_title) 702 .setPositiveButton(android.R.string.ok, null) 703 .setMessage(msg) 704 .create(); 705 } 706 707 return super.onCreateDialog(id); 708 } 709 710 @Override onPrepareDialog(int id, Dialog dialog)711 protected void onPrepareDialog(int id, Dialog dialog) { 712 super.onPrepareDialog(id, dialog); 713 714 if (id == ERROR_DIALOG_ID) { 715 String msg = getErrorMsg(); 716 717 if (msg != null) { 718 ((AlertDialog)dialog).setMessage(msg); 719 } 720 } 721 } 722 deleteApn()723 private void deleteApn() { 724 getContentResolver().delete(mUri, null, null); 725 finish(); 726 } 727 starify(String value)728 private String starify(String value) { 729 if (value == null || value.length() == 0) { 730 return sNotSet; 731 } else { 732 char[] password = new char[value.length()]; 733 for (int i = 0; i < password.length; i++) { 734 password[i] = '*'; 735 } 736 return new String(password); 737 } 738 } 739 checkNull(String value)740 private String checkNull(String value) { 741 if (value == null || value.length() == 0) { 742 return sNotSet; 743 } else { 744 return value; 745 } 746 } 747 checkNotSet(String value)748 private String checkNotSet(String value) { 749 if (value == null || value.equals(sNotSet)) { 750 return ""; 751 } else { 752 return value; 753 } 754 } 755 onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)756 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 757 Preference pref = findPreference(key); 758 if (pref != null) { 759 if (pref.equals(mPassword)){ 760 pref.setSummary(starify(sharedPreferences.getString(key, ""))); 761 } else if (pref.equals(mCarrierEnabled) || pref.equals(mBearerMulti)) { 762 // do nothing 763 } else { 764 pref.setSummary(checkNull(sharedPreferences.getString(key, ""))); 765 } 766 } 767 } 768 } 769