diff options
author | John Wang <johnwang@google.com> | 2011-06-07 13:16:09 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-06-07 13:16:09 -0700 |
commit | 1f8665895f71904b9d757854277cb637841356c3 (patch) | |
tree | ea94cf6ddf3e49f958f9f401b031de15a0c523d4 /policy | |
parent | e139167c9109aee203f5fbbdeeab656994d9c9ac (diff) | |
parent | 71030e536522449f34dc584fda94f34e7be6ee19 (diff) | |
download | frameworks_base-1f8665895f71904b9d757854277cb637841356c3.zip frameworks_base-1f8665895f71904b9d757854277cb637841356c3.tar.gz frameworks_base-1f8665895f71904b9d757854277cb637841356c3.tar.bz2 |
am 71030e53: Merge "Add SIM PUK unlockscreen." into honeycomb-LTE
* commit '71030e536522449f34dc584fda94f34e7be6ee19':
Add SIM PUK unlockscreen.
Diffstat (limited to 'policy')
5 files changed, 520 insertions, 22 deletions
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java index 5ed67a9..72209f6 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java @@ -480,11 +480,11 @@ public class KeyguardUpdateMonitor { } /** - * Report that the user succesfully entered the sim pin so we + * Report that the user succesfully entered the sim pin or puk so we * have the information earlier than waiting for the intent * broadcast from the telephony code. */ - public void reportSimPinUnlocked() { + public void reportSimUnlocked() { mSimState = IccCard.State.READY; } diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 2fda3aa..874acd0 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -116,6 +116,11 @@ public class LockPatternKeyguardView extends KeyguardViewBase { SimPin, /** + * Unlock by entering a sim puk. + */ + SimPuk, + + /** * Unlock by entering an account's login and password. */ Account, @@ -222,8 +227,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase { public void goToUnlockScreen() { final IccCard.State simState = mUpdateMonitor.getSimState(); if (stuckOnLockScreenBecauseSimMissing() - || (simState == IccCard.State.PUK_REQUIRED)){ - // stuck on lock screen when sim missing or puk'd + || (simState == IccCard.State.PUK_REQUIRED + && !mLockPatternUtils.isPukUnlockScreenEnable())){ + // stuck on lock screen when sim missing or + // puk'd but puk unlock screen is disabled return; } if (!isSecure()) { @@ -522,8 +529,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase { secure = mLockPatternUtils.isLockPatternEnabled(); break; case SimPin: - secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED - || mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED; + secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED; + break; + case SimPuk: + secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED; break; case Account: secure = true; @@ -592,6 +601,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase { View createUnlockScreenFor(UnlockMode unlockMode) { View unlockView = null; + + if (DEBUG) Log.d(TAG, + "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback); + if (unlockMode == UnlockMode.Pattern) { PatternUnlockScreen view = new PatternUnlockScreen( mContext, @@ -600,10 +613,15 @@ public class LockPatternKeyguardView extends KeyguardViewBase { mUpdateMonitor, mKeyguardScreenCallback, mUpdateMonitor.getFailedAttempts()); - if (DEBUG) Log.d(TAG, - "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback); view.setEnableFallback(mEnableFallback); unlockView = view; + } else if (unlockMode == UnlockMode.SimPuk) { + unlockView = new SimPukUnlockScreen( + mContext, + mConfiguration, + mUpdateMonitor, + mKeyguardScreenCallback, + mLockPatternUtils); } else if (unlockMode == UnlockMode.SimPin) { unlockView = new SimUnlockScreen( mContext, @@ -654,7 +672,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase { */ private Mode getInitialMode() { final IccCard.State simState = mUpdateMonitor.getSimState(); - if (stuckOnLockScreenBecauseSimMissing() || (simState == IccCard.State.PUK_REQUIRED)) { + if (stuckOnLockScreenBecauseSimMissing() || + (simState == IccCard.State.PUK_REQUIRED && + !mLockPatternUtils.isPukUnlockScreenEnable())) { return Mode.LockScreen; } else { // Show LockScreen first for any screen other than Pattern unlock. @@ -676,8 +696,10 @@ 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) { + if (simState == IccCard.State.PIN_REQUIRED) { currentMode = UnlockMode.SimPin; + } else if (simState == IccCard.State.PUK_REQUIRED) { + currentMode = UnlockMode.SimPuk; } else { final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality(); switch (mode) { diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index a9d5ce4..7331bda 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -232,7 +232,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen, /** {@inheritDoc} */ public void onGrabbedStateChange(View v, int grabbedState) { - if (DBG) Log.v(TAG, "*** LockScreen accel is " + if (DBG) Log.v(TAG, "*** LockScreen accel is " + (mEnergyWave.isHardwareAccelerated() ? "on":"off")); // Don't poke the wake lock when returning to a state where the handle is // not grabbed since that can happen when the system (instead of the user) @@ -579,10 +579,16 @@ class LockScreen extends LinearLayout implements KeyguardScreen, mScreenLocked.setText(R.string.lockscreen_sim_puk_locked_instructions); // layout - mScreenLocked.setVisibility(View.VISIBLE); - mEmergencyCallText.setVisibility(View.VISIBLE); - mEmergencyCallButton.setVisibility(View.VISIBLE); - disableUnlock(); + if (mLockPatternUtils.isPukUnlockScreenEnable()) { + mScreenLocked.setVisibility(View.INVISIBLE); + mEmergencyCallText.setVisibility(View.GONE); + enableUnlock(); + } else { + mScreenLocked.setVisibility(View.VISIBLE); + mEmergencyCallText.setVisibility(View.VISIBLE); + mEmergencyCallButton.setVisibility(View.VISIBLE); + disableUnlock(); + } break; } } diff --git a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java new file mode 100644 index 0000000..544bb3d --- /dev/null +++ b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2008 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.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.res.Configuration; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.telephony.ITelephony; +import com.android.internal.telephony.IccCard; +import com.android.internal.widget.LockPatternUtils; + +import android.text.Editable; +import android.util.Log; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.android.internal.R; + +/** + * Displays a dialer like interface to unlock the SIM PUK. + */ +public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen, + View.OnClickListener, KeyguardUpdateMonitor.InfoCallback { + + private static final int DIGIT_PRESS_WAKE_MILLIS = 5000; + + private final KeyguardUpdateMonitor mUpdateMonitor; + private final KeyguardScreenCallback mCallback; + + private TextView mHeaderText; + private TextView mPukText; + private TextView mPinText; + + private TextView mFocusedEntry; + + private TextView mOkButton; + private Button mEmergencyCallButton; + + private View mDelPukButton; + private View mDelPinButton; + + private ProgressDialog mSimUnlockProgressDialog = null; + + private LockPatternUtils mLockPatternUtils; + + private int mCreationOrientation; + + private int mKeyboardHidden; + + private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + public SimPukUnlockScreen(Context context, Configuration configuration, + KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback, + LockPatternUtils lockpatternutils) { + super(context); + mUpdateMonitor = updateMonitor; + mCallback = callback;; + + mCreationOrientation = configuration.orientation; + mKeyboardHidden = configuration.hardKeyboardHidden; + mLockPatternUtils = lockpatternutils; + + LayoutInflater inflater = LayoutInflater.from(context); + if (mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) { + inflater.inflate( + R.layout.keyguard_screen_sim_puk_landscape, this, true); + } else { + inflater.inflate( + R.layout.keyguard_screen_sim_puk_portrait, this, true); + new TouchInput(); + } + + mHeaderText = (TextView) findViewById(R.id.headerText); + mPukText = (TextView) findViewById(R.id.pukDisplay); + mPukText.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + requestFocus(mPukText); + mCallback.pokeWakelock(); + } + }); + mPinText = (TextView) findViewById(R.id.pinDisplay); + mPinText.setOnClickListener(this); + + mDelPukButton = findViewById(R.id.pukDel); + mDelPukButton.setOnClickListener(this); + mDelPinButton = findViewById(R.id.pinDel); + mDelPinButton.setOnClickListener(this); + + + mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall); + mOkButton = (TextView) findViewById(R.id.ok); + + mHeaderText.setText(R.string.keyguard_password_enter_puk_code); + mPukText.setFocusable(false); + mPinText.setFocusable(false); + mOkButton.setOnClickListener(this); + + requestFocus(mPukText); + + if (mLockPatternUtils.isEmergencyCallCapable()) { + mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); + mEmergencyCallButton.setOnClickListener(this); + } else { + mEmergencyCallButton.setVisibility(View.GONE); + } + + setFocusableInTouchMode(true); + } + + private void requestFocus(TextView entry) { + mFocusedEntry = entry; + mFocusedEntry.setText(""); + } + + /** {@inheritDoc} */ + public boolean needsInput() { + return true; + } + + /** {@inheritDoc} */ + public void onPause() { + + } + + /** {@inheritDoc} */ + public void onResume() { + // start fresh + mHeaderText.setText(R.string.keyguard_password_enter_puk_code); + requestFocus(mPukText); + mPinText.setText(""); + + if (mLockPatternUtils.isEmergencyCallCapable()) { + mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); + } + } + + /** {@inheritDoc} */ + public void cleanUp() { + // dismiss the dialog. + if (mSimUnlockProgressDialog != null) { + mSimUnlockProgressDialog.dismiss(); + mSimUnlockProgressDialog = null; + } + mUpdateMonitor.removeCallback(this); + } + + + /** + * Since the IPC can block, we want to run the request in a separate thread + * with a callback. + */ + private abstract class CheckSimPuk extends Thread { + + private final String mPin, mPuk; + + protected CheckSimPuk(String puk, String pin) { + mPuk = puk; + mPin = pin; + } + + abstract void onSimLockChangedResponse(boolean success); + + @Override + public void run() { + try { + final boolean result = ITelephony.Stub.asInterface(ServiceManager + .checkService("phone")).supplyPuk(mPuk, mPin); + + post(new Runnable() { + public void run() { + onSimLockChangedResponse(result); + } + }); + } catch (RemoteException e) { + post(new Runnable() { + public void run() { + onSimLockChangedResponse(false); + } + }); + } + } + } + + public void onClick(View v) { + if (v == mDelPukButton) { + final Editable digits = mPukText.getEditableText(); + final int len = digits.length(); + if (len > 0) { + digits.delete(len-1, len); + } + mCallback.pokeWakelock(); + } else if (v == mDelPinButton) { + final Editable digits = mPinText.getEditableText(); + final int len = digits.length(); + if (len > 0) { + digits.delete(len-1, len); + } + mCallback.pokeWakelock(); + } else if (v == mPinText) { + requestFocus(mPinText); + mCallback.pokeWakelock(); + } else if (v == mEmergencyCallButton) { + mCallback.takeEmergencyCallAction(); + } else if (v == mOkButton) { + checkPuk(); + } + } + + private Dialog getSimUnlockProgressDialog() { + if (mSimUnlockProgressDialog == null) { + mSimUnlockProgressDialog = new ProgressDialog(mContext); + mSimUnlockProgressDialog.setMessage( + mContext.getString(R.string.lockscreen_sim_unlock_progress_dialog_message)); + mSimUnlockProgressDialog.setIndeterminate(true); + mSimUnlockProgressDialog.setCancelable(false); + mSimUnlockProgressDialog.getWindow().setType( + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + if (!mContext.getResources().getBoolean( + com.android.internal.R.bool.config_sf_slowBlur)) { + mSimUnlockProgressDialog.getWindow().setFlags( + WindowManager.LayoutParams.FLAG_BLUR_BEHIND, + WindowManager.LayoutParams.FLAG_BLUR_BEHIND); + } + } + return mSimUnlockProgressDialog; + } + + private void checkPuk() { + // make sure that the puk is at least 8 digits long. + if (mPukText.getText().length() < 8) { + // otherwise, display a message to the user, and don't submit. + mHeaderText.setText(R.string.invalidPuk); + mPukText.setText(""); + mCallback.pokeWakelock(); + return; + } + + if (mPinText.getText().length() < 4 + || mPinText.getText().length() > 8) { + // otherwise, display a message to the user, and don't submit. + mHeaderText.setText(R.string.invalidPin); + mPinText.setText(""); + mCallback.pokeWakelock(); + return; + } + + getSimUnlockProgressDialog().show(); + + new CheckSimPuk(mPukText.getText().toString(), + mPinText.getText().toString()) { + void onSimLockChangedResponse(boolean success) { + if (mSimUnlockProgressDialog != null) { + mSimUnlockProgressDialog.hide(); + } + if (success) { + // before closing the keyguard, report back that + // the sim is unlocked so it knows right away + mUpdateMonitor.reportSimUnlocked(); + mCallback.goToUnlockScreen(); + } else { + mHeaderText.setText(R.string.badPuk); + mPukText.setText(""); + mPinText.setText(""); + } + mCallback.pokeWakelock(); + } + }.start(); + } + + + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + mCallback.goToLockScreen(); + return true; + } + final char match = event.getMatch(DIGITS); + if (match != 0) { + reportDigit(match - '0'); + return true; + } + if (keyCode == KeyEvent.KEYCODE_DEL) { + mFocusedEntry.onKeyDown(keyCode, event); + final Editable digits = mFocusedEntry.getEditableText(); + final int len = digits.length(); + if (len > 0) { + digits.delete(len-1, len); + } + mCallback.pokeWakelock(); + return true; + } + + if (keyCode == KeyEvent.KEYCODE_ENTER) { + checkPuk(); + return true; + } + + return false; + } + + private void reportDigit(int digit) { + mFocusedEntry.append(Integer.toString(digit)); + } + + void updateConfiguration() { + Configuration newConfig = getResources().getConfiguration(); + if (newConfig.orientation != mCreationOrientation) { + mCallback.recreateMe(newConfig); + } else if (newConfig.hardKeyboardHidden != mKeyboardHidden) { + mKeyboardHidden = newConfig.hardKeyboardHidden; + final boolean isKeyboardOpen = + (mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO); + if (mUpdateMonitor.isKeyguardBypassEnabled() && isKeyboardOpen) { + mCallback.goToUnlockScreen(); + } + } + + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + updateConfiguration(); + } + + /** {@inheritDoc} */ + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + updateConfiguration(); + } + + /** + * Helper class to handle input from touch dialer. Only relevant when + * the keyboard is shut. + */ + private class TouchInput implements View.OnClickListener { + private TextView mZero; + private TextView mOne; + private TextView mTwo; + private TextView mThree; + private TextView mFour; + private TextView mFive; + private TextView mSix; + private TextView mSeven; + private TextView mEight; + private TextView mNine; + private TextView mCancelButton; + + private TouchInput() { + mZero = (TextView) findViewById(R.id.zero); + mOne = (TextView) findViewById(R.id.one); + mTwo = (TextView) findViewById(R.id.two); + mThree = (TextView) findViewById(R.id.three); + mFour = (TextView) findViewById(R.id.four); + mFive = (TextView) findViewById(R.id.five); + mSix = (TextView) findViewById(R.id.six); + mSeven = (TextView) findViewById(R.id.seven); + mEight = (TextView) findViewById(R.id.eight); + mNine = (TextView) findViewById(R.id.nine); + mCancelButton = (TextView) findViewById(R.id.cancel); + + mZero.setText("0"); + mOne.setText("1"); + mTwo.setText("2"); + mThree.setText("3"); + mFour.setText("4"); + mFive.setText("5"); + mSix.setText("6"); + mSeven.setText("7"); + mEight.setText("8"); + mNine.setText("9"); + + mZero.setOnClickListener(this); + mOne.setOnClickListener(this); + mTwo.setOnClickListener(this); + mThree.setOnClickListener(this); + mFour.setOnClickListener(this); + mFive.setOnClickListener(this); + mSix.setOnClickListener(this); + mSeven.setOnClickListener(this); + mEight.setOnClickListener(this); + mNine.setOnClickListener(this); + mCancelButton.setOnClickListener(this); + } + + + public void onClick(View v) { + if (v == mCancelButton) { + mCallback.goToLockScreen(); + return; + } + + final int digit = checkDigit(v); + if (digit >= 0) { + mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS); + reportDigit(digit); + } + } + + private int checkDigit(View v) { + int digit = -1; + if (v == mZero) { + digit = 0; + } else if (v == mOne) { + digit = 1; + } else if (v == mTwo) { + digit = 2; + } else if (v == mThree) { + digit = 3; + } else if (v == mFour) { + digit = 4; + } else if (v == mFive) { + digit = 5; + } else if (v == mSix) { + digit = 6; + } else if (v == mSeven) { + digit = 7; + } else if (v == mEight) { + digit = 8; + } else if (v == mNine) { + digit = 9; + } + return digit; + } + } + + public void onPhoneStateChanged(String newState) { + if (mLockPatternUtils.isEmergencyCallCapable()) { + mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); + } + } + + public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { + + } + + public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { + + } + + public void onRingerModeChanged(int state) { + + } + + public void onTimeChanged() { + + } +} diff --git a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java index 486e7aa..7255c27 100644 --- a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java +++ b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java @@ -92,16 +92,17 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie mBackSpaceButton = findViewById(R.id.backspace); mBackSpaceButton.setOnClickListener(this); - mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); mOkButton = (TextView) findViewById(R.id.ok); mHeaderText.setText(R.string.keyguard_password_enter_pin_code); mPinText.setFocusable(false); - mEmergencyCallButton.setOnClickListener(this); mOkButton.setOnClickListener(this); + mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall); + mEmergencyCallButton.setOnClickListener(this); + mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); + setFocusableInTouchMode(true); } @@ -229,7 +230,7 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie if (success) { // before closing the keyguard, report back that // the sim is unlocked so it knows right away - mUpdateMonitor.reportSimPinUnlocked(); + mUpdateMonitor.reportSimUnlocked(); mCallback.goToUnlockScreen(); } else { mHeaderText.setText(R.string.keyguard_password_wrong_pin_code); @@ -291,9 +292,8 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie mCallback.goToUnlockScreen(); } } - } - + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); @@ -403,7 +403,7 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie } public void onPhoneStateChanged(String newState) { - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); + mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); } public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { |