diff options
7 files changed, 102 insertions, 43 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 172aaf6..7ca8fc1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -426,7 +426,9 @@ public class KeyguardViewMediator extends SystemUI { } public void keyguardDone(boolean authenticated) { - KeyguardViewMediator.this.keyguardDone(authenticated, true); + if (!mKeyguardDonePending) { + KeyguardViewMediator.this.keyguardDone(authenticated, true); + } } public void keyguardDoneDrawing() { @@ -1049,9 +1051,6 @@ public class KeyguardViewMediator extends SystemUI { public void keyguardDone(boolean authenticated, boolean wakeup) { if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")"); EventLog.writeEvent(70000, 2); - synchronized (this) { - mKeyguardDonePending = false; - } Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0, wakeup ? 1 : 0); mHandler.sendMessage(msg); } @@ -1122,6 +1121,9 @@ public class KeyguardViewMediator extends SystemUI { */ private void handleKeyguardDone(boolean authenticated, boolean wakeup) { if (DEBUG) Log.d(TAG, "handleKeyguardDone"); + synchronized (this) { + mKeyguardDonePending = false; + } if (authenticated) { mUpdateMonitor.clearFailedUnlockAttempts(); @@ -1297,6 +1299,7 @@ public class KeyguardViewMediator extends SystemUI { } private void handleOnActivityDrawn() { + if (DEBUG) Log.d(TAG, "handleOnActivityDrawn: mKeyguardDonePending=" + mKeyguardDonePending); if (mKeyguardDonePending) { mStatusBarKeyguardViewManager.onActivityDrawn(); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 0dae028..3a1fafe 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1538,9 +1538,6 @@ final class ActivityStack { ActivityOptions.abort(options); if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); - - // Make sure to notify Keyguard as well if it is waiting for an activity to be drawn. - mStackSupervisor.notifyActivityDrawnForKeyguard(); return false; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 099151f..120002e 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -656,7 +656,6 @@ public final class ActivityStackSupervisor implements DisplayListener { void reportActivityVisibleLocked(ActivityRecord r) { sendWaitingVisibleReportLocked(r); - notifyActivityDrawnForKeyguard(); } void sendWaitingVisibleReportLocked(ActivityRecord r) { @@ -1832,6 +1831,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final ActivityStack lastStack = getLastStack(); ActivityRecord curTop = lastStack == null? null : lastStack.topRunningNonDelayedActivityLocked(notTop); + boolean movedToFront = false; if (curTop != null && (curTop.task != intentActivity.task || curTop.task != lastStack.topTask())) { r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); @@ -1851,6 +1851,7 @@ public final class ActivityStackSupervisor implements DisplayListener { intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); } options = null; + movedToFront = true; } } // If the caller has requested that the target task be @@ -1865,6 +1866,12 @@ public final class ActivityStackSupervisor implements DisplayListener { // sure we have correctly resumed the top activity. if (doResume) { resumeTopActivitiesLocked(targetStack, null, options); + + // Make sure to notify Keyguard as well if we are not running an app + // transition later. + if (!movedToFront) { + notifyActivityDrawnForKeyguard(); + } } else { ActivityOptions.abort(options); } @@ -1956,6 +1963,11 @@ public final class ActivityStackSupervisor implements DisplayListener { // sure we have correctly resumed the top activity. if (doResume) { targetStack.resumeTopActivityLocked(null, options); + if (!movedToFront) { + // Make sure to notify Keyguard as well if we are not running an app + // transition later. + notifyActivityDrawnForKeyguard(); + } } else { ActivityOptions.abort(options); } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 82e4bb1..8af8578 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD; import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION; import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE; @@ -241,6 +242,7 @@ public class WindowAnimator { winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f); winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS); winAnimator.mAnimationIsEntrance = false; + winAnimator.mAnimationStartTime = -1; } } else { if (DEBUG_KEYGUARD) Slog.d(TAG, @@ -263,6 +265,7 @@ public class WindowAnimator { null : winShowWhenLocked.mAppToken; boolean wallpaperInUnForceHiding = false; + boolean startingInUnForceHiding = false; ArrayList<WindowStateAnimator> unForceHiding = null; WindowState wallpaper = null; for (int i = windows.size() - 1; i >= 0; i--) { @@ -344,8 +347,13 @@ public class WindowAnimator { if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Now policy hidden: " + win); } else { - if (!win.showLw(false, false)) { - // Was already showing. + boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null + && !winAnimator.mKeyguardGoingAwayAnimation + && win.hasDrawnLw(); + + // If the window is already showing and we don't need to apply an existing + // Keyguard exit animation, skip. + if (!win.showLw(false, false) && !applyExistingExitAnimation) { continue; } final boolean visibleNow = win.isVisibleNow(); @@ -364,11 +372,19 @@ public class WindowAnimator { if ((flags & FLAG_SHOW_WALLPAPER) != 0) { wallpaperInUnForceHiding = true; } - } else if (mPostKeyguardExitAnimation != null) { + if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { + startingInUnForceHiding = true; + } + } else if (applyExistingExitAnimation) { // We're already in the middle of an animation. Use the existing // animation to bring in this window. - winAnimator.setAnimation(mPostKeyguardExitAnimation); - winAnimator.keyguardGoingAwayAnimation = true; + if (DEBUG_KEYGUARD) Slog.v(TAG, + "Applying existing Keyguard exit animation to new window: win=" + + win); + Animation a = mPolicy.createForceHideEnterAnimation( + false, mKeyguardGoingAwayToNotificationShade); + winAnimator.setAnimation(a, mPostKeyguardExitAnimation.getStartTime()); + winAnimator.mKeyguardGoingAwayAnimation = true; } final WindowState currentFocus = mService.mCurrentFocus; if (currentFocus == null || currentFocus.mLayer < win.mLayer) { @@ -421,25 +437,34 @@ public class WindowAnimator { } // end forall windows // If we have windows that are being show due to them no longer - // being force-hidden, apply the appropriate animation to them. + // being force-hidden, apply the appropriate animation to them if animations are not + // disabled. if (unForceHiding != null) { - // This only happens the first time that we detect the keyguard is animating out. - if (mKeyguardGoingAwayDisableWindowAnimations) { - if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: skipping anim for windows"); - } else { - if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: created anim for windows=" - + unForceHiding); - mPostKeyguardExitAnimation = mPolicy.createForceHideEnterAnimation( - wallpaperInUnForceHiding, mKeyguardGoingAwayToNotificationShade); - } - if (mPostKeyguardExitAnimation != null) { + if (!mKeyguardGoingAwayDisableWindowAnimations) { + boolean first = true; for (int i=unForceHiding.size()-1; i>=0; i--) { final WindowStateAnimator winAnimator = unForceHiding.get(i); - winAnimator.setAnimation(mPostKeyguardExitAnimation); - winAnimator.keyguardGoingAwayAnimation = true; + Animation a = mPolicy.createForceHideEnterAnimation( + wallpaperInUnForceHiding && !startingInUnForceHiding, + mKeyguardGoingAwayToNotificationShade); + if (a != null) { + if (DEBUG_KEYGUARD) Slog.v(TAG, + "Starting keyguard exit animation on window " + winAnimator.mWin); + winAnimator.setAnimation(a); + winAnimator.mKeyguardGoingAwayAnimation = true; + if (first) { + mPostKeyguardExitAnimation = a; + mPostKeyguardExitAnimation.setStartTime(mCurrentTime); + first = false; + } + } } + } else if (mKeyguardGoingAway) { + mPolicy.startKeyguardExitAnimation(mCurrentTime, 0 /* duration */); + mKeyguardGoingAway = false; } + // Wallpaper is going away in un-force-hide motion, animate it as well. if (!wallpaperInUnForceHiding && wallpaper != null && !mKeyguardGoingAwayDisableWindowAnimations) { @@ -459,8 +484,10 @@ public class WindowAnimator { mPostKeyguardExitAnimation.getStartOffset(), mPostKeyguardExitAnimation.getDuration()); mKeyguardGoingAway = false; - } else if (mPostKeyguardExitAnimation.hasEnded()) { + } else if (mCurrentTime - mPostKeyguardExitAnimation.getStartTime() + > mPostKeyguardExitAnimation.getDuration()) { // Done with the animation, reset. + if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations."); mPostKeyguardExitAnimation = null; } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 6cb1e4a..1e492a5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1759,7 +1759,7 @@ public class WindowManagerService extends IWindowManager.Stub // wallpaper during the animation so it doesn't flicker out. final boolean hasWallpaper = (w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 || (w.mAppToken != null - && w.mWinAnimator.keyguardGoingAwayAnimation); + && w.mWinAnimator.mKeyguardGoingAwayAnimation); if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) { if (DEBUG_WALLPAPER) Slog.v(TAG, @@ -2541,8 +2541,8 @@ public class WindowManagerService extends IWindowManager.Stub } mInputMonitor.updateInputWindowsLw(false /*force*/); - if (true || localLOGV) Slog.v(TAG, "addWindow: New client " + client.asBinder() - + ": window=" + win + " Callers=" + Debug.getCallers(5)); + if (true || localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG, "addWindow: New client " + + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5)); if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) { reportNewConfig = true; @@ -5411,7 +5411,7 @@ public class WindowManagerService extends IWindowManager.Stub public void notifyActivityDrawnForKeyguard() { if (DEBUG_KEYGUARD) Slog.d(TAG, "notifyActivityDrawnForKeyguard: waiting=" - + mKeyguardWaitingForActivityDrawn); + + mKeyguardWaitingForActivityDrawn + " Callers=" + Debug.getCallers(5)); synchronized (mWindowMap) { if (mKeyguardWaitingForActivityDrawn) { mPolicy.notifyActivityDrawnForKeyguardLw(); @@ -9322,6 +9322,7 @@ public class WindowManagerService extends IWindowManager.Stub } updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/); mFocusMayChange = false; + notifyActivityDrawnForKeyguard(); } return changes; @@ -9809,7 +9810,8 @@ public class WindowManagerService extends IWindowManager.Stub atoken.numInterestingWindows = atoken.numDrawnWindows = 0; atoken.startingDisplayed = false; } - if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION) + if ((w.isOnScreenIgnoringKeyguard() + || winAnimator.mAttrType == TYPE_BASE_APPLICATION) && !w.mExiting && !w.mDestroying) { if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f9efc80..021a6e4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -935,7 +935,15 @@ final class WindowState implements WindowManagerPolicy.WindowState { * being visible. */ boolean isOnScreen() { - if (!mHasSurface || !mPolicyVisibility || mDestroying) { + return mPolicyVisibility && isOnScreenIgnoringKeyguard(); + } + + /** + * Like isOnScreen(), but ignores any force hiding of the window due + * to the keyguard. + */ + boolean isOnScreenIgnoringKeyguard() { + if (!mHasSurface || mDestroying) { return false; } final AppWindowToken atoken = mAppToken; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 819ca50..e929065 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -97,6 +97,7 @@ class WindowStateAnimator { boolean mWasAnimating; // Were we animating going into the most recent animation step? int mAnimLayer; int mLastLayer; + long mAnimationStartTime; SurfaceControl mSurfaceControl; SurfaceControl mPendingDestroySurface; @@ -147,7 +148,7 @@ class WindowStateAnimator { * window is first added or shown, cleared when the callback has been made. */ boolean mEnteringAnimation; - boolean keyguardGoingAwayAnimation; + boolean mKeyguardGoingAwayAnimation; /** This is set when there is no Surface */ static final int NO_SURFACE = 0; @@ -210,7 +211,7 @@ class WindowStateAnimator { mIsWallpaper = win.mIsWallpaper; } - public void setAnimation(Animation anim) { + public void setAnimation(Animation anim, long startTime) { if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim); mAnimating = false; mLocalAnimating = false; @@ -221,6 +222,11 @@ class WindowStateAnimator { mTransformation.clear(); mTransformation.setAlpha(mLastHidden ? 0 : 1); mHasLocalTransformation = true; + mAnimationStartTime = startTime; + } + + public void setAnimation(Animation anim) { + setAnimation(anim, -1); } public void clearAnimation() { @@ -229,7 +235,7 @@ class WindowStateAnimator { mLocalAnimating = false; mAnimation.cancel(); mAnimation = null; - keyguardGoingAwayAnimation = false; + mKeyguardGoingAwayAnimation = false; } } @@ -299,7 +305,9 @@ class WindowStateAnimator { final DisplayInfo displayInfo = displayContent.getDisplayInfo(); mAnimDw = displayInfo.appWidth; mAnimDh = displayInfo.appHeight; - mAnimation.setStartTime(currentTime); + mAnimation.setStartTime(mAnimationStartTime != -1 + ? mAnimationStartTime + : currentTime); mLocalAnimating = true; mAnimating = true; } @@ -351,7 +359,7 @@ class WindowStateAnimator { + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false)); mAnimating = false; - keyguardGoingAwayAnimation = false; + mKeyguardGoingAwayAnimation = false; mLocalAnimating = false; if (mAnimation != null) { mAnimation.cancel(); @@ -500,9 +508,6 @@ class WindowStateAnimator { Slog.v(TAG, "Draw state now committed in " + mWin); } mDrawState = COMMIT_DRAW_PENDING; - if (startingWindow) { - mService.notifyActivityDrawnForKeyguard(); - } return true; } return false; @@ -1786,9 +1791,14 @@ class WindowStateAnimator { * @return true if an animation has been loaded. */ boolean applyAnimationLocked(int transit, boolean isEntrance) { - if (mLocalAnimating && mAnimationIsEntrance == isEntrance) { + if ((mLocalAnimating && mAnimationIsEntrance == isEntrance) + || mKeyguardGoingAwayAnimation) { // If we are trying to apply an animation, but already running - // an animation of the same type, then just leave that one alone. + // an animation of the same type, or when we are playing the Keyguard dismissing + // animation, then just leave that one alone. + + // TODO: if mKeyguardGoingAwayAnimation and this is a exiting starting window, modify + // existing animation to fade it out as well. return true; } |