am 7031ab0d: Add credential storage settings.

Merge commit '7031ab0d756327496ac3ce1e082b53c94be2f3b1'

* commit '7031ab0d756327496ac3ce1e082b53c94be2f3b1':
  Add credential storage settings.
This commit is contained in:
Hung-ying Tyan
2009-07-06 11:21:57 -07:00
committed by The Android Open Source Project
7 changed files with 737 additions and 13 deletions

View File

@@ -0,0 +1,58 @@
<?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"/>
<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

@@ -0,0 +1,76 @@
<?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_first_time_hint"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/vpn_connect_normal_text_size"
android:text="@string/cstor_first_time_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"
android:text="@string/cstor_password_empty_error" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/cstor_old_password_block"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
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"
android:layout_height="wrap_content"
android:text="@string/cstor_new_password" />
<EditText android:id="@+id/cstor_new_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/cstor_confirm_password" />
<EditText android:id="@+id/cstor_confirm_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,40 @@
<?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_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:textStyle="bold" />
<EditText android:id="@+id/cstor_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
</LinearLayout>
</ScrollView>

View File

@@ -16,5 +16,6 @@
<resources> <resources>
<color name="black">#000</color> <color name="black">#000</color>
<color name="red">#F00</color>
</resources> </resources>

View File

@@ -1950,11 +1950,13 @@ found in the list of installed applications.</string>
<string name="cstor_access_title">Use secure credentials</string> <string name="cstor_access_title">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="cstor_access_summary">Allow applications to access secure certificates and other credentials</string>
<!-- Title of dialog to enable/dislable access to credential storage -->
<string name="cstor_access_dialog_title">Enter password</string>
<!-- Title of preference to set storage password --> <!-- Title of preference to set storage password -->
<string name="cstor_set_passwd_title">Set storage password</string> <string name="cstor_set_passwd_title">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 secure credential storage password</string> <string name="cstor_set_passwd_summary">Set or change the credential storage password</string>
<!-- Title of dialog to set storage password --> <!-- Title of dialog to set storage password -->
<string name="cstor_set_passwd_dialog_title">Set password</string> <string name="cstor_set_passwd_dialog_title">Set password</string>
@@ -1962,7 +1964,16 @@ found in the list of installed applications.</string>
<string name="cstor_reset_title">Clear storage</string> <string name="cstor_reset_title">Clear storage</string>
<!-- Summary of preference to reset storage --> <!-- Summary of preference to reset storage -->
<string name="cstor_reset_summary">Clear credential storage of all contents and reset its 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 certificates and other stored credentials and reset the 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 -->
<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="cstor_old_password">Current password:</string>
@@ -1971,9 +1982,21 @@ found in the list of installed applications.</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="cstor_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">You must set a password for credential storage before you can store secure certificates and other credentials in it.</string> <string name="cstor_first_time_hint">You must set a password for the credential storage.</string>
<string name="cstor_password_error">Passwords do not match.</string> <string name="cstor_password_error">Please enter the correct password.</string>
<string name="cstor_password_empty_error">Please fill up all the fields.</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="cstor_password_error_reset_warning_plural">Please enter the correct password. You have %d more tries to enter the correct password before the credential storage is erased.</string>
<string name="cstor_passwords_error">Passwords do not match.</string>
<string name="cstor_passwords_empty_error">You must enter and confirm a password.</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 and must not contain spaces.</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>
<!-- toast message -->
<string name="cstor_is_enabled">Credential storage is enabled.</string>
<!-- toast message -->
<string name="cstor_is_added">%s is added.</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

