diff options
| -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
diff --git a/api/17.txt b/api/17.txt index 91dc71f58b3a..f236a74f46ec 100644 --- a/api/17.txt +++ b/api/17.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/api/current.txt b/api/current.txt index 91dc71f58b3a..f236a74f46ec 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 dd51764e9cdb..cb78763a6937 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 3074370b298b..e4ca8d83cf9a 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 008904670019..545d1a944782 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 817a2344a545..43f7a0803b77 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: |