summaryrefslogtreecommitdiffstats
path: root/policy/src
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-08-18 18:30:09 -0700
committerDianne Hackborn <hackbod@google.com>2011-08-23 17:44:52 -0700
commit29aae6f36e565b8f2a99f2193597b964bb800ee8 (patch)
tree72d0d0798fe9549ebc82e1766464d1fe3ea5233f /policy/src
parent5b56f7d6f662a543d0432a46047a55f1ee900994 (diff)
downloadframeworks_base-29aae6f36e565b8f2a99f2193597b964bb800ee8.zip
frameworks_base-29aae6f36e565b8f2a99f2193597b964bb800ee8.tar.gz
frameworks_base-29aae6f36e565b8f2a99f2193597b964bb800ee8.tar.bz2
Fix issue #4279860: previous UI flashes before showing lock screen...
...(when turning display on after recently turning it off) Also clean up when we decide to turn the screen on to improve that transition. There are still problems here with turning it on before the wallpaper gets dispayed. Change-Id: I2bc56c12e5ad75a1ce5a0546f43a845bf0823e66
Diffstat (limited to 'policy/src')
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java229
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java23
3 files changed, 158 insertions, 96 deletions
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index afa92f1..9629702 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -43,7 +43,7 @@ import android.widget.TextView;
*
*/
class KeyguardStatusViewManager implements OnClickListener {
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final String TAG = "KeyguardStatusView";
public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 431f8e0..5661116 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -116,6 +116,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
private static final int SET_HIDDEN = 12;
private static final int KEYGUARD_TIMEOUT = 13;
+ private static final int REPORT_SHOW_DONE = 14;
/**
* The default amount of time we stay awake (used for all key input)
@@ -238,6 +239,8 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
private boolean mScreenOn = false;
+ private boolean mShowPending = false;
+
// last known state of the cellular connection
private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
@@ -306,7 +309,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
synchronized (this) {
if (DEBUG) Log.d(TAG, "onSystemReady");
mSystemReady = true;
- doKeyguard();
+ doKeyguardLocked();
}
}
@@ -363,7 +366,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
if (timeout <= 0) {
// Lock now
mSuppressNextLockSound = true;
- doKeyguard();
+ doKeyguardLocked();
} else {
// Lock in the future
long when = SystemClock.elapsedRealtime() + timeout;
@@ -379,7 +382,19 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
} else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
// Do not enable the keyguard if the prox sensor forced the screen off.
} else {
- doKeyguard();
+ if (!doKeyguardLocked() && why == WindowManagerPolicy.OFF_BECAUSE_OF_USER) {
+ // The user has explicitly turned off the screen, causing it
+ // to lock. We want to block here until the keyguard window
+ // has shown, so the power manager won't complete the screen
+ // off flow until that point, so we know it won't turn *on*
+ // the screen until this is done.
+ while (mShowPending) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
}
}
}
@@ -553,56 +568,58 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
}
/**
- * Enable the keyguard if the settings are appropriate.
+ * Enable the keyguard if the settings are appropriate. Return true if all
+ * work that will happen is done; returns false if the caller can wait for
+ * the keyguard to be shown.
*/
- private void doKeyguard() {
- synchronized (this) {
- // if another app is disabling us, don't show
- if (!mExternallyEnabled) {
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
-
- // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
- // for an occasional ugly flicker in this situation:
- // 1) receive a call with the screen on (no keyguard) or make a call
- // 2) screen times out
- // 3) user hits key to turn screen back on
- // instead, we reenable the keyguard when we know the screen is off and the call
- // ends (see the broadcast receiver below)
- // TODO: clean this up when we have better support at the window manager level
- // for apps that wish to be on top of the keyguard
- return;
- }
-
- // if the keyguard is already showing, don't bother
- if (mKeyguardViewManager.isShowing()) {
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
- return;
- }
+ private boolean doKeyguardLocked() {
+ // if another app is disabling us, don't show
+ if (!mExternallyEnabled) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
+
+ // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
+ // for an occasional ugly flicker in this situation:
+ // 1) receive a call with the screen on (no keyguard) or make a call
+ // 2) screen times out
+ // 3) user hits key to turn screen back on
+ // instead, we reenable the keyguard when we know the screen is off and the call
+ // ends (see the broadcast receiver below)
+ // TODO: clean this up when we have better support at the window manager level
+ // for apps that wish to be on top of the keyguard
+ return true;
+ }
- // if the setup wizard hasn't run yet, don't show
- final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
- false);
- final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
- final IccCard.State state = mUpdateMonitor.getSimState();
- final boolean lockedOrMissing = state.isPinLocked()
- || ((state == IccCard.State.ABSENT
- || state == IccCard.State.PERM_DISABLED)
- && requireSim);
-
- if (!lockedOrMissing && !provisioned) {
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
- + " and the sim is not locked or missing");
- return;
- }
+ // if the keyguard is already showing, don't bother
+ if (mKeyguardViewManager.isShowing()) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+ return true;
+ }
- if (mLockPatternUtils.isLockScreenDisabled()) {
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
- return;
- }
+ // if the setup wizard hasn't run yet, don't show
+ final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
+ false);
+ final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
+ final IccCard.State state = mUpdateMonitor.getSimState();
+ final boolean lockedOrMissing = state.isPinLocked()
+ || ((state == IccCard.State.ABSENT
+ || state == IccCard.State.PERM_DISABLED)
+ && requireSim);
+
+ if (!lockedOrMissing && !provisioned) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
+ + " and the sim is not locked or missing");
+ return true;
+ }
- if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
- showLocked();
+ if (mLockPatternUtils.isLockScreenDisabled()) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
+ return true;
}
+
+ if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
+ mShowPending = true;
+ showLocked();
+ return false;
}
/**
@@ -696,41 +713,49 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
case ABSENT:
// only force lock screen in case of missing sim if user hasn't
// gone through setup wizard
- if (!mUpdateMonitor.isDeviceProvisioned()) {
- if (!isShowing()) {
- if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
- + " we need to show the keyguard since the "
- + "device isn't provisioned yet.");
- doKeyguard();
- } else {
- resetStateLocked();
+ synchronized (this) {
+ if (!mUpdateMonitor.isDeviceProvisioned()) {
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
+ + " we need to show the keyguard since the "
+ + "device isn't provisioned yet.");
+ doKeyguardLocked();
+ } else {
+ resetStateLocked();
+ }
}
}
break;
case PIN_REQUIRED:
case PUK_REQUIRED:
- if (!isShowing()) {
- if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't showing, we need "
- + "to show the keyguard so the user can enter their sim pin");
- doKeyguard();
- } else {
- resetStateLocked();
+ synchronized (this) {
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't showing, we need "
+ + "to show the keyguard so the user can enter their sim pin");
+ doKeyguardLocked();
+ } else {
+ resetStateLocked();
+ }
}
break;
case PERM_DISABLED:
- if (!isShowing()) {
- if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
- + "keygaurd isn't showing.");
- doKeyguard();
- } else {
- if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
- + "show permanently disabled message in lockscreen.");
- resetStateLocked();
+ synchronized (this) {
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
+ + "keygaurd isn't showing.");
+ doKeyguardLocked();
+ } else {
+ if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
+ + "show permanently disabled message in lockscreen.");
+ resetStateLocked();
+ }
}
break;
case READY:
- if (isShowing()) {
- resetStateLocked();
+ synchronized (this) {
+ if (isShowing()) {
+ resetStateLocked();
+ }
}
break;
}
@@ -751,27 +776,31 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
+ sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
- if (mDelayedShowingSequence == sequence) {
- // Don't play lockscreen SFX if the screen went off due to
- // timeout.
- mSuppressNextLockSound = true;
-
- doKeyguard();
+ synchronized (KeyguardViewMediator.this) {
+ if (mDelayedShowingSequence == sequence) {
+ // Don't play lockscreen SFX if the screen went off due to
+ // timeout.
+ mSuppressNextLockSound = true;
+
+ doKeyguardLocked();
+ }
}
} else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
mPhoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
- if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState) // call ending
- && !mScreenOn // screen off
- && mExternallyEnabled) { // not disabled by any app
-
- // note: this is a way to gracefully reenable the keyguard when the call
- // ends and the screen is off without always reenabling the keyguard
- // each time the screen turns off while in call (and having an occasional ugly
- // flicker while turning back on the screen and disabling the keyguard again).
- if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
- + "keyguard is showing");
- doKeyguard();
+ synchronized (KeyguardViewMediator.this) {
+ if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState) // call ending
+ && !mScreenOn // screen off
+ && mExternallyEnabled) { // not disabled by any app
+
+ // note: this is a way to gracefully reenable the keyguard when the call
+ // ends and the screen is off without always reenabling the keyguard
+ // each time the screen turns off while in call (and having an occasional ugly
+ // flicker while turning back on the screen and disabling the keyguard again).
+ if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
+ + "keyguard is showing");
+ doKeyguardLocked();
+ }
}
}
}
@@ -962,7 +991,15 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
handleSetHidden(msg.arg1 != 0);
break;
case KEYGUARD_TIMEOUT:
- doKeyguard();
+ synchronized (KeyguardViewMediator.this) {
+ doKeyguardLocked();
+ }
+ break;
+ case REPORT_SHOW_DONE:
+ synchronized (KeyguardViewMediator.this) {
+ mShowPending = false;
+ KeyguardViewMediator.this.notifyAll();
+ }
break;
}
}
@@ -1062,8 +1099,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
if (DEBUG) Log.d(TAG, "handleShow");
if (!mSystemReady) return;
- playSounds(true);
-
mKeyguardViewManager.show();
mShowing = true;
adjustUserActivityLocked();
@@ -1072,7 +1107,17 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
ActivityManagerNative.getDefault().closeSystemDialogs("lock");
} catch (RemoteException e) {
}
+
+ // Do this at the end to not slow down display of the keyguard.
+ playSounds(true);
+
mShowKeyguardWakeLock.release();
+
+ // We won't say the show is done yet because the view hierarchy
+ // still needs to do the traversal. Posting this message allows
+ // us to hold off until that is done.
+ Message msg = mHandler.obtainMessage(REPORT_SHOW_DONE);
+ mHandler.sendMessage(msg);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 1d5fbc0a..be129a8 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -120,6 +120,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
import android.view.KeyCharacterMap.FallbackAction;
@@ -197,8 +198,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// things in here CAN NOT take focus, but are shown on top of everything else.
static final int SYSTEM_OVERLAY_LAYER = 20;
static final int SECURE_SYSTEM_OVERLAY_LAYER = 21;
+ static final int BOOT_PROGRESS_LAYER = 22;
// the (mouse) pointer layer
- static final int POINTER_LAYER = 22;
+ static final int POINTER_LAYER = 23;
static final int APPLICATION_MEDIA_SUBLAYER = -2;
static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -1095,6 +1097,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return POINTER_LAYER;
case TYPE_NAVIGATION_BAR:
return NAVIGATION_BAR_LAYER;
+ case TYPE_BOOT_PROGRESS:
+ return BOOT_PROGRESS_LAYER;
}
Log.e(TAG, "Unknown window type: " + type);
return APPLICATION_LAYER;
@@ -2797,13 +2801,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0);
- mKeyguardMediator.onScreenTurnedOff(why);
synchronized (mLock) {
mScreenOn = false;
+ }
+ mKeyguardMediator.onScreenTurnedOff(why);
+ synchronized (mLock) {
updateOrientationListenerLp();
updateLockScreenTimeout();
updateScreenSaverTimeoutLocked();
}
+ try {
+ mWindowManager.waitForAllDrawn();
+ } catch (RemoteException e) {
+ }
+ // Wait for one frame to give surface flinger time to do its
+ // compositing. Yes this is a hack, but I am really not up right now for
+ // implementing some mechanism to block until SF is done. :p
+ try {
+ Thread.sleep(20);
+ } catch (InterruptedException e) {
+ }
}
/** {@inheritDoc} */
@@ -3092,7 +3109,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mBootMsgDialog.setIndeterminate(true);
mBootMsgDialog.getWindow().setType(
- WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY);
+ WindowManager.LayoutParams.TYPE_BOOT_PROGRESS);
mBootMsgDialog.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DIM_BEHIND
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);