diff options
Diffstat (limited to 'services/core/java/com/android/server/wm')
7 files changed, 260 insertions, 120 deletions
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java index c09ea5c..3f5ae56 100644 --- a/services/core/java/com/android/server/wm/DimLayer.java +++ b/services/core/java/com/android/server/wm/DimLayer.java @@ -140,10 +140,9 @@ public class DimLayer { } /** - * @param layer The new layer value. - * @param inTransaction Whether the call is made within a surface transaction. + * NOTE: Must be called with Surface transaction open. */ - void adjustSurface(int layer, boolean inTransaction) { + private void adjustBounds() { final int dw, dh; final float xPos, yPos; if (!mStack.isFullscreen()) { @@ -163,29 +162,31 @@ public class DimLayer { yPos = -1 * dh / 6; } - try { - if (!inTransaction) { - SurfaceControl.openTransaction(); - } - mDimSurface.setPosition(xPos, yPos); - mDimSurface.setSize(dw, dh); - mDimSurface.setLayer(layer); - } catch (RuntimeException e) { - Slog.w(TAG, "Failure setting size or layer", e); - } finally { - if (!inTransaction) { - SurfaceControl.closeTransaction(); - } - } + mDimSurface.setPosition(xPos, yPos); + mDimSurface.setSize(dw, dh); + mLastBounds.set(mBounds); - mLayer = layer; } - // Assumes that surface transactions are currently closed. - void setBounds(Rect bounds) { + /** + * @param bounds The new bounds to set + * @param inTransaction Whether the call is made within a surface transaction. + */ + void setBounds(Rect bounds, boolean inTransaction) { mBounds.set(bounds); if (isDimming() && !mLastBounds.equals(bounds)) { - adjustSurface(mLayer, false); + try { + if (!inTransaction) { + SurfaceControl.openTransaction(); + } + adjustBounds(); + } catch (RuntimeException e) { + Slog.w(TAG, "Failure setting size", e); + } finally { + if (!inTransaction) { + SurfaceControl.closeTransaction(); + } + } } } @@ -224,9 +225,10 @@ public class DimLayer { return; } - if (!mLastBounds.equals(mBounds) || mLayer != layer) { - adjustSurface(layer, true); + if (!mLastBounds.equals(mBounds)) { + adjustBounds(); } + setLayer(layer); long curTime = SystemClock.uptimeMillis(); final boolean animating = isAnimating(); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index f57adaf..4f20f50 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -241,6 +241,7 @@ class DisplayContent { mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); } } + mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion); } void switchUserStacks(int newUserId) { diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 27ac32a..ad50e05a 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -148,7 +148,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { if (timeout >= 0) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. - return timeout; + return timeout * 1000000L; // nanoseconds } } catch (RemoteException ex) { } diff --git a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java b/services/core/java/com/android/server/wm/StackTapPointerEventListener.java index 19d8ab3..1a85993 100644 --- a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java +++ b/services/core/java/com/android/server/wm/StackTapPointerEventListener.java @@ -31,7 +31,7 @@ public class StackTapPointerEventListener implements PointerEventListener { private float mDownX; private float mDownY; private int mPointerId; - final private Region mTouchExcludeRegion; + final private Region mTouchExcludeRegion = new Region(); private final WindowManagerService mService; private final DisplayContent mDisplayContent; @@ -39,7 +39,6 @@ public class StackTapPointerEventListener implements PointerEventListener { DisplayContent displayContent) { mService = service; mDisplayContent = displayContent; - mTouchExcludeRegion = displayContent.mTouchExcludeRegion; DisplayInfo info = displayContent.getDisplayInfo(); mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES); } @@ -57,8 +56,9 @@ public class StackTapPointerEventListener implements PointerEventListener { if (mPointerId >= 0) { int index = motionEvent.findPointerIndex(mPointerId); if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC - || (motionEvent.getX(index) - mDownX) > mMotionSlop - || (motionEvent.getY(index) - mDownY) > mMotionSlop) { + || index < 0 + || Math.abs(motionEvent.getX(index) - mDownX) > mMotionSlop + || Math.abs(motionEvent.getY(index) - mDownY) > mMotionSlop) { mPointerId = -1; } } @@ -71,12 +71,15 @@ public class StackTapPointerEventListener implements PointerEventListener { if (mPointerId == motionEvent.getPointerId(index)) { final int x = (int)motionEvent.getX(index); final int y = (int)motionEvent.getY(index); - if ((motionEvent.getEventTime() - motionEvent.getDownTime()) - < TAP_TIMEOUT_MSEC - && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop - && !mTouchExcludeRegion.contains(x, y)) { - mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y, - mDisplayContent).sendToTarget(); + synchronized(this) { + if ((motionEvent.getEventTime() - motionEvent.getDownTime()) + < TAP_TIMEOUT_MSEC + && Math.abs(x - mDownX) < mMotionSlop + && Math.abs(y - mDownY) < mMotionSlop + && !mTouchExcludeRegion.contains(x, y)) { + mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y, + mDisplayContent).sendToTarget(); + } } mPointerId = -1; } @@ -84,4 +87,10 @@ public class StackTapPointerEventListener implements PointerEventListener { } } } + + void setTouchExcludeRegion(Region newRegion) { + synchronized (this) { + mTouchExcludeRegion.set(newRegion); + } + } } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 238c77e..d313e3f 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -126,8 +126,8 @@ public class TaskStack { return false; } - mDimLayer.setBounds(bounds); - mAnimationBackgroundSurface.setBounds(bounds); + mDimLayer.setBounds(bounds, false); + mAnimationBackgroundSurface.setBounds(bounds, false); mBounds.set(bounds); return true; @@ -191,7 +191,9 @@ public class TaskStack { mTasks.add(stackNdx, task); task.mStack = this; - mDisplayContent.moveStack(this, true); + if (toTop) { + mDisplayContent.moveStack(this, true); + } EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, stackNdx); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b75622b..566518c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -507,10 +507,16 @@ public class WindowManagerService extends IWindowManager.Stub int mLastDisplayFreezeDuration = 0; Object mLastFinishedFreezeSource = null; boolean mWaitingForConfig = false; - boolean mWindowsFreezingScreen = false; + + final static int WINDOWS_FREEZING_SCREENS_NONE = 0; + final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1; + final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2; + private int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE; + boolean mClientFreezingScreen = false; int mAppsFreezingScreen = 0; int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; int mLayoutSeq = 0; @@ -616,6 +622,13 @@ public class WindowManagerService extends IWindowManager.Stub static final long WALLPAPER_TIMEOUT_RECOVERY = 10000; boolean mAnimateWallpaperWithTarget; + // We give a wallpaper up to 1000ms to finish drawing before playing app transitions. + static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 1000; + static final int WALLPAPER_DRAW_NORMAL = 0; + static final int WALLPAPER_DRAW_PENDING = 1; + static final int WALLPAPER_DRAW_TIMEOUT = 2; + int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL; + AppWindowToken mFocusedApp = null; PowerManager mPowerManager; @@ -3135,6 +3148,10 @@ public class WindowManagerService extends IWindowManager.Stub } winAnimator.mEnteringAnimation = true; if (toBeDisplayed) { + if ((win.mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) + == SOFT_INPUT_ADJUST_RESIZE) { + win.mLayoutNeeded = true; + } if (win.isDrawnLw() && okToDisplay()) { winAnimator.applyEnterAnimationLocked(); } @@ -3724,43 +3741,70 @@ public class WindowManagerService extends IWindowManager.Stub } } - public int getOrientationFromWindowsLocked() { - if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) { - // If the display is frozen, some activities may be in the middle - // of restarting, and thus have removed their old window. If the - // window has the flag to hide the lock screen, then the lock screen - // can re-appear and inflict its own orientation on us. Keep the - // orientation stable until this all settles down. - return mLastWindowForcedOrientation; - } - - // TODO(multidisplay): Change to the correct display. - final WindowList windows = getDefaultWindowListLocked(); - int pos = windows.size() - 1; - while (pos >= 0) { - WindowState win = windows.get(pos); - pos--; - if (win.mAppToken != null) { - // We hit an application window. so the orientation will be determined by the - // app window. No point in continuing further. - return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } - if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) { - continue; + public int getOrientationLocked() { + if (mDisplayFrozen) { + if (mLastWindowForcedOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { + if (DEBUG_ORIENTATION) Slog.v(TAG, "Display is frozen, return " + + mLastWindowForcedOrientation); + // If the display is frozen, some activities may be in the middle + // of restarting, and thus have removed their old window. If the + // window has the flag to hide the lock screen, then the lock screen + // can re-appear and inflict its own orientation on us. Keep the + // orientation stable until this all settles down. + return mLastWindowForcedOrientation; } - int req = win.mAttrs.screenOrientation; - if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) || - (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){ - continue; + } else { + // TODO(multidisplay): Change to the correct display. + final WindowList windows = getDefaultWindowListLocked(); + int pos = windows.size() - 1; + while (pos >= 0) { + WindowState win = windows.get(pos); + pos--; + if (win.mAppToken != null) { + // We hit an application window. so the orientation will be determined by the + // app window. No point in continuing further. + break; + } + if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) { + continue; + } + int req = win.mAttrs.screenOrientation; + if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) || + (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){ + continue; + } + + if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req); + if (mPolicy.isKeyguardHostWindow(win.mAttrs)) { + mLastKeyguardForcedOrientation = req; + } + return (mLastWindowForcedOrientation = req); } + mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req); - return (mLastWindowForcedOrientation=req); + if (mPolicy.isKeyguardLocked()) { + // The screen is locked and no top system window is requesting an orientation. + // Return either the orientation of the show-when-locked app (if there is any) or + // the orientation of the keyguard. No point in searching from the rest of apps. + WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw(); + AppWindowToken appShowWhenLocked = winShowWhenLocked == null ? + null : winShowWhenLocked.mAppToken; + if (appShowWhenLocked != null) { + int req = appShowWhenLocked.requestedOrientation; + if (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { + req = mLastKeyguardForcedOrientation; + } + if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + appShowWhenLocked + + " -- show when locked, return " + req); + return req; + } + if (DEBUG_ORIENTATION) Slog.v(TAG, + "No one is requesting an orientation when the screen is locked"); + return mLastKeyguardForcedOrientation; + } } - return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } - public int getOrientationFromAppTokensLocked() { + // Top system windows are not requesting an orientation. Start searching from apps. int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean findingBehind = false; boolean lastFullscreen = false; @@ -3832,8 +3876,11 @@ public class WindowManagerService extends IWindowManager.Stub findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND); } } - if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation"); - return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation, return " + + mForcedAppOrientation); + // The next app has not been requested to be visible, so we keep the current orientation + // to prevent freezing/unfreezing the display too early. + return mForcedAppOrientation; } @Override @@ -3913,11 +3960,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean updateOrientationFromAppTokensLocked(boolean inTransaction) { long ident = Binder.clearCallingIdentity(); try { - int req = getOrientationFromWindowsLocked(); - if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { - req = getOrientationFromAppTokensLocked(); - } - + int req = getOrientationLocked(); if (req != mForcedAppOrientation) { mForcedAppOrientation = req; //send a message to Policy indicating orientation change to take @@ -4054,6 +4097,15 @@ public class WindowManagerService extends IWindowManager.Stub if (changed) { mFocusedApp = newFocus; mInputMonitor.setFocusedAppLw(newFocus); + setFocusedStackFrame(); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedApp"); + SurfaceControl.openTransaction(); + try { + setFocusedStackLayer(); + } finally { + SurfaceControl.closeTransaction(); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedApp"); + } } if (moveFocusNow && changed) { @@ -4096,6 +4148,8 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.prepare(); mStartingIconInTransition = false; mSkipAppTransitionAnimation = false; + } + if (mAppTransition.isTransitionSet()) { mH.removeMessages(H.APP_TRANSITION_TIMEOUT); mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000); } @@ -4599,19 +4653,19 @@ public class WindowManagerService extends IWindowManager.Stub wtoken.hiddenRequested, HIDE_STACK_CRAWLS ? null : new RuntimeException("here").fillInStackTrace()); + mOpeningApps.remove(wtoken); + mClosingApps.remove(wtoken); + wtoken.waitingToShow = wtoken.waitingToHide = false; + wtoken.hiddenRequested = !visible; + // If we are preparing an app transition, then delay changing // the visibility of this token until we execute that transition. if (okToDisplay() && mAppTransition.isTransitionSet()) { - wtoken.hiddenRequested = !visible; - if (!wtoken.startingDisplayed) { if (DEBUG_APP_TRANSITIONS) Slog.v( TAG, "Setting dummy animation on: " + wtoken); wtoken.mAppAnimator.setDummyAnimation(); } - mOpeningApps.remove(wtoken); - mClosingApps.remove(wtoken); - wtoken.waitingToShow = wtoken.waitingToHide = false; wtoken.inPendingTransaction = true; if (visible) { mOpeningApps.add(wtoken); @@ -4666,6 +4720,7 @@ public class WindowManagerService extends IWindowManager.Stub } final long origId = Binder.clearCallingIdentity(); + wtoken.inPendingTransaction = false; setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction); wtoken.updateReportedVisibilityLocked(); @@ -4684,7 +4739,8 @@ public class WindowManagerService extends IWindowManager.Stub WindowState w = wtoken.allAppWindows.get(i); if (w.mAppFreezing) { w.mAppFreezing = false; - if (w.mHasSurface && !w.mOrientationChanging) { + if (w.mHasSurface && !w.mOrientationChanging + && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) { if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w); w.mOrientationChanging = true; mInnerFields.mOrientationChangeComplete = false; @@ -4733,7 +4789,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mAppsFreezingScreen == 1) { startFreezingDisplayLocked(false, 0, 0); mH.removeMessages(H.APP_FREEZE_TIMEOUT); - mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000); + mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000); } } final int N = wtoken.allAppWindows.size(); @@ -4895,8 +4951,19 @@ public class WindowManagerService extends IWindowManager.Stub if (NW > 0) { mWindowsChanged = true; } + int targetDisplayId = -1; + Task targetTask = mTaskIdToTask.get(token.appWindowToken.groupId); + if (targetTask != null) { + DisplayContent targetDisplayContent = targetTask.getDisplayContent(); + if (targetDisplayContent != null) { + targetDisplayId = targetDisplayContent.getDisplayId(); + } + } for (int i = 0; i < NW; i++) { WindowState win = windows.get(i); + if (targetDisplayId != -1 && win.getDisplayId() != targetDisplayId) { + continue; + } if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win); win.getWindowList().remove(win); int j = win.mChildWindows.size(); @@ -6211,9 +6278,13 @@ public class WindowManagerService extends IWindowManager.Stub } if (ws.mAppToken != null && ws.mAppToken.token == appToken && - ws.isDisplayedLw()) { + ws.isDisplayedLw() && winAnim.mSurfaceShown) { screenshotReady = true; } + + if (ws.isFullscreen(dw, dh) && ws.isOpaqueDrawn()){ + break; + } } if (appToken != null && appWin == null) { @@ -6509,7 +6580,7 @@ public class WindowManagerService extends IWindowManager.Stub mAltOrientation = altOrientation; mPolicy.setRotationLw(mRotation); - mWindowsFreezingScreen = true; + mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE; mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION); mWaitingForConfig = true; @@ -7259,6 +7330,7 @@ public class WindowManagerService extends IWindowManager.Stub displayInfo.getAppMetrics(mDisplayMetrics); mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager( displayContent.getDisplayId(), displayInfo); + displayContent.mBaseDisplayRect.set(0, 0, dw, dh); } if (false) { Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight); @@ -7642,6 +7714,7 @@ public class WindowManagerService extends IWindowManager.Stub public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37; public static final int RESET_ANR_MESSAGE = 38; + public static final int WALLPAPER_DRAW_PENDING_TIMEOUT = 39; @Override public void handleMessage(Message msg) { @@ -7877,6 +7950,7 @@ public class WindowManagerService extends IWindowManager.Stub // TODO(multidisplay): Can non-default displays rotate? synchronized (mWindowMap) { Slog.w(TAG, "Window freeze timeout expired."); + mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT; final WindowList windows = getDefaultWindowListLocked(); int i = windows.size(); while (i > 0) { @@ -7896,8 +7970,12 @@ public class WindowManagerService extends IWindowManager.Stub case APP_TRANSITION_TIMEOUT: { synchronized (mWindowMap) { - if (mAppTransition.isTransitionSet()) { - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT"); + if (mAppTransition.isTransitionSet() || !mOpeningApps.isEmpty() + || !mClosingApps.isEmpty()) { + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT." + + " isTransitionSet()=" + mAppTransition.isTransitionSet() + + " mOpeningApps.size()=" + mOpeningApps.size() + + " mClosingApps.size()=" + mClosingApps.size()); mAppTransition.setTimeout(); performLayoutAndPlaceSurfacesLocked(); } @@ -7944,6 +8022,7 @@ public class WindowManagerService extends IWindowManager.Stub case APP_FREEZE_TIMEOUT: { synchronized (mWindowMap) { Slog.w(TAG, "App freeze timeout expired."); + mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT; final int numStacks = mStackIdToStack.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { final TaskStack stack = mStackIdToStack.valueAt(stackNdx); @@ -8158,6 +8237,17 @@ public class WindowManagerService extends IWindowManager.Stub } } break; + case WALLPAPER_DRAW_PENDING_TIMEOUT: { + synchronized (mWindowMap) { + if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) { + mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT; + if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG, + "*** WALLPAPER DRAW TIMEOUT"); + performLayoutAndPlaceSurfacesLocked(); + } + } + } + break; } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); @@ -8922,7 +9012,8 @@ public class WindowManagerService extends IWindowManager.Stub if (!gone || !win.mHaveFrame || win.mLayoutNeeded || ((win.isConfigChanged() || win.setInsetsChanged()) && ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || - win.mAppToken != null && win.mAppToken.layoutConfigChanges)) + (win.mHasSurface && win.mAppToken != null && + win.mAppToken.layoutConfigChanges))) || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) { if (!win.mLayoutAttached) { if (initial) { @@ -9017,13 +9108,13 @@ public class WindowManagerService extends IWindowManager.Stub // If the screen is currently frozen or off, then keep // it frozen/off until this window draws at its new // orientation. - if (!okToDisplay()) { + if (!okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) { if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w); w.mOrientationChanging = true; w.mLastFreezeDuration = 0; mInnerFields.mOrientationChangeComplete = false; - if (!mWindowsFreezingScreen) { - mWindowsFreezingScreen = true; + if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) { + mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE; // XXX should probably keep timeout from // when we first froze the display. mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); @@ -9047,10 +9138,7 @@ public class WindowManagerService extends IWindowManager.Stub "Checking " + NN + " opening apps (frozen=" + mDisplayFrozen + " timeout=" + mAppTransition.isTimeout() + ")..."); - if (!mDisplayFrozen && !mAppTransition.isTimeout()) { - // If the display isn't frozen, wait to do anything until - // all of the apps are ready. Otherwise just go because - // we'll unfreeze the display when everyone is ready. + if (!mAppTransition.isTimeout()) { for (i=0; i<NN && goodToGo; i++) { AppWindowToken wtoken = mOpeningApps.valueAt(i); if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, @@ -9063,6 +9151,39 @@ public class WindowManagerService extends IWindowManager.Stub goodToGo = false; } } + if (goodToGo && isWallpaperVisible(mWallpaperTarget)) { + boolean wallpaperGoodToGo = true; + for (int curTokenIndex = mWallpaperTokens.size() - 1; + curTokenIndex >= 0 && wallpaperGoodToGo; curTokenIndex--) { + WindowToken token = mWallpaperTokens.get(curTokenIndex); + for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0; + curWallpaperIndex--) { + WindowState wallpaper = token.windows.get(curWallpaperIndex); + if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) { + // We've told this wallpaper to be visible, but it is not drawn yet + wallpaperGoodToGo = false; + if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) { + // wait for this wallpaper until it is drawn or timeout + goodToGo = false; + } + if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) { + mWallpaperDrawState = WALLPAPER_DRAW_PENDING; + mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT); + mH.sendEmptyMessageDelayed(H.WALLPAPER_DRAW_PENDING_TIMEOUT, + WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION); + } + if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG, + "Wallpaper should be visible but has not been drawn yet. " + + "mWallpaperDrawState=" + mWallpaperDrawState); + break; + } + } + } + if (wallpaperGoodToGo) { + mWallpaperDrawState = WALLPAPER_DRAW_NORMAL; + mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT); + } + } } if (goodToGo) { if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO"); @@ -10019,8 +10140,8 @@ public class WindowManagerService extends IWindowManager.Stub "With display frozen, orientationChangeComplete=" + mInnerFields.mOrientationChangeComplete); if (mInnerFields.mOrientationChangeComplete) { - if (mWindowsFreezingScreen) { - mWindowsFreezingScreen = false; + if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) { + mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE; mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource; mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); } @@ -10308,7 +10429,7 @@ public class WindowManagerService extends IWindowManager.Stub } else { mInnerFields.mOrientationChangeComplete = true; mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource; - if (mWindowsFreezingScreen) { + if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) { doRequest = true; } } @@ -10653,13 +10774,15 @@ public class WindowManagerService extends IWindowManager.Stub return; } - if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen - || mClientFreezingScreen) { + if (mWaitingForConfig || mAppsFreezingScreen > 0 + || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE + || mClientFreezingScreen || !mOpeningApps.isEmpty()) { if (DEBUG_ORIENTATION) Slog.d(TAG, "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig + ", mAppsFreezingScreen=" + mAppsFreezingScreen + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen - + ", mClientFreezingScreen=" + mClientFreezingScreen); + + ", mClientFreezingScreen=" + mClientFreezingScreen + + ", mOpeningApps.size()=" + mOpeningApps.size()); return; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e0d2673..a2b1880 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -431,28 +431,26 @@ final class WindowState implements WindowManagerPolicy.WindowState { mAttachedWindow = attachedWindow; if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow); - int children_size = mAttachedWindow.mChildWindows.size(); - if (children_size == 0) { - mAttachedWindow.mChildWindows.add(this); + final WindowList childWindows = mAttachedWindow.mChildWindows; + final int numChildWindows = childWindows.size(); + if (numChildWindows == 0) { + childWindows.add(this); } else { - for (int i = 0; i < children_size; i++) { - WindowState child = (WindowState)mAttachedWindow.mChildWindows.get(i); - if (this.mSubLayer < child.mSubLayer) { - mAttachedWindow.mChildWindows.add(i, this); + boolean added = false; + for (int i = 0; i < numChildWindows; i++) { + final int childSubLayer = childWindows.get(i).mSubLayer; + if (mSubLayer < childSubLayer + || (mSubLayer == childSubLayer && childSubLayer < 0)) { + // We insert the child window into the list ordered by the sub-layer. For + // same sub-layers, the negative one should go below others; the positive + // one should go above others. + childWindows.add(i, this); + added = true; break; - } else if (this.mSubLayer > child.mSubLayer) { - continue; - } - - if (this.mBaseLayer <= child.mBaseLayer) { - mAttachedWindow.mChildWindows.add(i, this); - break; - } else { - continue; } } - if (children_size == mAttachedWindow.mChildWindows.size()) { - mAttachedWindow.mChildWindows.add(this); + if (!added) { + childWindows.add(this); } } @@ -1500,6 +1498,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { mOrientationChanging = false; mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime); + // We are assuming the hosting process is dead or in a zombie state. + Slog.w(TAG, "Failed to report 'resized' to the client of " + this + + ", removing this window."); + mService.mPendingRemove.add(this); + mService.requestTraversalLocked(); } } |