Loading services/core/java/com/android/server/wm/WindowManagerService.java +133 −172 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.StatusBarManager.DISABLE_MASK; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; Loading @@ -31,8 +32,6 @@ import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHA import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; Loading @@ -46,6 +45,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH; Loading Loading @@ -2537,11 +2538,8 @@ public class WindowManagerService extends IWindowManager.Stub Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig, Surface outSurface) { boolean toBeDisplayed = false; boolean inTouchMode; int result = 0; boolean configChanged; boolean surfaceChanged = false; boolean dragResizing = false; boolean hasStatusBarPermission = mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) == PackageManager.PERMISSION_GRANTED; Loading @@ -2558,31 +2556,21 @@ public class WindowManagerService extends IWindowManager.Stub win.setRequestedSize(requestedWidth, requestedHeight); } int attrChanges = 0; int flagChanges = 0; if (attrs != null) { mPolicy.adjustWindowParamsLw(attrs); } // if they don't have the permission, mask out the status bar bits int systemUiVisibility = 0; if (attrs != null) { systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility); if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) { if (seq == win.mSeq) { int systemUiVisibility = attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility; if ((systemUiVisibility & DISABLE_MASK) != 0) { if (!hasStatusBarPermission) { systemUiVisibility &= ~StatusBarManager.DISABLE_MASK; } systemUiVisibility &= ~DISABLE_MASK; } } if (attrs != null && seq == win.mSeq) { win.mSystemUiVisibility = systemUiVisibility; } winAnimator.mSurfaceDestroyDeferred = (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0; int attrChanges = 0; int flagChanges = 0; if (attrs != null) { if (win.mAttrs.type != attrs.type) { throw new IllegalArgumentException( "Window type can not be changed after the window is added."); Loading @@ -2597,30 +2585,15 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs); winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0; win.mEnforceSizeCompat = (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) { winAnimator.mAlpha = attrs.alpha; } final boolean scaledWindow = ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0); if (scaledWindow) { // requested{Width|Height} Surface's physical size // attrs.{width|height} Size on screen win.mHScale = (attrs.width != requestedWidth) ? (attrs.width / (float)requestedWidth) : 1.0f; win.mVScale = (attrs.height != requestedHeight) ? (attrs.height / (float)requestedHeight) : 1.0f; } else { win.mHScale = win.mVScale = 1; } win.setWindowScale(requestedWidth, requestedHeight); boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0; final boolean isDefaultDisplay = win.isDefaultDisplay(); boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) Loading @@ -2644,78 +2617,10 @@ public class WindowManagerService extends IWindowManager.Stub } if (viewVisibility == View.VISIBLE && (win.mAppToken == null || !win.mAppToken.clientHidden)) { toBeDisplayed = !win.isVisibleLw(); if (win.mExiting) { winAnimator.cancelExitAnimationForNextAnimationLocked(); win.mExiting = false; } if (win.mDestroying) { win.mDestroying = false; mDestroySurface.remove(win); } if (oldVisibility == View.GONE) { winAnimator.mEnterAnimationPending = true; } 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(); } if ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + win); win.mTurnOnScreen = true; } if (win.isConfigChanged()) { if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win + " visible with new config: " + mCurConfiguration); outConfig.setTo(mCurConfiguration); } } if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) { // If the format can be changed in place yaay! // If not, fall back to a surface re-build if (!winAnimator.tryChangeFormatInPlaceLocked()) { winAnimator.destroySurfaceLocked(); toBeDisplayed = true; surfaceChanged = true; } } // If we're starting a drag-resize, we'll be changing the surface size as well as // notifying the client to render to with an offset from the surface's top-left. if (win.isDragResizeChanged()) { win.setDragResizing(); if (win.mHasSurface) { winAnimator.preserveSurfaceLocked(); toBeDisplayed = true; } } dragResizing = win.isDragResizing(); if (win.isAnimatingWithSavedSurface()) { // If we're animating with a saved surface now, request client to report draw. // We still need to know when the real thing is drawn. toBeDisplayed = true; } result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges, oldVisibility); try { if (!win.mHasSurface) { surfaceChanged = true; } SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); if (surfaceControl != null) { outSurface.copyFrom(surfaceControl); if (SHOW_TRANSACTIONS) Slog.i(TAG, " OUT SURFACE " + outSurface + ": copied"); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. outSurface.release(); } result = createSurfaceControl(outSurface, result, win, winAnimator); } catch (Exception e) { mInputMonitor.updateInputWindowsLw(true /*force*/); Loading @@ -2725,27 +2630,14 @@ public class WindowManagerService extends IWindowManager.Stub Binder.restoreCallingIdentity(origId); return 0; } if (toBeDisplayed) { if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { focusMayChange = isDefaultDisplay; } if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) { if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) { mInputMethodWindow = win; imMayMove = true; } if (win.mAttrs.type == TYPE_BASE_APPLICATION && win.mAppToken != null && win.mAppToken.startingWindow != null) { // Special handling of starting window over the base // window of the app: propagate lock screen flags to it, // to provide the correct semantics while starting. final int mask = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs; sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask); } win.adjustStartingWindowFlags(); } else { winAnimator.mEnterAnimationPending = false; winAnimator.mEnteringAnimation = false; Loading @@ -2759,41 +2651,14 @@ public class WindowManagerService extends IWindowManager.Stub // don't want to destroy the saved surface. // If we are not currently running the exit animation, we // need to see about starting one. if (!win.mExiting && !win.isAnimatingWithSavedSurface()) { surfaceChanged = true; // Try starting an animation; if there isn't one, we // can destroy the surface right away. int transit = WindowManagerPolicy.TRANSIT_EXIT; if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; } if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { focusMayChange = isDefaultDisplay; win.mExiting = true; } else if (win.mWinAnimator.isAnimating()) { // Currently in a hide animation... turn this into // an exit. win.mExiting = true; } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) { // If the wallpaper is currently behind this // window, we need to change both of them inside // of a transaction to avoid artifacts. win.mExiting = true; win.mWinAnimator.mAnimating = true; } else { if (mInputMethodWindow == win) { mInputMethodWindow = null; } if (!win.shouldSaveSurface()) { winAnimator.destroySurfaceLocked(); } } //TODO (multidisplay): Magnification is supported only for the default if (mAccessibilityController != null && win.getDisplayId() == Display.DEFAULT_DISPLAY) { mAccessibilityController.onWindowTransitionLocked(win, transit); } final boolean notExitingOrAnimating = !win.mExiting && !win.isAnimatingWithSavedSurface(); result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0; if (notExitingOrAnimating) { focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay, focusMayChange); } } Loading @@ -2812,6 +2677,7 @@ public class WindowManagerService extends IWindowManager.Stub // updateFocusedWindowLocked() already assigned layers so we only need to // reassign them at this point if the IM window state gets shuffled boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0; if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) { // Little hack here -- we -should- be able to rely on the // function to return true if the IME has moved and needs Loading Loading @@ -2855,7 +2721,7 @@ public class WindowManagerService extends IWindowManager.Stub if (localLOGV || DEBUG_FOCUS) Slog.v( TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange); inTouchMode = mInTouchMode; result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0; mInputMonitor.updateInputWindowsLw(true /*force*/); Loading @@ -2867,13 +2733,108 @@ public class WindowManagerService extends IWindowManager.Stub if (configChanged) { sendNewConfiguration(); } Binder.restoreCallingIdentity(origId); return result; } private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator, boolean isDefaultDisplay, boolean focusMayChange) { // Try starting an animation; if there isn't one, we // can destroy the surface right away. int transit = WindowManagerPolicy.TRANSIT_EXIT; if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; } if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { focusMayChange = isDefaultDisplay; win.mExiting = true; } else if (win.mWinAnimator.isAnimating()) { // Currently in a hide animation... turn this into // an exit. win.mExiting = true; } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) { // If the wallpaper is currently behind this // window, we need to change both of them inside // of a transaction to avoid artifacts. win.mExiting = true; win.mWinAnimator.mAnimating = true; } else { if (mInputMethodWindow == win) { mInputMethodWindow = null; } if (!win.shouldSaveSurface()) { winAnimator.destroySurfaceLocked(); } } //TODO (multidisplay): Magnification is supported only for the default if (mAccessibilityController != null && win.getDisplayId() == Display.DEFAULT_DISPLAY) { mAccessibilityController.onWindowTransitionLocked(win, transit); } return focusMayChange; } private int createSurfaceControl(Surface outSurface, int result, WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; } SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); if (surfaceControl != null) { outSurface.copyFrom(surfaceControl); if (SHOW_TRANSACTIONS) Slog.i(TAG, " OUT SURFACE " + outSurface + ": copied"); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. outSurface.release(); } return result; } return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0) | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0) | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0) | (dragResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0); private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win, WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) { result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0; if (win.mExiting) { winAnimator.cancelExitAnimationForNextAnimationLocked(); win.mExiting = false; } if (win.mDestroying) { win.mDestroying = false; mDestroySurface.remove(win); } if (oldVisibility == View.GONE) { winAnimator.mEnterAnimationPending = true; } winAnimator.mEnteringAnimation = true; if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { win.prepareWindowToDisplayDuringRelayout(outConfig); } if ((attrChanges& LayoutParams.FORMAT_CHANGED) != 0) { // If the format can be changed in place yaay! // If not, fall back to a surface re-build if (!winAnimator.tryChangeFormatInPlaceLocked()) { winAnimator.destroySurfaceLocked(); result |= RELAYOUT_RES_SURFACE_CHANGED | WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } } // If we're starting a drag-resize, we'll be changing the surface size as well as // notifying the client to render to with an offset from the surface's top-left. if (win.isDragResizeChanged()) { win.setDragResizing(); if (win.mHasSurface) { winAnimator.preserveSurfaceLocked(); result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } } result |= win.isDragResizing() ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0; if (win.isAnimatingWithSavedSurface()) { // If we're animating with a saved surface now, request client to report draw. // We still need to know when the real thing is drawn. result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } return result; } public void performDeferredDestroyWindow(Session session, IWindow client) { Loading services/core/java/com/android/server/wm/WindowState.java +56 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,19 @@ package com.android.server.wm; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_SCALED; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; Loading Loading @@ -606,7 +613,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { final int ph = mContainingFrame.height(); int w,h; if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) { if ((mAttrs.flags & FLAG_SCALED) != 0) { if (mAttrs.width < 0) { w = pw; } else if (mEnforceSizeCompat) { Loading Loading @@ -1447,6 +1454,54 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } void prepareWindowToDisplayDuringRelayout(Configuration outConfig) { if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) == SOFT_INPUT_ADJUST_RESIZE) { mLayoutNeeded = true; } if (isDrawnLw() && mService.okToDisplay()) { mWinAnimator.applyEnterAnimationLocked(); } if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); mTurnOnScreen = true; } if (isConfigChanged()) { if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: " + mService.mCurConfiguration); outConfig.setTo(mService.mCurConfiguration); } } void adjustStartingWindowFlags() { if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null && mAppToken.startingWindow != null) { // Special handling of starting window over the base // window of the app: propagate lock screen flags to it, // to provide the correct semantics while starting. final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs; sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask); } } void setWindowScale(int requestedWidth, int requestedHeight) { final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0; if (scaledWindow) { // requested{Width|Height} Surface's physical size // attrs.{width|height} Size on screen // TODO: We don't check if attrs != null here. Is it implicitly checked? mHScale = (mAttrs.width != requestedWidth) ? (mAttrs.width / (float)requestedWidth) : 1.0f; mVScale = (mAttrs.height != requestedHeight) ? (mAttrs.height / (float)requestedHeight) : 1.0f; } else { mHScale = mVScale = 1; } } private class DeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Loading Loading
services/core/java/com/android/server/wm/WindowManagerService.java +133 −172 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.StatusBarManager.DISABLE_MASK; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; Loading @@ -31,8 +32,6 @@ import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHA import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; Loading @@ -46,6 +45,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH; Loading Loading @@ -2537,11 +2538,8 @@ public class WindowManagerService extends IWindowManager.Stub Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig, Surface outSurface) { boolean toBeDisplayed = false; boolean inTouchMode; int result = 0; boolean configChanged; boolean surfaceChanged = false; boolean dragResizing = false; boolean hasStatusBarPermission = mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) == PackageManager.PERMISSION_GRANTED; Loading @@ -2558,31 +2556,21 @@ public class WindowManagerService extends IWindowManager.Stub win.setRequestedSize(requestedWidth, requestedHeight); } int attrChanges = 0; int flagChanges = 0; if (attrs != null) { mPolicy.adjustWindowParamsLw(attrs); } // if they don't have the permission, mask out the status bar bits int systemUiVisibility = 0; if (attrs != null) { systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility); if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) { if (seq == win.mSeq) { int systemUiVisibility = attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility; if ((systemUiVisibility & DISABLE_MASK) != 0) { if (!hasStatusBarPermission) { systemUiVisibility &= ~StatusBarManager.DISABLE_MASK; } systemUiVisibility &= ~DISABLE_MASK; } } if (attrs != null && seq == win.mSeq) { win.mSystemUiVisibility = systemUiVisibility; } winAnimator.mSurfaceDestroyDeferred = (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0; int attrChanges = 0; int flagChanges = 0; if (attrs != null) { if (win.mAttrs.type != attrs.type) { throw new IllegalArgumentException( "Window type can not be changed after the window is added."); Loading @@ -2597,30 +2585,15 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs); winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0; win.mEnforceSizeCompat = (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) { winAnimator.mAlpha = attrs.alpha; } final boolean scaledWindow = ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0); if (scaledWindow) { // requested{Width|Height} Surface's physical size // attrs.{width|height} Size on screen win.mHScale = (attrs.width != requestedWidth) ? (attrs.width / (float)requestedWidth) : 1.0f; win.mVScale = (attrs.height != requestedHeight) ? (attrs.height / (float)requestedHeight) : 1.0f; } else { win.mHScale = win.mVScale = 1; } win.setWindowScale(requestedWidth, requestedHeight); boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0; final boolean isDefaultDisplay = win.isDefaultDisplay(); boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) Loading @@ -2644,78 +2617,10 @@ public class WindowManagerService extends IWindowManager.Stub } if (viewVisibility == View.VISIBLE && (win.mAppToken == null || !win.mAppToken.clientHidden)) { toBeDisplayed = !win.isVisibleLw(); if (win.mExiting) { winAnimator.cancelExitAnimationForNextAnimationLocked(); win.mExiting = false; } if (win.mDestroying) { win.mDestroying = false; mDestroySurface.remove(win); } if (oldVisibility == View.GONE) { winAnimator.mEnterAnimationPending = true; } 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(); } if ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + win); win.mTurnOnScreen = true; } if (win.isConfigChanged()) { if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win + " visible with new config: " + mCurConfiguration); outConfig.setTo(mCurConfiguration); } } if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) { // If the format can be changed in place yaay! // If not, fall back to a surface re-build if (!winAnimator.tryChangeFormatInPlaceLocked()) { winAnimator.destroySurfaceLocked(); toBeDisplayed = true; surfaceChanged = true; } } // If we're starting a drag-resize, we'll be changing the surface size as well as // notifying the client to render to with an offset from the surface's top-left. if (win.isDragResizeChanged()) { win.setDragResizing(); if (win.mHasSurface) { winAnimator.preserveSurfaceLocked(); toBeDisplayed = true; } } dragResizing = win.isDragResizing(); if (win.isAnimatingWithSavedSurface()) { // If we're animating with a saved surface now, request client to report draw. // We still need to know when the real thing is drawn. toBeDisplayed = true; } result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges, oldVisibility); try { if (!win.mHasSurface) { surfaceChanged = true; } SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); if (surfaceControl != null) { outSurface.copyFrom(surfaceControl); if (SHOW_TRANSACTIONS) Slog.i(TAG, " OUT SURFACE " + outSurface + ": copied"); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. outSurface.release(); } result = createSurfaceControl(outSurface, result, win, winAnimator); } catch (Exception e) { mInputMonitor.updateInputWindowsLw(true /*force*/); Loading @@ -2725,27 +2630,14 @@ public class WindowManagerService extends IWindowManager.Stub Binder.restoreCallingIdentity(origId); return 0; } if (toBeDisplayed) { if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { focusMayChange = isDefaultDisplay; } if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) { if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) { mInputMethodWindow = win; imMayMove = true; } if (win.mAttrs.type == TYPE_BASE_APPLICATION && win.mAppToken != null && win.mAppToken.startingWindow != null) { // Special handling of starting window over the base // window of the app: propagate lock screen flags to it, // to provide the correct semantics while starting. final int mask = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs; sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask); } win.adjustStartingWindowFlags(); } else { winAnimator.mEnterAnimationPending = false; winAnimator.mEnteringAnimation = false; Loading @@ -2759,41 +2651,14 @@ public class WindowManagerService extends IWindowManager.Stub // don't want to destroy the saved surface. // If we are not currently running the exit animation, we // need to see about starting one. if (!win.mExiting && !win.isAnimatingWithSavedSurface()) { surfaceChanged = true; // Try starting an animation; if there isn't one, we // can destroy the surface right away. int transit = WindowManagerPolicy.TRANSIT_EXIT; if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; } if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { focusMayChange = isDefaultDisplay; win.mExiting = true; } else if (win.mWinAnimator.isAnimating()) { // Currently in a hide animation... turn this into // an exit. win.mExiting = true; } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) { // If the wallpaper is currently behind this // window, we need to change both of them inside // of a transaction to avoid artifacts. win.mExiting = true; win.mWinAnimator.mAnimating = true; } else { if (mInputMethodWindow == win) { mInputMethodWindow = null; } if (!win.shouldSaveSurface()) { winAnimator.destroySurfaceLocked(); } } //TODO (multidisplay): Magnification is supported only for the default if (mAccessibilityController != null && win.getDisplayId() == Display.DEFAULT_DISPLAY) { mAccessibilityController.onWindowTransitionLocked(win, transit); } final boolean notExitingOrAnimating = !win.mExiting && !win.isAnimatingWithSavedSurface(); result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0; if (notExitingOrAnimating) { focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay, focusMayChange); } } Loading @@ -2812,6 +2677,7 @@ public class WindowManagerService extends IWindowManager.Stub // updateFocusedWindowLocked() already assigned layers so we only need to // reassign them at this point if the IM window state gets shuffled boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0; if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) { // Little hack here -- we -should- be able to rely on the // function to return true if the IME has moved and needs Loading Loading @@ -2855,7 +2721,7 @@ public class WindowManagerService extends IWindowManager.Stub if (localLOGV || DEBUG_FOCUS) Slog.v( TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange); inTouchMode = mInTouchMode; result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0; mInputMonitor.updateInputWindowsLw(true /*force*/); Loading @@ -2867,13 +2733,108 @@ public class WindowManagerService extends IWindowManager.Stub if (configChanged) { sendNewConfiguration(); } Binder.restoreCallingIdentity(origId); return result; } private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator, boolean isDefaultDisplay, boolean focusMayChange) { // Try starting an animation; if there isn't one, we // can destroy the surface right away. int transit = WindowManagerPolicy.TRANSIT_EXIT; if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; } if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { focusMayChange = isDefaultDisplay; win.mExiting = true; } else if (win.mWinAnimator.isAnimating()) { // Currently in a hide animation... turn this into // an exit. win.mExiting = true; } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) { // If the wallpaper is currently behind this // window, we need to change both of them inside // of a transaction to avoid artifacts. win.mExiting = true; win.mWinAnimator.mAnimating = true; } else { if (mInputMethodWindow == win) { mInputMethodWindow = null; } if (!win.shouldSaveSurface()) { winAnimator.destroySurfaceLocked(); } } //TODO (multidisplay): Magnification is supported only for the default if (mAccessibilityController != null && win.getDisplayId() == Display.DEFAULT_DISPLAY) { mAccessibilityController.onWindowTransitionLocked(win, transit); } return focusMayChange; } private int createSurfaceControl(Surface outSurface, int result, WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; } SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); if (surfaceControl != null) { outSurface.copyFrom(surfaceControl); if (SHOW_TRANSACTIONS) Slog.i(TAG, " OUT SURFACE " + outSurface + ": copied"); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. outSurface.release(); } return result; } return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0) | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0) | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0) | (dragResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0); private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win, WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) { result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0; if (win.mExiting) { winAnimator.cancelExitAnimationForNextAnimationLocked(); win.mExiting = false; } if (win.mDestroying) { win.mDestroying = false; mDestroySurface.remove(win); } if (oldVisibility == View.GONE) { winAnimator.mEnterAnimationPending = true; } winAnimator.mEnteringAnimation = true; if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { win.prepareWindowToDisplayDuringRelayout(outConfig); } if ((attrChanges& LayoutParams.FORMAT_CHANGED) != 0) { // If the format can be changed in place yaay! // If not, fall back to a surface re-build if (!winAnimator.tryChangeFormatInPlaceLocked()) { winAnimator.destroySurfaceLocked(); result |= RELAYOUT_RES_SURFACE_CHANGED | WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } } // If we're starting a drag-resize, we'll be changing the surface size as well as // notifying the client to render to with an offset from the surface's top-left. if (win.isDragResizeChanged()) { win.setDragResizing(); if (win.mHasSurface) { winAnimator.preserveSurfaceLocked(); result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } } result |= win.isDragResizing() ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0; if (win.isAnimatingWithSavedSurface()) { // If we're animating with a saved surface now, request client to report draw. // We still need to know when the real thing is drawn. result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } return result; } public void performDeferredDestroyWindow(Session session, IWindow client) { Loading
services/core/java/com/android/server/wm/WindowState.java +56 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,19 @@ package com.android.server.wm; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_SCALED; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; Loading Loading @@ -606,7 +613,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { final int ph = mContainingFrame.height(); int w,h; if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) { if ((mAttrs.flags & FLAG_SCALED) != 0) { if (mAttrs.width < 0) { w = pw; } else if (mEnforceSizeCompat) { Loading Loading @@ -1447,6 +1454,54 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } void prepareWindowToDisplayDuringRelayout(Configuration outConfig) { if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) == SOFT_INPUT_ADJUST_RESIZE) { mLayoutNeeded = true; } if (isDrawnLw() && mService.okToDisplay()) { mWinAnimator.applyEnterAnimationLocked(); } if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); mTurnOnScreen = true; } if (isConfigChanged()) { if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: " + mService.mCurConfiguration); outConfig.setTo(mService.mCurConfiguration); } } void adjustStartingWindowFlags() { if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null && mAppToken.startingWindow != null) { // Special handling of starting window over the base // window of the app: propagate lock screen flags to it, // to provide the correct semantics while starting. final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs; sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask); } } void setWindowScale(int requestedWidth, int requestedHeight) { final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0; if (scaledWindow) { // requested{Width|Height} Surface's physical size // attrs.{width|height} Size on screen // TODO: We don't check if attrs != null here. Is it implicitly checked? mHScale = (mAttrs.width != requestedWidth) ? (mAttrs.width / (float)requestedWidth) : 1.0f; mVScale = (mAttrs.height != requestedHeight) ? (mAttrs.height / (float)requestedHeight) : 1.0f; } else { mHScale = mVScale = 1; } } private class DeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Loading