diff options
author | Dianne Hackborn <hackbod@google.com> | 2012-10-05 18:37:54 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2012-10-05 20:38:31 -0700 |
commit | 4c1e3183baf39ab69c0289c1511877a8bb0b0f75 (patch) | |
tree | c92b0102185b0b767a96db712d08ebdcd82892b7 | |
parent | f948500239803b2b7247ff5058e39e4d645c5b70 (diff) | |
download | frameworks_base-4c1e3183baf39ab69c0289c1511877a8bb0b0f75.zip frameworks_base-4c1e3183baf39ab69c0289c1511877a8bb0b0f75.tar.gz frameworks_base-4c1e3183baf39ab69c0289c1511877a8bb0b0f75.tar.bz2 |
Fix issue #7296314, issue #7296314.
7296314 Crashing dreams are stuck
7296510 Transition from lock screen to dreaming is really bad
The window layer for dreams is now moved down below the keyguard,
so that some of the expected stuff like crash and ANR dialogs can
be seen on top of them. While doing this, I reorganized how we
define the layers so the constants are just in the switch statement,
so it is much less crazy-making trying to read how things go
together.
We now have some special cases for when a dream is being shown
to turn off its animation if the keyguard is currently shown.
Since we know it will be hiding the keyguard we need it to be
shown immediately so that you don't see whatever is behind it.
Cleaned up some handling of when the lock screen is displayed
while a FLAG_SHOW_WHEN_LOCKED window is displayed, so that the
lockscreen doesn't transiently get shown and mess up the fullscreen
or system UI state. This also fixes problems with any normal
activity that is doing this.
Hid the methods on DreamService for setting lights out mode. It
doesn't make sense to have such methods on DreamService, because
you can just as well do that on your own View that is showing the
dream content, and when you can do that you can fully participate
in the (required) interactions about it such as being told when
the mode goes away.
The DreamService method for going fullscreen now uses the window
flag for doing this, which is what you want, because you want this
state to persistent on that window and not get knocked out if
something above the window tickles the system UI state.
Also fixed the problem where dreams that hid the status bar would
have a jerky animation when going away, since they were causing the
activity behind them to be layed out without the lock screen. This
is a kind-of ugly special case in the window manager right now to
just not layout windows that are behind a dream. Good enough for MR1.
Change-Id: Ied2ab86ae068b1db0ff5973882f6d17b515edbcd
-rw-r--r-- | api/17.txt | 2 | ||||
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | core/java/android/service/dreams/DreamService.java | 28 | ||||
-rwxr-xr-x | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 224 | ||||
-rwxr-xr-x | services/java/com/android/server/wm/WindowManagerService.java | 23 | ||||
-rw-r--r-- | services/java/com/android/server/wm/WindowStateAnimator.java | 2 |
6 files changed, 156 insertions, 125 deletions
@@ -20347,7 +20347,6 @@ package android.service.dreams { method public android.view.WindowManager getWindowManager(); method public boolean isFullscreen(); method public boolean isInteractive(); - method public boolean isLowProfile(); method public boolean isScreenBright(); method public void onActionModeFinished(android.view.ActionMode); method public void onActionModeStarted(android.view.ActionMode); @@ -20372,7 +20371,6 @@ package android.service.dreams { method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public void setFullscreen(boolean); method public void setInteractive(boolean); - method public void setLowProfile(boolean); method public void setScreenBright(boolean); field public static final java.lang.String DREAM_META_DATA = "android.service.dream"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.DreamService"; diff --git a/api/current.txt b/api/current.txt index 91dc71f..f236a74 100644 --- a/api/current.txt +++ b/api/current.txt @@ -20347,7 +20347,6 @@ package android.service.dreams { method public android.view.WindowManager getWindowManager(); method public boolean isFullscreen(); method public boolean isInteractive(); - method public boolean isLowProfile(); method public boolean isScreenBright(); method public void onActionModeFinished(android.view.ActionMode); method public void onActionModeStarted(android.view.ActionMode); @@ -20372,7 +20371,6 @@ package android.service.dreams { method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public void setFullscreen(boolean); method public void setInteractive(boolean); - method public void setLowProfile(boolean); method public void setScreenBright(boolean); field public static final java.lang.String DREAM_META_DATA = "android.service.dream"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.DreamService"; diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index dd51764..cb78763 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -22,6 +22,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.Service; import android.content.Intent; +import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.os.IBinder; @@ -401,6 +402,9 @@ public class DreamService extends Service implements Window.Callback { * Sets View.SYSTEM_UI_FLAG_LOW_PROFILE on the content view. * * @param lowProfile True to set View.SYSTEM_UI_FLAG_LOW_PROFILE + * @hide There is no reason to have this -- dreams can set this flag + * on their own content view, and from there can actually do the + * correct interactions with it (seeing when it is cleared etc). */ public void setLowProfile(boolean lowProfile) { mLowProfile = lowProfile; @@ -412,20 +416,23 @@ public class DreamService extends Service implements Window.Callback { * Returns whether or not this dream is in low profile mode. Defaults to true. * * @see #setLowProfile(boolean) + * @hide */ public boolean isLowProfile() { return getSystemUiVisibilityFlagValue(View.SYSTEM_UI_FLAG_LOW_PROFILE, mLowProfile); } /** - * Sets View.SYSTEM_UI_FLAG_FULLSCREEN on the content view. + * Controls {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} + * on the dream's window. * - * @param fullscreen True to set View.SYSTEM_UI_FLAG_FULLSCREEN + * @param fullscreen If true, the fullscreen flag will be set; else it + * will be cleared. */ public void setFullscreen(boolean fullscreen) { mFullscreen = fullscreen; - int flag = View.SYSTEM_UI_FLAG_FULLSCREEN; - applySystemUiVisibilityFlags(mFullscreen ? flag : 0, flag); + int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN; + applyWindowFlags(mFullscreen ? flag : 0, flag); } /** @@ -434,7 +441,7 @@ public class DreamService extends Service implements Window.Callback { * @see #setFullscreen(boolean) */ public boolean isFullscreen() { - return getSystemUiVisibilityFlagValue(View.SYSTEM_UI_FLAG_FULLSCREEN, mFullscreen); + return mFullscreen; } /** @@ -565,6 +572,7 @@ public class DreamService extends Service implements Window.Callback { mWindow.setCallback(this); mWindow.requestFeature(Window.FEATURE_NO_TITLE); mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000)); + mWindow.setFormat(PixelFormat.OPAQUE); if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s", windowToken, WindowManager.LayoutParams.TYPE_DREAM)); @@ -573,9 +581,12 @@ public class DreamService extends Service implements Window.Callback { lp.type = WindowManager.LayoutParams.TYPE_DREAM; lp.token = windowToken; lp.windowAnimations = com.android.internal.R.style.Animation_Dream; - lp.flags |= ( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + lp.flags |= ( WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON + | (mFullscreen ? WindowManager.LayoutParams.FLAG_FULLSCREEN : 0) | (mScreenBright ? WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON : 0) ); mWindow.setAttributes(lp); @@ -588,9 +599,8 @@ public class DreamService extends Service implements Window.Callback { if (mDebug) Slog.v(TAG, "Window added on thread " + Thread.currentThread().getId()); try { applySystemUiVisibilityFlags( - (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0) - | (mFullscreen ? View.SYSTEM_UI_FLAG_FULLSCREEN : 0), - View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN); + (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0), + View.SYSTEM_UI_FLAG_LOW_PROFILE); getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes()); } catch (Throwable t) { Slog.w("Crashed adding window view", t); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 3074370..e4ca8d8 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -182,56 +182,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int LONG_PRESS_HOME_RECENT_DIALOG = 1; static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2; - // wallpaper is at the bottom, though the window manager may move it. - static final int UNIVERSE_BACKGROUND_LAYER = 1; - static final int WALLPAPER_LAYER = 2; - static final int APPLICATION_LAYER = 2; - static final int PHONE_LAYER = 3; - static final int SEARCH_BAR_LAYER = 4; - static final int SYSTEM_DIALOG_LAYER = 5; - // toasts and the plugged-in battery thing - static final int TOAST_LAYER = 6; - // SIM errors and unlock. Not sure if this really should be in a high layer. - static final int PRIORITY_PHONE_LAYER = 7; - // like the ANR / app crashed dialogs - static final int SYSTEM_ALERT_LAYER = 8; - // on-screen keyboards and other such input method user interfaces go here. - static final int INPUT_METHOD_LAYER = 9; - // on-screen keyboards and other such input method user interfaces go here. - static final int INPUT_METHOD_DIALOG_LAYER = 10; - // the keyguard; nothing on top of these can take focus, since they are - // responsible for power management when displayed. - static final int KEYGUARD_LAYER = 11; - static final int KEYGUARD_DIALOG_LAYER = 12; - // used for Dreams (screensavers with TYPE_DREAM windows) - static final int SCREENSAVER_LAYER = 13; - static final int STATUS_BAR_SUB_PANEL_LAYER = 14; - static final int STATUS_BAR_LAYER = 15; - static final int STATUS_BAR_PANEL_LAYER = 16; - // the on-screen volume indicator and controller shown when the user - // changes the device volume - static final int VOLUME_OVERLAY_LAYER = 17; - // things in here CAN NOT take focus, but are shown on top of everything else. - static final int SYSTEM_OVERLAY_LAYER = 18; - // the navigation bar, if available, shows atop most things - static final int NAVIGATION_BAR_LAYER = 19; - // some panels (e.g. search) need to show on top of the navigation bar - static final int NAVIGATION_BAR_PANEL_LAYER = 20; - // system-level error dialogs - static final int SYSTEM_ERROR_LAYER = 21; - // used to highlight the magnified portion of a display - static final int MAGNIFICATION_OVERLAY_LAYER = 22; - // used to simulate secondary display devices - static final int DISPLAY_OVERLAY_LAYER = 23; - // the drag layer: input for drag-and-drop is associated with this window, - // which sits above all other focusable windows - static final int DRAG_LAYER = 24; - static final int SECURE_SYSTEM_OVERLAY_LAYER = 25; - static final int BOOT_PROGRESS_LAYER = 26; - // the (mouse) pointer layer - static final int POINTER_LAYER = 27; - static final int HIDDEN_NAV_CONSUMER_LAYER = 28; - static final int APPLICATION_MEDIA_SUBLAYER = -2; static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; static final int APPLICATION_PANEL_SUBLAYER = 1; @@ -459,8 +409,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mTopFullscreenOpaqueWindowState; boolean mTopIsFullscreen; boolean mForceStatusBar; + boolean mForceStatusBarFromKeyguard; boolean mHideLockScreen; boolean mDismissKeyguard; + boolean mNoDreamEnterAnim; boolean mHomePressed; boolean mHomeLongPressed; Intent mHomeIntent; @@ -1353,70 +1305,90 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public int windowTypeToLayerLw(int type) { if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { - return APPLICATION_LAYER; + return 2; } switch (type) { - case TYPE_STATUS_BAR: - return STATUS_BAR_LAYER; - case TYPE_STATUS_BAR_PANEL: - return STATUS_BAR_PANEL_LAYER; - case TYPE_STATUS_BAR_SUB_PANEL: - return STATUS_BAR_SUB_PANEL_LAYER; - case TYPE_SYSTEM_DIALOG: - return SYSTEM_DIALOG_LAYER; - case TYPE_SEARCH_BAR: - return SEARCH_BAR_LAYER; + case TYPE_UNIVERSE_BACKGROUND: + return 1; + case TYPE_WALLPAPER: + // wallpaper is at the bottom, though the window manager may move it. + return 2; case TYPE_PHONE: - return PHONE_LAYER; - case TYPE_KEYGUARD: - return KEYGUARD_LAYER; - case TYPE_KEYGUARD_DIALOG: - return KEYGUARD_DIALOG_LAYER; + return 3; + case TYPE_SEARCH_BAR: + return 4; + case TYPE_RECENTS_OVERLAY: + case TYPE_SYSTEM_DIALOG: + return 5; + case TYPE_TOAST: + // toasts and the plugged-in battery thing + return 6; + case TYPE_PRIORITY_PHONE: + // SIM errors and unlock. Not sure if this really should be in a high layer. + return 7; + case TYPE_DREAM: + // used for Dreams (screensavers with TYPE_DREAM windows) + return 8; case TYPE_SYSTEM_ALERT: - return SYSTEM_ALERT_LAYER; - case TYPE_SYSTEM_ERROR: - return SYSTEM_ERROR_LAYER; + // like the ANR / app crashed dialogs + return 9; case TYPE_INPUT_METHOD: - return INPUT_METHOD_LAYER; + // on-screen keyboards and other such input method user interfaces go here. + return 10; case TYPE_INPUT_METHOD_DIALOG: - return INPUT_METHOD_DIALOG_LAYER; + // on-screen keyboards and other such input method user interfaces go here. + return 11; + case TYPE_KEYGUARD: + // the keyguard; nothing on top of these can take focus, since they are + // responsible for power management when displayed. + return 12; + case TYPE_KEYGUARD_DIALOG: + return 13; + case TYPE_STATUS_BAR_SUB_PANEL: + return 14; + case TYPE_STATUS_BAR: + return 15; + case TYPE_STATUS_BAR_PANEL: + return 16; case TYPE_VOLUME_OVERLAY: - return VOLUME_OVERLAY_LAYER; + // the on-screen volume indicator and controller shown when the user + // changes the device volume + return 17; case TYPE_SYSTEM_OVERLAY: - return SYSTEM_OVERLAY_LAYER; - case TYPE_SECURE_SYSTEM_OVERLAY: - return SECURE_SYSTEM_OVERLAY_LAYER; - case TYPE_PRIORITY_PHONE: - return PRIORITY_PHONE_LAYER; - case TYPE_TOAST: - return TOAST_LAYER; - case TYPE_WALLPAPER: - return WALLPAPER_LAYER; - case TYPE_DRAG: - return DRAG_LAYER; - case TYPE_POINTER: - return POINTER_LAYER; + // the on-screen volume indicator and controller shown when the user + // changes the device volume + return 18; case TYPE_NAVIGATION_BAR: - return NAVIGATION_BAR_LAYER; + // the navigation bar, if available, shows atop most things + return 19; case TYPE_NAVIGATION_BAR_PANEL: - return NAVIGATION_BAR_PANEL_LAYER; + // some panels (e.g. search) need to show on top of the navigation bar + return 20; + case TYPE_SYSTEM_ERROR: + // system-level error dialogs + return 21; + case TYPE_MAGNIFICATION_OVERLAY: + // used to highlight the magnified portion of a display + return 22; + case TYPE_DISPLAY_OVERLAY: + // used to simulate secondary display devices + return 23; + case TYPE_DRAG: + // the drag layer: input for drag-and-drop is associated with this window, + // which sits above all other focusable windows + return 24; + case TYPE_SECURE_SYSTEM_OVERLAY: + return 25; case TYPE_BOOT_PROGRESS: - return BOOT_PROGRESS_LAYER; + return 26; + case TYPE_POINTER: + // the (mouse) pointer layer + return 27; case TYPE_HIDDEN_NAV_CONSUMER: - return HIDDEN_NAV_CONSUMER_LAYER; - case TYPE_DREAM: - return SCREENSAVER_LAYER; - case TYPE_UNIVERSE_BACKGROUND: - return UNIVERSE_BACKGROUND_LAYER; - case TYPE_DISPLAY_OVERLAY: - return DISPLAY_OVERLAY_LAYER; - case TYPE_MAGNIFICATION_OVERLAY: - return MAGNIFICATION_OVERLAY_LAYER; - case TYPE_RECENTS_OVERLAY: - return SYSTEM_DIALOG_LAYER; + return 28; } Log.e(TAG, "Unknown window type: " + type); - return APPLICATION_LAYER; + return 2; } /** {@inheritDoc} */ @@ -1437,11 +1409,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } public int getMaxWallpaperLayer() { - return STATUS_BAR_LAYER; + return windowTypeToLayerLw(TYPE_STATUS_BAR); } public int getAboveUniverseLayer() { - return SYSTEM_ERROR_LAYER; + return windowTypeToLayerLw(TYPE_SYSTEM_ERROR); } public boolean hasSystemNavBar() { @@ -1493,11 +1465,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) { return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD; } - + public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) { return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER + && attrs.type != WindowManager.LayoutParams.TYPE_DREAM && attrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND; } @@ -1730,6 +1703,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT"); return com.android.internal.R.anim.app_starting_exit; } + } else if (win.getAttrs().type == TYPE_DREAM && mNoDreamEnterAnim + && transit == TRANSIT_ENTER) { + // Special case: we are animating in a dream, while the keyguard + // is shown. We don't want an animation on the dream, because + // we need it shown immediately with the keyguard animating away + // to reveal it. + return -1; } return 0; @@ -2919,10 +2899,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { mTopFullscreenOpaqueWindowState = null; mForceStatusBar = false; + mForceStatusBarFromKeyguard = false; mHideLockScreen = false; mAllowLockscreenWhenOn = false; mDismissKeyguard = false; + mNoDreamEnterAnim = false; } /** {@inheritDoc} */ @@ -2933,7 +2915,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mTopFullscreenOpaqueWindowState == null && win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) { if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) { - mForceStatusBar = true; + if (attrs.type == TYPE_KEYGUARD) { + mForceStatusBarFromKeyguard = true; + } else { + mForceStatusBar = true; + } + } + if (attrs.type == TYPE_KEYGUARD) { + mNoDreamEnterAnim = true; } if (((attrs.type >= FIRST_APPLICATION_WINDOW && attrs.type <= LAST_APPLICATION_WINDOW) || attrs.type == TYPE_DREAM) @@ -2942,13 +2931,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) { if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win); mTopFullscreenOpaqueWindowState = win; + if (attrs.type == TYPE_DREAM) { + mNoDreamEnterAnim = true; + } if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) { - if (localLOGV) Log.v(TAG, "Setting mHideLockScreen to true by win " + win); + if (DEBUG_LAYOUT) Log.v(TAG, "Setting mHideLockScreen to true by win " + win); mHideLockScreen = true; + mForceStatusBarFromKeyguard = false; } if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) { - if (localLOGV) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win); + if (DEBUG_LAYOUT) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win); mDismissKeyguard = true; + mForceStatusBarFromKeyguard = false; } if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { mAllowLockscreenWhenOn = true; @@ -2968,8 +2962,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mStatusBar != null) { if (DEBUG_LAYOUT) Log.i(TAG, "force=" + mForceStatusBar + + " forcefkg=" + mForceStatusBarFromKeyguard + " top=" + mTopFullscreenOpaqueWindowState); - if (mForceStatusBar) { + if (mForceStatusBar || mForceStatusBarFromKeyguard) { if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: forced"); if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; } else if (mTopFullscreenOpaqueWindowState != null) { @@ -4349,6 +4344,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mFocusedWindow == null) { return 0; } + if (mFocusedWindow.getAttrs().type == TYPE_KEYGUARD && mHideLockScreen == true) { + // We are updating at a point where the keyguard has gotten + // focus, but we were last in a state where the top window is + // hiding it. This is probably because the keyguard as been + // shown while the top window was displayed, so we want to ignore + // it here because this is just a very transient change and it + // will quickly lose focus once it correctly gets hidden. + return 0; + } final int visibility = mFocusedWindow.getSystemUiVisibility() & ~mResettingSystemUiFlags & ~mForceClearedSystemUiFlags; @@ -4495,9 +4499,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer); pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState="); pw.println(mTopFullscreenOpaqueWindowState); - pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); - pw.print(" mForceStatusBar="); pw.print(mForceStatusBar); + pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); pw.print(" mHideLockScreen="); pw.println(mHideLockScreen); + pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); + pw.print(" mForceStatusBarFromKeyguard="); + pw.println(mForceStatusBarFromKeyguard); pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard); pw.print(" mHomePressed="); pw.println(mHomePressed); pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 0089046..545d1a9 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -8237,7 +8237,9 @@ public class WindowManagerService extends IWindowManager.Stub int seq = mLayoutSeq+1; if (seq < 0) seq = 0; mLayoutSeq = seq; - + + boolean behindDream = false; + // First perform layout of any root windows (not attached // to another window). int topAttached = -1; @@ -8247,7 +8249,8 @@ public class WindowManagerService extends IWindowManager.Stub // Don't do layout of a window if it is not visible, or // soon won't be visible, to avoid wasting time and funky // changes while a window is animating away. - final boolean gone = win.isGoneForLayoutLw(); + final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) + || win.isGoneForLayoutLw(); if (DEBUG_LAYOUT && !win.mLayoutAttached) { Slog.v(TAG, "1ST PASS " + win @@ -8282,6 +8285,12 @@ public class WindowManagerService extends IWindowManager.Stub //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); win.mContentChanged = false; } + if (win.mAttrs.type == TYPE_DREAM) { + // Don't layout windows behind a dream, so that if it + // does stuff like hide the status bar we won't get a + // bad transition when it goes away. + behindDream = true; + } win.mLayoutNeeded = false; win.prelayout(); mPolicy.layoutWindowLw(win, win.mAttrs, null); @@ -8306,6 +8315,8 @@ public class WindowManagerService extends IWindowManager.Stub mAnimator.mUniverseBackground = universeBackground; } + boolean attachedBehindDream = false; + // Now perform layout of attached windows, which usually // depend on the position of the window they are attached to. // XXX does not deal with windows that are attached to windows @@ -8323,6 +8334,9 @@ public class WindowManagerService extends IWindowManager.Stub // if they want. (We do the normal layout for INVISIBLE // windows, since that means "perform layout as normal, // just don't display"). + if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) { + continue; + } if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled) || !win.mHaveFrame || win.mLayoutNeeded) { if (initial) { @@ -8338,6 +8352,11 @@ public class WindowManagerService extends IWindowManager.Stub + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame); } + } else if (win.mAttrs.type == TYPE_DREAM) { + // Don't layout windows behind a dream, so that if it + // does stuff like hide the status bar we won't get a + // bad transition when it goes away. + attachedBehindDream = behindDream; } } diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 817a234..43f7a08 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -1500,7 +1500,7 @@ class WindowStateAnimator { int attr = -1; Animation a = null; if (anim != 0) { - a = AnimationUtils.loadAnimation(mContext, anim); + a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null; } else { switch (transit) { case WindowManagerPolicy.TRANSIT_ENTER: |