Extract credential storage dialogs to a new activity.

Since now SecuritySettings is a fragment, not an activity, reacting
to intents is not easier anymore. The new activity is transparent,
and it works just like a dialog. This change also refactor'ed
SecuritySettings by moving some preference construction into
security_settings_misc.xml.

Bug: 3120992
Bug: 2117436
Change-Id: I8bd3fc7faa2a31d100b8d67310f9266260cfc31d
This commit is contained in:
Chia-chi Yeh
2011-01-20 18:46:01 +08:00
parent 9b37821d67
commit 91d65a20af
9 changed files with 505 additions and 610 deletions

View File

@@ -626,14 +626,6 @@
android:resource="@id/security_settings" />
</activity>
<activity android:name="CredentialInstaller"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.credentials.SYSTEM_INSTALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="Settings$PrivacySettingsActivity"
android:theme="@android:style/Theme.Holo"
android:label="@string/privacy_settings_title"
@@ -651,6 +643,18 @@
android:resource="@id/privacy_settings" />
</activity>
<activity android:name="CredentialStorage"
android:theme="@style/Transparent"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="com.android.credentials.UNLOCK" />
<action android:name="com.android.credentials.INSTALL" />
<action android:name="com.android.credentials.SET_PASSWORD" />
<action android:name="com.android.credentials.RESET" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="DeviceAdminSettings"
android:label="@string/device_admin_settings_title"
android:theme="@style/TallTitleBarTheme"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
<!-- Copyright (C) 2011 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.
@@ -18,7 +18,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -27,14 +27,12 @@
<TextView android:id="@+id/hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/vpn_connect_normal_text_size"
android:text="@string/credentials_first_time_hint"
android:layout_marginBottom="10sp"
android:visibility="gone"/>
android:layout_marginBottom="10sp"/>
<TextView android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10sp"
android:textColor="@color/red"
android:textStyle="bold"
android:visibility="gone"/>
@@ -44,30 +42,39 @@
android:layout_height="wrap_content"
android:text="@string/credentials_old_password"
android:visibility="gone"/>
<EditText android:id="@+id/old_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"
android:password="true"
android:singleLine="true"
android:visibility="gone"/>
<LinearLayout android:id="@+id/new_passwords"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/credentials_new_password" />
android:text="@string/credentials_new_password"/>
<EditText android:id="@+id/new_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
android:password="true"
android:singleLine="true"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/credentials_confirm_password" />
android:text="@string/credentials_confirm_password"/>
<EditText android:id="@+id/confirm_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
android:password="true"
android:singleLine="true"/>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -1,49 +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="match_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dip">
<TextView android:id="@+id/hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/vpn_connect_normal_text_size"
android:text="@string/credentials_unlock_hint"
android:layout_marginBottom="10sp"
android:visibility="gone"/>
<TextView android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:textStyle="bold"
android:visibility="gone"/>
<EditText android:id="@+id/old_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:password="True"
android:singleLine="True"/>
</LinearLayout>
</ScrollView>

View File

