SecuritySettings: clean up.

This commit is contained in:
Chia-chi Yeh
2009-10-02 00:39:14 +08:00
parent 28f1a0fc5b
commit 02f58e898d
5 changed files with 282 additions and 431 deletions

View File

@@ -24,40 +24,37 @@
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:padding="15dip"> android:padding="15dip">
<TextView android:id="@+id/cstor_first_time_hint" <TextView android:id="@+id/hint"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="@dimen/vpn_connect_normal_text_size" android:textSize="@dimen/vpn_connect_normal_text_size"
android:text="@string/cstor_first_time_hint" android:text="@string/credentials_first_time_hint"
android:layout_marginBottom="10sp" /> android:layout_marginBottom="10sp"
android:visibility="gone"/>
<TextView android:id="@+id/cstor_error" <TextView android:id="@+id/error"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" android:textColor="@color/red"
android:textStyle="bold" android:textStyle="bold"
android:text="@string/cstor_password_empty_error" /> android:visibility="gone"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <TextView android:id="@+id/old_password_prompt"
android:id="@+id/cstor_old_password_block" android:layout_width="fill_parent"
android:orientation="vertical" android:layout_height="wrap_content"
android:text="@string/credentials_old_password"
android:visibility="gone"/>
<EditText android:id="@+id/old_password"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="wrap_content"
> android:password="True"
<TextView android:layout_width="fill_parent" android:singleLine="True"
android:layout_height="wrap_content" android:visibility="gone"/>
android:text="@string/cstor_old_password" />
<EditText android:id="@+id/cstor_old_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
</LinearLayout>
<TextView android:layout_width="fill_parent" <TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/cstor_new_password" /> android:text="@string/credentials_new_password" />
<EditText android:id="@+id/cstor_new_password" <EditText android:id="@+id/new_password"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:password="True" android:password="True"
@@ -65,8 +62,8 @@
<TextView android:layout_width="fill_parent" <TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/cstor_confirm_password" /> android:text="@string/credentials_confirm_password" />
<EditText android:id="@+id/cstor_confirm_password" <EditText android:id="@+id/confirm_password"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:password="True" android:password="True"

View File

@@ -24,20 +24,22 @@
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:padding="15dip"> android:padding="15dip">
<TextView android:id="@+id/cstor_access_dialog_hint_from_action" <TextView android:id="@+id/hint"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="@dimen/vpn_connect_normal_text_size" android:textSize="@dimen/vpn_connect_normal_text_size"
android:text="@string/cstor_access_dialog_hint_from_action" android:text="@string/credentials_unlock_hint"
android:layout_marginBottom="10sp" /> android:layout_marginBottom="10sp"
android:visibility="gone"/>
<TextView android:id="@+id/cstor_error" <TextView android:id="@+id/error"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" android:textColor="@color/red"
android:textStyle="bold" /> android:textStyle="bold"
android:visibility="gone"/>
<EditText android:id="@+id/cstor_password" <EditText android:id="@+id/old_password"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:password="True" android:password="True"

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="15dip">
<TextView android:id="@+id/cstor_name_credential_hint"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/vpn_connect_normal_text_size"
android:text="@string/cstor_name_credential_hint"
android:layout_marginBottom="10sp" />
<TextView android:id="@+id/cstor_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:textStyle="bold" />
<TextView android:id="@+id/cstor_credential_name_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/cstor_credential_name" />
<EditText android:id="@+id/cstor_credential_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="True"/>
<LinearLayout android:id="@+id/cstor_credential_password_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dip">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/cstor_credential_password" />
<EditText android:id="@+id/cstor_credential_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
</LinearLayout>
<TextView android:id="@+id/cstor_credential_info_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/cstor_credential_info" />
<TextView android:id="@+id/cstor_credential_info"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>

View File

