diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2009-08-03 07:45:47 -0700 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2009-08-03 07:45:47 -0700 |
commit | 2877e184f378aae5c71ebf852360f0a5ee4b02c4 (patch) | |
tree | ea39bba77379aa8722ac823cb77b61f1972979f6 | |
parent | 5f16c148dad5a1b8593473bef2f3b8d05d902017 (diff) | |
parent | ed47f1e497abf5ad31b1c7035ae04478e9932986 (diff) | |
download | packages_apps_Settings-2877e184f378aae5c71ebf852360f0a5ee4b02c4.zip packages_apps_Settings-2877e184f378aae5c71ebf852360f0a5ee4b02c4.tar.gz packages_apps_Settings-2877e184f378aae5c71ebf852360f0a5ee4b02c4.tar.bz2 |
merge from donut
-rw-r--r-- | res/values/strings.xml | 16 | ||||
-rw-r--r-- | res/xml/device_info_settings.xml | 3 | ||||
-rw-r--r-- | src/com/android/settings/ManageApplications.java | 76 | ||||
-rw-r--r-- | src/com/android/settings/SecuritySettings.java | 117 | ||||
-rw-r--r-- | src/com/android/settings/TextToSpeechSettings.java | 14 | ||||
-rw-r--r-- | src/com/android/settings/deviceinfo/Status.java | 28 | ||||
-rw-r--r-- | src/com/android/settings/fuelgauge/PowerUsageSummary.java | 2 | ||||
-rw-r--r-- | src/com/android/settings/vpn/L2tpEditor.java | 43 | ||||
-rw-r--r-- | src/com/android/settings/vpn/L2tpIpsecPskEditor.java | 33 | ||||
-rw-r--r-- | src/com/android/settings/vpn/PptpEditor.java | 75 | ||||
-rw-r--r-- | src/com/android/settings/vpn/VpnEditor.java | 31 | ||||
-rw-r--r-- | src/com/android/settings/vpn/VpnProfileEditor.java | 95 | ||||
-rw-r--r-- | src/com/android/settings/vpn/VpnSettings.java | 187 | ||||
-rw-r--r-- | src/com/android/settings/wifi/AccessPointDialog.java | 55 | ||||
-rw-r--r-- | src/com/android/settings/wifi/AccessPointState.java | 18 | ||||
-rw-r--r-- | src/com/android/settings/wifi/WifiSettings.java | 23 |
16 files changed, 595 insertions, 221 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml index c891979..5d89800 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1737,7 +1737,7 @@ found in the list of installed applications.</string> <!-- Description for wifi connectivity --> <string name="battery_desc_wifi">Battery used by Wi-Fi</string> <!-- Suggestion for wifi connectivity power drain --> - <string name="battery_sugg_wifi">Turn off WiFi when not using it or where it is not available</string> + <string name="battery_sugg_wifi">Turn off Wi-Fi when not using it or where it is not available</string> <!-- Description for bluetooth power consumption detail --> <string name="battery_desc_bluetooth">Battery used by bluetooth</string> @@ -1829,7 +1829,7 @@ found in the list of installed applications.</string> <string name="vpn_yes_button">Yes</string> <string name="vpn_no_button">No</string> <string name="vpn_back_button">Back</string> - <string name="vpn_mistake_button">No, it's a mistake</string> + <string name="vpn_mistake_button">No</string> <string name="vpn_menu_done">Save</string> <string name="vpn_menu_cancel">Cancel</string> @@ -1848,7 +1848,10 @@ found in the list of installed applications.</string> <string name="vpn_confirm_edit_profile_cancellation">Are you sure you want to discard the changes made to this profile?</string> <string name="vpn_confirm_reconnect">Unable to connect to the network. Do you want to try again?</string> <string name="vpn_unknown_server_dialog_msg">Server name cannot be resolved. Do you want to check your server name setting?</string> + <string name="vpn_challenge_error_dialog_msg">Challenge error. Do you want to check your secret setting?</string> + <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> <string name="vpn_auth_error_dialog_msg">The username or password you entered is incorrect. Do you want to try again?</string> + <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> <!-- VPN type selection activity title --> <string name="vpn_type_title">Add VPN</string> @@ -1894,6 +1897,8 @@ found in the list of installed applications.</string> <!-- Complete term --> <string name="vpn_l2tp_secret">L2TP secret</string> <string name="vpn_a_l2tp_secret">an L2TP secret</string> + <string name="vpn_pptp_encryption_title">encryption</string> + <string name="vpn_pptp_encryption">PPTP encryption</string> <!-- Preference title --> <string name="vpn_ipsec_presharedkey_title">Set IPSec pre-shared key</string> @@ -1935,6 +1940,10 @@ found in the list of installed applications.</string> <string name="vpn_settings_title">VPN settings</string> <!-- Summary of preference to enter the VPN settings activity --> <string name="vpn_settings_summary">Set up & manage Virtual Private Networks (VPNs)</string> + <!-- A secret edit field's grayed out value when it has not been modified --> + <string name="vpn_secret_unchanged">(unchanged)</string> + <!-- A secret edit field's grayed out value when it has not been set --> + <string name="vpn_secret_not_set">(not set)</string> <!-- Title of preference group for credential storage settings --> <string name="cstor_settings_category">Credential storage</string> @@ -1991,6 +2000,9 @@ found in the list of installed applications.</string> <string name="cstor_name_empty_error">Please enter a name.</string> <string name="cstor_name_char_error">Please enter a name that contains only letters and numbers.</string> <string name="cstor_storage_error">Unable to save the certificate. Click OK to retry.</string> + <string name="cstor_unable_to_save_cert">Unable to save the certificate. The credential storage is not enabled or properly initialized.</string> + <string name="cstor_cert_not_saved">The certificate is not saved.</string> + <string name="cstor_is_reset">The credential storage is erased.</string> <!-- toast message --> <string name="cstor_is_enabled">Credential storage is enabled.</string> diff --git a/res/xml/device_info_settings.xml b/res/xml/device_info_settings.xml index 80370e2..56810b4 100644 --- a/res/xml/device_info_settings.xml +++ b/res/xml/device_info_settings.xml @@ -76,12 +76,13 @@ </PreferenceScreen> <!-- Contributors --> + <!-- <PreferenceScreen android:key="contributors" android:title="@string/contributors_title"> <intent android:action="android.settings.TEAM" /> </PreferenceScreen> - + --> <!-- System Tutorial - launches activity --> <PreferenceScreen android:key="system_tutorial" android:title="@string/system_tutorial_list_item_title" diff --git a/src/com/android/settings/ManageApplications.java b/src/com/android/settings/ManageApplications.java index 642a48e..0d4895e 100644 --- a/src/com/android/settings/ManageApplications.java +++ b/src/com/android/settings/ManageApplications.java @@ -355,7 +355,7 @@ public class ManageApplications extends ListActivity implements Log.w(TAG, "Couldnt find application info for:"+pkgName); break; } - mObserver.invokeGetSizeInfo(info); + mObserver.invokeGetSizeInfo(pkgName); break; case ADD_PKG_DONE: if(localLOGV) Log.i(TAG, "Message ADD_PKG_DONE"); @@ -367,7 +367,12 @@ public class ManageApplications extends ListActivity implements if (status) { size = data.getLong(ATTR_PKG_STATS); formattedSize = data.getString(ATTR_PKG_SIZE_STR); - mAppInfoAdapter.addToList(pkgName, size, formattedSize); + int idx = mAppInfoAdapter.getIndex(pkgName); + if (idx == -1) { + mAppInfoAdapter.addToList(pkgName, size, formattedSize); + } else { + mAppInfoAdapter.updatePackage(pkgName, size, formattedSize); + } } break; case REFRESH_LABELS: @@ -1121,7 +1126,7 @@ public class ManageApplications extends ListActivity implements } return mSizeComparator; } - + public void bulkUpdateIcons(Map<String, Drawable> icons) { if (icons == null) { return; @@ -1162,19 +1167,6 @@ public class ManageApplications extends ListActivity implements } } - public boolean updateAppLabel(String pkgName, CharSequence label) { - if ((pkgName == null) || (label == null)) { - return false; - } - AppInfo aInfo = mCache.getEntry(pkgName); - if (aInfo != null) { - aInfo.refreshLabel(label); - notifyDataSetChanged(); - return true; - } - return false; - } - private boolean shouldBeInList(int filterOption, ApplicationInfo info) { // Match filter here if (filterOption == FILTER_APPS_RUNNING) { @@ -1246,6 +1238,24 @@ public class ManageApplications extends ListActivity implements } } + public void updatePackage(String pkgName, + long size, String formattedSize) { + ApplicationInfo info = null; + try { + info = mPm.getApplicationInfo(pkgName, + PackageManager.GET_UNINSTALLED_PACKAGES); + } catch (NameNotFoundException e) { + return; + } + AppInfo aInfo = mCache.getEntry(pkgName); + if (aInfo != null) { + aInfo.refreshLabel(info.loadLabel(mPm)); + aInfo.refreshIcon(info.loadIcon(mPm)); + aInfo.setSize(size, formattedSize); + notifyDataSetChanged(); + } + } + private void removePkgBase(String pkgName) { int imax = mAppList.size(); for (int i = 0; i < imax; i++) { @@ -1300,7 +1310,7 @@ public class ManageApplications extends ListActivity implements for (int i = 0; i < pkgs.length; i++) { AppInfo entry = mCache.getEntry(pkgs[i]); if (entry == null) { - Log.w(TAG, "Entry for package:"+ pkgs[i] +"doesn't exist in map"); + if (localLOGV) Log.w(TAG, "Entry for package:"+ pkgs[i] +"doesn't exist in map"); continue; } if (entry.setSize(sizes[i], formatted[i])) { @@ -1311,21 +1321,6 @@ public class ManageApplications extends ListActivity implements notifyDataSetChanged(); } } - - public void updateAppSize(String pkgName, long size, String formattedSize) { - if(pkgName == null) { - return; - } - AppInfo entry = mCache.getEntry(pkgName); - if (entry == null) { - Log.w(TAG, "Entry for package:"+pkgName+"doesnt exist in map"); - return; - } - // Copy the index into the newly updated entry - if (entry.setSize(size, formattedSize)) { - notifyDataSetChanged(); - } - } } /* @@ -1371,7 +1366,7 @@ public class ManageApplications extends ListActivity implements * and the AppInfo object corresponding to the package name are set on the message */ class PkgSizeObserver extends IPackageStatsObserver.Stub { - private ApplicationInfo mAppInfo; + String pkgName; public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) { if(DEBUG_PKG_DELAY) { try { @@ -1379,12 +1374,11 @@ public class ManageApplications extends ListActivity implements } catch (InterruptedException e) { } } - AppInfo appInfo = null; Bundle data = new Bundle(); - data.putString(ATTR_PKG_NAME, mAppInfo.packageName); + data.putString(ATTR_PKG_NAME, pkgName); data.putBoolean(ATTR_GET_SIZE_STATUS, pSucceeded); if(pSucceeded && pStats != null) { - if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pStats.packageName+", ("+ + if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pkgName+", ("+ pStats.cacheSize+","+ pStats.codeSize+", "+pStats.dataSize); long total = getTotalSize(pStats); @@ -1400,14 +1394,14 @@ public class ManageApplications extends ListActivity implements mHandler.sendMessage(msg); } - public void invokeGetSizeInfo(ApplicationInfo pAppInfo) { - if(pAppInfo == null || pAppInfo.packageName == null) { + public void invokeGetSizeInfo(String packageName) { + if (packageName == null) { return; } + pkgName = packageName; if(localLOGV) Log.i(TAG, "Invoking getPackageSizeInfo for package:"+ - pAppInfo.packageName); - mAppInfo = pAppInfo; - mPm.getPackageSizeInfo(pAppInfo.packageName, this); + packageName); + mPm.getPackageSizeInfo(packageName, this); } } diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 63d88d3..5a5804e 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -42,6 +42,7 @@ import android.security.Keystore; import android.text.Html; import android.text.TextUtils; import android.text.method.LinkMovementMethod; +import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; @@ -464,15 +465,26 @@ public class SecuritySettings extends PreferenceActivity implements if (ACTION_ADD_CREDENTIAL.equals(action)) { mCstorAddCredentialHelper = new CstorAddCredentialHelper(intent); - showDialog(CSTOR_NAME_CREDENTIAL_DIALOG); + showCstorDialog(CSTOR_NAME_CREDENTIAL_DIALOG); } else if (ACTION_UNLOCK_CREDENTIAL_STORAGE.equals(action)) { mSpecialIntent = intent; - showDialog(mCstorHelper.isCstorInitialized() + showCstorDialog(mCstorHelper.isCstorInitialized() ? CSTOR_UNLOCK_DIALOG : CSTOR_INIT_DIALOG); } } + private void showCstorDialog(int dialogId) { + mDialogId = dialogId; + showDialog(dialogId); + + if (dialogId == CSTOR_NAME_CREDENTIAL_DIALOG) { + // set mView back as mView may be replaced by CSTOR_INIT_DIALOG + // or CSTOR_UNLOCK_DIALOG + mView = mCstorAddCredentialHelper.mView; + } + } + private boolean isCstorUnlocked() { return (mKeystore.getState() == Keystore.UNLOCKED); } @@ -514,15 +526,53 @@ public class SecuritySettings extends PreferenceActivity implements mKeystore.reset(); enablePreferences(false); mAccessCheckBox.setChecked(false); + Toast.makeText(SecuritySettings.this, R.string.cstor_is_reset, + Toast.LENGTH_LONG).show(); + } + + private boolean addCredential() { + if (mCstorAddCredentialHelper.saveToStorage() != 0) { + // set mView back as mView may be replaced by CSTOR_INIT_DIALOG + // or CSTOR_UNLOCK_DIALOG + mView = mCstorAddCredentialHelper.mView; + if (mCstorAddCredentialHelper.isPkcs12Keystore()) { + showError(R.string.cstor_password_error); + } else { + showError(R.string.cstor_storage_error); + } + Log.d("CSTOR", "failed to add credential"); + return false; + } + Log.d("CSTOR", "credential is added: " + + mCstorAddCredentialHelper.getName()); + String formatString = + getString(R.string.cstor_is_added); + String message = String.format(formatString, + mCstorAddCredentialHelper.getName()); + Toast.makeText(SecuritySettings.this, message, + Toast.LENGTH_LONG).show(); + return true; } public void onCancel(DialogInterface dialog) { - if (mCstorAddCredentialHelper != null) { - // release the object here so that it doesn't get triggerred in - // onDismiss() - mCstorAddCredentialHelper = null; - finish(); + if (mCstorAddCredentialHelper == null) return; + + switch (mDialogId) { + case CSTOR_INIT_DIALOG: + case CSTOR_UNLOCK_DIALOG: + Toast.makeText(SecuritySettings.this, + R.string.cstor_unable_to_save_cert, + Toast.LENGTH_LONG).show(); + break; + + case CSTOR_NAME_CREDENTIAL_DIALOG: + Toast.makeText(SecuritySettings.this, + R.string.cstor_cert_not_saved, + Toast.LENGTH_LONG).show(); + break; } + mCstorAddCredentialHelper = null; + finish(); } public void onClick(DialogInterface dialog, int which) { @@ -554,31 +604,34 @@ public class SecuritySettings extends PreferenceActivity implements public void onDismiss(DialogInterface dialog) { if (!mConfirm) { mConfirm = true; - showDialog(mDialogId); + showCstorDialog(mDialogId); } else { - removeDialog(mDialogId); - if (mDialogId == CSTOR_UNLOCK_DIALOG) { mAccessCheckBox.setChecked(isCstorUnlocked()); } if (mCstorAddCredentialHelper != null) { if (!isCstorInitialized()) { - showDialog(CSTOR_INIT_DIALOG); + showCstorDialog(CSTOR_INIT_DIALOG); } else if (!isCstorUnlocked()) { - showDialog(CSTOR_UNLOCK_DIALOG); + showCstorDialog(CSTOR_UNLOCK_DIALOG); } else { - String formatString = - getString(R.string.cstor_is_added); - String message = String.format(formatString, - mCstorAddCredentialHelper.getName()); - Toast.makeText(SecuritySettings.this, message, - Toast.LENGTH_SHORT).show(); - finish(); + if (addCredential()) { + // succeeded + finish(); + } else { + // failed + if (mDialogId != CSTOR_NAME_CREDENTIAL_DIALOG) { + removeDialog(mDialogId); + } + showCstorDialog(CSTOR_NAME_CREDENTIAL_DIALOG); + } } + return; } else if (mSpecialIntent != null) { finish(); } + removeDialog(mDialogId); } } @@ -625,15 +678,6 @@ public class SecuritySettings extends PreferenceActivity implements mCstorAddCredentialHelper.setPassword(password); } - if (mCstorAddCredentialHelper.saveToStorage() < 0) { - if (mCstorAddCredentialHelper.isPkcs12Keystore()) { - showError(R.string.cstor_password_error); - } else { - showError(R.string.cstor_storage_error); - } - return false; - } - return true; } @@ -760,7 +804,7 @@ public class SecuritySettings extends PreferenceActivity implements public boolean onPreferenceChange( Preference pref, Object value) { if (((Boolean) value)) { - showDialog(isCstorInitialized() + showCstorDialog(isCstorInitialized() ? CSTOR_UNLOCK_DIALOG : CSTOR_INIT_DIALOG); } else { @@ -781,7 +825,7 @@ public class SecuritySettings extends PreferenceActivity implements pref.setOnPreferenceClickListener( new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference pref) { - showDialog(isCstorInitialized() + showCstorDialog(isCstorInitialized() ? CSTOR_CHANGE_PASSWORD_DIALOG : CSTOR_INIT_DIALOG); return true; @@ -797,7 +841,7 @@ public class SecuritySettings extends PreferenceActivity implements pref.setOnPreferenceClickListener( new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference pref) { - showDialog(CSTOR_RESET_DIALOG); + showCstorDialog(CSTOR_RESET_DIALOG); return true; } }); @@ -807,7 +851,6 @@ public class SecuritySettings extends PreferenceActivity implements } private Dialog createUnlockDialog() { - mDialogId = CSTOR_UNLOCK_DIALOG; mView = View.inflate(SecuritySettings.this, R.layout.cstor_unlock_dialog_view, null); hideError(); @@ -830,7 +873,6 @@ public class SecuritySettings extends PreferenceActivity implements } private Dialog createSetPasswordDialog(int id) { - mDialogId = id; mView = View.inflate(SecuritySettings.this, R.layout.cstor_set_password_dialog_view, null); hideError(); @@ -870,7 +912,6 @@ public class SecuritySettings extends PreferenceActivity implements } private Dialog createResetDialog() { - mDialogId = CSTOR_RESET_DIALOG; return new AlertDialog.Builder(SecuritySettings.this) .setTitle(android.R.string.dialog_alert_title) .setIcon(android.R.drawable.ic_dialog_alert) @@ -881,9 +922,12 @@ public class SecuritySettings extends PreferenceActivity implements } private Dialog createNameCredentialDialog() { - mDialogId = CSTOR_NAME_CREDENTIAL_DIALOG; mView = View.inflate(SecuritySettings.this, R.layout.cstor_name_credential_dialog_view, null); + if (mCstorAddCredentialHelper != null) { + mCstorAddCredentialHelper.mView = mView; + } + hideError(); if (!mCstorAddCredentialHelper.isPkcs12Keystore()) { hide(R.id.cstor_credential_password_container); @@ -915,6 +959,7 @@ public class SecuritySettings extends PreferenceActivity implements private String mDescription; private String mName; private String mPassword; + private View mView; CstorAddCredentialHelper(Intent intent) { parse(intent); @@ -958,7 +1003,7 @@ public class SecuritySettings extends PreferenceActivity implements byte[] blob = mItemList.get(i); int ret = ks.put(mNamespaceList.get(i), mName, new String(blob)); - if (ret < 0) return ret; + if (ret != 0) return ret; } } return 0; diff --git a/src/com/android/settings/TextToSpeechSettings.java b/src/com/android/settings/TextToSpeechSettings.java index 789368a..e17a6d6 100644 --- a/src/com/android/settings/TextToSpeechSettings.java +++ b/src/com/android/settings/TextToSpeechSettings.java @@ -59,7 +59,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements private static final String LOCALE_DELIMITER = "-"; private static final String FALLBACK_TTS_DEFAULT_SYNTH = - TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_SYNTH; + TextToSpeech.Engine.DEFAULT_SYNTH; private Preference mPlayExample = null; private Preference mInstallData = null; @@ -141,7 +141,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements intVal = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS); } catch (SettingNotFoundException e) { // "use default" setting not found, initialize it - intVal = TextToSpeech.Engine.FALLBACK_TTS_USE_DEFAULTS; + intVal = TextToSpeech.Engine.USE_DEFAULTS; Settings.Secure.putInt(resolver, TTS_USE_DEFAULTS, intVal); } mUseDefaultPref.setChecked(intVal == 1); @@ -162,7 +162,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements intVal = Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE); } catch (SettingNotFoundException e) { // default rate setting not found, initialize it - intVal = TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_RATE; + intVal = TextToSpeech.Engine.DEFAULT_RATE; Settings.Secure.putInt(resolver, TTS_DEFAULT_RATE, intVal); } mDefaultRatePref.setValue(String.valueOf(intVal)); @@ -223,7 +223,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements private void checkVoiceData() { PackageManager pm = getPackageManager(); Intent intent = new Intent(); - intent.setAction("android.intent.action.CHECK_TTS_DATA"); + intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); // query only the package that matches that of the default engine for (int i = 0; i < resolveInfos.size(); i++) { @@ -243,7 +243,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements private void installVoiceData() { PackageManager pm = getPackageManager(); Intent intent = new Intent(); - intent.setAction("android.intent.action.INSTALL_TTS_DATA"); + intent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); // query only the package that matches that of the default engine for (int i = 0; i < resolveInfos.size(); i++) { @@ -260,7 +260,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements * Called when the TTS engine is initialized. */ public void onInit(int status) { - if (status == TextToSpeech.TTS_SUCCESS) { + if (status == TextToSpeech.SUCCESS) { Log.v(TAG, "TTS engine for settings screen initialized."); mEnableDemo = true; } else { @@ -337,7 +337,7 @@ public class TextToSpeechSettings extends PreferenceActivity implements // Play example if (mTts != null) { mTts.speak(getResources().getString(R.string.tts_demo), - TextToSpeech.TTS_QUEUE_FLUSH, null); + TextToSpeech.QUEUE_FLUSH, null); } return true; } diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java index a165754..7d22d91 100644 --- 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 { @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); + Preference removablePref; mHandler = new MyHandler(this); @@ -188,8 +189,15 @@ public class Status extends PreferenceActivity { setSummaryText("prl_version", mPhone.getCdmaPrlVersion()); // device is not GSM/UMTS, do not display GSM/UMTS features - getPreferenceScreen().removePreference(findPreference("imei")); - getPreferenceScreen().removePreference(findPreference("imei_sv")); + // check Null in case no specified preference in overlay xml + removablePref = findPreference("imei"); + if (removablePref != null) { + getPreferenceScreen().removePreference(removablePref); + } + removablePref = findPreference("imei_sv"); + if (removablePref != null) { + getPreferenceScreen().removePreference(removablePref); + } } else { setSummaryText("imei", mPhone.getDeviceId()); @@ -198,9 +206,19 @@ public class Status extends PreferenceActivity { .getDeviceSoftwareVersion()); // device is not CDMA, do not display CDMA features - getPreferenceScreen().removePreference(findPreference("prl_version")); - getPreferenceScreen().removePreference(findPreference("meid_number")); - getPreferenceScreen().removePreference(findPreference("min_number")); + // check Null in case no specified preference in overlay xml + removablePref = findPreference("prl_version"); + if (removablePref != null) { + getPreferenceScreen().removePreference(removablePref); + } + removablePref = findPreference("meid_number"); + if (removablePref != null) { + getPreferenceScreen().removePreference(removablePref); + } + removablePref = findPreference("min_number"); + if (removablePref != null) { + getPreferenceScreen().removePreference(removablePref); + } } setSummaryText("number", mPhone.getLine1Number()); diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index 3dc9914..10c9a43 100644 --- 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 { btPower += (btPingCount * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000; - addEntry(getString(R.string.power_bluetooth), DrainType.IDLE, btOnTimeMs, + addEntry(getString(R.string.power_bluetooth), DrainType.BLUETOOTH, btOnTimeMs, com.android.internal.R.drawable.ic_volume_bluetooth_in_call, btPower); } diff --git a/src/com/android/settings/vpn/L2tpEditor.java b/src/com/android/settings/vpn/L2tpEditor.java index 643ba3b..29036f2 100644 --- a/src/com/android/settings/vpn/L2tpEditor.java +++ b/src/com/android/settings/vpn/L2tpEditor.java @@ -30,9 +30,7 @@ import android.preference.PreferenceGroup; */ class L2tpEditor extends VpnProfileEditor { private CheckBoxPreference mSecret; - private EditTextPreference mSecretString; - private String mOriginalSecret; - private boolean mOriginalSecretEnabled; + private SecretHandler mSecretHandler; public L2tpEditor(L2tpProfile p) { super(p); @@ -43,11 +41,8 @@ class L2tpEditor extends VpnProfileEditor { Context c = subpanel.getContext(); subpanel.addPreference(createSecretPreference(c)); subpanel.addPreference(createSecretStringPreference(c)); - mSecretString.setEnabled(mSecret.isChecked()); L2tpProfile profile = (L2tpProfile) getProfile(); - mOriginalSecret = profile.getSecretString(); - mOriginalSecretEnabled = profile.isSecretEnabled(); } @Override @@ -55,9 +50,7 @@ class L2tpEditor extends VpnProfileEditor { String result = super.validate(); if (!mSecret.isChecked()) return result; - return ((result != null) - ? result - : validate(mSecretString, R.string.vpn_a_l2tp_secret)); + return ((result != null) ? result : mSecretHandler.validate()); } private Preference createSecretPreference(Context c) { @@ -73,7 +66,7 @@ class L2tpEditor extends VpnProfileEditor { Preference pref, Object newValue) { boolean enabled = (Boolean) newValue; profile.setSecretEnabled(enabled); - mSecretString.setEnabled(enabled); + mSecretHandler.getPreference().setEnabled(enabled); setSecretTitle(mSecret, R.string.vpn_l2tp_secret, enabled); setSecretSummary(mSecret, enabled); @@ -84,22 +77,22 @@ class L2tpEditor extends VpnProfileEditor { } private Preference createSecretStringPreference(Context c) { - final L2tpProfile profile = (L2tpProfile) getProfile(); - mSecretString = createSecretPreference(c, + SecretHandler sHandler = mSecretHandler = new SecretHandler(c, R.string.vpn_l2tp_secret_string_title, - R.string.vpn_l2tp_secret, - profile.getSecretString(), - new Preference.OnPreferenceChangeListener() { - public boolean onPreferenceChange( - Preference pref, Object newValue) { - profile.setSecretString((String) newValue); - setSecretSummary(mSecretString, - R.string.vpn_l2tp_secret, - (String) newValue); - return true; - } - }); - return mSecretString; + R.string.vpn_l2tp_secret) { + @Override + protected String getSecretFromProfile() { + return ((L2tpProfile) getProfile()).getSecretString(); + } + + @Override + protected void saveSecretToProfile(String secret) { + ((L2tpProfile) getProfile()).setSecretString(secret); + } + }; + Preference pref = sHandler.getPreference(); + pref.setEnabled(mSecret.isChecked()); + return pref; } private void setSecretSummary(CheckBoxPreference secret, boolean enabled) { diff --git a/src/com/android/settings/vpn/L2tpIpsecPskEditor.java b/src/com/android/settings/vpn/L2tpIpsecPskEditor.java index 11590da..1277c28 100644 --- a/src/com/android/settings/vpn/L2tpIpsecPskEditor.java +++ b/src/com/android/settings/vpn/L2tpIpsecPskEditor.java @@ -29,6 +29,7 @@ import android.preference.PreferenceGroup; */ class L2tpIpsecPskEditor extends L2tpEditor { private EditTextPreference mPresharedKey; + private SecretHandler mPskHandler; public L2tpIpsecPskEditor(L2tpIpsecPskProfile p) { super(p); @@ -45,27 +46,23 @@ class L2tpIpsecPskEditor extends L2tpEditor { public String validate() { String result = super.validate(); - return ((result != null) - ? result - : validate(mPresharedKey, R.string.vpn_a_ipsec_presharedkey)); + return ((result != null) ? result : mPskHandler.validate()); } private Preference createPresharedKeyPreference(Context c) { - final L2tpIpsecPskProfile profile = (L2tpIpsecPskProfile) getProfile(); - mPresharedKey = createSecretPreference(c, + SecretHandler pskHandler = mPskHandler = new SecretHandler(c, R.string.vpn_ipsec_presharedkey_title, - R.string.vpn_ipsec_presharedkey, - profile.getPresharedKey(), - new Preference.OnPreferenceChangeListener() { - public boolean onPreferenceChange( - Preference pref, Object newValue) { - profile.setPresharedKey((String) newValue); - setSecretSummary(mPresharedKey, - R.string.vpn_ipsec_presharedkey, - (String) newValue); - return true; - } - }); - return mPresharedKey; + R.string.vpn_ipsec_presharedkey) { + @Override + protected String getSecretFromProfile() { + return ((L2tpIpsecPskProfile) getProfile()).getPresharedKey(); + } + + @Override + protected void saveSecretToProfile(String secret) { + ((L2tpIpsecPskProfile) getProfile()).setPresharedKey(secret); + } + }; + return pskHandler.getPreference(); } } diff --git a/src/com/android/settings/vpn/PptpEditor.java b/src/com/android/settings/vpn/PptpEditor.java new file mode 100644 index 0000000..fafe6a7 --- /dev/null +++ b/src/com/android/settings/vpn/PptpEditor.java @@ -0,0 +1,75 @@ +/* * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.vpn; + +import com.android.settings.R; + +import android.content.Context; +import android.net.vpn.PptpProfile; +import android.preference.CheckBoxPreference; +import android.preference.Preference; +import android.preference.PreferenceGroup; + +/** + * The class for editing {@link PptpProfile}. + */ +class PptpEditor extends VpnProfileEditor { + private CheckBoxPreference mEncryption; + + public PptpEditor(PptpProfile p) { + super(p); + } + + @Override + protected void loadExtraPreferencesTo(PreferenceGroup subpanel) { + Context c = subpanel.getContext(); + subpanel.addPreference(createEncryptionPreference(c)); + + PptpProfile profile = (PptpProfile) getProfile(); + } + + private Preference createEncryptionPreference(Context c) { + final PptpProfile profile = (PptpProfile) getProfile(); + CheckBoxPreference encryption = mEncryption = new CheckBoxPreference(c); + boolean enabled = profile.isEncryptionEnabled(); + setSecretTitle(encryption, R.string.vpn_pptp_encryption_title, enabled); + encryption.setChecked(enabled); + setEncryptionSummary(encryption, enabled); + encryption.setOnPreferenceChangeListener( + new Preference.OnPreferenceChangeListener() { + public boolean onPreferenceChange( + Preference pref, Object newValue) { + boolean enabled = (Boolean) newValue; + profile.setEncryptionEnabled(enabled); + setSecretTitle(mEncryption, + R.string.vpn_pptp_encryption_title, enabled); + setEncryptionSummary(mEncryption, enabled); + return true; + } + }); + return encryption; + } + + private void setEncryptionSummary(CheckBoxPreference encryption, + boolean enabled) { + Context c = encryption.getContext(); + String formatString = c.getString(enabled + ? R.string.vpn_is_enabled + : R.string.vpn_is_disabled); + encryption.setSummary(String.format( + formatString, c.getString(R.string.vpn_pptp_encryption))); + } +} diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java index b4dc2b6..497f4bf 100644 --- a/src/com/android/settings/vpn/VpnEditor.java +++ b/src/com/android/settings/vpn/VpnEditor.java @@ -24,9 +24,11 @@ import android.content.Intent; import android.net.vpn.L2tpIpsecProfile; import android.net.vpn.L2tpIpsecPskProfile; import android.net.vpn.L2tpProfile; +import android.net.vpn.PptpProfile; import android.net.vpn.VpnProfile; import android.net.vpn.VpnType; import android.os.Bundle; +import android.os.Parcel; import android.os.Parcelable; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; @@ -47,6 +49,7 @@ public class VpnEditor extends PreferenceActivity { private VpnProfileEditor mProfileEditor; private boolean mAddingProfile; + private byte[] mOriginalProfileData; @Override public void onCreate(Bundle savedInstanceState) { @@ -61,6 +64,10 @@ public class VpnEditor extends PreferenceActivity { addPreferencesFromResource(R.xml.vpn_edit); initViewFor(p); + + Parcel parcel = Parcel.obtain(); + p.writeToParcel(parcel, 0); + mOriginalProfileData = parcel.marshall(); } @Override @@ -90,7 +97,11 @@ public class VpnEditor extends PreferenceActivity { return true; case MENU_CANCEL: - showCancellationConfirmDialog(); + if (profileChanged()) { + showCancellationConfirmDialog(); + } else { + finish(); + } return true; } return super.onOptionsItemSelected(item); @@ -131,7 +142,7 @@ public class VpnEditor extends PreferenceActivity { return false; } - setResult(getProfile()); + if (profileChanged()) setResult(getProfile()); return true; } @@ -152,6 +163,9 @@ public class VpnEditor extends PreferenceActivity { case L2TP: return new L2tpEditor((L2tpProfile) p); + case PPTP: + return new PptpEditor((PptpProfile) p); + default: return new VpnProfileEditor(p); } @@ -177,4 +191,17 @@ public class VpnEditor extends PreferenceActivity { private VpnProfile getProfile() { return mProfileEditor.getProfile(); } + + private boolean profileChanged() { + Parcel newParcel = Parcel.obtain(); + getProfile().writeToParcel(newParcel, 0); + byte[] newData = newParcel.marshall(); + if (mOriginalProfileData.length == newData.length) { + for (int i = 0, n = mOriginalProfileData.length; i < n; i++) { + if (mOriginalProfileData[i] != newData[i]) return true; + } + return false; + } + return true; + } } diff --git a/src/com/android/settings/vpn/VpnProfileEditor.java b/src/com/android/settings/vpn/VpnProfileEditor.java index bf2e57d..8dc3643 100644 --- 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; * The common class for editing {@link VpnProfile}. */ class VpnProfileEditor { - static final String SECRET_SET_INDICATOR = - new String(new byte[] {(byte) 1, (byte) 0}); - private static final String KEY_VPN_NAME = "vpn_name"; private EditTextPreference mName; @@ -69,6 +66,8 @@ class VpnProfileEditor { } }); setName(getProfile().getName()); + mName.getEditText().setInputType(InputType.TYPE_CLASS_TEXT + | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); subpanel.addPreference(createServerNamePreference(c)); loadExtraPreferencesTo(subpanel); @@ -147,22 +146,6 @@ class VpnProfileEditor { return pref; } - protected EditTextPreference createSecretPreference(Context c, int titleId, - int fieldNameId, String value, - Preference.OnPreferenceChangeListener listener) { - EditTextPreference pref = new EditTextPreference(c); - pref.setTitle(titleId); - pref.setDialogTitle(titleId); - pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); - pref.getEditText().setTransformationMethod( - new PasswordTransformationMethod()); - pref.setText(TextUtils.isEmpty(value) ? "" : SECRET_SET_INDICATOR); - setSecretSummary(pref, fieldNameId, value); - pref.setPersistent(true); - pref.setOnPreferenceChangeListener(listener); - return pref; - } - protected String validate(Preference pref, int fieldNameId) { Context c = pref.getContext(); String value = (pref instanceof EditTextPreference) @@ -191,15 +174,6 @@ class VpnProfileEditor { : v); } - protected void setSecretSummary(Preference pref, int fieldNameId, - String value) { - Context c = pref.getContext(); - String formatString = TextUtils.isEmpty(value) - ? c.getString(R.string.vpn_field_not_set) - : c.getString(R.string.vpn_field_is_set); - pref.setSummary(String.format(formatString, c.getString(fieldNameId))); - } - protected void setSecretTitle( CheckBoxPreference pref, int fieldNameId, boolean enabled) { Context c = pref.getContext(); @@ -215,4 +189,69 @@ class VpnProfileEditor { getProfile().setName(newName); setSummary(mName, R.string.vpn_name, newName); } + + // Secret is tricky to handle because empty field may mean "not set" or + // "unchanged". This class hides that logic from callers. + protected static abstract class SecretHandler { + private EditTextPreference mPref; + private int mFieldNameId; + private boolean mHadSecret; + + protected SecretHandler(Context c, int titleId, int fieldNameId) { + String value = getSecretFromProfile(); + mHadSecret = !TextUtils.isEmpty(value); + mFieldNameId = fieldNameId; + + EditTextPreference pref = mPref = new EditTextPreference(c); + pref.setTitle(titleId); + pref.setDialogTitle(titleId); + pref.getEditText().setInputType( + InputType.TYPE_TEXT_VARIATION_PASSWORD); + pref.getEditText().setTransformationMethod( + new PasswordTransformationMethod()); + pref.setText(""); + pref.getEditText().setHint(mHadSecret + ? R.string.vpn_secret_unchanged + : R.string.vpn_secret_not_set); + setSecretSummary(value); + pref.setPersistent(true); + saveSecretToProfile(""); + pref.setOnPreferenceChangeListener( + new Preference.OnPreferenceChangeListener() { + public boolean onPreferenceChange( + Preference pref, Object newValue) { + saveSecretToProfile((String) newValue); + setSecretSummary((String) newValue); + return true; + } + }); + } + + protected EditTextPreference getPreference() { + return mPref; + } + + protected String validate() { + Context c = mPref.getContext(); + String value = mPref.getText(); + return ((TextUtils.isEmpty(value) && !mHadSecret) + ? String.format( + c.getString(R.string.vpn_error_miss_entering), + c.getString(mFieldNameId)) + : null); + } + + private void setSecretSummary(String value) { + EditTextPreference pref = mPref; + Context c = pref.getContext(); + String formatString = (TextUtils.isEmpty(value) && !mHadSecret) + ? c.getString(R.string.vpn_field_not_set) + : c.getString(R.string.vpn_field_is_set); + pref.setSummary( + String.format(formatString, c.getString(mFieldNameId))); + } + + protected abstract String getSecretFromProfile(); + protected abstract void saveSecretToProfile(String secret); + } } diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java index f0e71f7..4dda152 100644 --- 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; import com.android.settings.R; import com.android.settings.SecuritySettings; -import static com.android.settings.vpn.VpnProfileEditor.SECRET_SET_INDICATOR; import android.app.AlertDialog; import android.app.Dialog; @@ -29,6 +28,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.net.vpn.IVpnService; +import android.net.vpn.L2tpIpsecProfile; import android.net.vpn.L2tpIpsecPskProfile; import android.net.vpn.L2tpProfile; import android.net.vpn.VpnManager; @@ -47,6 +47,7 @@ import android.preference.PreferenceCategory; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.preference.Preference.OnPreferenceClickListener; +import android.security.CertTool; import android.security.Keystore; import android.text.TextUtils; import android.util.Log; @@ -107,6 +108,9 @@ public class VpnSettings extends PreferenceActivity implements private static final int DIALOG_RECONNECT = 2; private static final int DIALOG_AUTH_ERROR = 3; private static final int DIALOG_UNKNOWN_SERVER = 4; + private static final int DIALOG_SECRET_NOT_SET = 5; + private static final int DIALOG_CHALLENGE_ERROR = 6; + private static final int DIALOG_REMOTE_HUNG_UP_ERROR = 7; private static final int NO_ERROR = 0; @@ -197,14 +201,23 @@ public class VpnSettings extends PreferenceActivity implements return createConnectDialog(); case DIALOG_RECONNECT: - return createReconnectDialogBuilder().create(); + return createReconnectDialog(); case DIALOG_AUTH_ERROR: return createAuthErrorDialog(); + case DIALOG_REMOTE_HUNG_UP_ERROR: + return createRemoteHungUpErrorDialog(); + + case DIALOG_CHALLENGE_ERROR: + return createChallengeErrorDialog(); + case DIALOG_UNKNOWN_SERVER: return createUnknownServerDialog(); + case DIALOG_SECRET_NOT_SET: + return createSecretNotSetDialog(); + default: return super.onCreateDialog(id); } @@ -219,14 +232,74 @@ public class VpnSettings extends PreferenceActivity implements this) .setNegativeButton(getString(android.R.string.cancel), this) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + public void onCancel(DialogInterface dialog) { + removeDialog(DIALOG_CONNECT); + onIdle(); + } + }) + .create(); + } + + private Dialog createReconnectDialog() { + return createCommonDialogBuilder() + .setMessage(R.string.vpn_confirm_reconnect) + .create(); + } + + private Dialog createAuthErrorDialog() { + return createCommonDialogBuilder() + .setMessage(R.string.vpn_auth_error_dialog_msg) + .create(); + } + + private Dialog createRemoteHungUpErrorDialog() { + return createCommonDialogBuilder() + .setMessage(R.string.vpn_remote_hung_up_error_dialog_msg) + .create(); + } + + private Dialog createChallengeErrorDialog() { + return createCommonEditDialogBuilder() + .setMessage(R.string.vpn_challenge_error_dialog_msg) .create(); } - private AlertDialog.Builder createReconnectDialogBuilder() { + private Dialog createUnknownServerDialog() { + return createCommonEditDialogBuilder() + .setMessage(R.string.vpn_unknown_server_dialog_msg) + .create(); + } + + private Dialog createSecretNotSetDialog() { + return createCommonDialogBuilder() + .setMessage(R.string.vpn_secret_not_set_dialog_msg) + .setPositiveButton(R.string.vpn_yes_button, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int w) { + VpnProfile p = mConnectingActor.getProfile(); + startVpnEditor(p); + } + }) + .create(); + } + + private AlertDialog.Builder createCommonEditDialogBuilder() { + return createCommonDialogBuilder() + .setPositiveButton(R.string.vpn_yes_button, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int w) { + VpnProfile p = mConnectingActor.getProfile(); + onIdle(); + startVpnEditor(p); + } + }); + } + + private AlertDialog.Builder createCommonDialogBuilder() { return new AlertDialog.Builder(this) .setTitle(android.R.string.dialog_alert_title) .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(R.string.vpn_confirm_reconnect) .setPositiveButton(R.string.vpn_yes_button, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int w) { @@ -246,26 +319,6 @@ public class VpnSettings extends PreferenceActivity implements }); } - private Dialog createAuthErrorDialog() { - return createReconnectDialogBuilder() - .setMessage(R.string.vpn_auth_error_dialog_msg) - .create(); - } - - private Dialog createUnknownServerDialog() { - return createReconnectDialogBuilder() - .setMessage(R.string.vpn_unknown_server_dialog_msg) - .setPositiveButton(R.string.vpn_yes_button, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int w) { - VpnProfile p = mConnectingActor.getProfile(); - onIdle(); - startVpnEditor(p); - } - }) - .create(); - } - @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { @@ -413,6 +466,7 @@ public class VpnSettings extends PreferenceActivity implements } } else { removeDialog(DIALOG_CONNECT); + onIdle(); } } @@ -629,6 +683,7 @@ public class VpnSettings extends PreferenceActivity implements mConnectingActor = getActor(p); mActiveProfile = p; + if (!checkSecrets(p)) return; if (mConnectingActor.isConnectDialogNeeded()) { showDialog(DIALOG_CONNECT); } else { @@ -693,6 +748,14 @@ public class VpnSettings extends PreferenceActivity implements showDialog(DIALOG_AUTH_ERROR); break; + case VpnManager.VPN_ERROR_REMOTE_HUNG_UP: + showDialog(DIALOG_REMOTE_HUNG_UP_ERROR); + break; + + case VpnManager.VPN_ERROR_CHALLENGE: + showDialog(DIALOG_CHALLENGE_ERROR); + break; + case VpnManager.VPN_ERROR_UNKNOWN_SERVER: showDialog(DIALOG_UNKNOWN_SERVER); break; @@ -707,6 +770,7 @@ public class VpnSettings extends PreferenceActivity implements } private void onIdle() { + Log.d(TAG, " onIdle()"); mActiveProfile = null; mConnectingActor = null; enableProfilePreferences(); @@ -847,34 +911,93 @@ public class VpnSettings extends PreferenceActivity implements return NAMESPACE_VPN + "_" + keyName; } + private boolean checkSecrets(VpnProfile p) { + Keystore ks = Keystore.getInstance(); + HashSet<String> secretSet = new HashSet<String>(); + boolean secretMissing = false; + + if (p instanceof L2tpIpsecProfile) { + L2tpIpsecProfile certProfile = (L2tpIpsecProfile) p; + CertTool certTool = CertTool.getInstance(); + Collections.addAll(secretSet, certTool.getAllCaCertificateKeys()); + String cert = certProfile.getCaCertificate(); + if (TextUtils.isEmpty(cert) || !secretSet.contains(cert)) { + certProfile.setCaCertificate(null); + secretMissing = true; + } + + secretSet.clear(); + Collections.addAll(secretSet, certTool.getAllUserCertificateKeys()); + cert = certProfile.getUserCertificate(); + if (TextUtils.isEmpty(cert) || !secretSet.contains(cert)) { + certProfile.setUserCertificate(null); + secretMissing = true; + } + } + + secretSet.clear(); + Collections.addAll(secretSet, ks.listKeys(NAMESPACE_VPN)); + + if (p instanceof L2tpIpsecPskProfile) { + L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p; + String presharedKey = pskProfile.getPresharedKey(); + String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); + if (TextUtils.isEmpty(presharedKey) + || !secretSet.contains(keyName)) { + pskProfile.setPresharedKey(null); + secretMissing = true; + } + } + + if (p instanceof L2tpProfile) { + L2tpProfile l2tpProfile = (L2tpProfile) p; + if (l2tpProfile.isSecretEnabled()) { + String secret = l2tpProfile.getSecretString(); + String keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); + if (TextUtils.isEmpty(secret) + || !secretSet.contains(keyName)) { + l2tpProfile.setSecretString(null); + secretMissing = true; + } + } + } + + if (secretMissing) { + showDialog(DIALOG_SECRET_NOT_SET); + return false; + } else { + return true; + } + } + private void processSecrets(VpnProfile p) { Keystore ks = Keystore.getInstance(); switch (p.getType()) { case L2TP_IPSEC_PSK: L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p; String presharedKey = pskProfile.getPresharedKey(); - if (!presharedKey.equals(SECRET_SET_INDICATOR)) { - String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); + String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); + if (!TextUtils.isEmpty(presharedKey)) { int ret = ks.put(NAMESPACE_VPN, keyName, presharedKey); - if (ret < 0) { + if (ret != 0) { Log.e(TAG, "keystore write failed: key=" + keyName); } - pskProfile.setPresharedKey(keyNameForDaemon(keyName)); } + pskProfile.setPresharedKey(keyNameForDaemon(keyName)); // pass through case L2TP: L2tpProfile l2tpProfile = (L2tpProfile) p; - String keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); + keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); if (l2tpProfile.isSecretEnabled()) { String secret = l2tpProfile.getSecretString(); - if (!secret.equals(SECRET_SET_INDICATOR)) { + if (!TextUtils.isEmpty(secret)) { int ret = ks.put(NAMESPACE_VPN, keyName, secret); - if (ret < 0) { + if (ret != 0) { Log.e(TAG, "keystore write failed: key=" + keyName); } - l2tpProfile.setSecretString(keyNameForDaemon(keyName)); } + l2tpProfile.setSecretString(keyNameForDaemon(keyName)); } else { ks.remove(NAMESPACE_VPN, keyName); } diff --git a/src/com/android/settings/wifi/AccessPointDialog.java b/src/com/android/settings/wifi/AccessPointDialog.java index c9f511b..5851a18 100644 --- 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 private Spinner mSecuritySpinner; private Spinner mWepTypeSpinner; private CertTool mCertTool; - + public AccessPointDialog(Context context, WifiLayer wifiLayer) { super(context); @@ -217,6 +217,14 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On setTitle(getContext().getString(titleId)); } + public void enableEnterpriseFields() { + setEnterpriseFieldsVisible(true); + updateCertificateSelection(); + setGenericPasswordVisible(true); + // Both WPA and WPA2 show the same caption, so either is ok + updatePasswordCaption(AccessPointState.WPA); + } + /** Called after flags are set, the dialog's layout/etc should be set up here */ private void onLayout() { final Context context = getContext(); @@ -246,7 +254,6 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On } else if (mMode == MODE_INFO) { if (mState.isEnterprise() && !mState.configured) { setLayout(R.layout.wifi_ap_configure); - defaultPasswordVisibility = false; setEnterpriseFieldsVisible(true); } else { setLayout(R.layout.wifi_ap_info); @@ -319,17 +326,26 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On if (mMode == MODE_CONFIGURE || (mState.isEnterprise() && !mState.configured)) { setEnterpriseFields(view); - mEapSpinner.setSelection(getSelectionIndex( - R.array.wifi_eap_entries, mState.getEap())); - mClientCertSpinner.setSelection(getSelectionIndex( - getAllUserCertificateKeys(), mState.getEnterpriseField( - AccessPointState.CLIENT_CERT))); - mCaCertSpinner.setSelection(getSelectionIndex( - getAllCaCertificateKeys(), mState.getEnterpriseField( - AccessPointState.CA_CERT))); + updateCertificateSelection(); } } + private void updateCertificateSelection() { + setSpinnerAdapter(mClientCertSpinner, getAllUserCertificateKeys()); + setSpinnerAdapter(mCaCertSpinner, getAllCaCertificateKeys()); + + mPhase2Spinner.setSelection(getSelectionIndex( + R.array.wifi_phase2_entries, mState.getPhase2())); + mEapSpinner.setSelection(getSelectionIndex( + R.array.wifi_eap_entries, mState.getEap())); + mClientCertSpinner.setSelection(getSelectionIndex( + getAllUserCertificateKeys(), mState.getEnterpriseField( + AccessPointState.CLIENT_CERT))); + mCaCertSpinner.setSelection(getSelectionIndex( + getAllCaCertificateKeys(), mState.getEnterpriseField( + AccessPointState.CA_CERT))); + } + private String[] getAllCaCertificateKeys() { return appendEmptyInSelection(mCertTool.getAllCaCertificateKeys()); } @@ -663,14 +679,15 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On } } switch (securityType) { + case SECURITY_IEEE8021X: case SECURITY_WPA_EAP: { - mState.setSecurity(AccessPointState.WPA_EAP); - mState.setEap(mEapSpinner.getSelectedItemPosition()); - break; - } - case SECURITY_IEEE8021X: { - mState.setSecurity(AccessPointState.IEEE8021X); + if (securityType == SECURITY_WPA_EAP) { + mState.setSecurity(AccessPointState.WPA_EAP); + } else { + mState.setSecurity(AccessPointState.IEEE8021X); + } mState.setEap(mEapSpinner.getSelectedItemPosition()); + mState.setPhase2((String)mPhase2Spinner.getSelectedItem()); break; } default: @@ -786,13 +803,9 @@ public class AccessPointDialog extends AlertDialog implements DialogInterface.On if (Keystore.getInstance().getState() != Keystore.UNLOCKED) { getContext().startActivity(new Intent( SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE)); - mSecuritySpinner.setSelection(0); return; } - setEnterpriseFieldsVisible(true); - setGenericPasswordVisible(true); - // Both WPA and WPA2 show the same caption, so either is ok - updatePasswordCaption(AccessPointState.WPA); + enableEnterpriseFields(); break; } } diff --git a/src/com/android/settings/wifi/AccessPointState.java b/src/com/android/settings/wifi/AccessPointState.java index 8fb651b..899c304 100644 --- 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 /* For Enterprise Fields */ public void setEnterpriseField(int field, String value) { - if (value != null && field >= 0 && field < MAX_ENTRPRISE_FIELD) { + if ((value != null) && (field >= 0) && (field < MAX_ENTRPRISE_FIELD)) { this.mEnterpriseFields[field] = value; requestRefresh(); } } + public void setPhase2(String phase2) { + if (!TextUtils.isEmpty(phase2) && (!phase2.equals("None"))) { + mPhase2 = phase2; + } + } + + public String getPhase2() { + return mPhase2; + } + public void setEap(int method) { mEap = EAP_METHOD[method]; requestRefresh(); @@ -495,6 +505,12 @@ public final class AccessPointState implements Comparable<AccessPointState>, Par config.hiddenSSID = hiddenSsid; config.SSID = convertToQuotedString(ssid); config.eap = mEap; + + if (!TextUtils.isEmpty(mPhase2)) { + config.phase2 = convertToQuotedString("auth=" + mPhase2); + } else { + config.phase2 = null; + } if (!TextUtils.isEmpty(mEnterpriseFields[IDENTITY])) { config.identity = convertToQuotedString(mEnterpriseFields[IDENTITY]); diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index a015534..f18992a 100644 --- 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 private Preference mAddOtherNetwork; private WeakHashMap<AccessPointState, AccessPointPreference> mAps; + + private AccessPointState mResumeState = null; + private int mResumeMode; //============================ // Wifi member variables @@ -152,8 +155,22 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba super.onResume(); mWifiLayer.onResume(); mWifiEnabler.resume(); + // do what we should have after keystore is unlocked. + if (mResumeState != null) { + if (Keystore.getInstance().getState() == Keystore.UNLOCKED) { + showAccessPointDialog(mResumeState, mResumeMode); + } + mResumeMode = -1; + mResumeState = null; + } else { + if (mResumeMode == AccessPointDialog.MODE_CONFIGURE) { + if (Keystore.getInstance().getState() == Keystore.UNLOCKED) { + ((AccessPointDialog) mDialog).enableEnterpriseFields(); + } + } + } } - + @Override protected void onPause() { super.onPause(); @@ -231,6 +248,7 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba public void onDismiss(DialogInterface dialog) { if (dialog == mDialog) { mDialog = null; + mResumeMode = -1; } } @@ -350,6 +368,7 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba dialog.setMode(AccessPointDialog.MODE_CONFIGURE); dialog.setTitle(R.string.wifi_add_other_network); dialog.setAutoSecurityAllowed(false); + mResumeMode = AccessPointDialog.MODE_CONFIGURE; showDialog(dialog); } @@ -358,6 +377,8 @@ public class WifiSettings extends PreferenceActivity implements WifiLayer.Callba Keystore.getInstance().getState() != Keystore.UNLOCKED) { startActivity(new Intent( SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE)); + mResumeState = state; + mResumeMode = mode; return; } AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer); |