@@ -2830,55 +2830,55 @@ found in the list of installed applications.</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="credentials_category">Credential storage</string>
<!-- Title of preference to enable/dislable access to credential storage -->
<!-- Title of preference group for credential storage settings [CHAR LIMIT=30] -->
<string name="credentials_title">Credential storage</string>
<!-- Title of preference to enable/dislable access to credential storage [CHAR LIMIT=30] -->
<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 [CHAR LIMIT=NONE] -->
<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 -->
<string name="credentials_unlock">Enter password</string>
<!-- Description of dialog to enable/dislable access to credential storage -->
<string name="credentials_unlock_hint">Enter the credential storage password.</string>
<!-- Title of preference to install certificates from SD card [CHAR LIMIT=25] -->
<string name="credentials_install_certificates" product="nosdcard">Install from USB storage</string>
<!-- Title of preference to install certificates from SD card -->
<string name="credentials_install_certificates" product="default">Install from SD card</string>
<!-- Summary of preference to install certificates from SD card [CHAR LIMIT=25] -->
<string name="credentials_install_certificates_summary" product="nosdcard">Install encrypted certificates from USB storage</string>
<!-- Summary of preference to install certificates from SD card -->
<string name="credentials_install_certificates_summary" product="default">Install encrypted certificates from SD card</string>
<!-- Title of preference to set storage password -->
<!-- Title of preference to install certificates from SD card [CHAR LIMIT=30] -->
<string name="credentials_install" product="nosdcard">Install from USB storage</string>
<!-- Title of preference to install certificates from SD card [CHAR LIMIT=30] -->
<string name="credentials_install" product="default">Install from SD card</string>
<!-- Summary of preference to install certificates from SD card [CHAR LIMIT=NONE] -->
<string name="credentials_install_summary" product="nosdcard">Install certificates from USB storage</string>
<!-- Summary of preference to install certificates from SD card [CHAR LIMIT=NONE] -->
<string name="credentials_install_summary" product="default">Install certificates from SD card</string>
<!-- Title of preference to set the password for credential storage [CHAR LIMIT=30] -->
<string name="credentials_set_password">Set password</string>
<!-- Summary of preference to set storage password -->
<string name="credentials_set_password_summary">Set or change the credential storage password</string>
<!-- Title of preference to reset credential storage -->
<string name="credentials_reset">Clear storage</string>
<!-- Summary of preference to reset credential storage -->
<string name="credentials_reset_summary">Clear credential storage of all contents and reset its password</string>
<!-- Description of dialog to reset the credential storage -->
<string name="credentials_reset_hint">Are you sure you want to delete all credentials and reset the credential storage password?</string>
<!-- Description for the old-password input box -->
<!-- Summary of preference to set the password for credential storage [CHAR LIMIT=NONE] -->
<string name="credentials_set_password_summary">Set or change the password for credential storage</string>
<!-- Title of preference to reset credential storage [CHAR LIMIT=30] -->
<string name="credentials_reset">Clear credentials</string>
<!-- Summary of preference to reset credential storage [CHAR LIMIT=NONE] -->
<string name="credentials_reset_summary">Remove all the contents and reset the password</string>
<!-- Title of dialog to enable credential storage [CHAR LIMIT=30] -->
<string name="credentials_unlock">Enter password</string>
<!-- Description of dialog to enable credential storage [CHAR LIMIT=NONE] -->
<string name="credentials_unlock_hint">Enter the password for credential storage.</string>
<!-- Description of dialog to set the password for credential storage [CHAR LIMIT=NONE] -->
<string name="credentials_password_hint">Set the password for credential storage. It must have at least 8 characters.</string>
<!-- Description of the input box for the old password [CHAR LIMIT=30] -->
<string name="credentials_old_password">Current password:</string>
<!-- Description for the new-password input box -->
<!-- Description of the input box for the new password [CHAR LIMIT=30] -->
<string name="credentials_new_password">New password:</string>
<!-- Description for the confirm-new-password input box -->
<!-- Description of the input box to confirm the new password [CHAR LIMIT=30] -->
<string name="credentials_confirm_password">Confirm new password:</string>
<!-- Description when user set up the storage for the very first time -->
<string name="credentials_first_time_hint">Set a password for the credential storage (at least 8 characters).</string>
<string name="credentials_wrong_password">Please enter the correct password.</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="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>
<!-- Description of dialog to reset credential storage [CHAR LIMIT=NONE] -->
<string name="credentials_reset_hint">All the contents will be removed, and the password will be reset. Are you sure about that?</string>
<!-- Error message [CHAR LIMIT=NONE] -->
<string name="credentials_passwords_mismatch">Passwords do not match.</string>
<string name="credentials_passwords_empty">You must enter and confirm a password.</string>
<string name="credentials_password_empty">Please enter the password.</string>
<string name="credentials_password_too_short">The password must have at least 8 characters.</string>
<!-- toast message -->
<string name="credentials_erased">The credential storage is erased.</string>
<!-- toast message -->
<!-- Error message [CHAR LIMIT=NONE] -->
<string name="credentials_wrong_password">Incorrect password.</string>
<!-- Error message [CHAR LIMIT=NONE] -->
<string name="credentials_reset_warning">Incorrect password. You have one more chance before credential storage is erased.</string>
<!-- Error message [CHAR LIMIT=NONE] -->
<string name="credentials_reset_warning_plural">Incorrect password. You have <xliff:g id="number" example="5">%1$d</xliff:g> more chances before credential storage is erased.</string>
<!-- Toast message [CHAR LIMIT=30] -->
<string name="credentials_erased">Credential storage is erased.</string>
<!-- Toast message [CHAR LIMIT=30] -->
<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 -->
<string name="emergency_tone_title">Emergency tone</string>

View File

