summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
Diffstat (limited to 'policy')
-rw-r--r--policy/com/android/internal/policy/impl/AccountUnlockScreen.java2
-rw-r--r--policy/com/android/internal/policy/impl/GlobalActions.java1
-rw-r--r--policy/com/android/internal/policy/impl/KeyguardScreenCallback.java11
-rw-r--r--policy/com/android/internal/policy/impl/KeyguardViewManager.java6
-rw-r--r--policy/com/android/internal/policy/impl/KeyguardViewMediator.java77
-rw-r--r--policy/com/android/internal/policy/impl/LockPatternKeyguardView.java99
-rw-r--r--policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java7
-rw-r--r--policy/com/android/internal/policy/impl/LockScreen.java62
-rw-r--r--policy/com/android/internal/policy/impl/PasswordUnlockScreen.java262
-rw-r--r--policy/com/android/internal/policy/impl/PhoneWindow.java13
-rwxr-xr-xpolicy/com/android/internal/policy/impl/PhoneWindowManager.java63
-rw-r--r--policy/com/android/internal/policy/impl/RecentApplicationsDialog.java7
-rw-r--r--policy/com/android/internal/policy/impl/SimUnlockScreen.java4
-rw-r--r--policy/com/android/internal/policy/impl/UnlockScreen.java33
14 files changed, 531 insertions, 116 deletions
diff --git a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java
index 7992dd8..26419dd 100644
--- a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java
@@ -177,12 +177,14 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
+ mCallback.reportSuccessfulUnlockAttempt();
// close the keyguard
mCallback.keyguardDone(true);
} else {
mInstructions.setText(R.string.lockscreen_glogin_invalid_input);
mPassword.setText("");
+ mCallback.reportFailedUnlockAttempt();
}
}
diff --git a/policy/com/android/internal/policy/impl/GlobalActions.java b/policy/com/android/internal/policy/impl/GlobalActions.java
index 2f1f024..8b6257f 100644
--- a/policy/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/com/android/internal/policy/impl/GlobalActions.java
@@ -548,6 +548,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
Settings.System.AIRPLANE_MODE_ON,
on ? 1 : 0);
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra("state", on);
mContext.sendBroadcast(intent);
}
diff --git a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java b/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java
index 6bb6a45..06a5f19 100644
--- a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java
+++ b/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java
@@ -63,13 +63,18 @@ public interface KeyguardScreenCallback extends KeyguardViewCallback {
void takeEmergencyCallAction();
/**
- * Report that the user had a failed attempt unlocking via the pattern.
+ * Report that the user had a failed attempt to unlock with password or pattern.
*/
- void reportFailedPatternAttempt();
+ void reportFailedUnlockAttempt();
+
+ /**
+ * Report that the user successfully entered their password or pattern.
+ */
+ void reportSuccessfulUnlockAttempt();
/**
* Report whether we there's another way to unlock the device.
- * @return true
+ * @return true
*/
boolean doesFallbackUnlockScreenExist();
}
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/com/android/internal/policy/impl/KeyguardViewManager.java
index d4dc429..ba1d7f5 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -99,7 +99,7 @@ public class KeyguardViewManager implements KeyguardWindowController {
mKeyguardHost = new KeyguardViewHost(mContext, mCallback);
- final int stretch = ViewGroup.LayoutParams.FILL_PARENT;
+ final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
| WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
@@ -127,8 +127,8 @@ public class KeyguardViewManager implements KeyguardWindowController {
mKeyguardView.setCallback(mCallback);
final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT);
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
mKeyguardHost.addView(mKeyguardView, lp);
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
index 8d71146..c3c36b48 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -22,6 +22,7 @@ import com.android.internal.widget.LockPatternUtils;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.PendingIntent;
+import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -90,7 +91,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
private final static String TAG = "KeyguardViewMediator";
- private static final String DELAYED_KEYGUARD_ACTION =
+ private static final String DELAYED_KEYGUARD_ACTION =
"com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
// used for handler messages
@@ -106,7 +107,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
private static final int KEYGUARD_DONE_DRAWING = 10;
private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
private static final int SET_HIDDEN = 12;
-
+
/**
* The default amount of time we stay awake (used for all key input)
*/
@@ -132,12 +133,13 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
* that is reenabling the keyguard.
*/
private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
-
+
private Context mContext;
private AlarmManager mAlarmManager;
+ private StatusBarManager mStatusBarManager;
private boolean mSystemReady;
-
+
/** Low level access to the power manager for enableUserActivity. Having this
* requires that we run in the system process. */
LocalPowerManager mRealPowerManager;
@@ -232,7 +234,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
mRealPowerManager = powerManager;
mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPM.newWakeLock(
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
"keyguard");
mWakeLock.setReferenceCounted(false);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
@@ -255,16 +257,15 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
mUpdateMonitor.registerSimStateCallback(this);
- mKeyguardViewProperties =
- new LockPatternKeyguardViewProperties(
- new LockPatternUtils(mContext.getContentResolver()),
- mUpdateMonitor);
+ mKeyguardViewProperties = new LockPatternKeyguardViewProperties(
+ new LockPatternUtils(mContext), mUpdateMonitor);
mKeyguardViewManager = new KeyguardViewManager(
context, WindowManagerImpl.getDefault(), this,
mKeyguardViewProperties, mUpdateMonitor);
mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
+ mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
}
/**
@@ -294,7 +295,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
mExitSecureCallback.onKeyguardExitResult(false);
mExitSecureCallback = null;
if (!mExternallyEnabled) {
- hideLocked();
+ hideLocked();
}
} else if (mShowing) {
notifyScreenOffLocked();
@@ -311,7 +312,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
sender);
- if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+ if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+ mDelayedShowingSequence);
} else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
// Do not enable the keyguard if the prox sensor forced the screen off.
@@ -449,6 +450,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
if (mHidden != isHidden) {
mHidden = isHidden;
adjustUserActivityLocked();
+ adjustStatusBarLocked();
}
}
}
@@ -504,7 +506,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
return;
}
-
+
// if the setup wizard hasn't run yet, don't show
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
false);
@@ -518,7 +520,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
+ " and the sim is not locked or missing");
return;
}
-
+
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked();
}
@@ -556,7 +558,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
/**
* Send a message to keyguard telling it the screen just turned on.
- * @see #onScreenTurnedOn()
+ * @see #onScreenTurnedOn()
* @see #handleNotifyScreenOn
*/
private void notifyScreenOnLocked() {
@@ -599,7 +601,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
/**
* Send message to keyguard telling it to hide itself
- * @see #handleHide()
+ * @see #handleHide()
*/
private void hideLocked() {
if (DEBUG) Log.d(TAG, "hideLocked");
@@ -647,7 +649,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
public boolean isSecure() {
return mKeyguardViewProperties.isSecure();
}
-
+
private BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -688,7 +690,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
* The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
* Be sure not to take any action that takes a long time; any significant
* action should be posted to a handler.
- *
+ *
* @param keyCode The keycode of the key that woke the device
* @return Whether we poked the wake lock (and turned the screen on)
*/
@@ -711,12 +713,12 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_MUTE:
- case KeyEvent.KEYCODE_HEADSETHOOK:
- case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
- case KeyEvent.KEYCODE_MEDIA_STOP:
- case KeyEvent.KEYCODE_MEDIA_NEXT:
- case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
- case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_CAMERA:
return false;
@@ -749,7 +751,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
/**
* {@inheritDoc}
*
- * @see #handleKeyguardDone
+ * @see #handleKeyguardDone
*/
public void keyguardDone(boolean authenticated) {
keyguardDone(authenticated, true);
@@ -757,14 +759,14 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
public void keyguardDone(boolean authenticated, boolean wakeup) {
synchronized (this) {
- EventLog.writeEvent(70000, 2);
+ EventLog.writeEvent(70000, 2);
if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
msg.arg1 = wakeup ? 1 : 0;
mHandler.sendMessage(msg);
if (authenticated) {
- mUpdateMonitor.clearFailedAttempts();
+ mUpdateMonitor.clearFailedAttempts();
}
if (mExitSecureCallback != null) {
@@ -898,10 +900,11 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleShow");
if (!mSystemReady) return;
-
+
mKeyguardViewManager.show();
mShowing = true;
adjustUserActivityLocked();
+ adjustStatusBarLocked();
try {
ActivityManagerNative.getDefault().closeSystemDialogs("lock");
} catch (RemoteException e) {
@@ -925,6 +928,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
mKeyguardViewManager.hide();
mShowing = false;
adjustUserActivityLocked();
+ adjustStatusBarLocked();
}
}
@@ -939,6 +943,23 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
}
}
+ private void adjustStatusBarLocked() {
+ if (mStatusBarManager == null) {
+ mStatusBarManager = (StatusBarManager)
+ mContext.getSystemService(Context.STATUS_BAR_SERVICE);
+ }
+ if (mStatusBarManager == null) {
+ Log.w(TAG, "Could not get status bar manager");
+ } else {
+ // if the keyguard is shown, allow the status bar to open
+ // only if the keyguard is insecure and is covered by another window
+ boolean enable = !mShowing || (mHidden && !isSecure());
+ mStatusBarManager.disable(enable ?
+ StatusBarManager.DISABLE_NONE :
+ StatusBarManager.DISABLE_EXPAND);
+ }
+ }
+
/**
* Handle message sent by {@link #wakeWhenReadyLocked(int)}
* @param keyCode The key that woke the device.
@@ -969,7 +990,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
}
/**
- * Handle message sent by {@link #resetStateLocked()}
+ * Handle message sent by {@link #resetStateLocked()}
* @see #RESET
*/
private void handleReset() {
diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 85918fb..1e7d62e 100644
--- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -113,7 +113,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
}
/**
@@ -141,6 +146,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase
*/
private final LockPatternUtils mLockPatternUtils;
+ private int mNumAccounts;
private boolean mIsPortrait;
/**
@@ -153,22 +159,22 @@ public class LockPatternKeyguardView extends KeyguardViewBase
&& (mUpdateMonitor.getSimState() == IccCard.State.ABSENT);
}
+ // Called by AccountManager.getAccountByTypeAndFeatures() below...
public void run(AccountManagerFuture<Account[]> future) {
- // We err on the side of caution.
- // In case of error we assume we have a SAML account.
- boolean hasSAMLAccount = true;
+ int samlAccounts = 0;
try {
- hasSAMLAccount = future.getResult().length > 0;
+ samlAccounts = future.getResult().length;
} catch (OperationCanceledException e) {
} catch (IOException e) {
} catch (AuthenticatorException e) {
}
- mEnableFallback = !hasSAMLAccount;
+ // At least one of the accounts must be non-SAML to enable the fallback.
+ mEnableFallback = samlAccounts < mNumAccounts;
if (mUnlockScreen == null) {
Log.w(TAG, "no unlock screen when receiving AccountManager information");
} else if (mUnlockScreen instanceof UnlockScreen) {
- ((UnlockScreen)mUnlockScreen).setEnableFallback(true);
+ ((UnlockScreen)mUnlockScreen).setEnableFallback(mEnableFallback);
}
}
@@ -290,6 +296,14 @@ public class LockPatternKeyguardView extends KeyguardViewBase
public boolean doesFallbackUnlockScreenExist() {
return mEnableFallback;
}
+
+ public void reportFailedUnlockAttempt() {
+ mLockPatternUtils.reportFailedPasswordAttempt();
+ }
+
+ public void reportSuccessfulUnlockAttempt() {
+ mLockPatternUtils.reportSuccessfulPasswordAttempt();
+ }
};
/**
@@ -317,12 +331,19 @@ public class LockPatternKeyguardView extends KeyguardViewBase
mUnlockScreen = createUnlockScreenFor(unlockMode);
mUnlockScreenMode = unlockMode;
+ maybeEnableFallback(context);
+
+ addView(mUnlockScreen);
+ updateScreen(mMode);
+ }
+
+ private void maybeEnableFallback(Context context) {
// Ask the account manager if we have an account that can be used as a
// fallback in case the user forgets his pattern. The response comes
// back in run() below; don't bother asking until you've called
// createUnlockScreenFor(), else the information will go unused.
- final boolean hasAccount = AccountManager.get(context).getAccounts().length > 0;
- if (hasAccount) {
+ mNumAccounts = AccountManager.get(context).getAccounts().length;
+ if (mNumAccounts > 0) {
/* If we have a SAML account which requires web login we can not use the
fallback screen UI to ask the user for credentials.
For now we will disable fallback screen in this case.
@@ -332,9 +353,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase
AccountManager.get(context).getAccountsByTypeAndFeatures(
"com.google", features, this, null);
}
-
- addView(mUnlockScreen);
- updateScreen(mMode);
}
@@ -460,16 +478,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) {
@@ -553,6 +580,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);
}
@@ -604,13 +637,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/LockScreen.java b/policy/com/android/internal/policy/impl/LockScreen.java
index c370f9e..657bff1 100644
--- a/policy/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/com/android/internal/policy/impl/LockScreen.java
@@ -23,6 +23,7 @@ import com.android.internal.widget.SlidingTab;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.ColorStateList;
import android.text.format.DateFormat;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -274,9 +275,14 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
getContext().getString(R.string.global_action_silent_mode_on_status) :
getContext().getString(R.string.global_action_silent_mode_off_status);
- final int toastIcon = mSilentMode ? R.drawable.ic_lock_ringer_off
- : R.drawable.ic_lock_ringer_on;
- toastMessage(mScreenLocked, message, toastIcon);
+ final int toastIcon = mSilentMode
+ ? R.drawable.ic_lock_ringer_off
+ : R.drawable.ic_lock_ringer_on;
+
+ final int toastColor = mSilentMode
+ ? getContext().getResources().getColor(R.color.keyguard_text_color_soundoff)
+ : getContext().getResources().getColor(R.color.keyguard_text_color_soundon);
+ toastMessage(mScreenLocked, message, toastColor, toastIcon);
mCallback.pokeWakelock();
}
}
@@ -292,32 +298,43 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
}
/**
- * Displays a message in a text view and then removes it.
+ * Displays a message in a text view and then restores the previous text.
* @param textView The text view.
* @param text The text.
+ * @param color The color to apply to the text, or 0 if the existing color should be used.
* @param iconResourceId The left hand icon.
*/
- private void toastMessage(final TextView textView, final String text, final int iconResourceId) {
+ private void toastMessage(final TextView textView, final String text, final int color, final int iconResourceId) {
+ if (DBG) android.util.Log.d("LockScreen", "toastMessage(text=" + text +", color=" + color + ")");
+
if (mPendingR1 != null) {
textView.removeCallbacks(mPendingR1);
mPendingR1 = null;
}
if (mPendingR2 != null) {
+ mPendingR2.run(); // fire immediately, restoring non-toasted appearance
textView.removeCallbacks(mPendingR2);
mPendingR2 = null;
}
+ final String oldText = textView.getText().toString();
+ final ColorStateList oldColors = textView.getTextColors();
+
mPendingR1 = new Runnable() {
public void run() {
textView.setText(text);
+ if (color != 0) {
+ textView.setTextColor(color);
+ }
textView.setCompoundDrawablesWithIntrinsicBounds(iconResourceId, 0, 0, 0);
- textView.setCompoundDrawablePadding(4);
}
};
+
textView.postDelayed(mPendingR1, 0);
mPendingR2 = new Runnable() {
public void run() {
- textView.setText("");
+ textView.setText(oldText);
+ textView.setTextColor(oldColors);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
};
@@ -415,11 +432,11 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
updateLayout(mStatus);
}
- private void putEmergencyBelow(int viewId) {
+ private void addRelativeLayoutRule(View view, int rule, int viewId) {
final RelativeLayout.LayoutParams layoutParams =
- (RelativeLayout.LayoutParams) mEmergencyCallButton.getLayoutParams();
- layoutParams.addRule(RelativeLayout.BELOW, viewId);
- mEmergencyCallButton.setLayoutParams(layoutParams);
+ (RelativeLayout.LayoutParams) view.getLayoutParams();
+ layoutParams.addRule(rule, viewId);
+ view.setLayoutParams(layoutParams);
}
/**
@@ -455,6 +472,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
* Update the layout to match the current status.
*/
private void updateLayout(Status status) {
+ // The emergency call button appears where the carrier would
+ // ordinarily be shown, so if one is VISIBLE the other must be
+ // INVISIBLE.
switch (status) {
case Normal:
// text
@@ -485,31 +505,31 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
break;
case SimMissing:
// text
- mCarrier.setText(
+ mCarrier.setText("");
+ mScreenLocked.setText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_missing_sim_message_short)));
- mScreenLocked.setText(R.string.lockscreen_instructions_when_pattern_disabled);
+ // previously shown here: lockscreen_instructions_when_pattern_disabled
// layout
- mScreenLocked.setVisibility(View.INVISIBLE);
+ mScreenLocked.setVisibility(View.VISIBLE);
mSelector.setVisibility(View.VISIBLE);
mEmergencyCallButton.setVisibility(View.VISIBLE);
- putEmergencyBelow(R.id.screenLocked);
break;
case SimMissingLocked:
// text
- mCarrier.setText(
+ mCarrier.setText("");
+ mScreenLocked.setText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_missing_sim_message_short)));
- mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions);
+ // previously shown here: lockscreen_missing_sim_instructions
// layout
mScreenLocked.setVisibility(View.VISIBLE);
mSelector.setVisibility(View.GONE);
mEmergencyCallButton.setVisibility(View.VISIBLE);
- putEmergencyBelow(R.id.screenLocked);
break;
case SimLocked:
// text
@@ -525,17 +545,17 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
break;
case SimPukLocked:
// text
- mCarrier.setText(
+ mCarrier.setText("");
+ mScreenLocked.setText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_sim_puk_locked_message)));
- mScreenLocked.setText(R.string.lockscreen_sim_puk_locked_instructions);
+ // previously shown here: lockscreen_sim_puk_locked_instructions);
// layout
mScreenLocked.setVisibility(View.VISIBLE);
mSelector.setVisibility(View.GONE);
mEmergencyCallButton.setVisibility(View.VISIBLE);
- putEmergencyBelow(R.id.screenLocked);
break;
}
}
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..1a250b8
--- /dev/null
+++ b/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -0,0 +1,262 @@
+/*
+ * 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 static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+ // To avoid accidental lockout due to events while the device in in the pocket, ignore
+ // any passwords with length less than or equal to this length.
+ private static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
+
+ 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)) {
+ mCallback.keyguardDone(true);
+ mCallback.reportSuccessfulUnlockAttempt();
+ } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {
+ // to avoid accidental lockout, only count attempts that are long enough to be a
+ // real password. This may require some tweaking.
+ mCallback.reportFailedUnlockAttempt();
+ }
+ 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/PhoneWindow.java b/policy/com/android/internal/policy/impl/PhoneWindow.java
index 6dd5d93..55772b2 100644
--- a/policy/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindow.java
@@ -15,7 +15,7 @@
package com.android.internal.policy.impl;
-import static android.view.ViewGroup.LayoutParams.FILL_PARENT;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@@ -41,8 +41,6 @@ import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -61,7 +59,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewManager;
import android.view.VolumePanel;
@@ -204,7 +201,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public void setContentView(View view) {
- setContentView(view, new ViewGroup.LayoutParams(FILL_PARENT, FILL_PARENT));
+ setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
@Override
@@ -424,7 +421,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
int backgroundResId;
- if (lp.width == ViewGroup.LayoutParams.FILL_PARENT) {
+ if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
// If the contents is fill parent for the width, set the
// corresponding background
backgroundResId = st.fullBackground;
@@ -1811,7 +1808,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (SWEEP_OPEN_MENU) {
if (mMenuBackground == null && mFeatureId < 0
&& getAttributes().height
- == WindowManager.LayoutParams.FILL_PARENT) {
+ == WindowManager.LayoutParams.MATCH_PARENT) {
mMenuBackground = getContext().getResources().getDrawable(
com.android.internal.R.drawable.menu_background);
}
@@ -2151,7 +2148,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mDecor.startChanging();
View in = mLayoutInflater.inflate(layoutResource, null);
- decor.addView(in, new ViewGroup.LayoutParams(FILL_PARENT, FILL_PARENT));
+ decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
if (contentParent == null) {
diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
index 30f0d2d..f071771 100755
--- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -100,6 +100,8 @@ import android.view.animation.AnimationUtils;
import android.media.IAudioService;
import android.media.AudioManager;
+import java.util.ArrayList;
+
/**
* WindowManagerPolicy implementation for the Android phone UI. This
* introduces a new method suffix, Lp, for an internal lock of the
@@ -181,6 +183,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mSafeMode;
WindowState mStatusBar = null;
+ final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
WindowState mKeyguard = null;
KeyguardViewMediator mKeyguardMediator;
GlobalActions mGlobalActions;
@@ -802,8 +805,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- win.setLayout(WindowManager.LayoutParams.FILL_PARENT,
- WindowManager.LayoutParams.FILL_PARENT);
+ win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.MATCH_PARENT);
final WindowManager.LayoutParams params = win.getAttributes();
params.token = appToken;
@@ -881,6 +884,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
mStatusBar = win;
break;
+ case TYPE_STATUS_BAR_PANEL:
+ mStatusBarPanels.add(win);
+ break;
case TYPE_KEYGUARD:
if (mKeyguard != null) {
return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
@@ -898,6 +904,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
else if (mKeyguard == win) {
mKeyguard = null;
+ } else {
+ mStatusBarPanels.remove(win);
}
}
@@ -1436,7 +1444,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mKeyguard != null) {
if (localLOGV) Log.v(TAG, "finishLayoutLw::mHideKeyguard="+mHideLockScreen);
if (mDismissKeyguard && !mKeyguardMediator.isSecure()) {
- if (mKeyguard.hideLw(false)) {
+ if (mKeyguard.hideLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1449,14 +1457,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
});
}
} else if (mHideLockScreen) {
- if (mKeyguard.hideLw(false)) {
+ if (mKeyguard.hideLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
}
mKeyguardMediator.setHidden(true);
} else {
- if (mKeyguard.showLw(false)) {
+ if (mKeyguard.showLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1493,6 +1501,33 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return false;
}
+ public boolean allowAppAnimationsLw() {
+ if (mKeyguard != null && mKeyguard.isVisibleLw()) {
+ // If keyguard is currently visible, no reason to animate
+ // behind it.
+ return false;
+ }
+ if (mStatusBar != null && mStatusBar.isVisibleLw()) {
+ Rect rect = new Rect(mStatusBar.getShownFrameLw());
+ for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
+ WindowState w = mStatusBarPanels.get(i);
+ if (w.isVisibleLw()) {
+ rect.union(w.getShownFrameLw());
+ }
+ }
+ final int insetw = mW/10;
+ final int inseth = mH/10;
+ if (rect.contains(insetw, inseth, mW-insetw, mH-inseth)) {
+ // All of the status bar windows put together cover the
+ // screen, so the app can't be seen. (Note this test doesn't
+ // work if the rects of these windows are at off offsets or
+ // sizes, causing gaps in the rect union we have computed.)
+ return false;
+ }
+ }
+ return true;
+ }
+
/** {@inheritDoc} */
public boolean preprocessInputEventTq(RawInputEvent event) {
switch (event.type) {
@@ -1725,8 +1760,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHandler.removeCallbacks(mPowerLongPress);
if (mShouldTurnOffOnKeyUp) {
mShouldTurnOffOnKeyUp = false;
- boolean gohome = (mEndcallBehavior & ENDCALL_HOME) != 0;
- boolean sleeps = (mEndcallBehavior & ENDCALL_SLEEPS) != 0;
+ boolean gohome, sleeps;
+ if (code == KeyEvent.KEYCODE_ENDCALL) {
+ gohome = (mEndcallBehavior & ENDCALL_HOME) != 0;
+ sleeps = (mEndcallBehavior & ENDCALL_SLEEPS) != 0;
+ } else {
+ gohome = false;
+ sleeps = true;
+ }
if (keyguardActive
|| (sleeps && !gohome)
|| (gohome && !goHome() && sleeps)) {
@@ -1919,6 +1960,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/** {@inheritDoc} */
+ public boolean isScreenOn() {
+ return mScreenOn;
+ }
+
+ /** {@inheritDoc} */
public void enableKeyguard(boolean enabled) {
mKeyguardMediator.setKeyguardEnabled(enabled);
}
@@ -1928,8 +1974,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mKeyguardMediator.verifyUnlock(callback);
}
- /** {@inheritDoc} */
- public boolean keyguardIsShowingTq() {
+ private boolean keyguardIsShowingTq() {
return mKeyguardMediator.isShowingAndNotHidden();
}
diff --git a/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java
index 4c46be5..c5aafa5 100644
--- a/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ b/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java
@@ -110,8 +110,11 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
if (b == v) {
// prepare a launch intent and send it
Intent intent = (Intent)b.getTag();
- intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
- getContext().startActivity(intent);
+ if (intent != null) {
+ intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+ getContext().startActivity(intent);
+ }
+ break;
}
}
dismiss();
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..5e6e54d 100644
--- a/policy/com/android/internal/policy/impl/UnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/UnlockScreen.java
@@ -52,12 +52,20 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient
// how long before we clear the wrong pattern
private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000;
- // how long we stay awake once the user is ready to enter a pattern
+ // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK
private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000;
+ // how long we stay awake after the user hits the first dot.
+ private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000;
+
// how many cells the user has to cross before we poke the wakelock
private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
+ // This dictates how long a pattern should be before we count it as an attempt.
+ // This should be long enough to avoid false triggers while the device is in a pocket,
+ // as this can lead to a wiped device if a {@link DeviceAdmin} is active and has it enabled.
+ private static final int MIN_PATTERN_BEFORE_REPORT = 3;
+
private int mFailedPatternAttemptsSinceLastTimeout = 0;
private int mTotalFailedPatternAttempts = 0;
private CountDownTimer mCountdownTimer = null;
@@ -197,6 +205,7 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient
// emergency call buttons
final OnClickListener emergencyClick = new OnClickListener() {
public void onClick(View v) {
+ mCallback.pokeWakelock();
mCallback.takeEmergencyCallAction();
}
};
@@ -465,6 +474,9 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient
// the user actually trying to draw a pattern of some minimal length.
if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
+ } else {
+ // Give just a little extra time if they hit one of the first few dots
+ mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
}
}
@@ -475,6 +487,7 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient
mInstructions = "";
updateStatusLines();
mCallback.keyguardDone(true);
+ mCallback.reportSuccessfulUnlockAttempt();
} else {
if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
@@ -483,19 +496,21 @@ class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient
if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
mTotalFailedPatternAttempts++;
mFailedPatternAttemptsSinceLastTimeout++;
- mCallback.reportFailedPatternAttempt();
}
if (mFailedPatternAttemptsSinceLastTimeout >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
handleAttemptLockout(deadline);
- return;
+ } else {
+ // TODO mUnlockIcon.setVisibility(View.VISIBLE);
+ mInstructions = getContext().getString(R.string.lockscreen_pattern_wrong);
+ updateStatusLines();
+ mLockPatternView.postDelayed(
+ mCancelPatternRunnable,
+ PATTERN_CLEAR_TIMEOUT_MS);
+ }
+ if (pattern.size() > MIN_PATTERN_BEFORE_REPORT) {
+ mCallback.reportFailedUnlockAttempt();
}
- // TODO mUnlockIcon.setVisibility(View.VISIBLE);
- mInstructions = getContext().getString(R.string.lockscreen_pattern_wrong);
- updateStatusLines();
- mLockPatternView.postDelayed(
- mCancelPatternRunnable,
- PATTERN_CLEAR_TIMEOUT_MS);
}
}
}