@@ -2077,72 +2077,50 @@ found in the list of installed applications.</string>
<string name="vpn_secret_not_set">(not set)</string> <string name="vpn_secret_not_set">(not set)</string>
<!-- Title of preference group for credential storage settings --> <!-- Title of preference group for credential storage settings -->
<string name="cstor_settings_category">Credential storage</string> <string name="credentials_category">Credential storage</string>
<!-- Title of preference to enable/dislable access to credential storage --> <!-- Title of preference to enable/dislable access to credential storage -->
<string name="cstor_access_title">Use secure credentials</string> <string name="credentials_access">Use secure credentials</string>
<!-- Summary of preference to enable/dislable access to credential storage --> <!-- Summary of preference to enable/dislable access to credential storage -->
<string name="cstor_access_summary">Allow applications to access secure certificates and other credentials</string> <string name="credentials_access_summary">Allow applications to access secure certificates and other credentials</string>
<!-- Title of dialog to enable/dislable access to credential storage --> <!-- Title of dialog to enable/dislable access to credential storage -->
<string name="cstor_access_dialog_title">Enter password</string> <string name="credentials_unlock">Enter password</string>
<!-- Description of dialog to enable/dislable access to credential storage from an action that requires the credential storage --> <!-- Description of dialog to enable/dislable access to credential storage -->
<string name="cstor_access_dialog_hint_from_action">Enter the credential storage password.</string> <string name="credentials_unlock_hint">Enter the credential storage password.</string>
<!-- Title of preference to install certificates from SD card -->
<!-- Title of preference to install p12 cert from SD card --> <string name="credentials_install_certificates">Install from SD card</string>
<string name="cstor_cert_install_title">Install from SD card</string> <!-- Summary of preference to install certificates from SD card -->
<!-- Summary of preference to install p12 cert from SD card --> <string name="credentials_install_certificates_summary">Install encrypted certificates from SD card</string>
<string name="cstor_cert_install_summary">Install encrypted certificates from SD card</string>
<!-- Title of preference to set storage password --> <!-- Title of preference to set storage password -->
<string name="cstor_set_passwd_title">Set password</string> <string name="credentials_set_password">Set password</string>
<!-- Summary of preference to set storage password --> <!-- Summary of preference to set storage password -->
<string name="cstor_set_passwd_summary">Set or change the credential storage password</string> <string name="credentials_set_password_summary">Set or change the credential storage password</string>
<!-- Title of dialog to set storage password --> <!-- Title of preference to reset credential storage -->
<string name="cstor_set_passwd_dialog_title">Set password</string> <string name="credentials_reset">Clear storage</string>
<!-- Summary of preference to reset credential storage -->
<!-- Title of preference to reset storage --> <string name="credentials_reset_summary">Clear credential storage of all contents and reset its password</string>
<string name="cstor_reset_title">Clear storage</string> <!-- Description of dialog to reset the credential storage -->
<!-- Summary of preference to reset storage --> <string name="credentials_reset_hint">Are you sure you want to delete all credentials and reset the credential storage password?</string>
<string name="cstor_reset_summary">Clear credential storage of all contents and reset its password</string>
<string name="cstor_reset_hint">Are you sure you want to delete all credentials and reset the credential storage password?</string>
<!-- Title of dialog to name a credential -->
<string name="cstor_name_credential_dialog_title">Name the certificate</string>
<!-- Description for the credential name input box -->
<string name="cstor_credential_name">Certificate name:</string>
<!-- Title of the credential info -->
<!-- Description for the credential password input box -->
<string name="cstor_credential_password">Password to extract the certificate:</string>
<string name="cstor_credential_info">Certificate details:</string>
<string name="cstor_name_credential_hint">The name can contain only letters and numbers.</string>
<!-- Description for the old-password input box --> <!-- Description for the old-password input box -->
<string name="cstor_old_password">Current password:</string> <string name="credentials_old_password">Current password:</string>
<!-- Description for the new-password input box --> <!-- Description for the new-password input box -->
<string name="cstor_new_password">New password:</string> <string name="credentials_new_password">New password:</string>
<!-- Description for the confirm-new-password input box --> <!-- Description for the confirm-new-password input box -->
<string name="cstor_confirm_password">Confirm new password:</string> <string name="credentials_confirm_password">Confirm new password:</string>
<!-- Description when user set up the storage for the very first time --> <!-- Description when user set up the storage for the very first time -->
<string name="cstor_first_time_hint">Set a password for the credential storage (at least 8 characters).</string> <string name="credentials_first_time_hint">Set a password for the credential storage (at least 8 characters).</string>
<!-- Description when user set up the storage for the very first time from an action that requires the credential storage--> <string name="credentials_wrong_password">Please enter the correct password.</string>
<string name="cstor_first_time_hint_from_action">Set a password for the credential storage.</string> <string name="credentials_reset_warning">Please enter the correct password. You have one more try to enter the correct password before the credential storage is erased.</string>
<string name="cstor_password_error">Please enter the correct password.</string> <string name="credentials_reset_warning_plural">Please enter the correct password. You have <xliff:g id="number" example="5">%1$d</xliff:g> more tries to enter the correct password before the credential storage is erased.</string>
<string name="cstor_password_error_reset_warning">Please enter the correct password. You have one more try to enter the correct password before the credential storage is erased.</string> <string name="credentials_passwords_mismatch">Passwords do not match.</string>
<string name="cstor_password_error_reset_warning_plural">Please enter the correct password. You have <xliff:g id="number" example="5">%d</xliff:g> more tries to enter the correct password before the credential storage is erased.</string> <string name="credentials_passwords_empty">You must enter and confirm a password.</string>
<string name="cstor_passwords_error">Passwords do not match.</string> <string name="credentials_password_empty">Please enter the password.</string>
<string name="cstor_passwords_empty_error">You must enter and confirm a password.</string> <string name="credentials_password_too_short">The password must have at least 8 characters.</string>
<string name="cstor_password_empty_error">Please enter the password.</string>
<string name="cstor_password_verification_error">Please enter the password again. The password must have at least 8 characters.</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 --> <!-- toast message -->
<string name="cstor_is_enabled">Credential storage is enabled.</string> <string name="credentials_erased">The credential storage is erased.</string>
<!-- toast message --> <!-- toast message -->
<string name="cstor_is_added"><xliff:g id="credential">%s</xliff:g> is added.</string> <string name="credentials_enabled">Credential storage is enabled.</string>
<!-- toast message -->
<string name="credentials_disabled">Credential storage is disabled.</string>
<!-- Sound settings screen, setting check box label --> <!-- Sound settings screen, setting check box label -->
<string name="emergency_tone_title">Emergency tone</string> <string name="emergency_tone_title">Emergency tone</string>

View File

@@ -93,7 +93,7 @@ public class SecuritySettings extends PreferenceActivity {
private static final int CSTOR_UNLOCK_DIALOG = 3; private static final int CSTOR_UNLOCK_DIALOG = 3;
private static final int CSTOR_RESET_DIALOG = 4; private static final int CSTOR_RESET_DIALOG = 4;
private CstorHelper mCstorHelper = new CstorHelper(); private CredentialStorage mCredentialStorage = new CredentialStorage();
private CheckBoxPreference mNetwork; private CheckBoxPreference mNetwork;
private CheckBoxPreference mGps; private CheckBoxPreference mGps;
@@ -132,7 +132,7 @@ public class SecuritySettings extends PreferenceActivity {
mContentQueryMap = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, null); mContentQueryMap = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, null);
mContentQueryMap.addObserver(new SettingsObserver()); mContentQueryMap.addObserver(new SettingsObserver());
mCstorHelper.handleIntent(getIntent()); mCredentialStorage.handleIntent(getIntent());
} }
private PreferenceScreen createPreferenceHierarchy() { private PreferenceScreen createPreferenceHierarchy() {
@@ -203,10 +203,10 @@ public class SecuritySettings extends PreferenceActivity {
passwordsCat.addPreference(showPassword); passwordsCat.addPreference(showPassword);
// Credential storage // Credential storage
PreferenceCategory credStoreCat = new PreferenceCategory(this); PreferenceCategory credentialsCat = new PreferenceCategory(this);
credStoreCat.setTitle(R.string.cstor_settings_category); credentialsCat.setTitle(R.string.credentials_category);
root.addPreference(credStoreCat); root.addPreference(credentialsCat);
mCstorHelper.createPreferences(credStoreCat); mCredentialStorage.createPreferences(credentialsCat);
return root; return root;
} }
@@ -232,7 +232,7 @@ public class SecuritySettings extends PreferenceActivity {
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(), mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
mCstorHelper.resume(); mCredentialStorage.resume();
} }
@Override @Override
@@ -341,138 +341,160 @@ public class SecuritySettings extends PreferenceActivity {
@Override @Override
protected Dialog onCreateDialog(int id) { protected Dialog onCreateDialog(int id) {
switch (id) { return mCredentialStorage.createDialog(id);
case CSTOR_INIT_DIALOG:
case CSTOR_CHANGE_PASSWORD_DIALOG:
return mCstorHelper.createSetPasswordDialog(id);
case CSTOR_UNLOCK_DIALOG:
return mCstorHelper.createUnlockDialog();
case CSTOR_RESET_DIALOG:
return mCstorHelper.createResetDialog();
default:
return null;
}
} }
private class CstorHelper implements DialogInterface.OnClickListener, private class CredentialStorage implements DialogInterface.OnClickListener,
DialogInterface.OnDismissListener { DialogInterface.OnDismissListener, Preference.OnPreferenceChangeListener,
Preference.OnPreferenceClickListener {
private static final int MINIMUM_PASSWORD_LENGTH = 8;
private static final int UNLOCK_DIALOG = 1;
private static final int PASSWORD_DIALOG = 2;
private static final int RESET_DIALOG = 3;
private KeyStore mKeyStore = KeyStore.getInstance(); private KeyStore mKeyStore = KeyStore.getInstance();
private int mState; private int mState;
private View mView;
private int mDialogId; private int mDialogId;
private boolean mRetry; private boolean mSubmit;
private CheckBoxPreference mAccessCheckBox; private CheckBoxPreference mAccessCheckBox;
private Preference mInstallButton;
private Preference mPasswordButton;
private Preference mResetButton; private Preference mResetButton;
private Intent mExternalIntent; private Intent mExternalIntent;
CstorHelper() {
mState = mKeyStore.test();
}
void handleIntent(Intent intent) { void handleIntent(Intent intent) {
if (intent == null) return; if (intent != null) {
String action = intent.getAction(); if (Credentials.UNLOCK_ACTION.equals(intent.getAction())) {
mExternalIntent = intent;
if (Credentials.UNLOCK_ACTION.equals(action)) { showDialog((mState == KeyStore.UNINITIALIZED) ?
mExternalIntent = intent; PASSWORD_DIALOG : UNLOCK_DIALOG);
showCstorDialog(mState == KeyStore.UNINITIALIZED
? CSTOR_INIT_DIALOG : CSTOR_UNLOCK_DIALOG);
}
}
void resume() {
if (mExternalIntent != null) return;
updatePreferences(mKeyStore.test());
}
private void updatePreferences(int state) {
mAccessCheckBox.setEnabled(state != KeyStore.UNINITIALIZED);
mAccessCheckBox.setChecked(state == KeyStore.NO_ERROR);
mResetButton.setEnabled(state != KeyStore.UNINITIALIZED);
// Show a toast message if the state is changed.
if (mState == state) return;
if (state == KeyStore.NO_ERROR) {
Toast.makeText(SecuritySettings.this, R.string.cstor_is_enabled,
Toast.LENGTH_SHORT).show();
} else if (state == KeyStore.UNINITIALIZED) {
Toast.makeText(SecuritySettings.this, R.string.cstor_is_reset,
Toast.LENGTH_LONG).show();
}
// TODO: disabled?
mState = state;
}
private void lockCstor() {
mKeyStore.lock();
updatePreferences(KeyStore.LOCKED);
}
private int unlockCstor(String passwd) {
mKeyStore.unlock(passwd);
return mKeyStore.getLastError();
}
private int changeCstorPassword(String oldPasswd, String newPasswd) {
mKeyStore.password(oldPasswd, newPasswd);
return mKeyStore.getLastError();
}
private void initCstor(String passwd) {
mKeyStore.password(passwd);
updatePreferences(KeyStore.NO_ERROR);
}
private void resetCstor() {
mKeyStore.reset();
updatePreferences(KeyStore.UNINITIALIZED);
}
private void showCstorDialog(int dialogId) {
mDialogId = dialogId;
mRetry = false;
showDialog(dialogId);
}
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_NEGATIVE) return;
switch (mDialogId) {
case CSTOR_INIT_DIALOG:
case CSTOR_CHANGE_PASSWORD_DIALOG:
mRetry = !checkPasswords((Dialog) dialog);
break;
case CSTOR_UNLOCK_DIALOG:
mRetry = !checkPassword((Dialog) dialog);
break;
case CSTOR_RESET_DIALOG:
resetCstor();
break;
}
}
public void onDismiss(DialogInterface dialog) {
if (mRetry) {
showCstorDialog(mDialogId);
} else {
removeDialog(mDialogId);
updatePreferences(mState); // may revert checkbox
if (mExternalIntent != null) {
finish();
} }
} }
} }
// returns false if there is no error. void resume() {
private boolean checkError(int error) { mState = mKeyStore.test();
updatePreferences(mState);
}
Dialog createDialog(int id) {
mDialogId = id;
Log.v("Create", "Dialog " + id);
switch (id) {
case UNLOCK_DIALOG:
return createUnlockDialog();
case PASSWORD_DIALOG:
return createPasswordDialog();
case RESET_DIALOG:
return createResetDialog();
}
return null;
}
private void initialize(String password) {
mKeyStore.password(password);
updatePreferences(KeyStore.NO_ERROR);
}
private void reset() {
mKeyStore.reset();
updatePreferences(KeyStore.UNINITIALIZED);
}
private void lock() {
mKeyStore.lock();
updatePreferences(KeyStore.LOCKED);
}
private int unlock(String password) {
mKeyStore.unlock(password);
return mKeyStore.getLastError();
}
private int changePassword(String oldPassword, String newPassword) {
mKeyStore.password(oldPassword, newPassword);
return mKeyStore.getLastError();
}
public boolean onPreferenceChange(Preference preference, Object value) {
if (preference == mAccessCheckBox) {
if ((Boolean) value) {
showDialog((mState == KeyStore.UNINITIALIZED) ?
PASSWORD_DIALOG : UNLOCK_DIALOG);
} else {
lock();
}
return true;
}
return false;
}
public boolean onPreferenceClick(Preference preference) {
if (preference == mInstallButton) {
Credentials.getInstance().installFromSdCard(SecuritySettings.this);
} else if (preference == mPasswordButton) {
showDialog(PASSWORD_DIALOG);
} else if (preference == mResetButton) {
showDialog(RESET_DIALOG);
} else {
return false;
}
return true;
}
public void onClick(DialogInterface dialog, int button) {
mSubmit = (button == DialogInterface.BUTTON_POSITIVE);
if (button == DialogInterface.BUTTON_NEUTRAL) {
reset();
}
}
public void onDismiss(DialogInterface dialog) {
if (mSubmit && !isFinishing()) {
mSubmit = false;
if (!checkPassword((Dialog) dialog)) {
showDialog(mDialogId);
return;
}
}
removeDialog(mDialogId);
updatePreferences(mState);
if (mExternalIntent != null) {
mExternalIntent = null;
finish();
}
}
// Return true if there is no error.
private boolean checkPassword(Dialog dialog) {
String oldPassword = getText(dialog, R.id.old_password);
String newPassword = getText(dialog, R.id.new_password);
String confirmPassword = getText(dialog, R.id.confirm_password);
if (oldPassword != null && oldPassword.length() == 0) {
showError(dialog, R.string.credentials_password_empty);
return false;
} else if (newPassword == null) {
return !checkError(dialog, unlock(oldPassword));
} else if (newPassword.length() == 0 || confirmPassword.length() == 0) {
showError(dialog, R.string.credentials_passwords_empty);
} else if (newPassword.length() < MINIMUM_PASSWORD_LENGTH) {
showError(dialog, R.string.credentials_password_too_short);
} else if (!newPassword.equals(confirmPassword)) {
showError(dialog, R.string.credentials_passwords_mismatch);
} else if (oldPassword == null) {
initialize(newPassword);
return true;
} else {
return !checkError(dialog, changePassword(oldPassword, newPassword));
}
return false;
}
// Return false if there is no error.
private boolean checkError(Dialog dialog, int error) {
if (error == KeyStore.NO_ERROR) { if (error == KeyStore.NO_ERROR) {
updatePreferences(KeyStore.NO_ERROR); updatePreferences(KeyStore.NO_ERROR);
return false; return false;
@@ -486,199 +508,125 @@ public class SecuritySettings extends PreferenceActivity {
} }
int count = error - KeyStore.WRONG_PASSWORD + 1; int count = error - KeyStore.WRONG_PASSWORD + 1;
if (count > 3) { if (count > 3) {
showError(R.string.cstor_password_error); showError(dialog, R.string.credentials_wrong_password);
return true; } else if (count == 1) {
} showError(dialog, R.string.credentials_reset_warning);
TextView v = showError(R.string.cstor_password_error_reset_warning);
if (count == 1) {
v.setText(R.string.cstor_password_error_reset_warning);
} else { } else {
String format = getString( showError(dialog, R.string.credentials_reset_warning_plural, count);
R.string.cstor_password_error_reset_warning_plural);
v.setText(String.format(format, count));
} }
return true; return true;
} }
// returns true if the password is correct private String getText(Dialog dialog, int viewId) {
private boolean checkPassword(Dialog d) { TextView view = (TextView) dialog.findViewById(viewId);
hideError(); return (view == null || view.getVisibility() == View.GONE) ? null :
view.getText().toString();
String passwd = getText(R.id.cstor_password);
if (TextUtils.isEmpty(passwd)) {
showError(R.string.cstor_password_empty_error);
return false;
}
return !checkError(unlockCstor(passwd));
} }
// returns true if the passwords are correct private void showError(Dialog dialog, int stringId, Object... formatArgs) {
private boolean checkPasswords(Dialog d) { TextView view = (TextView) dialog.findViewById(R.id.error);
hideError(); if (view != null) {
if (formatArgs == null || formatArgs.length == 0) {
String oldPasswd = getText(R.id.cstor_old_password); view.setText(stringId);
String newPasswd = getText(R.id.cstor_new_password);
String confirmPasswd = getText(R.id.cstor_confirm_password);
if ((mDialogId == CSTOR_CHANGE_PASSWORD_DIALOG)
&& TextUtils.isEmpty(oldPasswd)) {
showError(R.string.cstor_password_empty_error);
} else if (TextUtils.isEmpty(newPasswd)
|| TextUtils.isEmpty(confirmPasswd)) {
showError(R.string.cstor_passwords_empty_error);
} else if (newPasswd.length() < CSTOR_MIN_PASSWORD_LENGTH) {
showError(R.string.cstor_password_verification_error);
} else if (!newPasswd.equals(confirmPasswd)) {
showError(R.string.cstor_passwords_error);
} else {
if (mDialogId == CSTOR_CHANGE_PASSWORD_DIALOG) {
return !checkError(changeCstorPassword(oldPasswd, newPasswd));
} else { } else {
initCstor(newPasswd); view.setText(dialog.getContext().getString(stringId, formatArgs));
return true;
} }
view.setVisibility(View.VISIBLE);
} }
return false;
}
private TextView showError(int messageId) {
TextView v = (TextView) mView.findViewById(R.id.cstor_error);
v.setText(messageId);
if (v != null) v.setVisibility(View.VISIBLE);
return v;
}
private void hideError() {
hide(R.id.cstor_error);
}
private void hide(int viewId) {
View v = mView.findViewById(viewId);
if (v != null) v.setVisibility(View.GONE);
}
private String getText(int viewId) {
return ((TextView) mView.findViewById(viewId)).getText().toString();
} }
private void createPreferences(PreferenceCategory category) { private void createPreferences(PreferenceCategory category) {
mAccessCheckBox = new CheckBoxPreference(SecuritySettings.this); mAccessCheckBox = new CheckBoxPreference(SecuritySettings.this);
mAccessCheckBox.setTitle(R.string.cstor_access_title); mAccessCheckBox.setTitle(R.string.credentials_access);
mAccessCheckBox.setSummary(R.string.cstor_access_summary); mAccessCheckBox.setSummary(R.string.credentials_access_summary);
mAccessCheckBox.setOnPreferenceChangeListener( mAccessCheckBox.setOnPreferenceChangeListener(this);
new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(
Preference pref, Object value) {
if (((Boolean) value)) {
showCstorDialog(CSTOR_UNLOCK_DIALOG);
} else {
lockCstor();
}
return true;
}
});
category.addPreference(mAccessCheckBox); category.addPreference(mAccessCheckBox);
Preference install = new Preference(SecuritySettings.this); mInstallButton = new Preference(SecuritySettings.this);
install.setTitle(R.string.cstor_cert_install_title); mInstallButton.setTitle(R.string.credentials_install_certificates);
install.setSummary(R.string.cstor_cert_install_summary); mInstallButton.setSummary(R.string.credentials_install_certificates_summary);
install.setOnPreferenceClickListener( mInstallButton.setOnPreferenceClickListener(this);
new Preference.OnPreferenceClickListener() { category.addPreference(mInstallButton);
public boolean onPreferenceClick(Preference pref) {
Credentials.getInstance().installFromSdCard(
SecuritySettings.this);
return true;
}
});
category.addPreference(install);
Preference password = new Preference(SecuritySettings.this); mPasswordButton = new Preference(SecuritySettings.this);
password.setTitle(R.string.cstor_set_passwd_title); mPasswordButton.setTitle(R.string.credentials_set_password);
password.setSummary(R.string.cstor_set_passwd_summary); mPasswordButton.setSummary(R.string.credentials_set_password_summary);
password.setOnPreferenceClickListener( mPasswordButton.setOnPreferenceClickListener(this);
new Preference.OnPreferenceClickListener() { category.addPreference(mPasswordButton);
public boolean onPreferenceClick(Preference pref) {
showCstorDialog(mState == KeyStore.UNINITIALIZED
? CSTOR_INIT_DIALOG
: CSTOR_CHANGE_PASSWORD_DIALOG);
return true;
}
});
category.addPreference(password);
mResetButton = new Preference(SecuritySettings.this); mResetButton = new Preference(SecuritySettings.this);
mResetButton.setTitle(R.string.cstor_reset_title); mResetButton.setTitle(R.string.credentials_reset);
mResetButton.setSummary(R.string.cstor_reset_summary); mResetButton.setSummary(R.string.credentials_reset_summary);
mResetButton.setOnPreferenceClickListener( mResetButton.setOnPreferenceClickListener(this);
new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference pref) {
showCstorDialog(CSTOR_RESET_DIALOG);
return true;
}
});
category.addPreference(mResetButton); category.addPreference(mResetButton);
}
updatePreferences(mState); private void updatePreferences(int state) {
mAccessCheckBox.setEnabled(state != KeyStore.UNINITIALIZED);
mAccessCheckBox.setChecked(state == KeyStore.NO_ERROR);
mResetButton.setEnabled(state != KeyStore.UNINITIALIZED);
// Show a toast message if the state is changed.
if (mState == state) return;
if (state == KeyStore.NO_ERROR) {
Toast.makeText(SecuritySettings.this, R.string.credentials_enabled,
Toast.LENGTH_SHORT).show();
} else if (state == KeyStore.UNINITIALIZED) {
Toast.makeText(SecuritySettings.this, R.string.credentials_erased,
Toast.LENGTH_SHORT).show();
} else if (state == KeyStore.LOCKED) {
Toast.makeText(SecuritySettings.this, R.string.credentials_disabled,
Toast.LENGTH_SHORT).show();
}
mState = state;
} }
private Dialog createUnlockDialog() { private Dialog createUnlockDialog() {
mView = View.inflate(SecuritySettings.this, View view = View.inflate(SecuritySettings.this,
R.layout.cstor_unlock_dialog_view, null); R.layout.credentials_unlock_dialog, null);
hideError();
// show extra hint only when the action comes from outside // show extra hint only when the action comes from outside
if (mExternalIntent == null) { if (mExternalIntent != null) {
hide(R.id.cstor_access_dialog_hint_from_action); view.findViewById(R.id.hint).setVisibility(View.VISIBLE);
} }
Dialog d = new AlertDialog.Builder(SecuritySettings.this) Dialog dialog = new AlertDialog.Builder(SecuritySettings.this)
.setView(mView) .setView(view)
.setTitle(R.string.cstor_access_dialog_title) .setTitle(R.string.credentials_unlock)
.setPositiveButton(android.R.string.ok, this) .setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this) .setNegativeButton(android.R.string.cancel, this)
.create(); .create();
d.setOnDismissListener(this); dialog.setOnDismissListener(this);
return d; return dialog;
} }
private Dialog createSetPasswordDialog(int id) { private Dialog createPasswordDialog() {
mView = View.inflate(SecuritySettings.this, View view = View.inflate(SecuritySettings.this,
R.layout.cstor_set_password_dialog_view, null); R.layout.credentials_password_dialog, null);
hideError();
switch (id) { if (mState == KeyStore.UNINITIALIZED) {
case CSTOR_INIT_DIALOG: view.findViewById(R.id.hint).setVisibility(View.VISIBLE);
mView.findViewById(R.id.cstor_old_password_block) } else {
.setVisibility(View.GONE); view.findViewById(R.id.old_password_prompt).setVisibility(View.VISIBLE);
break; view.findViewById(R.id.old_password).setVisibility(View.VISIBLE);
case CSTOR_CHANGE_PASSWORD_DIALOG:
mView.findViewById(R.id.cstor_first_time_hint)
.setVisibility(View.GONE);
break;
default:
throw new RuntimeException(
"Unknown dialog id: " + mDialogId);
} }
Dialog d = new AlertDialog.Builder(SecuritySettings.this) Dialog dialog = new AlertDialog.Builder(SecuritySettings.this)
.setView(mView) .setView(view)
.setTitle(R.string.cstor_set_passwd_dialog_title) .setTitle(R.string.credentials_set_password)
.setPositiveButton(android.R.string.ok, this) .setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this) .setNegativeButton(android.R.string.cancel, this)
.create(); .create();
d.setOnDismissListener(this); dialog.setOnDismissListener(this);
return d; return dialog;
} }
private Dialog createResetDialog() { private Dialog createResetDialog() {
return new AlertDialog.Builder(SecuritySettings.this) return new AlertDialog.Builder(SecuritySettings.this)
.setTitle(android.R.string.dialog_alert_title) .setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert) .setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.cstor_reset_hint) .setMessage(R.string.credentials_reset_hint)
.setPositiveButton(getString(android.R.string.ok), this) .setNeutralButton(getString(android.R.string.ok), this)
.setNegativeButton(getString(android.R.string.cancel), this) .setNegativeButton(getString(android.R.string.cancel), this)
.create(); .create();
} }