@@ -114,4 +114,10 @@
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
<style name="Transparent">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
</style>
</resources>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:key="sim_lock"
android:title="@string/sim_lock_settings_title"
android:persistent="false">
<Preference android:title="@string/sim_lock_settings_category"
android:persistent="false">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.IccLockSettings"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory android:title="@string/security_passwords_title"
android:persistent="false">
<CheckBoxPreference android:key="show_password"
android:title="@string/show_password"
android:summary="@string/show_password_summary"
android:persistent="false"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/device_admin_title"
android:persistent="false">
<Preference android:title="@string/manage_device_admin"
android:summary="@string/manage_device_admin_summary"
android:persistent="false">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.DeviceAdminSettings"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory android:title="@string/credentials_title"
android:persistent="false">
<CheckBoxPreference android:key="enable_credentials"
android:title="@string/credentials_access"
android:summary="@string/credentials_access_summary"
android:persistent="false"/>
<Preference android:title="@string/credentials_install"
android:summary="@string/credentials_install_summary"
android:persistent="false">
<intent android:action="android.credentials.INSTALL"
android:targetPackage="com.android.certinstaller"
android:targetClass="com.android.certinstaller.CertInstallerMain"/>
</Preference>
<Preference android:title="@string/credentials_set_password"
android:summary="@string/credentials_set_password_summary"
android:persistent="false">
<intent android:action="com.android.credentials.SET_PASSWORD"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.CredentialStorage"/>
</Preference>
<Preference android:key="reset_credentials"
android:title="@string/credentials_reset"
android:summary="@string/credentials_reset_summary"
android:persistent="false">
<intent android:action="com.android.credentials.RESET"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.CredentialStorage"/>
</Preference>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,85 +0,0 @@
/*
* 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;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.security.Credentials;
import android.security.KeyStore;
import android.util.Log;
/**
* Installs credentials to the system keystore. It reacts to the
* {@link Credentials#SYSTEM_INSTALL_ACTION} intent. All the key-value pairs in
* the intent are installed to the system keystore. For security reason, the
* current implementation limits that only com.android.certinstaller can use
* this service.
*/
public class CredentialInstaller extends Activity {
private static final String TAG = "CredentialInstaller";
private static final String UNLOCKING = "ulck";
private KeyStore mKeyStore = KeyStore.getInstance();
private boolean mUnlocking = false;
@Override
protected void onResume() {
super.onResume();
if (!"com.android.certinstaller".equals(getCallingPackage())) finish();
if (isKeyStoreUnlocked()) {
install();
} else if (!mUnlocking) {
mUnlocking = true;
Credentials.getInstance().unlock(this);
return;
}
finish();
}
@Override
protected void onSaveInstanceState(Bundle outStates) {
super.onSaveInstanceState(outStates);
outStates.putBoolean(UNLOCKING, mUnlocking);
}
@Override
protected void onRestoreInstanceState(Bundle savedStates) {
super.onRestoreInstanceState(savedStates);
mUnlocking = savedStates.getBoolean(UNLOCKING);
}
private void install() {
Intent intent = getIntent();
Bundle bundle = (intent == null) ? null : intent.getExtras();
if (bundle == null) return;
for (String key : bundle.keySet()) {
byte[] data = bundle.getByteArray(key);
if (data == null) continue;
boolean success = mKeyStore.put(key.getBytes(), data);
Log.d(TAG, "install " + key + ": " + data.length + " success? " + success);
if (!success) return;
}
setResult(RESULT_OK);
}
private boolean isKeyStoreUnlocked() {
return (mKeyStore.test() == KeyStore.NO_ERROR);
}
}

View File

@@ -0,0 +1,230 @@
/*
* Copyright (C) 2011 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;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.security.KeyStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
public class CredentialStorage extends Activity implements TextWatcher,
DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
public static final String ACTION_UNLOCK = "com.android.credentials.UNLOCK";
public static final String ACTION_SET_PASSWORD = "com.android.credentials.SET_PASSWORD";
public static final String ACTION_INSTALL = "com.android.credentials.INSTALL";
public static final String ACTION_RESET = "com.android.credentials.RESET";
private static final String TAG = "CredentialStorage";
private KeyStore mKeyStore = KeyStore.getInstance();
private boolean mSubmit = false;
private Bundle mBundle;
private TextView mOldPassword;
private TextView mNewPassword;
private TextView mConfirmPassword;
private TextView mError;
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String action = intent.getAction();
int state = mKeyStore.test();
if (ACTION_RESET.equals(action)) {
showResetDialog();
} else if (ACTION_SET_PASSWORD.equals(action)) {
showPasswordDialog(state == KeyStore.UNINITIALIZED);
} else {
if (ACTION_INSTALL.equals(action) &&
"com.android.certinstaller".equals(getCallingPackage())) {
mBundle = intent.getExtras();
}
if (state == KeyStore.UNINITIALIZED) {
showPasswordDialog(true);
} else if (state == KeyStore.LOCKED) {
showUnlockDialog();
} else {
install();
finish();
}
}
}
private void install() {
if (mBundle != null && !mBundle.isEmpty()) {
try {
for (String key : mBundle.keySet()) {
byte[] value = mBundle.getByteArray(key);
if (value != null && !mKeyStore.put(key.getBytes("UTF-8"), value)) {
Log.e(TAG, "Failed to install " + key);
return;
}
}
setResult(RESULT_OK);
} catch (UnsupportedEncodingException e) {
// Should never happen.
throw new RuntimeException(e);
}
}
}
private void showResetDialog() {
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.credentials_reset_hint)
.setNeutralButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
dialog.setOnDismissListener(this);
dialog.show();
}
private void showPasswordDialog(boolean firstTime) {
View view = View.inflate(this, R.layout.credentials_dialog, null);
((TextView) view.findViewById(R.id.hint)).setText(R.string.credentials_password_hint);
if (!firstTime) {
view.findViewById(R.id.old_password_prompt).setVisibility(View.VISIBLE);
mOldPassword = (TextView) view.findViewById(R.id.old_password);
mOldPassword.setVisibility(View.VISIBLE);
mOldPassword.addTextChangedListener(this);
}
view.findViewById(R.id.new_passwords).setVisibility(View.VISIBLE);
mNewPassword = (TextView) view.findViewById(R.id.new_password);
mNewPassword.addTextChangedListener(this);
mConfirmPassword = (TextView) view.findViewById(R.id.confirm_password);
mConfirmPassword.addTextChangedListener(this);
mError = (TextView) view.findViewById(R.id.error);
AlertDialog dialog = new AlertDialog.Builder(this)
.setView(view)
.setTitle(R.string.credentials_set_password)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
dialog.setOnDismissListener(this);
dialog.show();
mButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
mButton.setEnabled(false);
}
private void showUnlockDialog() {
View view = View.inflate(this, R.layout.credentials_dialog, null);
((TextView) view.findViewById(R.id.hint)).setText(R.string.credentials_unlock_hint);
mOldPassword = (TextView) view.findViewById(R.id.old_password);
mOldPassword.setVisibility(View.VISIBLE);
mOldPassword.addTextChangedListener(this);
mError = (TextView) view.findViewById(R.id.error);
AlertDialog dialog = new AlertDialog.Builder(this)
.setView(view)
.setTitle(R.string.credentials_unlock)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
dialog.setOnDismissListener(this);
dialog.show();
mButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
mButton.setEnabled(false);
}
public void afterTextChanged(Editable editable) {
if ((mOldPassword == null || mOldPassword.getText().length() > 0) &&
(mNewPassword == null || mNewPassword.getText().length() >= 8) &&
(mConfirmPassword == null || mConfirmPassword.getText().length() >= 8)) {
mButton.setEnabled(true);
} else {
mButton.setEnabled(false);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s,int start, int before, int count) {
}
public void onClick(DialogInterface dialog, int button) {
mSubmit = (button == DialogInterface.BUTTON_POSITIVE);
if (button == DialogInterface.BUTTON_NEUTRAL) {
mKeyStore.reset();
Toast.makeText(this, R.string.credentials_erased, Toast.LENGTH_SHORT).show();
}
}
public void onDismiss(DialogInterface dialog) {
if (mSubmit) {
mSubmit = false;
mError.setVisibility(View.VISIBLE);
if (mNewPassword == null) {
mKeyStore.unlock(mOldPassword.getText().toString());
} else {
String newPassword = mNewPassword.getText().toString();
String confirmPassword = mConfirmPassword.getText().toString();
if (!newPassword.equals(confirmPassword)) {
mError.setText(R.string.credentials_passwords_mismatch);
((AlertDialog) dialog).show();
return;
} else if (mOldPassword == null) {
mKeyStore.password(newPassword);
} else {
mKeyStore.password(mOldPassword.getText().toString(), newPassword);
}
}
int error = mKeyStore.getLastError();
if (error == KeyStore.NO_ERROR) {
Toast.makeText(this, R.string.credentials_enabled, Toast.LENGTH_SHORT).show();
install();
} else if (error == KeyStore.UNINITIALIZED) {
Toast.makeText(this, R.string.credentials_erased, Toast.LENGTH_SHORT).show();
} else if (error >= KeyStore.WRONG_PASSWORD) {
int count = error - KeyStore.WRONG_PASSWORD + 1;
if (count > 3) {
mError.setText(R.string.credentials_wrong_password);
} else if (count == 1) {
mError.setText(R.string.credentials_reset_warning);
} else {
mError.setText(getString(R.string.credentials_reset_warning_plural, count));
}
((AlertDialog) dialog).show();
return;
}
}
finish();
}
}

View File

@@ -63,39 +63,32 @@ import java.util.Observer;
*/
public class SecuritySettings extends SettingsPreferenceFragment
implements OnPreferenceChangeListener {
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
private static final String KEY_ENCRYPTION = "encryption";
// Lock Settings
private static final String PACKAGE = "com.android.settings";
private static final String ICC_LOCK_SETTINGS = PACKAGE + ".IccLockSettings";
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
private static final String KEY_LOCK_ENABLED = "lockenabled";
private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
private static final String KEY_TACTILE_FEEDBACK_ENABLED = "unlock_tactile_feedback";
private static final String KEY_SECURITY_CATEGORY = "security_category";
private CheckBoxPreference mVisiblePattern;
private CheckBoxPreference mTactileFeedback;
private CheckBoxPreference mShowPassword;
private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
// Location Settings
private static final String LOCATION_CATEGORY = "location_category";
private static final String LOCATION_NETWORK = "location_network";
private static final String LOCATION_GPS = "location_gps";
private static final String ASSISTED_GPS = "assisted_gps";
private static final String USE_LOCATION = "location_use_for_services";
private static final String LOCK_AFTER_TIMEOUT_KEY = "lock_after_timeout";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
private static final int FALLBACK_LOCK_AFTER_TIMEOUT_VALUE = 5000; // compatible with pre-Froyo
private static final String KEY_LOCATION_CATEGORY = "location_category";
private static final String KEY_LOCATION_NETWORK = "location_network";
private static final String KEY_LOCATION_GPS = "location_gps";
private static final String KEY_ASSISTED_GPS = "assisted_gps";
private static final String KEY_USE_LOCATION = "location_use_for_services";
// Misc Settings
private static final String KEY_SIM_LOCK = "sim_lock";
private static final String KEY_SHOW_PASSWORD = "show_password";
private static final String KEY_ENABLE_CREDENTIALS = "enable_credentials";
private static final String KEY_RESET_CREDENTIALS = "reset_credentials";
private static final String TAG = "SecuritySettings";
// Credential storage
private final CredentialStorage mCredentialStorage = new CredentialStorage();
private CheckBoxPreference mNetwork;
private CheckBoxPreference mGps;
private CheckBoxPreference mAssistedGps;
@@ -112,13 +105,15 @@ public class SecuritySettings extends SettingsPreferenceFragment
private LockPatternUtils mLockPatternUtils;
private ListPreference mLockAfter;
private SettingsObserver mSettingsObserver;
private Observer mSettingsObserver;
private final class SettingsObserver implements Observer {
public void update(Observable o, Object arg) {
updateToggles();
}
}
private CheckBoxPreference mVisiblePattern;
private CheckBoxPreference mTactileFeedback;
private CheckBoxPreference mShowPassword;
private CheckBoxPreference mEnableCredentials;
private Preference mResetCredentials;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -129,10 +124,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
createPreferenceHierarchy();
updateToggles();
}
@Override
@@ -144,31 +135,33 @@ public class SecuritySettings extends SettingsPreferenceFragment
new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},
null);
mContentQueryMap = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, null);
mContentQueryMap.addObserver(mSettingsObserver = new SettingsObserver());
}
@Override
public void onStop() {
super.onStop();
if (mSettingsObserver != null) {
mContentQueryMap.deleteObserver(mSettingsObserver);
}
}
private PreferenceScreen createPreferenceHierarchy() {
PreferenceScreen root = this.getPreferenceScreen();
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
addPreferencesFromResource(R.xml.security_settings);
root = this.getPreferenceScreen();
root = getPreferenceScreen();
mNetwork = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_NETWORK);
mGps = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_GPS);
mAssistedGps = (CheckBoxPreference) getPreferenceScreen().findPreference(ASSISTED_GPS);
mNetwork = (CheckBoxPreference) root.findPreference(KEY_LOCATION_NETWORK);
mGps = (CheckBoxPreference) root.findPreference(KEY_LOCATION_GPS);
mAssistedGps = (CheckBoxPreference) root.findPreference(KEY_ASSISTED_GPS);
if (GoogleLocationSettingHelper.isAvailable(getActivity())) {
// GSF present, Add setting for 'Use My Location'
PreferenceGroup locationCat = (PreferenceGroup) root.findPreference(LOCATION_CATEGORY);
PreferenceGroup locationCat =
(PreferenceGroup) root.findPreference(KEY_LOCATION_CATEGORY);
CheckBoxPreference useLocation = new CheckBoxPreference(getActivity());
useLocation.setKey(USE_LOCATION);
useLocation.setKey(KEY_USE_LOCATION);
useLocation.setTitle(R.string.use_location_title);
useLocation.setSummaryOn(R.string.use_location_summary_enabled);
useLocation.setSummaryOff(R.string.use_location_summary_disabled);
@@ -181,8 +174,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
mUseLocation = useLocation;
}
PreferenceManager pm = getPreferenceManager();
// Add options for device encryption
// TODO: It still needs to be determined how a device specifies that it supports
// encryption. That mechanism needs to be checked before adding the following code
@@ -215,98 +206,62 @@ public class SecuritySettings extends SettingsPreferenceFragment
addPreferencesFromResource(resid);
// lock after preference
mLockAfter = setupLockAfterPreference(pm);
mLockAfter = (ListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT);
if (mLockAfter != null) {
setupLockAfterPreference();
updateLockAfterPreferenceSummary();
}
// visible pattern
mVisiblePattern = (CheckBoxPreference) pm.findPreference(KEY_VISIBLE_PATTERN);
mVisiblePattern = (CheckBoxPreference) root.findPreference(KEY_VISIBLE_PATTERN);
// tactile feedback. Should be common to all unlock preference screens.
mTactileFeedback = (CheckBoxPreference) pm.findPreference(KEY_TACTILE_FEEDBACK_ENABLED);
mTactileFeedback = (CheckBoxPreference) root.findPreference(KEY_TACTILE_FEEDBACK_ENABLED);
if (!((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).hasVibrator()) {
PreferenceGroup securityCategory = (PreferenceGroup)
pm.findPreference(KEY_SECURITY_CATEGORY);
root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null && mTactileFeedback != null) {
securityCategory.removePreference(mTactileFeedback);
}
}
int activePhoneType = TelephonyManager.getDefault().getPhoneType();
// Append the rest of the settings
addPreferencesFromResource(R.xml.security_settings_misc);
// do not display SIM lock for CDMA phone
if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType)
{
PreferenceScreen simLockPreferences = getPreferenceManager()
.createPreferenceScreen(getActivity());
simLockPreferences.setTitle(R.string.sim_lock_settings_category);
// Intent to launch SIM lock settings
simLockPreferences.setIntent(new Intent().setClassName(PACKAGE, ICC_LOCK_SETTINGS));
PreferenceCategory simLockCat = new PreferenceCategory(getActivity());
simLockCat.setTitle(R.string.sim_lock_settings_title);
root.addPreference(simLockCat);
simLockCat.addPreference(simLockPreferences);
// Do not display SIM lock for CDMA phone
if (TelephonyManager.PHONE_TYPE_CDMA == TelephonyManager.getDefault().getPhoneType()) {
root.removePreference(root.findPreference(KEY_SIM_LOCK));
}
// Passwords
PreferenceCategory passwordsCat = new PreferenceCategory(getActivity());
passwordsCat.setTitle(R.string.security_passwords_title);
root.addPreference(passwordsCat);
CheckBoxPreference showPassword = mShowPassword = new CheckBoxPreference(getActivity());
showPassword.setKey("show_password");
showPassword.setTitle(R.string.show_password);
showPassword.setSummary(R.string.show_password_summary);
showPassword.setPersistent(false);
passwordsCat.addPreference(showPassword);
// Device policies
PreferenceCategory devicePoliciesCat = new PreferenceCategory(getActivity());
devicePoliciesCat.setTitle(R.string.device_admin_title);
root.addPreference(devicePoliciesCat);
Preference deviceAdminButton = new Preference(getActivity());
deviceAdminButton.setTitle(R.string.manage_device_admin);
deviceAdminButton.setSummary(R.string.manage_device_admin_summary);
Intent deviceAdminIntent = new Intent();
deviceAdminIntent.setClass(getActivity(), DeviceAdminSettings.class);
deviceAdminButton.setIntent(deviceAdminIntent);
devicePoliciesCat.addPreference(deviceAdminButton);
// Show password
mShowPassword = (CheckBoxPreference) root.findPreference(KEY_SHOW_PASSWORD);
// Credential storage
PreferenceCategory credentialsCat = new PreferenceCategory(getActivity());
credentialsCat.setTitle(R.string.credentials_category);
root.addPreference(credentialsCat);
mCredentialStorage.createPreferences(credentialsCat);
mEnableCredentials = (CheckBoxPreference) root.findPreference(KEY_ENABLE_CREDENTIALS);
mEnableCredentials.setOnPreferenceChangeListener(this);
mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS);
return root;
}
private ListPreference setupLockAfterPreference(PreferenceManager pm) {
ListPreference result = (ListPreference) pm.findPreference(LOCK_AFTER_TIMEOUT_KEY);
if (result != null) {
int lockAfterValue = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
FALLBACK_LOCK_AFTER_TIMEOUT_VALUE);
result.setValue(String.valueOf(lockAfterValue));
result.setOnPreferenceChangeListener(this);
final long adminTimeout = mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0;
final ContentResolver cr = getContentResolver();
private void setupLockAfterPreference() {
// Compatible with pre-Froyo
long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
mLockAfter.setValue(String.valueOf(currentTimeout));
mLockAfter.setOnPreferenceChangeListener(this);
final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0);
final long displayTimeout = Math.max(0,
Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT, 0));
Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
if (adminTimeout > 0) {
// This setting is a slave to display timeout when a device policy is enforced.
// As such, maxLockTimeout = adminTimeout - displayTimeout.
// If there isn't enough time, shows "immediately" setting.
disableUnusableTimeouts(result, Math.max(0, adminTimeout - displayTimeout));
disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout));
}
}
return result;
}
private void updateLockAfterPreferenceSummary() {
// Not all security types have a "lock after" preference, so ignore those that don't.
if (mLockAfter == null) return;
// Update summary message with current value
long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 0);
@@ -319,14 +274,12 @@ public class SecuritySettings extends SettingsPreferenceFragment
best = i;
}
}
String summary = mLockAfter.getContext()
.getString(R.string.lock_after_timeout_summary, entries[best]);
mLockAfter.setSummary(summary);
mLockAfter.setSummary(getString(R.string.lock_after_timeout_summary, entries[best]));
}
private static void disableUnusableTimeouts(ListPreference pref, long maxTimeout) {
final CharSequence[] entries = pref.getEntries();
final CharSequence[] values = pref.getEntryValues();
private void disableUnusableTimeouts(long maxTimeout) {
final CharSequence[] entries = mLockAfter.getEntries();
final CharSequence[] values = mLockAfter.getEntryValues();
ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>();
ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>();
for (int i = 0; i < values.length; i++) {
@@ -337,20 +290,20 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
}
if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) {
pref.setEntries(
mLockAfter.setEntries(
revisedEntries.toArray(new CharSequence[revisedEntries.size()]));
pref.setEntryValues(
mLockAfter.setEntryValues(
revisedValues.toArray(new CharSequence[revisedValues.size()]));
final int userPreference = Integer.valueOf(pref.getValue());
final int userPreference = Integer.valueOf(mLockAfter.getValue());
if (userPreference <= maxTimeout) {
pref.setValue(String.valueOf(userPreference));
mLockAfter.setValue(String.valueOf(userPreference));
} else {
// There will be no highlighted selection since nothing in the list matches
// maxTimeout. The user can still select anything less than maxTimeout.
// TODO: maybe append maxTimeout to the list and mark selected.
}
}
pref.setEnabled(revisedEntries.size() > 0);
mLockAfter.setEnabled(revisedEntries.size() > 0);
}
@Override
@@ -360,6 +313,16 @@ public class SecuritySettings extends SettingsPreferenceFragment
// Make sure we reload the preference hierarchy since some of these settings
// depend on others...
createPreferenceHierarchy();
updateLocationToggles();
if (mSettingsObserver == null) {
mSettingsObserver = new Observer() {
public void update(Observable o, Object arg) {
updateLocationToggles();
}
};
mContentQueryMap.addObserver(mSettingsObserver);
}
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (mVisiblePattern != null) {
@@ -372,7 +335,10 @@ public class SecuritySettings extends SettingsPreferenceFragment
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
mCredentialStorage.resume();
int state = KeyStore.getInstance().test();
mEnableCredentials.setChecked(state == KeyStore.NO_ERROR);
mEnableCredentials.setEnabled(state != KeyStore.UNINITIALIZED);
mResetCredentials.setEnabled(state != KeyStore.UNINITIALIZED);
}
@Override
@@ -419,7 +385,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
/*
* Creates toggles for each available location provider
*/
private void updateToggles() {
private void updateLocationToggles() {
ContentResolver res = getContentResolver();
boolean gpsEnabled = Settings.Secure.isLocationProviderEnabled(
res, LocationManager.GPS_PROVIDER);
@@ -453,7 +419,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
public void showPasswordDialog() {
View view = View.inflate(SecuritySettings.this.getActivity(),
R.layout.credentials_password_dialog, null);
R.layout.credentials_dialog, null);
view.findViewById(R.id.new_passwords).setVisibility(View.VISIBLE);
Dialog dialog = new AlertDialog.Builder(SecuritySettings.this.getActivity())
.setView(view).setTitle(R.string.credentials_set_password)
@@ -521,7 +488,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
if (formatArgs == null || formatArgs.length == 0) {
view.setText(stringId);
} else {
view.setText(dialog.getContext().getString(stringId, formatArgs));
view.setText(getString(stringId, formatArgs));
}
view.setVisibility(View.VISIBLE);
}
@@ -529,299 +496,31 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
private class CredentialStorage implements DialogInterface.OnClickListener,
DialogInterface.OnDismissListener, Preference.OnPreferenceChangeListener,
Preference.OnPreferenceClickListener {
private static final int MINIMUM_PASSWORD_LENGTH = 8;
private final KeyStore mKeyStore = KeyStore.getInstance();
private int mState;
private boolean mSubmit = false;
private boolean mExternal = false;
private CheckBoxPreference mAccessCheckBox;
private Preference mInstallButton;
private Preference mPasswordButton;
private Preference mResetButton;
void resume() {
mState = mKeyStore.test();
updatePreferences(mState);
Intent intent = getActivity().getIntent();
if (!mExternal && intent != null &&
Credentials.UNLOCK_ACTION.equals(intent.getAction())) {
mExternal = true;
if (mState == KeyStore.UNINITIALIZED) {
showPasswordDialog();
} else if (mState == KeyStore.LOCKED) {
showUnlockDialog();
} else {
// TODO: Verify if this is the right way
SecuritySettings.this.getFragmentManager().popBackStack();
}
}
}
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) {
showUnlockDialog();
} else {
lock();
}
return true;
}
return false;
}
public boolean onPreferenceClick(Preference preference) {
if (preference == mInstallButton) {
Credentials.getInstance().installFromSdCard(SecuritySettings.this.getActivity());
} else if (preference == mPasswordButton) {
showPasswordDialog();
} else if (preference == mResetButton) {
showResetDialog();
} 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) {
// TODO:
//if (mSubmit && !isFinishing()) {
if (mSubmit) {
mSubmit = false;
if (!checkPassword((Dialog) dialog)) {
((Dialog) dialog).show();
return;
}
}
updatePreferences(mState);
if (mExternal) {
// TODO:
// 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) {
updatePreferences(KeyStore.NO_ERROR);
return false;
}
if (error == KeyStore.UNINITIALIZED) {
updatePreferences(KeyStore.UNINITIALIZED);
return false;
}
if (error < KeyStore.WRONG_PASSWORD) {
return false;
}
int count = error - KeyStore.WRONG_PASSWORD + 1;
if (count > 3) {
showError(dialog, R.string.credentials_wrong_password);
} else if (count == 1) {
showError(dialog, R.string.credentials_reset_warning);
} else {
showError(dialog, R.string.credentials_reset_warning_plural, count);
}
return true;
}
private String getText(Dialog dialog, int viewId) {
TextView view = (TextView) dialog.findViewById(viewId);
return (view == null || view.getVisibility() == View.GONE) ? null :
view.getText().toString();
}
private void showError(Dialog dialog, int stringId, Object... formatArgs) {
TextView view = (TextView) dialog.findViewById(R.id.error);
if (view != null) {
if (formatArgs == null || formatArgs.length == 0) {
view.setText(stringId);
} else {
view.setText(dialog.getContext().getString(stringId, formatArgs));
}
view.setVisibility(View.VISIBLE);
}
}
private void createPreferences(PreferenceCategory category) {
mAccessCheckBox = new CheckBoxPreference(SecuritySettings.this.getActivity());
mAccessCheckBox.setTitle(R.string.credentials_access);
mAccessCheckBox.setSummary(R.string.credentials_access_summary);
mAccessCheckBox.setOnPreferenceChangeListener(this);
category.addPreference(mAccessCheckBox);
mInstallButton = new Preference(SecuritySettings.this.getActivity());
mInstallButton.setTitle(R.string.credentials_install_certificates);
mInstallButton.setSummary(R.string.credentials_install_certificates_summary);
mInstallButton.setOnPreferenceClickListener(this);
category.addPreference(mInstallButton);
mPasswordButton = new Preference(SecuritySettings.this.getActivity());
mPasswordButton.setTitle(R.string.credentials_set_password);
mPasswordButton.setSummary(R.string.credentials_set_password_summary);
mPasswordButton.setOnPreferenceClickListener(this);
category.addPreference(mPasswordButton);
mResetButton = new Preference(SecuritySettings.this.getActivity());
mResetButton.setTitle(R.string.credentials_reset);
mResetButton.setSummary(R.string.credentials_reset_summary);
mResetButton.setOnPreferenceClickListener(this);
category.addPreference(mResetButton);
}
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;
} else if (state == KeyStore.NO_ERROR) {
Toast.makeText(SecuritySettings.this.getActivity(), R.string.credentials_enabled,
Toast.LENGTH_SHORT).show();
} else if (state == KeyStore.UNINITIALIZED) {
Toast.makeText(SecuritySettings.this.getActivity(), R.string.credentials_erased,
Toast.LENGTH_SHORT).show();
} else if (state == KeyStore.LOCKED) {
Toast.makeText(SecuritySettings.this.getActivity(), R.string.credentials_disabled,
Toast.LENGTH_SHORT).show();
}
mState = state;
}
private void showUnlockDialog() {
View view = View.inflate(SecuritySettings.this.getActivity(),
R.layout.credentials_unlock_dialog, null);
// Show extra hint only when the action comes from outside.
if (mExternal) {
view.findViewById(R.id.hint).setVisibility(View.VISIBLE);
}
Dialog dialog = new AlertDialog.Builder(SecuritySettings.this.getActivity())
.setView(view)
.setTitle(R.string.credentials_unlock)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
dialog.setOnDismissListener(this);
dialog.show();
}
private void showPasswordDialog() {
View view = View.inflate(SecuritySettings.this.getActivity(),
R.layout.credentials_password_dialog, null);
if (mState == KeyStore.UNINITIALIZED) {
view.findViewById(R.id.hint).setVisibility(View.VISIBLE);
} else {
view.findViewById(R.id.old_password_prompt).setVisibility(View.VISIBLE);
view.findViewById(R.id.old_password).setVisibility(View.VISIBLE);
}
Dialog dialog = new AlertDialog.Builder(SecuritySettings.this.getActivity())
.setView(view)
.setTitle(R.string.credentials_set_password)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
dialog.setOnDismissListener(this);
dialog.show();
}
private void showResetDialog() {
new AlertDialog.Builder(SecuritySettings.this.getActivity())
.setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.credentials_reset_hint)
.setNeutralButton(getResources().getString(android.R.string.ok), this)
.setNegativeButton(getResources().getString(android.R.string.cancel), this)
.create().show();
}
}
public boolean onPreferenceChange(Preference preference, Object value) {
if (preference == mLockAfter) {
int lockAfter = Integer.parseInt((String) value);
int timeout = Integer.parseInt((String) value);
try {
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, lockAfter);
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
} catch (NumberFormatException e) {
Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e);
}
updateLockAfterPreferenceSummary();
} else if (preference == mUseLocation) {
boolean newValue = value == null ? false : (Boolean) value;
boolean newValue = (value == null ? false : (Boolean) value);
GoogleLocationSettingHelper.setUseLocationForServices(getActivity(), newValue);
// We don't want to change the value immediately here, since the user may click
// disagree in the dialog that pops up. When the activity we just launched exits, this
// activity will be restated and the new value re-read, so the checkbox will get its
// new value then.
return false;
} else if (preference == mEnableCredentials) {
if (value != null && (Boolean) value) {
getActivity().startActivity(new Intent(CredentialStorage.ACTION_UNLOCK));
return false;
} else {
KeyStore.getInstance().lock();
}
}
return true;
}