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

@@ -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();
}
}