diff options
author | Jim Miller <jaggies@google.com> | 2009-12-22 19:04:23 -0800 |
---|---|---|
committer | Jim Miller <jaggies@google.com> | 2010-01-11 15:51:43 -0800 |
commit | 5e0f7ba8fa8045aab98664b5103d8620e9ac7f06 (patch) | |
tree | 8bcb4aa2c3f5f9266bebdb1ad49ddf804c5a8d11 /policy/com | |
parent | cc6828c676c0bfabbcbefa27f4be9183352f5fee (diff) | |
download | frameworks_base-5e0f7ba8fa8045aab98664b5103d8620e9ac7f06.zip frameworks_base-5e0f7ba8fa8045aab98664b5103d8620e9ac7f06.tar.gz frameworks_base-5e0f7ba8fa8045aab98664b5103d8620e9ac7f06.tar.bz2 |
Fix 2332563: Add password-lock support to lockscreen
Diffstat (limited to 'policy/com')
5 files changed, 316 insertions, 24 deletions
diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java index 66c5159..ccb7902 100644 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -111,7 +111,12 @@ public class LockPatternKeyguardView extends KeyguardViewBase /** * Unlock by entering an account's login and password. */ - Account + Account, + + /** + * Unlock by entering a password or PIN + */ + Password } /** @@ -268,7 +273,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase public void reportFailedPatternAttempt() { mUpdateMonitor.reportFailedAttempt(); final int failedAttempts = mUpdateMonitor.getFailedAttempts(); - if (DEBUG) Log.d(TAG, + if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts + " (enableFallback=" + mEnableFallback + ")"); if (mEnableFallback && failedAttempts == @@ -309,7 +314,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase mLockScreen = createLockScreen(); addView(mLockScreen); final UnlockMode unlockMode = getUnlockMode(); - if (DEBUG) Log.d(TAG, + if (DEBUG) Log.d(TAG, "LockPatternKeyguardView ctor: about to createUnlockScreenFor; mEnableFallback=" + mEnableFallback); mUnlockScreen = createUnlockScreenFor(unlockMode); @@ -434,16 +439,25 @@ public class LockPatternKeyguardView extends KeyguardViewBase private boolean isSecure() { UnlockMode unlockMode = getUnlockMode(); - if (unlockMode == UnlockMode.Pattern) { - return mLockPatternUtils.isLockPatternEnabled(); - } else if (unlockMode == UnlockMode.SimPin) { - return mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED - || mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED; - } else if (unlockMode == UnlockMode.Account) { - return true; - } else { - throw new IllegalStateException("unknown unlock mode " + unlockMode); + boolean secure = false; + switch (unlockMode) { + case Pattern: + secure = mLockPatternUtils.isLockPatternEnabled(); + break; + case SimPin: + secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED + || mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED; + break; + case Account: + secure = true; + break; + case Password: + secure = mLockPatternUtils.isLockPasswordEnabled(); + break; + default: + throw new IllegalStateException("unknown unlock mode " + unlockMode); } + return secure; } private void updateScreen(final Mode mode) { @@ -524,6 +538,12 @@ public class LockPatternKeyguardView extends KeyguardViewBase // "permanently locked" state.) return createUnlockScreenFor(UnlockMode.Pattern); } + } else if (unlockMode == UnlockMode.Password) { + return new PasswordUnlockScreen( + mContext, + mLockPatternUtils, + mUpdateMonitor, + mKeyguardScreenCallback); } else { throw new IllegalArgumentException("unknown unlock mode " + unlockMode); } @@ -575,13 +595,29 @@ public class LockPatternKeyguardView extends KeyguardViewBase */ private UnlockMode getUnlockMode() { final IccCard.State simState = mUpdateMonitor.getSimState(); + UnlockMode currentMode; if (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED) { - return UnlockMode.SimPin; + currentMode = UnlockMode.SimPin; } else { - return (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) ? - UnlockMode.Account: - UnlockMode.Pattern; + final int mode = mLockPatternUtils.getPasswordMode(); + switch (mode) { + case LockPatternUtils.MODE_PIN: + case LockPatternUtils.MODE_PASSWORD: + currentMode = UnlockMode.Password; + break; + case LockPatternUtils.MODE_PATTERN: + // "forgot pattern" button is only available in the pattern mode... + if (mForgotPattern && mLockPatternUtils.isPermanentlyLocked()) { + currentMode = UnlockMode.Account; + } else { + currentMode = UnlockMode.Pattern; + } + break; + default: + throw new IllegalStateException("Unknown unlock mode:" + mode); + } } + return currentMode; } private void showTimeoutDialog() { diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java index 8a62cbd..ed5a058 100644 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java +++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java @@ -50,12 +50,7 @@ public class LockPatternKeyguardViewProperties implements KeyguardViewProperties } public boolean isSecure() { - return isLockPatternSecure() || isSimPinSecure(); - } - - private boolean isLockPatternSecure() { - return mLockPatternUtils.isLockPatternEnabled() && mLockPatternUtils - .savedPatternExists(); + return mLockPatternUtils.isSecure() || isSimPinSecure(); } private boolean isSimPinSecure() { diff --git a/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java new file mode 100644 index 0000000..bb1950a --- /dev/null +++ b/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2010 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.internal.policy.impl; + +import android.content.Context; + +import com.android.internal.telephony.IccCard.State; +import com.android.internal.widget.LockPatternUtils; + +import android.text.Editable; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.android.internal.R; + +/** + * Displays a dialer-like interface or alphanumeric (latin-1) key entry for the user to enter + * an unlock password + */ +public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen, View.OnClickListener, + KeyguardUpdateMonitor.ConfigurationChangeCallback, KeyguardUpdateMonitor.InfoCallback { + + private static final int DIGIT_PRESS_WAKE_MILLIS = 5000; + + private final KeyguardUpdateMonitor mUpdateMonitor; + private final KeyguardScreenCallback mCallback; + + private final boolean mCreatedWithKeyboardOpen; + + private TextView mPasswordTextView; + private TextView mOkButton; + private TextView mEmergencyCallButton; + private View mBackSpaceButton; + private TextView mCarrier; + private LockPatternUtils mLockPatternUtils; + private Button mCancelButton; + private int mPasswordAttempts = 0; + private int mMinimumPasswordLength = 4; // TODO: get from policy store + + private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + public PasswordUnlockScreen(Context context, LockPatternUtils lockPatternUtils, + KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback) { + super(context); + mUpdateMonitor = updateMonitor; + mCallback = callback; + mCreatedWithKeyboardOpen = mUpdateMonitor.isKeyboardOpen(); + + LayoutInflater layoutInflater = LayoutInflater.from(context); + if (mCreatedWithKeyboardOpen) { + layoutInflater.inflate(R.layout.keyguard_screen_password_landscape, this, true); + } else { + layoutInflater.inflate(R.layout.keyguard_screen_password_portrait, this, true); + new TouchInput(); + } + + mPasswordTextView = (TextView) findViewById(R.id.pinDisplay); + mBackSpaceButton = findViewById(R.id.backspace); + mBackSpaceButton.setOnClickListener(this); + + // The cancel button is not used on this screen. + mCancelButton = (Button) findViewById(R.id.cancel); + if (mCancelButton != null) { + mCancelButton.setText(""); + } + + mEmergencyCallButton = (TextView) findViewById(R.id.emergencyCall); + mOkButton = (TextView) findViewById(R.id.ok); + + mPasswordTextView.setFocusable(false); + + mEmergencyCallButton.setOnClickListener(this); + mOkButton.setOnClickListener(this); + + mUpdateMonitor.registerConfigurationChangeCallback(this); + + mLockPatternUtils = lockPatternUtils; + mCarrier = (TextView) findViewById(R.id.carrier); + // until we get an update... + mCarrier.setText(LockScreen.getCarrierString(mUpdateMonitor.getTelephonyPlmn(), + mUpdateMonitor.getTelephonySpn())); + + updateMonitor.registerInfoCallback(this); + updateMonitor.registerConfigurationChangeCallback(this); + + setFocusableInTouchMode(true); + } + + /** {@inheritDoc} */ + public boolean needsInput() { + return true; + } + + /** {@inheritDoc} */ + public void onPause() { + + } + + /** {@inheritDoc} */ + public void onResume() { + // start fresh + mPasswordTextView.setText(""); + } + + /** {@inheritDoc} */ + public void cleanUp() { + mUpdateMonitor.removeCallback(this); + } + + public void onClick(View v) { + if (v == mBackSpaceButton) { + final Editable digits = mPasswordTextView.getEditableText(); + final int len = digits.length(); + if (len > 0) { + digits.delete(len-1, len); + } + } else if (v == mEmergencyCallButton) { + mCallback.takeEmergencyCallAction(); + } else if (v == mOkButton) { + verifyPasswordAndUnlock(); + } + mCallback.pokeWakelock(); + } + + private void verifyPasswordAndUnlock() { + String entry = mPasswordTextView.getText().toString(); + if (mLockPatternUtils.checkPassword(entry)) { + mPasswordAttempts = 0; + mCallback.keyguardDone(true); + } else if (entry.length() >= mMinimumPasswordLength ) { + // to avoid accidental lockout, only count attempts that are long enough to be a + // real password. This may require some tweaking. + mPasswordAttempts++; + } + mPasswordTextView.setText(""); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + return true; + } + + final char match = event.getMatch(DIGITS); + if (match != 0) { + reportDigit(match - '0'); + return true; + } + if (keyCode == KeyEvent.KEYCODE_DEL) { + mPasswordTextView.onKeyDown(keyCode, event); + return true; + } + + if (keyCode == KeyEvent.KEYCODE_ENTER) { + verifyPasswordAndUnlock(); + return true; + } + + return false; + } + + private void reportDigit(int digit) { + mPasswordTextView.append(Integer.toString(digit)); + } + + public void onOrientationChange(boolean inPortrait) { + + } + + public void onKeyboardChange(boolean isKeyboardOpen) { + if (isKeyboardOpen != mCreatedWithKeyboardOpen) { + mCallback.recreateMe(); + } + } + + /** + * Helper class to handle input from touch dialer. Only relevant when + * the keyboard is shut. + */ + private class TouchInput implements View.OnClickListener { + private int mDigitIds[] = { R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, + R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine }; + private TextView mCancelButton; + private TouchInput() { + for (int i = 0; i < mDigitIds.length; i++) { + Button button = (Button) findViewById(mDigitIds[i]); + button.setOnClickListener(this); + button.setText(Integer.toString(i)); + } + mCancelButton = (TextView) findViewById(R.id.cancel); + mCancelButton.setOnClickListener(this); + mOkButton = (TextView) findViewById(R.id.ok); + mOkButton.setOnClickListener(this); + } + + public void onClick(View v) { + if (v == mCancelButton) { + return; + } + if (v == mOkButton) { + verifyPasswordAndUnlock(); + } + + final int digit = checkDigit(v); + if (digit >= 0) { + mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS); + reportDigit(digit); + } + } + + private int checkDigit(View v) { + int digit = -1; + for (int i = 0; i < mDigitIds.length; i++) { + if (v.getId() == mDigitIds[i]) { + digit = i; + break; + } + } + return digit; + } + } + + /** {@inheritDoc} */ + public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { + mCarrier.setText(LockScreen.getCarrierString(plmn, spn)); + } + + public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { + + } + + public void onRingerModeChanged(int state) { + + } + + public void onTimeChanged() { + + } + + public void onSimStateChanged(State simState) { + + } +} diff --git a/policy/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/com/android/internal/policy/impl/SimUnlockScreen.java index 3881d11..8c738a7 100644 --- a/policy/com/android/internal/policy/impl/SimUnlockScreen.java +++ b/policy/com/android/internal/policy/impl/SimUnlockScreen.java @@ -27,7 +27,6 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; -import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.R; @@ -167,6 +166,7 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie } mCallback.pokeWakelock(); } else if (v == mEmergencyCallButton) { + mCallback.pokeWakelock(); mCallback.takeEmergencyCallAction(); } else if (v == mOkButton) { checkPin(); @@ -219,8 +219,8 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie mHeaderText.setText(R.string.keyguard_password_wrong_pin_code); mPinText.setText(""); mEnteredDigits = 0; - mCallback.pokeWakelock(); } + mCallback.pokeWakelock(); } }.start(); } diff --git a/policy/com/android/internal/policy/impl/UnlockScreen.java b/policy/com/android/internal/policy/impl/UnlockScreen.java index e090ac5..30ab879 100644 --- a/policy/com/android/internal/policy/impl/UnlockScreen.java +++ b/policy/com/android/internal/policy/impl/UnlockScreen.java @@ -197,6 +197,7 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient // emergency call buttons final OnClickListener emergencyClick = new OnClickListener() { public void onClick(View v) { + mCallback.pokeWakelock(); mCallback.takeEmergencyCallAction(); } }; |