packages/apps/Settings
Revisão | 2877e184f378aae5c71ebf852360f0a5ee4b02c4 (tree) |
---|---|
Hora | 2009-08-03 23:45:47 |
Autor | Jean-Baptiste Queru <jbq@goog...> |
Commiter | Jean-Baptiste Queru |
merge from donut
@@ -1737,7 +1737,7 @@ found in the list of installed applications.</string> | ||
1737 | 1737 | <!-- Description for wifi connectivity --> |
1738 | 1738 | <string name="battery_desc_wifi">Battery used by Wi-Fi</string> |
1739 | 1739 | <!-- Suggestion for wifi connectivity power drain --> |
1740 | - <string name="battery_sugg_wifi">Turn off WiFi when not using it or where it is not available</string> | |
1740 | + <string name="battery_sugg_wifi">Turn off Wi-Fi when not using it or where it is not available</string> | |
1741 | 1741 | |
1742 | 1742 | <!-- Description for bluetooth power consumption detail --> |
1743 | 1743 | <string name="battery_desc_bluetooth">Battery used by bluetooth</string> |
@@ -1829,7 +1829,7 @@ found in the list of installed applications.</string> | ||
1829 | 1829 | <string name="vpn_yes_button">Yes</string> |
1830 | 1830 | <string name="vpn_no_button">No</string> |
1831 | 1831 | <string name="vpn_back_button">Back</string> |
1832 | - <string name="vpn_mistake_button">No, it's a mistake</string> | |
1832 | + <string name="vpn_mistake_button">No</string> | |
1833 | 1833 | |
1834 | 1834 | <string name="vpn_menu_done">Save</string> |
1835 | 1835 | <string name="vpn_menu_cancel">Cancel</string> |
@@ -1848,7 +1848,10 @@ found in the list of installed applications.</string> | ||
1848 | 1848 | <string name="vpn_confirm_edit_profile_cancellation">Are you sure you want to discard the changes made to this profile?</string> |
1849 | 1849 | <string name="vpn_confirm_reconnect">Unable to connect to the network. Do you want to try again?</string> |
1850 | 1850 | <string name="vpn_unknown_server_dialog_msg">Server name cannot be resolved. Do you want to check your server name setting?</string> |
1851 | + <string name="vpn_challenge_error_dialog_msg">Challenge error. Do you want to check your secret setting?</string> | |
1852 | + <string name="vpn_secret_not_set_dialog_msg">One or more secrets are missing in this VPN configuration. Do you want to check your secret setting?</string> | |
1851 | 1853 | <string name="vpn_auth_error_dialog_msg">The username or password you entered is incorrect. Do you want to try again?</string> |
1854 | + <string name="vpn_remote_hung_up_error_dialog_msg">Server hung up. The username or password you entered could be incorrect. Do you want to try again?</string> | |
1852 | 1855 | |
1853 | 1856 | <!-- VPN type selection activity title --> |
1854 | 1857 | <string name="vpn_type_title">Add VPN</string> |
@@ -1894,6 +1897,8 @@ found in the list of installed applications.</string> | ||
1894 | 1897 | <!-- Complete term --> |
1895 | 1898 | <string name="vpn_l2tp_secret">L2TP secret</string> |
1896 | 1899 | <string name="vpn_a_l2tp_secret">an L2TP secret</string> |
1900 | + <string name="vpn_pptp_encryption_title">encryption</string> | |
1901 | + <string name="vpn_pptp_encryption">PPTP encryption</string> | |
1897 | 1902 | |
1898 | 1903 | <!-- Preference title --> |
1899 | 1904 | <string name="vpn_ipsec_presharedkey_title">Set IPSec pre-shared key</string> |
@@ -1935,6 +1940,10 @@ found in the list of installed applications.</string> | ||
1935 | 1940 | <string name="vpn_settings_title">VPN settings</string> |
1936 | 1941 | <!-- Summary of preference to enter the VPN settings activity --> |
1937 | 1942 | <string name="vpn_settings_summary">Set up & manage Virtual Private Networks (VPNs)</string> |
1943 | + <!-- A secret edit field's grayed out value when it has not been modified --> | |
1944 | + <string name="vpn_secret_unchanged">(unchanged)</string> | |
1945 | + <!-- A secret edit field's grayed out value when it has not been set --> | |
1946 | + <string name="vpn_secret_not_set">(not set)</string> | |
1938 | 1947 | |
1939 | 1948 | <!-- Title of preference group for credential storage settings --> |
1940 | 1949 | <string name="cstor_settings_category">Credential storage</string> |
@@ -1991,6 +2000,9 @@ found in the list of installed applications.</string> | ||
1991 | 2000 | <string name="cstor_name_empty_error">Please enter a name.</string> |
1992 | 2001 | <string name="cstor_name_char_error">Please enter a name that contains only letters and numbers.</string> |
1993 | 2002 | <string name="cstor_storage_error">Unable to save the certificate. Click OK to retry.</string> |
2003 | + <string name="cstor_unable_to_save_cert">Unable to save the certificate. The credential storage is not enabled or properly initialized.</string> | |
2004 | + <string name="cstor_cert_not_saved">The certificate is not saved.</string> | |
2005 | + <string name="cstor_is_reset">The credential storage is erased.</string> | |
1994 | 2006 | |
1995 | 2007 | <!-- toast message --> |
1996 | 2008 | <string name="cstor_is_enabled">Credential storage is enabled.</string> |
@@ -76,12 +76,13 @@ | ||
76 | 76 | </PreferenceScreen> |
77 | 77 | |
78 | 78 | <!-- Contributors --> |
79 | + <!-- | |
79 | 80 | <PreferenceScreen |
80 | 81 | android:key="contributors" |
81 | 82 | android:title="@string/contributors_title"> |
82 | 83 | <intent android:action="android.settings.TEAM" /> |
83 | 84 | </PreferenceScreen> |
84 | - | |
85 | + --> | |
85 | 86 | <!-- System Tutorial - launches activity --> |
86 | 87 | <PreferenceScreen android:key="system_tutorial" |
87 | 88 | android:title="@string/system_tutorial_list_item_title" |
@@ -355,7 +355,7 @@ public class ManageApplications extends ListActivity implements | ||
355 | 355 | Log.w(TAG, "Couldnt find application info for:"+pkgName); |
356 | 356 | break; |
357 | 357 | } |
358 | - mObserver.invokeGetSizeInfo(info); | |
358 | + mObserver.invokeGetSizeInfo(pkgName); | |
359 | 359 | break; |
360 | 360 | case ADD_PKG_DONE: |
361 | 361 | if(localLOGV) Log.i(TAG, "Message ADD_PKG_DONE"); |
@@ -367,7 +367,12 @@ public class ManageApplications extends ListActivity implements | ||
367 | 367 | if (status) { |
368 | 368 | size = data.getLong(ATTR_PKG_STATS); |
369 | 369 | formattedSize = data.getString(ATTR_PKG_SIZE_STR); |
370 | - mAppInfoAdapter.addToList(pkgName, size, formattedSize); | |
370 | + int idx = mAppInfoAdapter.getIndex(pkgName); | |
371 | + if (idx == -1) { | |
372 | + mAppInfoAdapter.addToList(pkgName, size, formattedSize); | |
373 | + } else { | |
374 | + mAppInfoAdapter.updatePackage(pkgName, size, formattedSize); | |
375 | + } | |
371 | 376 | } |
372 | 377 | break; |
373 | 378 | case REFRESH_LABELS: |
@@ -1121,7 +1126,7 @@ public class ManageApplications extends ListActivity implements | ||
1121 | 1126 | } |
1122 | 1127 | return mSizeComparator; |
1123 | 1128 | } |
1124 | - | |
1129 | + | |
1125 | 1130 | public void bulkUpdateIcons(Map<String, Drawable> icons) { |
1126 | 1131 | if (icons == null) { |
1127 | 1132 | return; |
@@ -1162,19 +1167,6 @@ public class ManageApplications extends ListActivity implements | ||
1162 | 1167 | } |
1163 | 1168 | } |
1164 | 1169 | |
1165 | - public boolean updateAppLabel(String pkgName, CharSequence label) { | |
1166 | - if ((pkgName == null) || (label == null)) { | |
1167 | - return false; | |
1168 | - } | |
1169 | - AppInfo aInfo = mCache.getEntry(pkgName); | |
1170 | - if (aInfo != null) { | |
1171 | - aInfo.refreshLabel(label); | |
1172 | - notifyDataSetChanged(); | |
1173 | - return true; | |
1174 | - } | |
1175 | - return false; | |
1176 | - } | |
1177 | - | |
1178 | 1170 | private boolean shouldBeInList(int filterOption, ApplicationInfo info) { |
1179 | 1171 | // Match filter here |
1180 | 1172 | if (filterOption == FILTER_APPS_RUNNING) { |
@@ -1246,6 +1238,24 @@ public class ManageApplications extends ListActivity implements | ||
1246 | 1238 | } |
1247 | 1239 | } |
1248 | 1240 | |
1241 | + public void updatePackage(String pkgName, | |
1242 | + long size, String formattedSize) { | |
1243 | + ApplicationInfo info = null; | |
1244 | + try { | |
1245 | + info = mPm.getApplicationInfo(pkgName, | |
1246 | + PackageManager.GET_UNINSTALLED_PACKAGES); | |
1247 | + } catch (NameNotFoundException e) { | |
1248 | + return; | |
1249 | + } | |
1250 | + AppInfo aInfo = mCache.getEntry(pkgName); | |
1251 | + if (aInfo != null) { | |
1252 | + aInfo.refreshLabel(info.loadLabel(mPm)); | |
1253 | + aInfo.refreshIcon(info.loadIcon(mPm)); | |
1254 | + aInfo.setSize(size, formattedSize); | |
1255 | + notifyDataSetChanged(); | |
1256 | + } | |
1257 | + } | |
1258 | + | |
1249 | 1259 | private void removePkgBase(String pkgName) { |
1250 | 1260 | int imax = mAppList.size(); |
1251 | 1261 | for (int i = 0; i < imax; i++) { |
@@ -1300,7 +1310,7 @@ public class ManageApplications extends ListActivity implements | ||
1300 | 1310 | for (int i = 0; i < pkgs.length; i++) { |
1301 | 1311 | AppInfo entry = mCache.getEntry(pkgs[i]); |
1302 | 1312 | if (entry == null) { |
1303 | - Log.w(TAG, "Entry for package:"+ pkgs[i] +"doesn't exist in map"); | |
1313 | + if (localLOGV) Log.w(TAG, "Entry for package:"+ pkgs[i] +"doesn't exist in map"); | |
1304 | 1314 | continue; |
1305 | 1315 | } |
1306 | 1316 | if (entry.setSize(sizes[i], formatted[i])) { |
@@ -1311,21 +1321,6 @@ public class ManageApplications extends ListActivity implements | ||
1311 | 1321 | notifyDataSetChanged(); |
1312 | 1322 | } |
1313 | 1323 | } |
1314 | - | |
1315 | - public void updateAppSize(String pkgName, long size, String formattedSize) { | |
1316 | - if(pkgName == null) { | |
1317 | - return; | |
1318 | - } | |
1319 | - AppInfo entry = mCache.getEntry(pkgName); | |
1320 | - if (entry == null) { | |
1321 | - Log.w(TAG, "Entry for package:"+pkgName+"doesnt exist in map"); | |
1322 | - return; | |
1323 | - } | |
1324 | - // Copy the index into the newly updated entry | |
1325 | - if (entry.setSize(size, formattedSize)) { | |
1326 | - notifyDataSetChanged(); | |
1327 | - } | |
1328 | - } | |
1329 | 1324 | } |
1330 | 1325 | |
1331 | 1326 | /* |
@@ -1371,7 +1366,7 @@ public class ManageApplications extends ListActivity implements | ||
1371 | 1366 | * and the AppInfo object corresponding to the package name are set on the message |
1372 | 1367 | */ |
1373 | 1368 | class PkgSizeObserver extends IPackageStatsObserver.Stub { |
1374 | - private ApplicationInfo mAppInfo; | |
1369 | + String pkgName; | |
1375 | 1370 | public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) { |
1376 | 1371 | if(DEBUG_PKG_DELAY) { |
1377 | 1372 | try { |
@@ -1379,12 +1374,11 @@ public class ManageApplications extends ListActivity implements | ||
1379 | 1374 | } catch (InterruptedException e) { |
1380 | 1375 | } |
1381 | 1376 | } |
1382 | - AppInfo appInfo = null; | |
1383 | 1377 | Bundle data = new Bundle(); |
1384 | - data.putString(ATTR_PKG_NAME, mAppInfo.packageName); | |
1378 | + data.putString(ATTR_PKG_NAME, pkgName); | |
1385 | 1379 | data.putBoolean(ATTR_GET_SIZE_STATUS, pSucceeded); |
1386 | 1380 | if(pSucceeded && pStats != null) { |
1387 | - if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pStats.packageName+", ("+ | |
1381 | + if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pkgName+", ("+ | |
1388 | 1382 | pStats.cacheSize+","+ |
1389 | 1383 | pStats.codeSize+", "+pStats.dataSize); |
1390 | 1384 | long total = getTotalSize(pStats); |
@@ -1400,14 +1394,14 @@ public class ManageApplications extends ListActivity implements | ||
1400 | 1394 | mHandler.sendMessage(msg); |
1401 | 1395 | } |
1402 | 1396 | |
1403 | - public void invokeGetSizeInfo(ApplicationInfo pAppInfo) { | |
1404 | - if(pAppInfo == null || pAppInfo.packageName == null) { | |
1397 | + public void invokeGetSizeInfo(String packageName) { | |
1398 | + if (packageName == null) { | |
1405 | 1399 | return; |
1406 | 1400 | } |
1401 | + pkgName = packageName; | |
1407 | 1402 | if(localLOGV) Log.i(TAG, "Invoking getPackageSizeInfo for package:"+ |
1408 | - pAppInfo.packageName); | |
1409 | - mAppInfo = pAppInfo; | |
1410 | - mPm.getPackageSizeInfo(pAppInfo.packageName, this); | |
1403 | + packageName); | |
1404 | + mPm.getPackageSizeInfo(packageName, this); | |
1411 | 1405 | } |
1412 | 1406 | } |
1413 | 1407 |
@@ -42,6 +42,7 @@ import android.security.Keystore; | ||
42 | 42 | import android.text.Html; |
43 | 43 | import android.text.TextUtils; |
44 | 44 | import android.text.method.LinkMovementMethod; |
45 | +import android.util.Log; | |
45 | 46 | import android.view.View; |
46 | 47 | import android.widget.TextView; |
47 | 48 | import android.widget.Toast; |
@@ -464,15 +465,26 @@ public class SecuritySettings extends PreferenceActivity implements | ||
464 | 465 | |
465 | 466 | if (ACTION_ADD_CREDENTIAL.equals(action)) { |
466 | 467 | mCstorAddCredentialHelper = new CstorAddCredentialHelper(intent); |
467 | - showDialog(CSTOR_NAME_CREDENTIAL_DIALOG); | |
468 | + showCstorDialog(CSTOR_NAME_CREDENTIAL_DIALOG); | |
468 | 469 | } else if (ACTION_UNLOCK_CREDENTIAL_STORAGE.equals(action)) { |
469 | 470 | mSpecialIntent = intent; |
470 | - showDialog(mCstorHelper.isCstorInitialized() | |
471 | + showCstorDialog(mCstorHelper.isCstorInitialized() | |
471 | 472 | ? CSTOR_UNLOCK_DIALOG |
472 | 473 | : CSTOR_INIT_DIALOG); |
473 | 474 | } |
474 | 475 | } |
475 | 476 | |
477 | + private void showCstorDialog(int dialogId) { | |
478 | + mDialogId = dialogId; | |
479 | + showDialog(dialogId); | |
480 | + | |
481 | + if (dialogId == CSTOR_NAME_CREDENTIAL_DIALOG) { | |
482 | + // set mView back as mView may be replaced by CSTOR_INIT_DIALOG | |
483 | + // or CSTOR_UNLOCK_DIALOG | |
484 | + mView = mCstorAddCredentialHelper.mView; | |
485 | + } | |
486 | + } | |
487 | + | |
476 | 488 | private boolean isCstorUnlocked() { |
477 | 489 | return (mKeystore.getState() == Keystore.UNLOCKED); |
478 | 490 | } |
@@ -514,15 +526,53 @@ public class SecuritySettings extends PreferenceActivity implements | ||
514 | 526 | mKeystore.reset(); |
515 | 527 | enablePreferences(false); |
516 | 528 | mAccessCheckBox.setChecked(false); |
529 | + Toast.makeText(SecuritySettings.this, R.string.cstor_is_reset, | |
530 | + Toast.LENGTH_LONG).show(); | |
531 | + } | |
532 | + | |
533 | + private boolean addCredential() { | |
534 | + if (mCstorAddCredentialHelper.saveToStorage() != 0) { | |
535 | + // set mView back as mView may be replaced by CSTOR_INIT_DIALOG | |
536 | + // or CSTOR_UNLOCK_DIALOG | |
537 | + mView = mCstorAddCredentialHelper.mView; | |
538 | + if (mCstorAddCredentialHelper.isPkcs12Keystore()) { | |
539 | + showError(R.string.cstor_password_error); | |
540 | + } else { | |
541 | + showError(R.string.cstor_storage_error); | |
542 | + } | |
543 | + Log.d("CSTOR", "failed to add credential"); | |
544 | + return false; | |
545 | + } | |
546 | + Log.d("CSTOR", "credential is added: " | |
547 | + + mCstorAddCredentialHelper.getName()); | |
548 | + String formatString = | |
549 | + getString(R.string.cstor_is_added); | |
550 | + String message = String.format(formatString, | |
551 | + mCstorAddCredentialHelper.getName()); | |
552 | + Toast.makeText(SecuritySettings.this, message, | |
553 | + Toast.LENGTH_LONG).show(); | |
554 | + return true; | |
517 | 555 | } |
518 | 556 | |
519 | 557 | public void onCancel(DialogInterface dialog) { |
520 | - if (mCstorAddCredentialHelper != null) { | |
521 | - // release the object here so that it doesn't get triggerred in | |
522 | - // onDismiss() | |
523 | - mCstorAddCredentialHelper = null; | |
524 | - finish(); | |
558 | + if (mCstorAddCredentialHelper == null) return; | |
559 | + | |
560 | + switch (mDialogId) { | |
561 | + case CSTOR_INIT_DIALOG: | |
562 | + case CSTOR_UNLOCK_DIALOG: | |
563 | + Toast.makeText(SecuritySettings.this, | |
564 | + R.string.cstor_unable_to_save_cert, | |
565 | + Toast.LENGTH_LONG).show(); | |
566 | + break; | |
567 | + | |
568 | + case CSTOR_NAME_CREDENTIAL_DIALOG: | |
569 | + Toast.makeText(SecuritySettings.this, | |
570 | + R.string.cstor_cert_not_saved, | |
571 | + Toast.LENGTH_LONG).show(); | |
572 | + break; | |
525 | 573 | } |
574 | + mCstorAddCredentialHelper = null; | |
575 | + finish(); | |
526 | 576 | } |
527 | 577 | |
528 | 578 | public void onClick(DialogInterface dialog, int which) { |
@@ -554,31 +604,34 @@ public class SecuritySettings extends PreferenceActivity implements | ||
554 | 604 | public void onDismiss(DialogInterface dialog) { |
555 | 605 | if (!mConfirm) { |
556 | 606 | mConfirm = true; |
557 | - showDialog(mDialogId); | |
607 | + showCstorDialog(mDialogId); | |
558 | 608 | } else { |
559 | - removeDialog(mDialogId); | |
560 | - | |
561 | 609 | if (mDialogId == CSTOR_UNLOCK_DIALOG) { |
562 | 610 | mAccessCheckBox.setChecked(isCstorUnlocked()); |
563 | 611 | } |
564 | 612 | |
565 | 613 | if (mCstorAddCredentialHelper != null) { |
566 | 614 | if (!isCstorInitialized()) { |
567 | - showDialog(CSTOR_INIT_DIALOG); | |
615 | + showCstorDialog(CSTOR_INIT_DIALOG); | |
568 | 616 | } else if (!isCstorUnlocked()) { |
569 | - showDialog(CSTOR_UNLOCK_DIALOG); | |
617 | + showCstorDialog(CSTOR_UNLOCK_DIALOG); | |
570 | 618 | } else { |
571 | - String formatString = | |
572 | - getString(R.string.cstor_is_added); | |
573 | - String message = String.format(formatString, | |
574 | - mCstorAddCredentialHelper.getName()); | |
575 | - Toast.makeText(SecuritySettings.this, message, | |
576 | - Toast.LENGTH_SHORT).show(); | |
577 | - finish(); | |
619 | + if (addCredential()) { | |
620 | + // succeeded | |
621 | + finish(); | |
622 | + } else { | |
623 | + // failed | |
624 | + if (mDialogId != CSTOR_NAME_CREDENTIAL_DIALOG) { | |
625 | + removeDialog(mDialogId); | |
626 | + } | |
627 | + showCstorDialog(CSTOR_NAME_CREDENTIAL_DIALOG); | |
628 | + } | |
578 | 629 | } |
630 | + return; | |
579 | 631 | } else if (mSpecialIntent != null) { |
580 | 632 | finish(); |
581 | 633 | } |
634 | + removeDialog(mDialogId); | |
582 | 635 | } |
583 | 636 | } |
584 | 637 |
@@ -625,15 +678,6 @@ public class SecuritySettings extends PreferenceActivity implements | ||
625 | 678 | mCstorAddCredentialHelper.setPassword(password); |
626 | 679 | } |
627 | 680 | |
628 | - if (mCstorAddCredentialHelper.saveToStorage() < 0) { | |
629 | - if (mCstorAddCredentialHelper.isPkcs12Keystore()) { | |
630 | - showError(R.string.cstor_password_error); | |
631 | - } else { | |
632 | - showError(R.string.cstor_storage_error); | |
633 | - } | |
634 | - return false; | |
635 | - } | |
636 | - | |
637 | 681 | return true; |
638 | 682 | } |
639 | 683 |
@@ -760,7 +804,7 @@ public class SecuritySettings extends PreferenceActivity implements | ||
760 | 804 | public boolean onPreferenceChange( |
761 | 805 | Preference pref, Object value) { |
762 | 806 | if (((Boolean) value)) { |
763 | - showDialog(isCstorInitialized() | |
807 | + showCstorDialog(isCstorInitialized() | |
764 | 808 | ? CSTOR_UNLOCK_DIALOG |
765 | 809 | : CSTOR_INIT_DIALOG); |
766 | 810 | } else { |
@@ -781,7 +825,7 @@ public class SecuritySettings extends PreferenceActivity implements | ||
781 | 825 | pref.setOnPreferenceClickListener( |
782 | 826 | new Preference.OnPreferenceClickListener() { |
783 | 827 | public boolean onPreferenceClick(Preference pref) { |
784 | - showDialog(isCstorInitialized() | |
828 | + showCstorDialog(isCstorInitialized() | |
785 | 829 | ? CSTOR_CHANGE_PASSWORD_DIALOG |
786 | 830 | : CSTOR_INIT_DIALOG); |
787 | 831 | return true; |
@@ -797,7 +841,7 @@ public class SecuritySettings extends PreferenceActivity implements | ||
797 | 841 | pref.setOnPreferenceClickListener( |
798 | 842 | new Preference.OnPreferenceClickListener() { |
799 | 843 | public boolean onPreferenceClick(Preference pref) { |
800 | - showDialog(CSTOR_RESET_DIALOG); | |
844 | + showCstorDialog(CSTOR_RESET_DIALOG); | |
801 | 845 | return true; |
802 | 846 | } |
803 | 847 | }); |
@@ -807,7 +851,6 @@ public class SecuritySettings extends PreferenceActivity implements | ||
807 | 851 | } |
808 | 852 | |
809 | 853 | private Dialog createUnlockDialog() { |
810 | - mDialogId = CSTOR_UNLOCK_DIALOG; | |
811 | 854 | mView = View.inflate(SecuritySettings.this, |
812 | 855 | R.layout.cstor_unlock_dialog_view, null); |
813 | 856 | hideError(); |
@@ -830,7 +873,6 @@ public class SecuritySettings extends PreferenceActivity implements | ||
830 | 873 | } |
831 | 874 | |
832 | 875 | private Dialog createSetPasswordDialog(int id) { |
833 | - mDialogId = id; | |
834 | 876 | mView = View.inflate(SecuritySettings.this, |
835 | 877 | R.layout.cstor_set_password_dialog_view, null); |
836 | 878 | hideError(); |
@@ -870,7 +912,6 @@ public class SecuritySettings extends PreferenceActivity implements | ||
870 | 912 | } |
871 | 913 | |
872 | 914 | private Dialog createResetDialog() { |
873 | - mDialogId = CSTOR_RESET_DIALOG; | |
874 | 915 | return new AlertDialog.Builder(SecuritySettings.this) |
875 | 916 | .setTitle(android.R.string.dialog_alert_title) |
876 | 917 | .setIcon(android.R.drawable.ic_dialog_alert) |
@@ -881,9 +922,12 @@ public class SecuritySettings extends PreferenceActivity implements | ||
881 | 922 | } |
882 | 923 | |
883 | 924 | private Dialog createNameCredentialDialog() { |
884 | - mDialogId = CSTOR_NAME_CREDENTIAL_DIALOG; | |
885 | 925 | mView = View.inflate(SecuritySettings.this, |
886 | 926 | R.layout.cstor_name_credential_dialog_view, null); |
927 | + if (mCstorAddCredentialHelper != null) { | |
928 | + mCstorAddCredentialHelper.mView = mView; | |
929 | + } | |
930 | + | |
887 | 931 | hideError(); |
888 | 932 | if (!mCstorAddCredentialHelper.isPkcs12Keystore()) { |
889 | 933 | hide(R.id.cstor_credential_password_container); |
@@ -915,6 +959,7 @@ public class SecuritySettings extends PreferenceActivity implements | ||
915 | 959 | private String mDescription; |
916 | 960 | private String mName; |
917 | 961 | private String mPassword; |
962 | + private View mView; | |
918 | 963 | |
919 | 964 | CstorAddCredentialHelper(Intent intent) { |
920 | 965 | parse(intent); |
@@ -958,7 +1003,7 @@ public class SecuritySettings extends PreferenceActivity implements | ||
958 | 1003 | byte[] blob = mItemList.get(i); |
959 | 1004 | int ret = ks.put(mNamespaceList.get(i), mName, |
960 | 1005 | new String(blob)); |
961 | - if (ret < 0) return ret; | |
1006 | + if (ret != 0) return ret; | |
962 | 1007 | } |
963 | 1008 | } |
964 | 1009 | return 0; |
@@ -59,7 +59,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
59 | 59 | private static final String LOCALE_DELIMITER = "-"; |
60 | 60 | |
61 | 61 | private static final String FALLBACK_TTS_DEFAULT_SYNTH = |
62 | - TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_SYNTH; | |
62 | + TextToSpeech.Engine.DEFAULT_SYNTH; | |
63 | 63 | |
64 | 64 | private Preference mPlayExample = null; |
65 | 65 | private Preference mInstallData = null; |
@@ -141,7 +141,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
141 | 141 | intVal = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS); |
142 | 142 | } catch (SettingNotFoundException e) { |
143 | 143 | // "use default" setting not found, initialize it |
144 | - intVal = TextToSpeech.Engine.FALLBACK_TTS_USE_DEFAULTS; | |
144 | + intVal = TextToSpeech.Engine.USE_DEFAULTS; | |
145 | 145 | Settings.Secure.putInt(resolver, TTS_USE_DEFAULTS, intVal); |
146 | 146 | } |
147 | 147 | mUseDefaultPref.setChecked(intVal == 1); |
@@ -162,7 +162,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
162 | 162 | intVal = Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE); |
163 | 163 | } catch (SettingNotFoundException e) { |
164 | 164 | // default rate setting not found, initialize it |
165 | - intVal = TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_RATE; | |
165 | + intVal = TextToSpeech.Engine.DEFAULT_RATE; | |
166 | 166 | Settings.Secure.putInt(resolver, TTS_DEFAULT_RATE, intVal); |
167 | 167 | } |
168 | 168 | mDefaultRatePref.setValue(String.valueOf(intVal)); |
@@ -223,7 +223,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
223 | 223 | private void checkVoiceData() { |
224 | 224 | PackageManager pm = getPackageManager(); |
225 | 225 | Intent intent = new Intent(); |
226 | - intent.setAction("android.intent.action.CHECK_TTS_DATA"); | |
226 | + intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); | |
227 | 227 | List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); |
228 | 228 | // query only the package that matches that of the default engine |
229 | 229 | for (int i = 0; i < resolveInfos.size(); i++) { |
@@ -243,7 +243,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
243 | 243 | private void installVoiceData() { |
244 | 244 | PackageManager pm = getPackageManager(); |
245 | 245 | Intent intent = new Intent(); |
246 | - intent.setAction("android.intent.action.INSTALL_TTS_DATA"); | |
246 | + intent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); | |
247 | 247 | List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); |
248 | 248 | // query only the package that matches that of the default engine |
249 | 249 | for (int i = 0; i < resolveInfos.size(); i++) { |
@@ -260,7 +260,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
260 | 260 | * Called when the TTS engine is initialized. |
261 | 261 | */ |
262 | 262 | public void onInit(int status) { |
263 | - if (status == TextToSpeech.TTS_SUCCESS) { | |
263 | + if (status == TextToSpeech.SUCCESS) { | |
264 | 264 | Log.v(TAG, "TTS engine for settings screen initialized."); |
265 | 265 | mEnableDemo = true; |
266 | 266 | } else { |
@@ -337,7 +337,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements | ||
337 | 337 | // Play example |
338 | 338 | if (mTts != null) { |
339 | 339 | mTts.speak(getResources().getString(R.string.tts_demo), |
340 | - TextToSpeech.TTS_QUEUE_FLUSH, null); | |
340 | + TextToSpeech.QUEUE_FLUSH, null); | |
341 | 341 | } |
342 | 342 | return true; |
343 | 343 | } |
@@ -162,6 +162,7 @@ public class Status extends PreferenceActivity { | ||
162 | 162 | @Override |
163 | 163 | protected void onCreate(Bundle icicle) { |
164 | 164 | super.onCreate(icicle); |
165 | + Preference removablePref; | |
165 | 166 | |
166 | 167 | mHandler = new MyHandler(this); |
167 | 168 |
@@ -188,8 +189,15 @@ public class Status extends PreferenceActivity { | ||
188 | 189 | setSummaryText("prl_version", mPhone.getCdmaPrlVersion()); |
189 | 190 | |
190 | 191 | // device is not GSM/UMTS, do not display GSM/UMTS features |
191 | - getPreferenceScreen().removePreference(findPreference("imei")); | |
192 | - getPreferenceScreen().removePreference(findPreference("imei_sv")); | |
192 | + // check Null in case no specified preference in overlay xml | |
193 | + removablePref = findPreference("imei"); | |
194 | + if (removablePref != null) { | |
195 | + getPreferenceScreen().removePreference(removablePref); | |
196 | + } | |
197 | + removablePref = findPreference("imei_sv"); | |
198 | + if (removablePref != null) { | |
199 | + getPreferenceScreen().removePreference(removablePref); | |
200 | + } | |
193 | 201 | } else { |
194 | 202 | setSummaryText("imei", mPhone.getDeviceId()); |
195 | 203 |
@@ -198,9 +206,19 @@ public class Status extends PreferenceActivity { | ||
198 | 206 | .getDeviceSoftwareVersion()); |
199 | 207 | |
200 | 208 | // device is not CDMA, do not display CDMA features |
201 | - getPreferenceScreen().removePreference(findPreference("prl_version")); | |
202 | - getPreferenceScreen().removePreference(findPreference("meid_number")); | |
203 | - getPreferenceScreen().removePreference(findPreference("min_number")); | |
209 | + // check Null in case no specified preference in overlay xml | |
210 | + removablePref = findPreference("prl_version"); | |
211 | + if (removablePref != null) { | |
212 | + getPreferenceScreen().removePreference(removablePref); | |
213 | + } | |
214 | + removablePref = findPreference("meid_number"); | |
215 | + if (removablePref != null) { | |
216 | + getPreferenceScreen().removePreference(removablePref); | |
217 | + } | |
218 | + removablePref = findPreference("min_number"); | |
219 | + if (removablePref != null) { | |
220 | + getPreferenceScreen().removePreference(removablePref); | |
221 | + } | |
204 | 222 | } |
205 | 223 | |
206 | 224 | setSummaryText("number", mPhone.getLine1Number()); |
@@ -463,7 +463,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { | ||
463 | 463 | btPower += (btPingCount |
464 | 464 | * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000; |
465 | 465 | |
466 | - addEntry(getString(R.string.power_bluetooth), DrainType.IDLE, btOnTimeMs, | |
466 | + addEntry(getString(R.string.power_bluetooth), DrainType.BLUETOOTH, btOnTimeMs, | |
467 | 467 | com.android.internal.R.drawable.ic_volume_bluetooth_in_call, btPower); |
468 | 468 | } |
469 | 469 |
@@ -30,9 +30,7 @@ import android.preference.PreferenceGroup; | ||
30 | 30 | */ |
31 | 31 | class L2tpEditor extends VpnProfileEditor { |
32 | 32 | private CheckBoxPreference mSecret; |
33 | - private EditTextPreference mSecretString; | |
34 | - private String mOriginalSecret; | |
35 | - private boolean mOriginalSecretEnabled; | |
33 | + private SecretHandler mSecretHandler; | |
36 | 34 | |
37 | 35 | public L2tpEditor(L2tpProfile p) { |
38 | 36 | super(p); |
@@ -43,11 +41,8 @@ class L2tpEditor extends VpnProfileEditor { | ||
43 | 41 | Context c = subpanel.getContext(); |
44 | 42 | subpanel.addPreference(createSecretPreference(c)); |
45 | 43 | subpanel.addPreference(createSecretStringPreference(c)); |
46 | - mSecretString.setEnabled(mSecret.isChecked()); | |
47 | 44 | |
48 | 45 | L2tpProfile profile = (L2tpProfile) getProfile(); |
49 | - mOriginalSecret = profile.getSecretString(); | |
50 | - mOriginalSecretEnabled = profile.isSecretEnabled(); | |
51 | 46 | } |
52 | 47 | |
53 | 48 | @Override |
@@ -55,9 +50,7 @@ class L2tpEditor extends VpnProfileEditor { | ||
55 | 50 | String result = super.validate(); |
56 | 51 | if (!mSecret.isChecked()) return result; |
57 | 52 | |
58 | - return ((result != null) | |
59 | - ? result | |
60 | - : validate(mSecretString, R.string.vpn_a_l2tp_secret)); | |
53 | + return ((result != null) ? result : mSecretHandler.validate()); | |
61 | 54 | } |
62 | 55 | |
63 | 56 | private Preference createSecretPreference(Context c) { |
@@ -73,7 +66,7 @@ class L2tpEditor extends VpnProfileEditor { | ||
73 | 66 | Preference pref, Object newValue) { |
74 | 67 | boolean enabled = (Boolean) newValue; |
75 | 68 | profile.setSecretEnabled(enabled); |
76 | - mSecretString.setEnabled(enabled); | |
69 | + mSecretHandler.getPreference().setEnabled(enabled); | |
77 | 70 | setSecretTitle(mSecret, R.string.vpn_l2tp_secret, |
78 | 71 | enabled); |
79 | 72 | setSecretSummary(mSecret, enabled); |
@@ -84,22 +77,22 @@ class L2tpEditor extends VpnProfileEditor { | ||
84 | 77 | } |
85 | 78 | |
86 | 79 | private Preference createSecretStringPreference(Context c) { |
87 | - final L2tpProfile profile = (L2tpProfile) getProfile(); | |
88 | - mSecretString = createSecretPreference(c, | |
80 | + SecretHandler sHandler = mSecretHandler = new SecretHandler(c, | |
89 | 81 | R.string.vpn_l2tp_secret_string_title, |
90 | - R.string.vpn_l2tp_secret, | |
91 | - profile.getSecretString(), | |
92 | - new Preference.OnPreferenceChangeListener() { | |
93 | - public boolean onPreferenceChange( | |
94 | - Preference pref, Object newValue) { | |
95 | - profile.setSecretString((String) newValue); | |
96 | - setSecretSummary(mSecretString, | |
97 | - R.string.vpn_l2tp_secret, | |
98 | - (String) newValue); | |
99 | - return true; | |
100 | - } | |
101 | - }); | |
102 | - return mSecretString; | |
82 | + R.string.vpn_l2tp_secret) { | |
83 | + @Override | |
84 | + protected String getSecretFromProfile() { | |
85 | + return ((L2tpProfile) getProfile()).getSecretString(); | |
86 | + } | |
87 | + | |
88 | + @Override | |
89 | + protected void saveSecretToProfile(String secret) { | |
90 | + ((L2tpProfile) getProfile()).setSecretString(secret); | |
91 | + } | |
92 | + }; | |
93 | + Preference pref = sHandler.getPreference(); | |
94 | + pref.setEnabled(mSecret.isChecked()); | |
95 | + return pref; | |
103 | 96 | } |
104 | 97 | |
105 | 98 | private void setSecretSummary(CheckBoxPreference secret, boolean enabled) { |
@@ -29,6 +29,7 @@ import android.preference.PreferenceGroup; | ||
29 | 29 | */ |
30 | 30 | class L2tpIpsecPskEditor extends L2tpEditor { |
31 | 31 | private EditTextPreference mPresharedKey; |
32 | + private SecretHandler mPskHandler; | |
32 | 33 | |
33 | 34 | public L2tpIpsecPskEditor(L2tpIpsecPskProfile p) { |
34 | 35 | super(p); |
@@ -45,27 +46,23 @@ class L2tpIpsecPskEditor extends L2tpEditor { | ||
45 | 46 | public String validate() { |
46 | 47 | String result = super.validate(); |
47 | 48 | |
48 | - return ((result != null) | |
49 | - ? result | |
50 | - : validate(mPresharedKey, R.string.vpn_a_ipsec_presharedkey)); | |
49 | + return ((result != null) ? result : mPskHandler.validate()); | |
51 | 50 | } |
52 | 51 | |
53 | 52 | private Preference createPresharedKeyPreference(Context c) { |
54 | - final L2tpIpsecPskProfile profile = (L2tpIpsecPskProfile) getProfile(); | |
55 | - mPresharedKey = createSecretPreference(c, | |
53 | + SecretHandler pskHandler = mPskHandler = new SecretHandler(c, | |
56 | 54 | R.string.vpn_ipsec_presharedkey_title, |
57 | - R.string.vpn_ipsec_presharedkey, | |
58 | - profile.getPresharedKey(), | |
59 | - new Preference.OnPreferenceChangeListener() { | |
60 | - public boolean onPreferenceChange( | |
61 | - Preference pref, Object newValue) { | |
62 | - profile.setPresharedKey((String) newValue); | |
63 | - setSecretSummary(mPresharedKey, | |
64 | - R.string.vpn_ipsec_presharedkey, | |
65 | - (String) newValue); | |
66 | - return true; | |
67 | - } | |
68 | - }); | |
69 | - return mPresharedKey; | |
55 | + R.string.vpn_ipsec_presharedkey) { | |
56 | + @Override | |
57 | + protected String getSecretFromProfile() { | |
58 | + return ((L2tpIpsecPskProfile) getProfile()).getPresharedKey(); | |
59 | + } | |
60 | + | |
61 | + @Override | |
62 | + protected void saveSecretToProfile(String secret) { | |
63 | + ((L2tpIpsecPskProfile) getProfile()).setPresharedKey(secret); | |
64 | + } | |
65 | + }; | |
66 | + return pskHandler.getPreference(); | |
70 | 67 | } |
71 | 68 | } |
@@ -0,0 +1,75 @@ | ||
1 | +/* * Copyright (C) 2009 The Android Open Source Project | |
2 | + * | |
3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | + * you may not use this file except in compliance with the License. | |
5 | + * You may obtain a copy of the License at | |
6 | + * | |
7 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * | |
9 | + * Unless required by applicable law or agreed to in writing, software | |
10 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | + * See the License for the specific language governing permissions and | |
13 | + * limitations under the License. | |
14 | + */ | |
15 | + | |
16 | +package com.android.settings.vpn; | |
17 | + | |
18 | +import com.android.settings.R; | |
19 | + | |
20 | +import android.content.Context; | |
21 | +import android.net.vpn.PptpProfile; | |
22 | +import android.preference.CheckBoxPreference; | |
23 | +import android.preference.Preference; | |
24 | +import android.preference.PreferenceGroup; | |
25 | + | |
26 | +/** | |
27 | + * The class for editing {@link PptpProfile}. | |
28 | + */ | |
29 | +class PptpEditor extends VpnProfileEditor { | |
30 | + private CheckBoxPreference mEncryption; | |
31 | + | |
32 | + public PptpEditor(PptpProfile p) { | |
33 | + super(p); | |
34 | + } | |
35 | + | |
36 | + @Override | |
37 | + protected void loadExtraPreferencesTo(PreferenceGroup subpanel) { | |
38 | + Context c = subpanel.getContext(); | |
39 | + subpanel.addPreference(createEncryptionPreference(c)); | |
40 | + | |
41 | + PptpProfile profile = (PptpProfile) getProfile(); | |
42 | + } | |
43 | + | |
44 | + private Preference createEncryptionPreference(Context c) { | |
45 | + final PptpProfile profile = (PptpProfile) getProfile(); | |
46 | + CheckBoxPreference encryption = mEncryption = new CheckBoxPreference(c); | |
47 | + boolean enabled = profile.isEncryptionEnabled(); | |
48 | + setSecretTitle(encryption, R.string.vpn_pptp_encryption_title, enabled); | |
49 | + encryption.setChecked(enabled); | |
50 | + setEncryptionSummary(encryption, enabled); | |
51 | + encryption.setOnPreferenceChangeListener( | |
52 | + new Preference.OnPreferenceChangeListener() { | |
53 | + public boolean onPreferenceChange( | |
54 | + Preference pref, Object newValue) { | |
55 | + boolean enabled = (Boolean) newValue; | |
56 | + profile.setEncryptionEnabled(enabled); | |
57 | + setSecretTitle(mEncryption, | |
58 | + R.string.vpn_pptp_encryption_title, enabled); | |
59 | + setEncryptionSummary(mEncryption, enabled); | |
60 | + return true; | |
61 | + } | |
62 | + }); | |
63 | + return encryption; | |
64 | + } | |
65 | + | |
66 | + private void setEncryptionSummary(CheckBoxPreference encryption, | |
67 | + boolean enabled) { | |
68 | + Context c = encryption.getContext(); | |
69 | + String formatString = c.getString(enabled | |
70 | + ? R.string.vpn_is_enabled | |
71 | + : R.string.vpn_is_disabled); | |
72 | + encryption.setSummary(String.format( | |
73 | + formatString, c.getString(R.string.vpn_pptp_encryption))); | |
74 | + } | |
75 | +} |
@@ -24,9 +24,11 @@ import android.content.Intent; | ||
24 | 24 | import android.net.vpn.L2tpIpsecProfile; |
25 | 25 | import android.net.vpn.L2tpIpsecPskProfile; |
26 | 26 | import android.net.vpn.L2tpProfile; |
27 | +import android.net.vpn.PptpProfile; | |
27 | 28 | import android.net.vpn.VpnProfile; |
28 | 29 | import android.net.vpn.VpnType; |
29 | 30 | import android.os.Bundle; |
31 | +import android.os.Parcel; | |
30 | 32 | import android.os.Parcelable; |
31 | 33 | import android.preference.PreferenceActivity; |
32 | 34 | import android.preference.PreferenceGroup; |
@@ -47,6 +49,7 @@ public class VpnEditor extends PreferenceActivity { | ||
47 | 49 | |
48 | 50 | private VpnProfileEditor mProfileEditor; |
49 | 51 | private boolean mAddingProfile; |
52 | + private byte[] mOriginalProfileData; | |
50 | 53 | |
51 | 54 | @Override |
52 | 55 | public void onCreate(Bundle savedInstanceState) { |
@@ -61,6 +64,10 @@ public class VpnEditor extends PreferenceActivity { | ||
61 | 64 | addPreferencesFromResource(R.xml.vpn_edit); |
62 | 65 | |
63 | 66 | initViewFor(p); |
67 | + | |
68 | + Parcel parcel = Parcel.obtain(); | |
69 | + p.writeToParcel(parcel, 0); | |
70 | + mOriginalProfileData = parcel.marshall(); | |
64 | 71 | } |
65 | 72 | |
66 | 73 | @Override |
@@ -90,7 +97,11 @@ public class VpnEditor extends PreferenceActivity { | ||
90 | 97 | return true; |
91 | 98 | |
92 | 99 | case MENU_CANCEL: |
93 | - showCancellationConfirmDialog(); | |
100 | + if (profileChanged()) { | |
101 | + showCancellationConfirmDialog(); | |
102 | + } else { | |
103 | + finish(); | |
104 | + } | |
94 | 105 | return true; |
95 | 106 | } |
96 | 107 | return super.onOptionsItemSelected(item); |
@@ -131,7 +142,7 @@ public class VpnEditor extends PreferenceActivity { | ||
131 | 142 | return false; |
132 | 143 | } |
133 | 144 | |
134 | - setResult(getProfile()); | |
145 | + if (profileChanged()) setResult(getProfile()); | |
135 | 146 | return true; |
136 | 147 | } |
137 | 148 |
@@ -152,6 +163,9 @@ public class VpnEditor extends PreferenceActivity { | ||
152 | 163 | case L2TP: |
153 | 164 | return new L2tpEditor((L2tpProfile) p); |
154 | 165 | |
166 | + case PPTP: | |
167 | + return new PptpEditor((PptpProfile) p); | |
168 | + | |
155 | 169 | default: |
156 | 170 | return new VpnProfileEditor(p); |
157 | 171 | } |
@@ -177,4 +191,17 @@ public class VpnEditor extends PreferenceActivity { | ||
177 | 191 | private VpnProfile getProfile() { |
178 | 192 | return mProfileEditor.getProfile(); |
179 | 193 | } |
194 | + | |
195 | + private boolean profileChanged() { | |
196 | + Parcel newParcel = Parcel.obtain(); | |
197 | + getProfile().writeToParcel(newParcel, 0); | |
198 | + byte[] newData = newParcel.marshall(); | |
199 | + if (mOriginalProfileData.length == newData.length) { | |
200 | + for (int i = 0, n = mOriginalProfileData.length; i < n; i++) { | |
201 | + if (mOriginalProfileData[i] != newData[i]) return true; | |
202 | + } | |
203 | + return false; | |
204 | + } | |
205 | + return true; | |
206 | + } | |
180 | 207 | } |
@@ -33,9 +33,6 @@ import android.text.method.PasswordTransformationMethod; | ||
33 | 33 | * The common class for editing {@link VpnProfile}. |
34 | 34 | */ |
35 | 35 | class VpnProfileEditor { |
36 | - static final String SECRET_SET_INDICATOR = | |
37 | - new String(new byte[] {(byte) 1, (byte) 0}); | |
38 | - | |
39 | 36 | private static final String KEY_VPN_NAME = "vpn_name"; |
40 | 37 | |
41 | 38 | private EditTextPreference mName; |
@@ -69,6 +66,8 @@ class VpnProfileEditor { | ||
69 | 66 | } |
70 | 67 | }); |
71 | 68 | setName(getProfile().getName()); |
69 | + mName.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | |
70 | + | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); | |
72 | 71 | |
73 | 72 | subpanel.addPreference(createServerNamePreference(c)); |
74 | 73 | loadExtraPreferencesTo(subpanel); |
@@ -147,22 +146,6 @@ class VpnProfileEditor { | ||
147 | 146 | return pref; |
148 | 147 | } |
149 | 148 | |
150 | - protected EditTextPreference createSecretPreference(Context c, int titleId, | |
151 | - int fieldNameId, String value, | |
152 | - Preference.OnPreferenceChangeListener listener) { | |
153 | - EditTextPreference pref = new EditTextPreference(c); | |
154 | - pref.setTitle(titleId); | |
155 | - pref.setDialogTitle(titleId); | |
156 | - pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); | |
157 | - pref.getEditText().setTransformationMethod( | |
158 | - new PasswordTransformationMethod()); | |
159 | - pref.setText(TextUtils.isEmpty(value) ? "" : SECRET_SET_INDICATOR); | |
160 | - setSecretSummary(pref, fieldNameId, value); | |
161 | - pref.setPersistent(true); | |
162 | - pref.setOnPreferenceChangeListener(listener); | |
163 | - return pref; | |
164 | - } | |
165 | - | |
166 | 149 | protected String validate(Preference pref, int fieldNameId) { |
167 | 150 | Context c = pref.getContext(); |
168 | 151 | String value = (pref instanceof EditTextPreference) |
@@ -191,15 +174,6 @@ class VpnProfileEditor { | ||
191 | 174 | : v); |
192 | 175 | } |
193 | 176 | |
194 | - protected void setSecretSummary(Preference pref, int fieldNameId, | |
195 | - String value) { | |
196 | - Context c = pref.getContext(); | |
197 | - String formatString = TextUtils.isEmpty(value) | |
198 | - ? c.getString(R.string.vpn_field_not_set) | |
199 | - : c.getString(R.string.vpn_field_is_set); | |
200 | - pref.setSummary(String.format(formatString, c.getString(fieldNameId))); | |
201 | - } | |
202 | - | |
203 | 177 | protected void setSecretTitle( |
204 | 178 | CheckBoxPreference pref, int fieldNameId, boolean enabled) { |
205 | 179 | Context c = pref.getContext(); |
@@ -215,4 +189,69 @@ class VpnProfileEditor { | ||
215 | 189 | getProfile().setName(newName); |
216 | 190 | setSummary(mName, R.string.vpn_name, newName); |
217 | 191 | } |
192 | + | |
193 | + // Secret is tricky to handle because empty field may mean "not set" or | |
194 | + // "unchanged". This class hides that logic from callers. | |
195 | + protected static abstract class SecretHandler { | |
196 | + private EditTextPreference mPref; | |
197 | + private int mFieldNameId; | |
198 | + private boolean mHadSecret; | |
199 | + | |
200 | + protected SecretHandler(Context c, int titleId, int fieldNameId) { | |
201 | + String value = getSecretFromProfile(); | |
202 | + mHadSecret = !TextUtils.isEmpty(value); | |
203 | + mFieldNameId = fieldNameId; | |
204 | + | |
205 | + EditTextPreference pref = mPref = new EditTextPreference(c); | |
206 | + pref.setTitle(titleId); | |
207 | + pref.setDialogTitle(titleId); | |
208 | + pref.getEditText().setInputType( | |
209 | + InputType.TYPE_TEXT_VARIATION_PASSWORD); | |
210 | + pref.getEditText().setTransformationMethod( | |
211 | + new PasswordTransformationMethod()); | |
212 | + pref.setText(""); | |
213 | + pref.getEditText().setHint(mHadSecret | |
214 | + ? R.string.vpn_secret_unchanged | |
215 | + : R.string.vpn_secret_not_set); | |
216 | + setSecretSummary(value); | |
217 | + pref.setPersistent(true); | |
218 | + saveSecretToProfile(""); | |
219 | + pref.setOnPreferenceChangeListener( | |
220 | + new Preference.OnPreferenceChangeListener() { | |
221 | + public boolean onPreferenceChange( | |
222 | + Preference pref, Object newValue) { | |
223 | + saveSecretToProfile((String) newValue); | |
224 | + setSecretSummary((String) newValue); | |
225 | + return true; | |
226 | + } | |
227 | + }); | |
228 | + } | |
229 | + | |
230 | + protected EditTextPreference getPreference() { | |
231 | + return mPref; | |
232 | + } | |
233 | + | |
234 | + protected String validate() { | |
235 | + Context c = mPref.getContext(); | |
236 | + String value = mPref.getText(); | |
237 | + return ((TextUtils.isEmpty(value) && !mHadSecret) | |
238 | + ? String.format( | |
239 | + c.getString(R.string.vpn_error_miss_entering), | |
240 | + c.getString(mFieldNameId)) | |
241 | + : null); | |
242 | + } | |
243 | + | |
244 | + private void setSecretSummary(String value) { | |
245 | + EditTextPreference pref = mPref; | |
246 | + Context c = pref.getContext(); | |
247 | + String formatString = (TextUtils.isEmpty(value) && !mHadSecret) | |
248 | + ? c.getString(R.string.vpn_field_not_set) | |
249 | + : c.getString(R.string.vpn_field_is_set); | |
250 | + pref.setSummary( | |
251 | + String.format(formatString, c.getString(mFieldNameId))); | |
252 | + } | |
253 | + | |
254 | + protected abstract String getSecretFromProfile(); | |
255 | + protected abstract void saveSecretToProfile(String secret); | |
256 | + } | |
218 | 257 | } |
@@ -18,7 +18,6 @@ package com.android.settings.vpn; | ||
18 | 18 | |
19 | 19 | import com.android.settings.R; |
20 | 20 | import com.android.settings.SecuritySettings; |
21 | -import static com.android.settings.vpn.VpnProfileEditor.SECRET_SET_INDICATOR; | |
22 | 21 | |
23 | 22 | import android.app.AlertDialog; |
24 | 23 | import android.app.Dialog; |
@@ -29,6 +28,7 @@ import android.content.DialogInterface; | ||
29 | 28 | import android.content.Intent; |
30 | 29 | import android.content.ServiceConnection; |
31 | 30 | import android.net.vpn.IVpnService; |
31 | +import android.net.vpn.L2tpIpsecProfile; | |
32 | 32 | import android.net.vpn.L2tpIpsecPskProfile; |
33 | 33 | import android.net.vpn.L2tpProfile; |
34 | 34 | import android.net.vpn.VpnManager; |
@@ -47,6 +47,7 @@ import android.preference.PreferenceCategory; | ||
47 | 47 | import android.preference.PreferenceManager; |
48 | 48 | import android.preference.PreferenceScreen; |
49 | 49 | import android.preference.Preference.OnPreferenceClickListener; |
50 | +import android.security.CertTool; | |
50 | 51 | import android.security.Keystore; |
51 | 52 | import android.text.TextUtils; |
52 | 53 | import android.util.Log; |
@@ -107,6 +108,9 @@ public class VpnSettings extends PreferenceActivity implements | ||
107 | 108 | private static final int DIALOG_RECONNECT = 2; |
108 | 109 | private static final int DIALOG_AUTH_ERROR = 3; |
109 | 110 | private static final int DIALOG_UNKNOWN_SERVER = 4; |
111 | + private static final int DIALOG_SECRET_NOT_SET = 5; | |
112 | + private static final int DIALOG_CHALLENGE_ERROR = 6; | |
113 | + private static final int DIALOG_REMOTE_HUNG_UP_ERROR = 7; | |
110 | 114 | |
111 | 115 | private static final int NO_ERROR = 0; |
112 | 116 |
@@ -197,14 +201,23 @@ public class VpnSettings extends PreferenceActivity implements | ||
197 | 201 | return createConnectDialog(); |
198 | 202 | |
199 | 203 | case DIALOG_RECONNECT: |
200 | - return createReconnectDialogBuilder().create(); | |
204 | + return createReconnectDialog(); | |
201 | 205 | |
202 | 206 | case DIALOG_AUTH_ERROR: |
203 | 207 | return createAuthErrorDialog(); |
204 | 208 | |
209 | + case DIALOG_REMOTE_HUNG_UP_ERROR: | |
210 | + return createRemoteHungUpErrorDialog(); | |
211 | + | |
212 | + case DIALOG_CHALLENGE_ERROR: | |
213 | + return createChallengeErrorDialog(); | |
214 | + | |
205 | 215 | case DIALOG_UNKNOWN_SERVER: |
206 | 216 | return createUnknownServerDialog(); |
207 | 217 | |
218 | + case DIALOG_SECRET_NOT_SET: | |
219 | + return createSecretNotSetDialog(); | |
220 | + | |
208 | 221 | default: |
209 | 222 | return super.onCreateDialog(id); |
210 | 223 | } |
@@ -219,14 +232,74 @@ public class VpnSettings extends PreferenceActivity implements | ||
219 | 232 | this) |
220 | 233 | .setNegativeButton(getString(android.R.string.cancel), |
221 | 234 | this) |
235 | + .setOnCancelListener(new DialogInterface.OnCancelListener() { | |
236 | + public void onCancel(DialogInterface dialog) { | |
237 | + removeDialog(DIALOG_CONNECT); | |
238 | + onIdle(); | |
239 | + } | |
240 | + }) | |
241 | + .create(); | |
242 | + } | |
243 | + | |
244 | + private Dialog createReconnectDialog() { | |
245 | + return createCommonDialogBuilder() | |
246 | + .setMessage(R.string.vpn_confirm_reconnect) | |
247 | + .create(); | |
248 | + } | |
249 | + | |
250 | + private Dialog createAuthErrorDialog() { | |
251 | + return createCommonDialogBuilder() | |
252 | + .setMessage(R.string.vpn_auth_error_dialog_msg) | |
253 | + .create(); | |
254 | + } | |
255 | + | |
256 | + private Dialog createRemoteHungUpErrorDialog() { | |
257 | + return createCommonDialogBuilder() | |
258 | + .setMessage(R.string.vpn_remote_hung_up_error_dialog_msg) | |
259 | + .create(); | |
260 | + } | |
261 | + | |
262 | + private Dialog createChallengeErrorDialog() { | |
263 | + return createCommonEditDialogBuilder() | |
264 | + .setMessage(R.string.vpn_challenge_error_dialog_msg) | |
222 | 265 | .create(); |
223 | 266 | } |
224 | 267 | |
225 | - private AlertDialog.Builder createReconnectDialogBuilder() { | |
268 | + private Dialog createUnknownServerDialog() { | |
269 | + return createCommonEditDialogBuilder() | |
270 | + .setMessage(R.string.vpn_unknown_server_dialog_msg) | |
271 | + .create(); | |
272 | + } | |
273 | + | |
274 | + private Dialog createSecretNotSetDialog() { | |
275 | + return createCommonDialogBuilder() | |
276 | + .setMessage(R.string.vpn_secret_not_set_dialog_msg) | |
277 | + .setPositiveButton(R.string.vpn_yes_button, | |
278 | + new DialogInterface.OnClickListener() { | |
279 | + public void onClick(DialogInterface dialog, int w) { | |
280 | + VpnProfile p = mConnectingActor.getProfile(); | |
281 | + startVpnEditor(p); | |
282 | + } | |
283 | + }) | |
284 | + .create(); | |
285 | + } | |
286 | + | |
287 | + private AlertDialog.Builder createCommonEditDialogBuilder() { | |
288 | + return createCommonDialogBuilder() | |
289 | + .setPositiveButton(R.string.vpn_yes_button, | |
290 | + new DialogInterface.OnClickListener() { | |
291 | + public void onClick(DialogInterface dialog, int w) { | |
292 | + VpnProfile p = mConnectingActor.getProfile(); | |
293 | + onIdle(); | |
294 | + startVpnEditor(p); | |
295 | + } | |
296 | + }); | |
297 | + } | |
298 | + | |
299 | + private AlertDialog.Builder createCommonDialogBuilder() { | |
226 | 300 | return new AlertDialog.Builder(this) |
227 | 301 | .setTitle(android.R.string.dialog_alert_title) |
228 | 302 | .setIcon(android.R.drawable.ic_dialog_alert) |
229 | - .setMessage(R.string.vpn_confirm_reconnect) | |
230 | 303 | .setPositiveButton(R.string.vpn_yes_button, |
231 | 304 | new DialogInterface.OnClickListener() { |
232 | 305 | public void onClick(DialogInterface dialog, int w) { |
@@ -246,26 +319,6 @@ public class VpnSettings extends PreferenceActivity implements | ||
246 | 319 | }); |
247 | 320 | } |
248 | 321 | |
249 | - private Dialog createAuthErrorDialog() { | |
250 | - return createReconnectDialogBuilder() | |
251 | - .setMessage(R.string.vpn_auth_error_dialog_msg) | |
252 | - .create(); | |
253 | - } | |
254 | - | |
255 | - private Dialog createUnknownServerDialog() { | |
256 | - return createReconnectDialogBuilder() | |
257 | - .setMessage(R.string.vpn_unknown_server_dialog_msg) | |
258 | - .setPositiveButton(R.string.vpn_yes_button, | |
259 | - new DialogInterface.OnClickListener() { | |
260 | - public void onClick(DialogInterface dialog, int w) { | |
261 | - VpnProfile p = mConnectingActor.getProfile(); | |
262 | - onIdle(); | |
263 | - startVpnEditor(p); | |
264 | - } | |
265 | - }) | |
266 | - .create(); | |
267 | - } | |
268 | - | |
269 | 322 | @Override |
270 | 323 | public void onCreateContextMenu(ContextMenu menu, View v, |
271 | 324 | ContextMenuInfo menuInfo) { |
@@ -413,6 +466,7 @@ public class VpnSettings extends PreferenceActivity implements | ||
413 | 466 | } |
414 | 467 | } else { |
415 | 468 | removeDialog(DIALOG_CONNECT); |
469 | + onIdle(); | |
416 | 470 | } |
417 | 471 | } |
418 | 472 |
@@ -629,6 +683,7 @@ public class VpnSettings extends PreferenceActivity implements | ||
629 | 683 | |
630 | 684 | mConnectingActor = getActor(p); |
631 | 685 | mActiveProfile = p; |
686 | + if (!checkSecrets(p)) return; | |
632 | 687 | if (mConnectingActor.isConnectDialogNeeded()) { |
633 | 688 | showDialog(DIALOG_CONNECT); |
634 | 689 | } else { |
@@ -693,6 +748,14 @@ public class VpnSettings extends PreferenceActivity implements | ||
693 | 748 | showDialog(DIALOG_AUTH_ERROR); |
694 | 749 | break; |
695 | 750 | |
751 | + case VpnManager.VPN_ERROR_REMOTE_HUNG_UP: | |
752 | + showDialog(DIALOG_REMOTE_HUNG_UP_ERROR); | |
753 | + break; | |
754 | + | |
755 | + case VpnManager.VPN_ERROR_CHALLENGE: | |
756 | + showDialog(DIALOG_CHALLENGE_ERROR); | |
757 | + break; | |
758 | + | |
696 | 759 | case VpnManager.VPN_ERROR_UNKNOWN_SERVER: |
697 | 760 | showDialog(DIALOG_UNKNOWN_SERVER); |
698 | 761 | break; |
@@ -707,6 +770,7 @@ public class VpnSettings extends PreferenceActivity implements | ||
707 | 770 | } |
708 | 771 | |
709 | 772 | private void onIdle() { |
773 | + Log.d(TAG, " onIdle()"); | |
710 | 774 | mActiveProfile = null; |
711 | 775 | mConnectingActor = null; |
712 | 776 | enableProfilePreferences(); |
@@ -847,34 +911,93 @@ public class VpnSettings extends PreferenceActivity implements | ||
847 | 911 | return NAMESPACE_VPN + "_" + keyName; |
848 | 912 | } |
849 | 913 | |
914 | + private boolean checkSecrets(VpnProfile p) { | |
915 | + Keystore ks = Keystore.getInstance(); | |
916 | + HashSet<String> secretSet = new HashSet<String>(); | |
917 | + boolean secretMissing = false; | |
918 | + | |
919 | + if (p instanceof L2tpIpsecProfile) { | |
920 | + L2tpIpsecProfile certProfile = (L2tpIpsecProfile) p; | |
921 | + CertTool certTool = CertTool.getInstance(); | |
922 | + Collections.addAll(secretSet, certTool.getAllCaCertificateKeys()); | |
923 | + String cert = certProfile.getCaCertificate(); | |
924 | + if (TextUtils.isEmpty(cert) || !secretSet.contains(cert)) { | |
925 | + certProfile.setCaCertificate(null); | |
926 | + secretMissing = true; | |
927 | + } | |
928 | + | |
929 | + secretSet.clear(); | |
930 | + Collections.addAll(secretSet, certTool.getAllUserCertificateKeys()); | |
931 | + cert = certProfile.getUserCertificate(); | |
932 | + if (TextUtils.isEmpty(cert) || !secretSet.contains(cert)) { | |
933 | + certProfile.setUserCertificate(null); | |
934 | + secretMissing = true; | |
935 | + } | |
936 | + } | |
937 | + | |
938 | + secretSet.clear(); | |
939 | + Collections.addAll(secretSet, ks.listKeys(NAMESPACE_VPN)); | |
940 | + | |
941 | + if (p instanceof L2tpIpsecPskProfile) { | |
942 | + L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p; | |
943 | + String presharedKey = pskProfile.getPresharedKey(); | |
944 | + String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); | |
945 | + if (TextUtils.isEmpty(presharedKey) | |
946 | + || !secretSet.contains(keyName)) { | |
947 | + pskProfile.setPresharedKey(null); | |
948 | + secretMissing = true; | |
949 | + } | |
950 | + } | |
951 | + | |
952 | + if (p instanceof L2tpProfile) { | |
953 | + L2tpProfile l2tpProfile = (L2tpProfile) p; | |
954 | + if (l2tpProfile.isSecretEnabled()) { | |
955 | + String secret = l2tpProfile.getSecretString(); | |
956 | + String keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); | |
957 | + if (TextUtils.isEmpty(secret) | |
958 | + || !secretSet.contains(keyName)) { | |
959 | + l2tpProfile.setSecretString(null); | |
960 | + secretMissing = true; | |
961 | + } | |
962 | + } | |
963 | + } | |
964 | + | |
965 | + if (secretMissing) { | |
966 | + showDialog(DIALOG_SECRET_NOT_SET); | |
967 | + return false; | |
968 | + } else { | |
969 | + return true; | |
970 | + } | |
971 | + } | |
972 | + | |
850 | 973 | private void processSecrets(VpnProfile p) { |
851 | 974 | Keystore ks = Keystore.getInstance(); |
852 | 975 | switch (p.getType()) { |
853 | 976 | case L2TP_IPSEC_PSK: |
854 | 977 | L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p; |
855 | 978 | String presharedKey = pskProfile.getPresharedKey(); |
856 | - if (!presharedKey.equals(SECRET_SET_INDICATOR)) { | |
857 | - String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); | |
979 | + String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); | |
980 | + if (!TextUtils.isEmpty(presharedKey)) { | |
858 | 981 | int ret = ks.put(NAMESPACE_VPN, keyName, presharedKey); |
859 | - if (ret < 0) { | |
982 | + if (ret != 0) { | |
860 | 983 | Log.e(TAG, "keystore write failed: key=" + keyName); |
861 | 984 | } |
862 | - pskProfile.setPresharedKey(keyNameForDaemon(keyName)); | |
863 | 985 | } |
986 | + pskProfile.setPresharedKey(keyNameForDaemon(keyName)); | |
864 | 987 | // pass through |
865 | 988 | |
866 | 989 | case L2TP: |
867 | 990 | L2tpProfile l2tpProfile = (L2tpProfile) p; |
868 | - String keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); | |
991 | + keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); | |
869 | 992 | if (l2tpProfile.isSecretEnabled()) { |
870 | 993 | String secret = l2tpProfile.getSecretString(); |
871 | - if (!secret.equals(SECRET_SET_INDICATOR)) { | |
994 | + if (!TextUtils.isEmpty(secret)) { | |
872 | 995 | int ret = ks.put(NAMESPACE_VPN, keyName, secret); |
873 | - if (ret < 0) { | |
996 | + if (ret != 0) { | |
874 | 997 | Log.e(TAG, "keystore write failed: key=" + keyName); |
875 | 998 | } |
876 | - l2tpProfile.setSecretString(keyNameForDaemon(keyName)); | |
877 | 999 | } |
1000 | + l2tpProfile.setSecretString(keyNameForDaemon(keyName)); | |
878 | 1001 | } else { |
879 | 1002 | ks.remove(NAMESPACE_VPN, keyName); |
880 | 1003 | } |
@@ -134,7 +134,7 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On | ||
134 | 134 | private Spinner mSecuritySpinner; |
135 | 135 | private Spinner mWepTypeSpinner; |
136 | 136 | private CertTool mCertTool; |
137 | - | |
137 | + | |
138 | 138 | public AccessPointDialog(Context context, WifiLayer wifiLayer) { |
139 | 139 | super(context); |
140 | 140 |
@@ -217,6 +217,14 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On | ||
217 | 217 | setTitle(getContext().getString(titleId)); |
218 | 218 | } |
219 | 219 | |
220 | + public void enableEnterpriseFields() { | |
221 | + setEnterpriseFieldsVisible(true); | |
222 | + updateCertificateSelection(); | |
223 | + setGenericPasswordVisible(true); | |
224 | + // Both WPA and WPA2 show the same caption, so either is ok | |
225 | + updatePasswordCaption(AccessPointState.WPA); | |
226 | + } | |
227 | + | |
220 | 228 | /** Called after flags are set, the dialog's layout/etc should be set up here */ |
221 | 229 | private void onLayout() { |
222 | 230 | final Context context = getContext(); |
@@ -246,7 +254,6 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On | ||
246 | 254 | } else if (mMode == MODE_INFO) { |
247 | 255 | if (mState.isEnterprise() && !mState.configured) { |
248 | 256 | setLayout(R.layout.wifi_ap_configure); |
249 | - defaultPasswordVisibility = false; | |
250 | 257 | setEnterpriseFieldsVisible(true); |
251 | 258 | } else { |
252 | 259 | setLayout(R.layout.wifi_ap_info); |
@@ -319,17 +326,26 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On | ||
319 | 326 | if (mMode == MODE_CONFIGURE || |
320 | 327 | (mState.isEnterprise() && !mState.configured)) { |
321 | 328 | setEnterpriseFields(view); |
322 | - mEapSpinner.setSelection(getSelectionIndex( | |
323 | - R.array.wifi_eap_entries, mState.getEap())); | |
324 | - mClientCertSpinner.setSelection(getSelectionIndex( | |
325 | - getAllUserCertificateKeys(), mState.getEnterpriseField( | |
326 | - AccessPointState.CLIENT_CERT))); | |
327 | - mCaCertSpinner.setSelection(getSelectionIndex( | |
328 | - getAllCaCertificateKeys(), mState.getEnterpriseField( | |
329 | - AccessPointState.CA_CERT))); | |
329 | + updateCertificateSelection(); | |
330 | 330 | } |
331 | 331 | } |
332 | 332 | |
333 | + private void updateCertificateSelection() { | |
334 | + setSpinnerAdapter(mClientCertSpinner, getAllUserCertificateKeys()); | |
335 | + setSpinnerAdapter(mCaCertSpinner, getAllCaCertificateKeys()); | |
336 | + | |
337 | + mPhase2Spinner.setSelection(getSelectionIndex( | |
338 | + R.array.wifi_phase2_entries, mState.getPhase2())); | |
339 | + mEapSpinner.setSelection(getSelectionIndex( | |
340 | + R.array.wifi_eap_entries, mState.getEap())); | |
341 | + mClientCertSpinner.setSelection(getSelectionIndex( | |
342 | + getAllUserCertificateKeys(), mState.getEnterpriseField( | |
343 | + AccessPointState.CLIENT_CERT))); | |
344 | + mCaCertSpinner.setSelection(getSelectionIndex( | |
345 | + getAllCaCertificateKeys(), mState.getEnterpriseField( | |
346 | + AccessPointState.CA_CERT))); | |
347 | + } | |
348 | + | |
333 | 349 | private String[] getAllCaCertificateKeys() { |
334 | 350 | return appendEmptyInSelection(mCertTool.getAllCaCertificateKeys()); |
335 | 351 | } |
@@ -663,14 +679,15 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On | ||
663 | 679 | } |
664 | 680 | } |
665 | 681 | switch (securityType) { |
682 | + case SECURITY_IEEE8021X: | |
666 | 683 | case SECURITY_WPA_EAP: { |
667 | - mState.setSecurity(AccessPointState.WPA_EAP); | |
668 | - mState.setEap(mEapSpinner.getSelectedItemPosition()); | |
669 | - break; | |
670 | - } | |
671 | - case SECURITY_IEEE8021X: { | |
672 | - mState.setSecurity(AccessPointState.IEEE8021X); | |
684 | + if (securityType == SECURITY_WPA_EAP) { | |
685 | + mState.setSecurity(AccessPointState.WPA_EAP); | |
686 | + } else { | |
687 | + mState.setSecurity(AccessPointState.IEEE8021X); | |
688 | + } | |
673 | 689 | mState.setEap(mEapSpinner.getSelectedItemPosition()); |
690 | + mState.setPhase2((String)mPhase2Spinner.getSelectedItem()); | |
674 | 691 | break; |
675 | 692 | } |
676 | 693 | default: |
@@ -786,13 +803,9 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On | ||
786 | 803 | if (Keystore.getInstance().getState() != Keystore.UNLOCKED) { |
787 | 804 | getContext().startActivity(new Intent( |
788 | 805 | SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE)); |
789 | - mSecuritySpinner.setSelection(0); | |
790 | 806 | return; |
791 | 807 | } |
792 | - setEnterpriseFieldsVisible(true); | |
793 | - setGenericPasswordVisible(true); | |
794 | - // Both WPA and WPA2 show the same caption, so either is ok | |
795 | - updatePasswordCaption(AccessPointState.WPA); | |
808 | + enableEnterpriseFields(); | |
796 | 809 | break; |
797 | 810 | } |
798 | 811 | } |
@@ -375,12 +375,22 @@ public final class AccessPointState implements Comparable<AccessPointState>, Par | ||
375 | 375 | |
376 | 376 | /* For Enterprise Fields */ |
377 | 377 | public void setEnterpriseField(int field, String value) { |
378 | - if (value != null && field >= 0 && field < MAX_ENTRPRISE_FIELD) { | |
378 | + if ((value != null) && (field >= 0) && (field < MAX_ENTRPRISE_FIELD)) { | |
379 | 379 | this.mEnterpriseFields[field] = value; |
380 | 380 | requestRefresh(); |
381 | 381 | } |
382 | 382 | } |
383 | 383 | |
384 | + public void setPhase2(String phase2) { | |
385 | + if (!TextUtils.isEmpty(phase2) && (!phase2.equals("None"))) { | |
386 | + mPhase2 = phase2; | |
387 | + } | |
388 | + } | |
389 | + | |
390 | + public String getPhase2() { | |
391 | + return mPhase2; | |
392 | + } | |
393 | + | |
384 | 394 | public void setEap(int method) { |
385 | 395 | mEap = EAP_METHOD[method]; |
386 | 396 | requestRefresh(); |
@@ -495,6 +505,12 @@ public final class AccessPointState implements Comparable<AccessPointState>, Par | ||
495 | 505 | config.hiddenSSID = hiddenSsid; |
496 | 506 | config.SSID = convertToQuotedString(ssid); |
497 | 507 | config.eap = mEap; |
508 | + | |
509 | + if (!TextUtils.isEmpty(mPhase2)) { | |
510 | + config.phase2 = convertToQuotedString("auth=" + mPhase2); | |
511 | + } else { | |
512 | + config.phase2 = null; | |
513 | + } | |
498 | 514 | if (!TextUtils.isEmpty(mEnterpriseFields[IDENTITY])) { |
499 | 515 | config.identity = |
500 | 516 | convertToQuotedString(mEnterpriseFields[IDENTITY]); |
@@ -86,6 +86,9 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba | ||
86 | 86 | private Preference mAddOtherNetwork; |
87 | 87 | |
88 | 88 | private WeakHashMap<AccessPointState, AccessPointPreference> mAps; |
89 | + | |
90 | + private AccessPointState mResumeState = null; | |
91 | + private int mResumeMode; | |
89 | 92 | |
90 | 93 | //============================ |
91 | 94 | // Wifi member variables |
@@ -152,8 +155,22 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba | ||
152 | 155 | super.onResume(); |
153 | 156 | mWifiLayer.onResume(); |
154 | 157 | mWifiEnabler.resume(); |
158 | + // do what we should have after keystore is unlocked. | |
159 | + if (mResumeState != null) { | |
160 | + if (Keystore.getInstance().getState() == Keystore.UNLOCKED) { | |
161 | + showAccessPointDialog(mResumeState, mResumeMode); | |
162 | + } | |
163 | + mResumeMode = -1; | |
164 | + mResumeState = null; | |
165 | + } else { | |
166 | + if (mResumeMode == AccessPointDialog.MODE_CONFIGURE) { | |
167 | + if (Keystore.getInstance().getState() == Keystore.UNLOCKED) { | |
168 | + ((AccessPointDialog) mDialog).enableEnterpriseFields(); | |
169 | + } | |
170 | + } | |
171 | + } | |
155 | 172 | } |
156 | - | |
173 | + | |
157 | 174 | @Override |
158 | 175 | protected void onPause() { |
159 | 176 | super.onPause(); |
@@ -231,6 +248,7 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba | ||
231 | 248 | public void onDismiss(DialogInterface dialog) { |
232 | 249 | if (dialog == mDialog) { |
233 | 250 | mDialog = null; |
251 | + mResumeMode = -1; | |
234 | 252 | } |
235 | 253 | } |
236 | 254 |
@@ -350,6 +368,7 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba | ||
350 | 368 | dialog.setMode(AccessPointDialog.MODE_CONFIGURE); |
351 | 369 | dialog.setTitle(R.string.wifi_add_other_network); |
352 | 370 | dialog.setAutoSecurityAllowed(false); |
371 | + mResumeMode = AccessPointDialog.MODE_CONFIGURE; | |
353 | 372 | showDialog(dialog); |
354 | 373 | } |
355 | 374 |
@@ -358,6 +377,8 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba | ||
358 | 377 | Keystore.getInstance().getState() != Keystore.UNLOCKED) { |
359 | 378 | startActivity(new Intent( |
360 | 379 | SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE)); |
380 | + mResumeState = state; | |
381 | + mResumeMode = mode; | |
361 | 382 | return; |
362 | 383 | } |
363 | 384 | AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer); |