@@ -30,18 +30,26 @@ import android.database.Cursor;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup; import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.provider.Settings; import android.provider.Settings;
import android.security.Keystore;
import android.text.Html;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
@@ -72,6 +80,25 @@ public class SecuritySettings extends PreferenceActivity implements
private static final String LOCATION_GPS = "location_gps"; private static final String LOCATION_GPS = "location_gps";
private static final String ASSISTED_GPS = "assisted_gps"; private static final String ASSISTED_GPS = "assisted_gps";
// Credential storage
private static final String ACTION_ADD_CREDENTIAL =
"android.security.ADD_CREDENTIAL";
private static final String ACTION_UNLOCK_CREDENTIAL_STORAGE =
"android.security.UNLOCK_CREDENTIAL_STORAGE";
private static final String KEY_CSTOR_TYPE_NAME = "typeName";
private static final String KEY_CSTOR_ITEM = "item";
private static final String KEY_CSTOR_NAMESPACE = "namespace";
private static final String KEY_CSTOR_DESCRIPTION = "description";
private static final int CSTOR_MIN_PASSWORD_LENGTH = 8;
private static final int CSTOR_INIT_DIALOG = 1;
private static final int CSTOR_CHANGE_PASSWORD_DIALOG = 2;
private static final int CSTOR_UNLOCK_DIALOG = 3;
private static final int CSTOR_RESET_DIALOG = 4;
private static final int CSTOR_NAME_CREDENTIAL_DIALOG = 5;
private CstorHelper mCstorHelper = new CstorHelper();
// Vendor specific // Vendor specific
private static final String GSETTINGS_PROVIDER = "com.google.android.providers.settings"; private static final String GSETTINGS_PROVIDER = "com.google.android.providers.settings";
private static final String USE_LOCATION = "use_location"; private static final String USE_LOCATION = "use_location";
@@ -131,6 +158,8 @@ public class SecuritySettings extends PreferenceActivity implements
if (getIntent().getBooleanExtra("SHOW_USE_LOCATION", false) && !doneUseLocation) { if (getIntent().getBooleanExtra("SHOW_USE_LOCATION", false) && !doneUseLocation) {
showUseLocationDialog(true); showUseLocationDialog(true);
} }
mCstorHelper.handleCstorIntents(getIntent());
} }
private PreferenceScreen createPreferenceHierarchy() { private PreferenceScreen createPreferenceHierarchy() {
@@ -200,6 +229,14 @@ public class SecuritySettings extends PreferenceActivity implements
showPassword.setPersistent(false); showPassword.setPersistent(false);
passwordsCat.addPreference(showPassword); passwordsCat.addPreference(showPassword);
// Credential storage
PreferenceCategory credStoreCat = new PreferenceCategory(this);
credStoreCat.setTitle(R.string.cstor_settings_category);
root.addPreference(credStoreCat);
credStoreCat.addPreference(mCstorHelper.createAccessCheckBox());
credStoreCat.addPreference(mCstorHelper.createSetPasswordPreference());
credStoreCat.addPreference(mCstorHelper.createResetPreference());
return root; return root;
} }
@@ -395,4 +432,491 @@ public class SecuritySettings extends PreferenceActivity implements
mUseLocation.setChecked(false); mUseLocation.setChecked(false);
} }
} }
@Override
protected Dialog onCreateDialog (int id) {
switch (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();
case CSTOR_NAME_CREDENTIAL_DIALOG:
return mCstorHelper.createNameCredentialDialog();
default:
return null;
}
}
private class CstorHelper implements
DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
private Keystore mKeystore = Keystore.getInstance();
private View mView;
private int mDialogId;
private boolean mConfirm = true;
private CheckBoxPreference mAccessCheckBox;
private Preference mResetButton;
private Intent mSpecialIntent;
private CstorAddCredentialHelper mCstorAddCredentialHelper;
void handleCstorIntents(Intent intent) {
if (intent == null) return;
String action = intent.getAction();
if (ACTION_ADD_CREDENTIAL.equals(action)) {
mCstorAddCredentialHelper = new CstorAddCredentialHelper(intent);
showDialog(CSTOR_NAME_CREDENTIAL_DIALOG);
} else if (ACTION_UNLOCK_CREDENTIAL_STORAGE.equals(action)) {
mSpecialIntent = intent;
showDialog(mCstorHelper.isCstorInitialized()
? CSTOR_UNLOCK_DIALOG
: CSTOR_INIT_DIALOG);
}
}
private boolean isCstorUnlocked() {
return (mKeystore.getState() == Keystore.UNLOCKED);
}
private boolean isCstorInitialized() {
return (mKeystore.getState() != Keystore.UNINITIALIZED);
}
private void lockCstor() {
mKeystore.lock();
mAccessCheckBox.setChecked(false);
}
private int unlockCstor(String passwd) {
int ret = mKeystore.unlock(passwd);
if (ret == -1) resetCstor();
if (ret == 0) {
Toast.makeText(SecuritySettings.this, R.string.cstor_is_enabled,
Toast.LENGTH_SHORT).show();
}
return ret;
}
private int changeCstorPassword(String oldPasswd, String newPasswd) {
int ret = mKeystore.changePassword(oldPasswd, newPasswd);
if (ret == -1) resetCstor();
return ret;
}
private void initCstor(String passwd) {
mKeystore.setPassword(passwd);
enablePreferences(true);
mAccessCheckBox.setChecked(true);
Toast.makeText(SecuritySettings.this, R.string.cstor_is_enabled,
Toast.LENGTH_SHORT).show();
}
private void resetCstor() {
mKeystore.reset();
enablePreferences(false);
mAccessCheckBox.setChecked(false);
}
private void addCredential() {
String message = String.format(getString(R.string.cstor_is_added),
mCstorAddCredentialHelper.getName());
Toast.makeText(SecuritySettings.this, message, Toast.LENGTH_SHORT)
.show();
}
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_NEGATIVE) {
if (mCstorAddCredentialHelper != null) finish();
return;
}
switch (mDialogId) {
case CSTOR_INIT_DIALOG:
case CSTOR_CHANGE_PASSWORD_DIALOG:
mConfirm = checkPasswords((Dialog) dialog);
break;
case CSTOR_UNLOCK_DIALOG:
mConfirm = checkUnlockPassword((Dialog) dialog);
break;
case CSTOR_RESET_DIALOG:
resetCstor();
break;
case CSTOR_NAME_CREDENTIAL_DIALOG:
mConfirm = checkAddCredential();
break;
}
}
public void onDismiss(DialogInterface dialog) {
if (!mConfirm) {
mConfirm = true;
showDialog(mDialogId);
} else {
removeDialog(mDialogId);
if (mCstorAddCredentialHelper != null) {
if (!isCstorInitialized()) {
showDialog(CSTOR_INIT_DIALOG);
} else if (!isCstorUnlocked()) {
showDialog(CSTOR_UNLOCK_DIALOG);
} else {
addCredential();
finish();
}
} else if (mSpecialIntent != null) {
finish();
}
}
}
private void showResetWarning(int count) {
TextView v = showError(count <= 3
? R.string.cstor_password_error_reset_warning
: R.string.cstor_password_error);
if (count <= 3) {
if (count == 1) {
v.setText(getString(
R.string.cstor_password_error_reset_warning));
} else {
String format = getString(
R.string.cstor_password_error_reset_warning_plural);
v.setText(String.format(format, count));
}
}
}
private boolean checkAddCredential() {
hideError();
String name = getText(R.id.cstor_credential_name);
if (TextUtils.isEmpty(name)) {
showError(R.string.cstor_name_empty_error);
return false;
}
for (int i = 0, len = name.length(); i < len; i++) {
if (!Character.isLetterOrDigit(name.charAt(i))) {
showError(R.string.cstor_name_char_error);
return false;
}
}
mCstorAddCredentialHelper.setName(name);
return true;
}
// returns true if the password is long enough and does not contain
// characters that we don't like
private boolean verifyPassword(String passwd) {
if (passwd == null) {
showError(R.string.cstor_passwords_empty_error);
return false;
} else if ((passwd.length() < CSTOR_MIN_PASSWORD_LENGTH)
|| passwd.contains(" ")) {
showError(R.string.cstor_password_verification_error);
return false;
} else {
return true;
}
}
// returns true if the password is ok
private boolean checkUnlockPassword(Dialog d) {
hideError();
String passwd = getText(R.id.cstor_password);
if (TextUtils.isEmpty(passwd)) {
showError(R.string.cstor_password_empty_error);
return false;
}
int count = unlockCstor(passwd);
if (count > 0) {
showResetWarning(count);
return false;
} else {
// done or reset
return true;
}
}
// returns true if the passwords are ok
private boolean checkPasswords(Dialog d) {
hideError();
String oldPasswd = getText(R.id.cstor_old_password);
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);
return false;
}
if (TextUtils.isEmpty(newPasswd)
&& TextUtils.isEmpty(confirmPasswd)) {
showError(R.string.cstor_passwords_empty_error);
return false;
}
if (!verifyPassword(newPasswd)) {
return false;
} else if (!newPasswd.equals(confirmPasswd)) {
showError(R.string.cstor_passwords_error);
return false;
}
if (mDialogId == CSTOR_CHANGE_PASSWORD_DIALOG) {
int count = changeCstorPassword(oldPasswd, newPasswd);
if (count > 0) {
showResetWarning(count);
return false;
} else {
// done or reset
return true;
}
} else {
initCstor(newPasswd);
return true;
}
}
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() {
View v = mView.findViewById(R.id.cstor_error);
if (v != null) v.setVisibility(View.GONE);
}
private String getText(int viewId) {
return ((TextView) mView.findViewById(viewId)).getText().toString();
}
private void setText(int viewId, String text) {
TextView v = (TextView) mView.findViewById(viewId);
if (v != null) v.setText(text);
}
private void enablePreferences(boolean enabled) {
mAccessCheckBox.setEnabled(enabled);
mResetButton.setEnabled(enabled);
}
private Preference createAccessCheckBox() {
CheckBoxPreference pref = new CheckBoxPreference(
SecuritySettings.this);
pref.setTitle(R.string.cstor_access_title);
pref.setSummary(R.string.cstor_access_summary);
pref.setChecked(isCstorUnlocked());
pref.setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(
Preference pref, Object value) {
if (((Boolean) value)) {
showDialog(isCstorInitialized()
? CSTOR_UNLOCK_DIALOG
: CSTOR_INIT_DIALOG);
} else {
lockCstor();
}
return true;
}
});
pref.setEnabled(isCstorInitialized());
mAccessCheckBox = pref;
return pref;
}
private Preference createSetPasswordPreference() {
Preference pref = new Preference(SecuritySettings.this);
pref.setTitle(R.string.cstor_set_passwd_title);
pref.setSummary(R.string.cstor_set_passwd_summary);
pref.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference pref) {
showDialog(isCstorInitialized()
? CSTOR_CHANGE_PASSWORD_DIALOG
: CSTOR_INIT_DIALOG);
return true;
}
});
return pref;
}
private Preference createResetPreference() {
Preference pref = new Preference(SecuritySettings.this);
pref.setTitle(R.string.cstor_reset_title);
pref.setSummary(R.string.cstor_reset_summary);
pref.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference pref) {
showDialog(CSTOR_RESET_DIALOG);
return true;
}
});
pref.setEnabled(isCstorInitialized());
mResetButton = pref;
return pref;
}
private Dialog createUnlockDialog() {
mDialogId = CSTOR_UNLOCK_DIALOG;
mView = View.inflate(SecuritySettings.this,
R.layout.cstor_unlock_dialog_view, null);
hideError();
Dialog d = new AlertDialog.Builder(SecuritySettings.this)
.setView(mView)
.setTitle(R.string.cstor_access_dialog_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.setCancelable(false)
.create();
d.setOnDismissListener(this);
return d;
}
private Dialog createSetPasswordDialog(int id) {
mDialogId = id;
mView = View.inflate(SecuritySettings.this,
R.layout.cstor_set_password_dialog_view, null);
hideError();
switch (id) {
case CSTOR_INIT_DIALOG:
mView.findViewById(R.id.cstor_old_password_block)
.setVisibility(View.GONE);
break;
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)
.setView(mView)
.setTitle(R.string.cstor_set_passwd_dialog_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.setCancelable(false)
.create();
d.setOnDismissListener(this);
return d;
}
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)
.setMessage(R.string.cstor_reset_hint)
.setPositiveButton(getString(android.R.string.ok), this)
.setNegativeButton(getString(android.R.string.cancel), this)
.create();
}
private Dialog createNameCredentialDialog() {
mDialogId = CSTOR_NAME_CREDENTIAL_DIALOG;
mView = View.inflate(SecuritySettings.this,
R.layout.cstor_name_credential_dialog_view, null);
hideError();
setText(R.id.cstor_credential_name_title,
getString(R.string.cstor_credential_name));
setText(R.id.cstor_credential_info_title,
getString(R.string.cstor_credential_info));
setText(R.id.cstor_credential_info,
mCstorAddCredentialHelper.getDescription().toString());
Dialog d = new AlertDialog.Builder(SecuritySettings.this)
.setView(mView)
.setTitle(R.string.cstor_name_credential_dialog_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.setCancelable(false)
.create();
d.setOnDismissListener(this);
return d;
}
}
private class CstorAddCredentialHelper {
private String mTypeName;
private List<byte[]> mItemList;
private List<String> mNamespaceList;
private String mDescription;
private String mName;
CstorAddCredentialHelper(Intent intent) {
parse(intent);
}
String getTypeName() {
return mTypeName;
}
byte[] getItem(int i) {
return mItemList.get(i);
}
String getNamespace(int i) {
return mNamespaceList.get(i);
}
CharSequence getDescription() {
return Html.fromHtml(mDescription);
}
void setName(String name) {
mName = name;
}
String getName() {
return mName;
}
private void parse(Intent intent) {
mTypeName = intent.getStringExtra(KEY_CSTOR_TYPE_NAME);
mItemList = new ArrayList<byte[]>();
mNamespaceList = new ArrayList<String>();
for (int i = 0; ; i++) {
byte[] blob = intent.getByteArrayExtra(KEY_CSTOR_ITEM + i);
if (blob == null) break;
mItemList.add(blob);
mNamespaceList.add(intent.getStringExtra(
KEY_CSTOR_NAMESPACE + i));
}
// build description string
StringBuilder sb = new StringBuilder();
for (int i = 0; ; i++) {
String s = intent.getStringExtra(KEY_CSTOR_DESCRIPTION + i);
if (s == null) break;
sb.append(s).append("<br>");
}
mDescription = sb.toString();
}
}
} }

View File

@@ -407,6 +407,7 @@ public class VpnSettings extends PreferenceActivity implements
}; };
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle(android.R.string.dialog_alert_title) .setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.vpn_confirm_profile_deletion) .setMessage(R.string.vpn_confirm_profile_deletion)
.setPositiveButton(android.R.string.ok, onClickListener) .setPositiveButton(android.R.string.ok, onClickListener)
.setNegativeButton(R.string.vpn_no_button, onClickListener) .setNegativeButton(R.string.vpn_no_button, onClickListener)
@@ -539,6 +540,7 @@ public class VpnSettings extends PreferenceActivity implements
private void showReconnectDialog(final VpnProfile p) { private void showReconnectDialog(final VpnProfile p) {
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle(android.R.string.dialog_alert_title) .setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.vpn_confirm_reconnect) .setMessage(R.string.vpn_confirm_reconnect)
.setPositiveButton(R.string.vpn_yes_button, .setPositiveButton(R.string.vpn_yes_button,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {