• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

packages/apps/Settings


Commit MetaInfo

Revisão2877e184f378aae5c71ebf852360f0a5ee4b02c4 (tree)
Hora2009-08-03 23:45:47
AutorJean-Baptiste Queru <jbq@goog...>
CommiterJean-Baptiste Queru

Mensagem de Log

merge from donut

Mudança Sumário

Diff

--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1737,7 +1737,7 @@ found in the list of installed applications.</string>
17371737 <!-- Description for wifi connectivity -->
17381738 <string name="battery_desc_wifi">Battery used by Wi-Fi</string>
17391739 <!-- 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>
17411741
17421742 <!-- Description for bluetooth power consumption detail -->
17431743 <string name="battery_desc_bluetooth">Battery used by bluetooth</string>
@@ -1829,7 +1829,7 @@ found in the list of installed applications.</string>
18291829 <string name="vpn_yes_button">Yes</string>
18301830 <string name="vpn_no_button">No</string>
18311831 <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>
18331833
18341834 <string name="vpn_menu_done">Save</string>
18351835 <string name="vpn_menu_cancel">Cancel</string>
@@ -1848,7 +1848,10 @@ found in the list of installed applications.</string>
18481848 <string name="vpn_confirm_edit_profile_cancellation">Are you sure you want to discard the changes made to this profile?</string>
18491849 <string name="vpn_confirm_reconnect">Unable to connect to the network. Do you want to try again?</string>
18501850 <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>
18511853 <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>
18521855
18531856 <!-- VPN type selection activity title -->
18541857 <string name="vpn_type_title">Add VPN</string>
@@ -1894,6 +1897,8 @@ found in the list of installed applications.</string>
18941897 <!-- Complete term -->
18951898 <string name="vpn_l2tp_secret">L2TP secret</string>
18961899 <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>
18971902
18981903 <!-- Preference title -->
18991904 <string name="vpn_ipsec_presharedkey_title">Set IPSec pre-shared key</string>
@@ -1935,6 +1940,10 @@ found in the list of installed applications.</string>
19351940 <string name="vpn_settings_title">VPN settings</string>
19361941 <!-- Summary of preference to enter the VPN settings activity -->
19371942 <string name="vpn_settings_summary">Set up &amp; 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>
19381947
19391948 <!-- Title of preference group for credential storage settings -->
19401949 <string name="cstor_settings_category">Credential storage</string>
@@ -1991,6 +2000,9 @@ found in the list of installed applications.</string>
19912000 <string name="cstor_name_empty_error">Please enter a name.</string>
19922001 <string name="cstor_name_char_error">Please enter a name that contains only letters and numbers.</string>
19932002 <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>
19942006
19952007 <!-- toast message -->
19962008 <string name="cstor_is_enabled">Credential storage is enabled.</string>
--- a/res/xml/device_info_settings.xml
+++ b/res/xml/device_info_settings.xml
@@ -76,12 +76,13 @@
7676 </PreferenceScreen>
7777
7878 <!-- Contributors -->
79+ <!--
7980 <PreferenceScreen
8081 android:key="contributors"
8182 android:title="@string/contributors_title">
8283 <intent android:action="android.settings.TEAM" />
8384 </PreferenceScreen>
84-
85+ -->
8586 <!-- System Tutorial - launches activity -->
8687 <PreferenceScreen android:key="system_tutorial"
8788 android:title="@string/system_tutorial_list_item_title"
--- a/src/com/android/settings/ManageApplications.java
+++ b/src/com/android/settings/ManageApplications.java
@@ -355,7 +355,7 @@ public class ManageApplications extends ListActivity implements
355355 Log.w(TAG, "Couldnt find application info for:"+pkgName);
356356 break;
357357 }
358- mObserver.invokeGetSizeInfo(info);
358+ mObserver.invokeGetSizeInfo(pkgName);
359359 break;
360360 case ADD_PKG_DONE:
361361 if(localLOGV) Log.i(TAG, "Message ADD_PKG_DONE");
@@ -367,7 +367,12 @@ public class ManageApplications extends ListActivity implements
367367 if (status) {
368368 size = data.getLong(ATTR_PKG_STATS);
369369 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+ }
371376 }
372377 break;
373378 case REFRESH_LABELS:
@@ -1121,7 +1126,7 @@ public class ManageApplications extends ListActivity implements
11211126 }
11221127 return mSizeComparator;
11231128 }
1124-
1129+
11251130 public void bulkUpdateIcons(Map<String, Drawable> icons) {
11261131 if (icons == null) {
11271132 return;
@@ -1162,19 +1167,6 @@ public class ManageApplications extends ListActivity implements
11621167 }
11631168 }
11641169
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-
11781170 private boolean shouldBeInList(int filterOption, ApplicationInfo info) {
11791171 // Match filter here
11801172 if (filterOption == FILTER_APPS_RUNNING) {
@@ -1246,6 +1238,24 @@ public class ManageApplications extends ListActivity implements
12461238 }
12471239 }
12481240
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+
12491259 private void removePkgBase(String pkgName) {
12501260 int imax = mAppList.size();
12511261 for (int i = 0; i < imax; i++) {
@@ -1300,7 +1310,7 @@ public class ManageApplications extends ListActivity implements
13001310 for (int i = 0; i < pkgs.length; i++) {
13011311 AppInfo entry = mCache.getEntry(pkgs[i]);
13021312 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");
13041314 continue;
13051315 }
13061316 if (entry.setSize(sizes[i], formatted[i])) {
@@ -1311,21 +1321,6 @@ public class ManageApplications extends ListActivity implements
13111321 notifyDataSetChanged();
13121322 }
13131323 }
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- }
13291324 }
13301325
13311326 /*
@@ -1371,7 +1366,7 @@ public class ManageApplications extends ListActivity implements
13711366 * and the AppInfo object corresponding to the package name are set on the message
13721367 */
13731368 class PkgSizeObserver extends IPackageStatsObserver.Stub {
1374- private ApplicationInfo mAppInfo;
1369+ String pkgName;
13751370 public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
13761371 if(DEBUG_PKG_DELAY) {
13771372 try {
@@ -1379,12 +1374,11 @@ public class ManageApplications extends ListActivity implements
13791374 } catch (InterruptedException e) {
13801375 }
13811376 }
1382- AppInfo appInfo = null;
13831377 Bundle data = new Bundle();
1384- data.putString(ATTR_PKG_NAME, mAppInfo.packageName);
1378+ data.putString(ATTR_PKG_NAME, pkgName);
13851379 data.putBoolean(ATTR_GET_SIZE_STATUS, pSucceeded);
13861380 if(pSucceeded && pStats != null) {
1387- if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pStats.packageName+", ("+
1381+ if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pkgName+", ("+
13881382 pStats.cacheSize+","+
13891383 pStats.codeSize+", "+pStats.dataSize);
13901384 long total = getTotalSize(pStats);
@@ -1400,14 +1394,14 @@ public class ManageApplications extends ListActivity implements
14001394 mHandler.sendMessage(msg);
14011395 }
14021396
1403- public void invokeGetSizeInfo(ApplicationInfo pAppInfo) {
1404- if(pAppInfo == null || pAppInfo.packageName == null) {
1397+ public void invokeGetSizeInfo(String packageName) {
1398+ if (packageName == null) {
14051399 return;
14061400 }
1401+ pkgName = packageName;
14071402 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);
14111405 }
14121406 }
14131407
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -42,6 +42,7 @@ import android.security.Keystore;
4242 import android.text.Html;
4343 import android.text.TextUtils;
4444 import android.text.method.LinkMovementMethod;
45+import android.util.Log;
4546 import android.view.View;
4647 import android.widget.TextView;
4748 import android.widget.Toast;
@@ -464,15 +465,26 @@ public class SecuritySettings extends PreferenceActivity implements
464465
465466 if (ACTION_ADD_CREDENTIAL.equals(action)) {
466467 mCstorAddCredentialHelper = new CstorAddCredentialHelper(intent);
467- showDialog(CSTOR_NAME_CREDENTIAL_DIALOG);
468+ showCstorDialog(CSTOR_NAME_CREDENTIAL_DIALOG);
468469 } else if (ACTION_UNLOCK_CREDENTIAL_STORAGE.equals(action)) {
469470 mSpecialIntent = intent;
470- showDialog(mCstorHelper.isCstorInitialized()
471+ showCstorDialog(mCstorHelper.isCstorInitialized()
471472 ? CSTOR_UNLOCK_DIALOG
472473 : CSTOR_INIT_DIALOG);
473474 }
474475 }
475476
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+
476488 private boolean isCstorUnlocked() {
477489 return (mKeystore.getState() == Keystore.UNLOCKED);
478490 }
@@ -514,15 +526,53 @@ public class SecuritySettings extends PreferenceActivity implements
514526 mKeystore.reset();
515527 enablePreferences(false);
516528 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;
517555 }
518556
519557 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;
525573 }
574+ mCstorAddCredentialHelper = null;
575+ finish();
526576 }
527577
528578 public void onClick(DialogInterface dialog, int which) {
@@ -554,31 +604,34 @@ public class SecuritySettings extends PreferenceActivity implements
554604 public void onDismiss(DialogInterface dialog) {
555605 if (!mConfirm) {
556606 mConfirm = true;
557- showDialog(mDialogId);
607+ showCstorDialog(mDialogId);
558608 } else {
559- removeDialog(mDialogId);
560-
561609 if (mDialogId == CSTOR_UNLOCK_DIALOG) {
562610 mAccessCheckBox.setChecked(isCstorUnlocked());
563611 }
564612
565613 if (mCstorAddCredentialHelper != null) {
566614 if (!isCstorInitialized()) {
567- showDialog(CSTOR_INIT_DIALOG);
615+ showCstorDialog(CSTOR_INIT_DIALOG);
568616 } else if (!isCstorUnlocked()) {
569- showDialog(CSTOR_UNLOCK_DIALOG);
617+ showCstorDialog(CSTOR_UNLOCK_DIALOG);
570618 } 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+ }
578629 }
630+ return;
579631 } else if (mSpecialIntent != null) {
580632 finish();
581633 }
634+ removeDialog(mDialogId);
582635 }
583636 }
584637
@@ -625,15 +678,6 @@ public class SecuritySettings extends PreferenceActivity implements
625678 mCstorAddCredentialHelper.setPassword(password);
626679 }
627680
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-
637681 return true;
638682 }
639683
@@ -760,7 +804,7 @@ public class SecuritySettings extends PreferenceActivity implements
760804 public boolean onPreferenceChange(
761805 Preference pref, Object value) {
762806 if (((Boolean) value)) {
763- showDialog(isCstorInitialized()
807+ showCstorDialog(isCstorInitialized()
764808 ? CSTOR_UNLOCK_DIALOG
765809 : CSTOR_INIT_DIALOG);
766810 } else {
@@ -781,7 +825,7 @@ public class SecuritySettings extends PreferenceActivity implements
781825 pref.setOnPreferenceClickListener(
782826 new Preference.OnPreferenceClickListener() {
783827 public boolean onPreferenceClick(Preference pref) {
784- showDialog(isCstorInitialized()
828+ showCstorDialog(isCstorInitialized()
785829 ? CSTOR_CHANGE_PASSWORD_DIALOG
786830 : CSTOR_INIT_DIALOG);
787831 return true;
@@ -797,7 +841,7 @@ public class SecuritySettings extends PreferenceActivity implements
797841 pref.setOnPreferenceClickListener(
798842 new Preference.OnPreferenceClickListener() {
799843 public boolean onPreferenceClick(Preference pref) {
800- showDialog(CSTOR_RESET_DIALOG);
844+ showCstorDialog(CSTOR_RESET_DIALOG);
801845 return true;
802846 }
803847 });
@@ -807,7 +851,6 @@ public class SecuritySettings extends PreferenceActivity implements
807851 }
808852
809853 private Dialog createUnlockDialog() {
810- mDialogId = CSTOR_UNLOCK_DIALOG;
811854 mView = View.inflate(SecuritySettings.this,
812855 R.layout.cstor_unlock_dialog_view, null);
813856 hideError();
@@ -830,7 +873,6 @@ public class SecuritySettings extends PreferenceActivity implements
830873 }
831874
832875 private Dialog createSetPasswordDialog(int id) {
833- mDialogId = id;
834876 mView = View.inflate(SecuritySettings.this,
835877 R.layout.cstor_set_password_dialog_view, null);
836878 hideError();
@@ -870,7 +912,6 @@ public class SecuritySettings extends PreferenceActivity implements
870912 }
871913
872914 private Dialog createResetDialog() {
873- mDialogId = CSTOR_RESET_DIALOG;
874915 return new AlertDialog.Builder(SecuritySettings.this)
875916 .setTitle(android.R.string.dialog_alert_title)
876917 .setIcon(android.R.drawable.ic_dialog_alert)
@@ -881,9 +922,12 @@ public class SecuritySettings extends PreferenceActivity implements
881922 }
882923
883924 private Dialog createNameCredentialDialog() {
884- mDialogId = CSTOR_NAME_CREDENTIAL_DIALOG;
885925 mView = View.inflate(SecuritySettings.this,
886926 R.layout.cstor_name_credential_dialog_view, null);
927+ if (mCstorAddCredentialHelper != null) {
928+ mCstorAddCredentialHelper.mView = mView;
929+ }
930+
887931 hideError();
888932 if (!mCstorAddCredentialHelper.isPkcs12Keystore()) {
889933 hide(R.id.cstor_credential_password_container);
@@ -915,6 +959,7 @@ public class SecuritySettings extends PreferenceActivity implements
915959 private String mDescription;
916960 private String mName;
917961 private String mPassword;
962+ private View mView;
918963
919964 CstorAddCredentialHelper(Intent intent) {
920965 parse(intent);
@@ -958,7 +1003,7 @@ public class SecuritySettings extends PreferenceActivity implements
9581003 byte[] blob = mItemList.get(i);
9591004 int ret = ks.put(mNamespaceList.get(i), mName,
9601005 new String(blob));
961- if (ret < 0) return ret;
1006+ if (ret != 0) return ret;
9621007 }
9631008 }
9641009 return 0;
--- a/src/com/android/settings/TextToSpeechSettings.java
+++ b/src/com/android/settings/TextToSpeechSettings.java
@@ -59,7 +59,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
5959 private static final String LOCALE_DELIMITER = "-";
6060
6161 private static final String FALLBACK_TTS_DEFAULT_SYNTH =
62- TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_SYNTH;
62+ TextToSpeech.Engine.DEFAULT_SYNTH;
6363
6464 private Preference mPlayExample = null;
6565 private Preference mInstallData = null;
@@ -141,7 +141,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
141141 intVal = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS);
142142 } catch (SettingNotFoundException e) {
143143 // "use default" setting not found, initialize it
144- intVal = TextToSpeech.Engine.FALLBACK_TTS_USE_DEFAULTS;
144+ intVal = TextToSpeech.Engine.USE_DEFAULTS;
145145 Settings.Secure.putInt(resolver, TTS_USE_DEFAULTS, intVal);
146146 }
147147 mUseDefaultPref.setChecked(intVal == 1);
@@ -162,7 +162,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
162162 intVal = Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE);
163163 } catch (SettingNotFoundException e) {
164164 // default rate setting not found, initialize it
165- intVal = TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_RATE;
165+ intVal = TextToSpeech.Engine.DEFAULT_RATE;
166166 Settings.Secure.putInt(resolver, TTS_DEFAULT_RATE, intVal);
167167 }
168168 mDefaultRatePref.setValue(String.valueOf(intVal));
@@ -223,7 +223,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
223223 private void checkVoiceData() {
224224 PackageManager pm = getPackageManager();
225225 Intent intent = new Intent();
226- intent.setAction("android.intent.action.CHECK_TTS_DATA");
226+ intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
227227 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
228228 // query only the package that matches that of the default engine
229229 for (int i = 0; i < resolveInfos.size(); i++) {
@@ -243,7 +243,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
243243 private void installVoiceData() {
244244 PackageManager pm = getPackageManager();
245245 Intent intent = new Intent();
246- intent.setAction("android.intent.action.INSTALL_TTS_DATA");
246+ intent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
247247 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
248248 // query only the package that matches that of the default engine
249249 for (int i = 0; i < resolveInfos.size(); i++) {
@@ -260,7 +260,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
260260 * Called when the TTS engine is initialized.
261261 */
262262 public void onInit(int status) {
263- if (status == TextToSpeech.TTS_SUCCESS) {
263+ if (status == TextToSpeech.SUCCESS) {
264264 Log.v(TAG, "TTS engine for settings screen initialized.");
265265 mEnableDemo = true;
266266 } else {
@@ -337,7 +337,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements
337337 // Play example
338338 if (mTts != null) {
339339 mTts.speak(getResources().getString(R.string.tts_demo),
340- TextToSpeech.TTS_QUEUE_FLUSH, null);
340+ TextToSpeech.QUEUE_FLUSH, null);
341341 }
342342 return true;
343343 }
--- a/src/com/android/settings/deviceinfo/Status.java
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -162,6 +162,7 @@ public class Status extends PreferenceActivity {
162162 @Override
163163 protected void onCreate(Bundle icicle) {
164164 super.onCreate(icicle);
165+ Preference removablePref;
165166
166167 mHandler = new MyHandler(this);
167168
@@ -188,8 +189,15 @@ public class Status extends PreferenceActivity {
188189 setSummaryText("prl_version", mPhone.getCdmaPrlVersion());
189190
190191 // 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+ }
193201 } else {
194202 setSummaryText("imei", mPhone.getDeviceId());
195203
@@ -198,9 +206,19 @@ public class Status extends PreferenceActivity {
198206 .getDeviceSoftwareVersion());
199207
200208 // 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+ }
204222 }
205223
206224 setSummaryText("number", mPhone.getLine1Number());
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -463,7 +463,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
463463 btPower += (btPingCount
464464 * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000;
465465
466- addEntry(getString(R.string.power_bluetooth), DrainType.IDLE, btOnTimeMs,
466+ addEntry(getString(R.string.power_bluetooth), DrainType.BLUETOOTH, btOnTimeMs,
467467 com.android.internal.R.drawable.ic_volume_bluetooth_in_call, btPower);
468468 }
469469
--- a/src/com/android/settings/vpn/L2tpEditor.java
+++ b/src/com/android/settings/vpn/L2tpEditor.java
@@ -30,9 +30,7 @@ import android.preference.PreferenceGroup;
3030 */
3131 class L2tpEditor extends VpnProfileEditor {
3232 private CheckBoxPreference mSecret;
33- private EditTextPreference mSecretString;
34- private String mOriginalSecret;
35- private boolean mOriginalSecretEnabled;
33+ private SecretHandler mSecretHandler;
3634
3735 public L2tpEditor(L2tpProfile p) {
3836 super(p);
@@ -43,11 +41,8 @@ class L2tpEditor extends VpnProfileEditor {
4341 Context c = subpanel.getContext();
4442 subpanel.addPreference(createSecretPreference(c));
4543 subpanel.addPreference(createSecretStringPreference(c));
46- mSecretString.setEnabled(mSecret.isChecked());
4744
4845 L2tpProfile profile = (L2tpProfile) getProfile();
49- mOriginalSecret = profile.getSecretString();
50- mOriginalSecretEnabled = profile.isSecretEnabled();
5146 }
5247
5348 @Override
@@ -55,9 +50,7 @@ class L2tpEditor extends VpnProfileEditor {
5550 String result = super.validate();
5651 if (!mSecret.isChecked()) return result;
5752
58- return ((result != null)
59- ? result
60- : validate(mSecretString, R.string.vpn_a_l2tp_secret));
53+ return ((result != null) ? result : mSecretHandler.validate());
6154 }
6255
6356 private Preference createSecretPreference(Context c) {
@@ -73,7 +66,7 @@ class L2tpEditor extends VpnProfileEditor {
7366 Preference pref, Object newValue) {
7467 boolean enabled = (Boolean) newValue;
7568 profile.setSecretEnabled(enabled);
76- mSecretString.setEnabled(enabled);
69+ mSecretHandler.getPreference().setEnabled(enabled);
7770 setSecretTitle(mSecret, R.string.vpn_l2tp_secret,
7871 enabled);
7972 setSecretSummary(mSecret, enabled);
@@ -84,22 +77,22 @@ class L2tpEditor extends VpnProfileEditor {
8477 }
8578
8679 private Preference createSecretStringPreference(Context c) {
87- final L2tpProfile profile = (L2tpProfile) getProfile();
88- mSecretString = createSecretPreference(c,
80+ SecretHandler sHandler = mSecretHandler = new SecretHandler(c,
8981 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;
10396 }
10497
10598 private void setSecretSummary(CheckBoxPreference secret, boolean enabled) {
--- a/src/com/android/settings/vpn/L2tpIpsecPskEditor.java
+++ b/src/com/android/settings/vpn/L2tpIpsecPskEditor.java
@@ -29,6 +29,7 @@ import android.preference.PreferenceGroup;
2929 */
3030 class L2tpIpsecPskEditor extends L2tpEditor {
3131 private EditTextPreference mPresharedKey;
32+ private SecretHandler mPskHandler;
3233
3334 public L2tpIpsecPskEditor(L2tpIpsecPskProfile p) {
3435 super(p);
@@ -45,27 +46,23 @@ class L2tpIpsecPskEditor extends L2tpEditor {
4546 public String validate() {
4647 String result = super.validate();
4748
48- return ((result != null)
49- ? result
50- : validate(mPresharedKey, R.string.vpn_a_ipsec_presharedkey));
49+ return ((result != null) ? result : mPskHandler.validate());
5150 }
5251
5352 private Preference createPresharedKeyPreference(Context c) {
54- final L2tpIpsecPskProfile profile = (L2tpIpsecPskProfile) getProfile();
55- mPresharedKey = createSecretPreference(c,
53+ SecretHandler pskHandler = mPskHandler = new SecretHandler(c,
5654 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();
7067 }
7168 }
--- /dev/null
+++ b/src/com/android/settings/vpn/PptpEditor.java
@@ -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+}
--- a/src/com/android/settings/vpn/VpnEditor.java
+++ b/src/com/android/settings/vpn/VpnEditor.java
@@ -24,9 +24,11 @@ import android.content.Intent;
2424 import android.net.vpn.L2tpIpsecProfile;
2525 import android.net.vpn.L2tpIpsecPskProfile;
2626 import android.net.vpn.L2tpProfile;
27+import android.net.vpn.PptpProfile;
2728 import android.net.vpn.VpnProfile;
2829 import android.net.vpn.VpnType;
2930 import android.os.Bundle;
31+import android.os.Parcel;
3032 import android.os.Parcelable;
3133 import android.preference.PreferenceActivity;
3234 import android.preference.PreferenceGroup;
@@ -47,6 +49,7 @@ public class VpnEditor extends PreferenceActivity {
4749
4850 private VpnProfileEditor mProfileEditor;
4951 private boolean mAddingProfile;
52+ private byte[] mOriginalProfileData;
5053
5154 @Override
5255 public void onCreate(Bundle savedInstanceState) {
@@ -61,6 +64,10 @@ public class VpnEditor extends PreferenceActivity {
6164 addPreferencesFromResource(R.xml.vpn_edit);
6265
6366 initViewFor(p);
67+
68+ Parcel parcel = Parcel.obtain();
69+ p.writeToParcel(parcel, 0);
70+ mOriginalProfileData = parcel.marshall();
6471 }
6572
6673 @Override
@@ -90,7 +97,11 @@ public class VpnEditor extends PreferenceActivity {
9097 return true;
9198
9299 case MENU_CANCEL:
93- showCancellationConfirmDialog();
100+ if (profileChanged()) {
101+ showCancellationConfirmDialog();
102+ } else {
103+ finish();
104+ }
94105 return true;
95106 }
96107 return super.onOptionsItemSelected(item);
@@ -131,7 +142,7 @@ public class VpnEditor extends PreferenceActivity {
131142 return false;
132143 }
133144
134- setResult(getProfile());
145+ if (profileChanged()) setResult(getProfile());
135146 return true;
136147 }
137148
@@ -152,6 +163,9 @@ public class VpnEditor extends PreferenceActivity {
152163 case L2TP:
153164 return new L2tpEditor((L2tpProfile) p);
154165
166+ case PPTP:
167+ return new PptpEditor((PptpProfile) p);
168+
155169 default:
156170 return new VpnProfileEditor(p);
157171 }
@@ -177,4 +191,17 @@ public class VpnEditor extends PreferenceActivity {
177191 private VpnProfile getProfile() {
178192 return mProfileEditor.getProfile();
179193 }
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+ }
180207 }
--- a/src/com/android/settings/vpn/VpnProfileEditor.java
+++ b/src/com/android/settings/vpn/VpnProfileEditor.java
@@ -33,9 +33,6 @@ import android.text.method.PasswordTransformationMethod;
3333 * The common class for editing {@link VpnProfile}.
3434 */
3535 class VpnProfileEditor {
36- static final String SECRET_SET_INDICATOR =
37- new String(new byte[] {(byte) 1, (byte) 0});
38-
3936 private static final String KEY_VPN_NAME = "vpn_name";
4037
4138 private EditTextPreference mName;
@@ -69,6 +66,8 @@ class VpnProfileEditor {
6966 }
7067 });
7168 setName(getProfile().getName());
69+ mName.getEditText().setInputType(InputType.TYPE_CLASS_TEXT
70+ | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
7271
7372 subpanel.addPreference(createServerNamePreference(c));
7473 loadExtraPreferencesTo(subpanel);
@@ -147,22 +146,6 @@ class VpnProfileEditor {
147146 return pref;
148147 }
149148
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-
166149 protected String validate(Preference pref, int fieldNameId) {
167150 Context c = pref.getContext();
168151 String value = (pref instanceof EditTextPreference)
@@ -191,15 +174,6 @@ class VpnProfileEditor {
191174 : v);
192175 }
193176
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-
203177 protected void setSecretTitle(
204178 CheckBoxPreference pref, int fieldNameId, boolean enabled) {
205179 Context c = pref.getContext();
@@ -215,4 +189,69 @@ class VpnProfileEditor {
215189 getProfile().setName(newName);
216190 setSummary(mName, R.string.vpn_name, newName);
217191 }
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+ }
218257 }
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -18,7 +18,6 @@ package com.android.settings.vpn;
1818
1919 import com.android.settings.R;
2020 import com.android.settings.SecuritySettings;
21-import static com.android.settings.vpn.VpnProfileEditor.SECRET_SET_INDICATOR;
2221
2322 import android.app.AlertDialog;
2423 import android.app.Dialog;
@@ -29,6 +28,7 @@ import android.content.DialogInterface;
2928 import android.content.Intent;
3029 import android.content.ServiceConnection;
3130 import android.net.vpn.IVpnService;
31+import android.net.vpn.L2tpIpsecProfile;
3232 import android.net.vpn.L2tpIpsecPskProfile;
3333 import android.net.vpn.L2tpProfile;
3434 import android.net.vpn.VpnManager;
@@ -47,6 +47,7 @@ import android.preference.PreferenceCategory;
4747 import android.preference.PreferenceManager;
4848 import android.preference.PreferenceScreen;
4949 import android.preference.Preference.OnPreferenceClickListener;
50+import android.security.CertTool;
5051 import android.security.Keystore;
5152 import android.text.TextUtils;
5253 import android.util.Log;
@@ -107,6 +108,9 @@ public class VpnSettings extends PreferenceActivity implements
107108 private static final int DIALOG_RECONNECT = 2;
108109 private static final int DIALOG_AUTH_ERROR = 3;
109110 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;
110114
111115 private static final int NO_ERROR = 0;
112116
@@ -197,14 +201,23 @@ public class VpnSettings extends PreferenceActivity implements
197201 return createConnectDialog();
198202
199203 case DIALOG_RECONNECT:
200- return createReconnectDialogBuilder().create();
204+ return createReconnectDialog();
201205
202206 case DIALOG_AUTH_ERROR:
203207 return createAuthErrorDialog();
204208
209+ case DIALOG_REMOTE_HUNG_UP_ERROR:
210+ return createRemoteHungUpErrorDialog();
211+
212+ case DIALOG_CHALLENGE_ERROR:
213+ return createChallengeErrorDialog();
214+
205215 case DIALOG_UNKNOWN_SERVER:
206216 return createUnknownServerDialog();
207217
218+ case DIALOG_SECRET_NOT_SET:
219+ return createSecretNotSetDialog();
220+
208221 default:
209222 return super.onCreateDialog(id);
210223 }
@@ -219,14 +232,74 @@ public class VpnSettings extends PreferenceActivity implements
219232 this)
220233 .setNegativeButton(getString(android.R.string.cancel),
221234 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)
222265 .create();
223266 }
224267
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() {
226300 return new AlertDialog.Builder(this)
227301 .setTitle(android.R.string.dialog_alert_title)
228302 .setIcon(android.R.drawable.ic_dialog_alert)
229- .setMessage(R.string.vpn_confirm_reconnect)
230303 .setPositiveButton(R.string.vpn_yes_button,
231304 new DialogInterface.OnClickListener() {
232305 public void onClick(DialogInterface dialog, int w) {
@@ -246,26 +319,6 @@ public class VpnSettings extends PreferenceActivity implements
246319 });
247320 }
248321
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-
269322 @Override
270323 public void onCreateContextMenu(ContextMenu menu, View v,
271324 ContextMenuInfo menuInfo) {
@@ -413,6 +466,7 @@ public class VpnSettings extends PreferenceActivity implements
413466 }
414467 } else {
415468 removeDialog(DIALOG_CONNECT);
469+ onIdle();
416470 }
417471 }
418472
@@ -629,6 +683,7 @@ public class VpnSettings extends PreferenceActivity implements
629683
630684 mConnectingActor = getActor(p);
631685 mActiveProfile = p;
686+ if (!checkSecrets(p)) return;
632687 if (mConnectingActor.isConnectDialogNeeded()) {
633688 showDialog(DIALOG_CONNECT);
634689 } else {
@@ -693,6 +748,14 @@ public class VpnSettings extends PreferenceActivity implements
693748 showDialog(DIALOG_AUTH_ERROR);
694749 break;
695750
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+
696759 case VpnManager.VPN_ERROR_UNKNOWN_SERVER:
697760 showDialog(DIALOG_UNKNOWN_SERVER);
698761 break;
@@ -707,6 +770,7 @@ public class VpnSettings extends PreferenceActivity implements
707770 }
708771
709772 private void onIdle() {
773+ Log.d(TAG, " onIdle()");
710774 mActiveProfile = null;
711775 mConnectingActor = null;
712776 enableProfilePreferences();
@@ -847,34 +911,93 @@ public class VpnSettings extends PreferenceActivity implements
847911 return NAMESPACE_VPN + "_" + keyName;
848912 }
849913
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+
850973 private void processSecrets(VpnProfile p) {
851974 Keystore ks = Keystore.getInstance();
852975 switch (p.getType()) {
853976 case L2TP_IPSEC_PSK:
854977 L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p;
855978 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)) {
858981 int ret = ks.put(NAMESPACE_VPN, keyName, presharedKey);
859- if (ret < 0) {
982+ if (ret != 0) {
860983 Log.e(TAG, "keystore write failed: key=" + keyName);
861984 }
862- pskProfile.setPresharedKey(keyNameForDaemon(keyName));
863985 }
986+ pskProfile.setPresharedKey(keyNameForDaemon(keyName));
864987 // pass through
865988
866989 case L2TP:
867990 L2tpProfile l2tpProfile = (L2tpProfile) p;
868- String keyName = KEY_PREFIX_L2TP_SECRET + p.getId();
991+ keyName = KEY_PREFIX_L2TP_SECRET + p.getId();
869992 if (l2tpProfile.isSecretEnabled()) {
870993 String secret = l2tpProfile.getSecretString();
871- if (!secret.equals(SECRET_SET_INDICATOR)) {
994+ if (!TextUtils.isEmpty(secret)) {
872995 int ret = ks.put(NAMESPACE_VPN, keyName, secret);
873- if (ret < 0) {
996+ if (ret != 0) {
874997 Log.e(TAG, "keystore write failed: key=" + keyName);
875998 }
876- l2tpProfile.setSecretString(keyNameForDaemon(keyName));
877999 }
1000+ l2tpProfile.setSecretString(keyNameForDaemon(keyName));
8781001 } else {
8791002 ks.remove(NAMESPACE_VPN, keyName);
8801003 }
--- a/src/com/android/settings/wifi/AccessPointDialog.java
+++ b/src/com/android/settings/wifi/AccessPointDialog.java
@@ -134,7 +134,7 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On
134134 private Spinner mSecuritySpinner;
135135 private Spinner mWepTypeSpinner;
136136 private CertTool mCertTool;
137-
137+
138138 public AccessPointDialog(Context context, WifiLayer wifiLayer) {
139139 super(context);
140140
@@ -217,6 +217,14 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On
217217 setTitle(getContext().getString(titleId));
218218 }
219219
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+
220228 /** Called after flags are set, the dialog's layout/etc should be set up here */
221229 private void onLayout() {
222230 final Context context = getContext();
@@ -246,7 +254,6 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On
246254 } else if (mMode == MODE_INFO) {
247255 if (mState.isEnterprise() && !mState.configured) {
248256 setLayout(R.layout.wifi_ap_configure);
249- defaultPasswordVisibility = false;
250257 setEnterpriseFieldsVisible(true);
251258 } else {
252259 setLayout(R.layout.wifi_ap_info);
@@ -319,17 +326,26 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On
319326 if (mMode == MODE_CONFIGURE ||
320327 (mState.isEnterprise() && !mState.configured)) {
321328 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();
330330 }
331331 }
332332
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+
333349 private String[] getAllCaCertificateKeys() {
334350 return appendEmptyInSelection(mCertTool.getAllCaCertificateKeys());
335351 }
@@ -663,14 +679,15 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On
663679 }
664680 }
665681 switch (securityType) {
682+ case SECURITY_IEEE8021X:
666683 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+ }
673689 mState.setEap(mEapSpinner.getSelectedItemPosition());
690+ mState.setPhase2((String)mPhase2Spinner.getSelectedItem());
674691 break;
675692 }
676693 default:
@@ -786,13 +803,9 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On
786803 if (Keystore.getInstance().getState() != Keystore.UNLOCKED) {
787804 getContext().startActivity(new Intent(
788805 SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE));
789- mSecuritySpinner.setSelection(0);
790806 return;
791807 }
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();
796809 break;
797810 }
798811 }
--- a/src/com/android/settings/wifi/AccessPointState.java
+++ b/src/com/android/settings/wifi/AccessPointState.java
@@ -375,12 +375,22 @@ public final class AccessPointState implements Comparable<AccessPointState>, Par
375375
376376 /* For Enterprise Fields */
377377 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)) {
379379 this.mEnterpriseFields[field] = value;
380380 requestRefresh();
381381 }
382382 }
383383
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+
384394 public void setEap(int method) {
385395 mEap = EAP_METHOD[method];
386396 requestRefresh();
@@ -495,6 +505,12 @@ public final class AccessPointState implements Comparable<AccessPointState>, Par
495505 config.hiddenSSID = hiddenSsid;
496506 config.SSID = convertToQuotedString(ssid);
497507 config.eap = mEap;
508+
509+ if (!TextUtils.isEmpty(mPhase2)) {
510+ config.phase2 = convertToQuotedString("auth=" + mPhase2);
511+ } else {
512+ config.phase2 = null;
513+ }
498514 if (!TextUtils.isEmpty(mEnterpriseFields[IDENTITY])) {
499515 config.identity =
500516 convertToQuotedString(mEnterpriseFields[IDENTITY]);
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -86,6 +86,9 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba
8686 private Preference mAddOtherNetwork;
8787
8888 private WeakHashMap<AccessPointState, AccessPointPreference> mAps;
89+
90+ private AccessPointState mResumeState = null;
91+ private int mResumeMode;
8992
9093 //============================
9194 // Wifi member variables
@@ -152,8 +155,22 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba
152155 super.onResume();
153156 mWifiLayer.onResume();
154157 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+ }
155172 }
156-
173+
157174 @Override
158175 protected void onPause() {
159176 super.onPause();
@@ -231,6 +248,7 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba
231248 public void onDismiss(DialogInterface dialog) {
232249 if (dialog == mDialog) {
233250 mDialog = null;
251+ mResumeMode = -1;
234252 }
235253 }
236254
@@ -350,6 +368,7 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba
350368 dialog.setMode(AccessPointDialog.MODE_CONFIGURE);
351369 dialog.setTitle(R.string.wifi_add_other_network);
352370 dialog.setAutoSecurityAllowed(false);
371+ mResumeMode = AccessPointDialog.MODE_CONFIGURE;
353372 showDialog(dialog);
354373 }
355374
@@ -358,6 +377,8 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba
358377 Keystore.getInstance().getState() != Keystore.UNLOCKED) {
359378 startActivity(new Intent(
360379 SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE));
380+ mResumeState = state;
381+ mResumeMode = mode;
361382 return;
362383 }
363384 AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer);