diff options
6 files changed, 184 insertions, 27 deletions
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 317408387526..c20fc75a51f3 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -24,6 +24,7 @@ import static android.graphics.Matrix.MSKEW_X; import static android.graphics.Matrix.MSKEW_Y; import static android.view.SurfaceControl.METADATA_WINDOW_TYPE; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; +import static android.view.ViewRootImpl.LOCAL_LAYOUT; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import android.animation.Animator; @@ -39,6 +40,7 @@ import android.app.Service; import android.app.WallpaperColors; import android.app.WallpaperInfo; import android.app.WallpaperManager; +import android.app.WindowConfiguration; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; @@ -257,6 +259,8 @@ public abstract class WallpaperService extends Service { private final Point mLastSurfaceSize = new Point(); private final Matrix mTmpMatrix = new Matrix(); private final float[] mTmpValues = new float[9]; + private final WindowLayout mWindowLayout = new WindowLayout(); + private final Rect mTempRect = new Rect(); final WindowManager.LayoutParams mLayout = new WindowManager.LayoutParams(); @@ -1091,7 +1095,8 @@ public abstract class WallpaperService extends Service { | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; final Configuration config = mMergedConfiguration.getMergedConfiguration(); - final Rect maxBounds = config.windowConfiguration.getMaxBounds(); + final WindowConfiguration winConfig = config.windowConfiguration; + final Rect maxBounds = winConfig.getMaxBounds(); if (myWidth == ViewGroup.LayoutParams.MATCH_PARENT && myHeight == ViewGroup.LayoutParams.MATCH_PARENT) { mLayout.width = myWidth; @@ -1149,10 +1154,28 @@ public abstract class WallpaperService extends Service { mLayout.surfaceInsets.set(0, 0, 0, 0); } - final int relayoutResult = mSession.relayout( - mWindow, mLayout, mWidth, mHeight, - View.VISIBLE, 0, mWinFrames, mMergedConfiguration, mSurfaceControl, - mInsetsState, mTempControls, mSyncSeqIdBundle); + int relayoutResult = 0; + if (LOCAL_LAYOUT) { + if (!mSurfaceControl.isValid()) { + relayoutResult = mSession.updateVisibility(mWindow, mLayout, + View.VISIBLE, mMergedConfiguration, mSurfaceControl, + mInsetsState, mTempControls); + } + + final Rect displayCutoutSafe = mTempRect; + mInsetsState.getDisplayCutoutSafe(displayCutoutSafe); + mWindowLayout.computeFrames(mLayout, mInsetsState, displayCutoutSafe, + winConfig.getBounds(), winConfig.getWindowingMode(), mWidth, + mHeight, mRequestedVisibilities, null /* attachedWindowFrame */, + 1f /* compatScale */, mWinFrames); + + mSession.updateLayout(mWindow, mLayout, 0 /* flags */, mWinFrames, mWidth, + mHeight); + } else { + relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight, + View.VISIBLE, 0, mWinFrames, mMergedConfiguration, + mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle); + } final int transformHint = SurfaceControl.rotationToBufferTransform( (mDisplayInstallOrientation + mDisplay.getRotation()) % 4); @@ -1202,7 +1225,7 @@ public abstract class WallpaperService extends Service { null /* ignoringVisibilityState */, config.isScreenRound(), false /* alwaysConsumeSystemBars */, mLayout.softInputMode, mLayout.flags, SYSTEM_UI_FLAG_VISIBLE, mLayout.type, - config.windowConfiguration.getWindowingMode(), null /* typeSideMap */); + winConfig.getWindowingMode(), null /* typeSideMap */); if (!fixedSize) { final Rect padding = mIWallpaperEngine.mDisplayPadding; diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index fd8690009a6d..70986024bc5b 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -107,6 +107,41 @@ interface IWindowSession { out InsetsState insetsState, out InsetsSourceControl[] activeControls, out Bundle bundle); + /** + * Changes the view visibility and the attributes of a window. This should only be called when + * the visibility of the root view is changed. This returns a valid surface if the root view is + * visible. This also returns the latest information for the caller to compute its window frame. + * + * @param window The window being updated. + * @param attrs If non-null, new attributes to apply to the window. + * @param viewVisibility Window root view's visibility. + * @param outMergedConfiguration New config container that holds global, override and merged + * config for window, if it is now becoming visible and the merged configuration has changed + * since it was last displayed. + * @param outSurfaceControl Object in which is placed the new display surface. + * @param outInsetsState The current insets state in the system. + * @param outActiveControls The insets source controls for the caller to override the insets + * state in the system. + * + * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}. + */ + int updateVisibility(IWindow window, in WindowManager.LayoutParams attrs, int viewVisibility, + out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl, + out InsetsState outInsetsState, out InsetsSourceControl[] outActiveControls); + + /** + * Reports the layout results and the attributes of a window to the server. + * + * @param window The window being reported. + * @param attrs If non-null, new attributes to apply to the window. + * @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING}. + * @param clientFrames the window frames computed by the client. + * @param requestedWidth The width the window wants to be. + * @param requestedHeight The height the window wants to be. + */ + oneway void updateLayout(IWindow window, in WindowManager.LayoutParams attrs, int flags, + in ClientWindowFrames clientFrames, int requestedWidth, int requestedHeight); + /* * Notify the window manager that an application is relaunching and * windows should be prepared for replacement. diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 172cd03900e7..2613c1a2992f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -78,11 +78,13 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_E 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_ATTACHED_DIALOG; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; +import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER; @@ -279,6 +281,13 @@ public final class ViewRootImpl implements ViewParent, public static final boolean CAPTION_ON_SHELL = false; /** + * Whether the client should compute the window frame on its own. + * @hide + */ + public static final boolean LOCAL_LAYOUT = + SystemProperties.getBoolean("persist.debug.local_layout", false); + + /** * Set this system property to true to force the view hierarchy to render * at 60 Hz. This can be used to measure the potential framerate. */ @@ -8083,17 +8092,68 @@ public final class ViewRootImpl implements ViewParent, final int requestedWidth = (int) (mView.getMeasuredWidth() * appScale + 0.5f); final int requestedHeight = (int) (mView.getMeasuredHeight() * appScale + 0.5f); - int relayoutResult = mWindowSession.relayout(mWindow, params, - requestedWidth, requestedHeight, viewVisibility, - insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, - mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, - mTempControls, mRelayoutBundle); - mSyncSeqId = mRelayoutBundle.getInt("seqid"); + mWillMove = false; + mWillResize = false; + int relayoutResult = 0; + WindowConfiguration winConfig = getConfiguration().windowConfiguration; + if (LOCAL_LAYOUT) { + if (mFirst || viewVisibility != mViewVisibility) { + relayoutResult = mWindowSession.updateVisibility(mWindow, params, viewVisibility, + mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls); + if (mTranslator != null) { + mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); + mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); + } + mInsetsController.onStateChanged(mTempInsets); + mInsetsController.onControlsChanged(mTempControls); + + mPendingAlwaysConsumeSystemBars = + (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; + } + final InsetsState state = mInsetsController.getState(); + final Rect displayCutoutSafe = mTempRect; + state.getDisplayCutoutSafe(displayCutoutSafe); + if (mWindowAttributes.type == TYPE_APPLICATION_STARTING) { + // TODO(b/210378379): Remove the special logic. + // Letting starting window use the window bounds from the pending config is for the + // fixed rotation, because the config is not overridden before the starting window + // is created. + winConfig = mPendingMergedConfiguration.getMergedConfiguration() + .windowConfiguration; + } + mWindowLayout.computeFrames(mWindowAttributes, state, displayCutoutSafe, + winConfig.getBounds(), winConfig.getWindowingMode(), requestedWidth, + requestedHeight, mInsetsController.getRequestedVisibilities(), + getAttachedWindowFrame(), 1f /* compatScale */, mTmpFrames); + + mWindowSession.updateLayout(mWindow, params, + insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mTmpFrames, + requestedWidth, requestedHeight); + + } else { + relayoutResult = mWindowSession.relayout(mWindow, params, + requestedWidth, requestedHeight, viewVisibility, + insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, + mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, + mTempControls, mRelayoutBundle); + mSyncSeqId = mRelayoutBundle.getInt("seqid"); + + if (mTranslator != null) { + mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); + mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame); + mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); + mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); + } + mInsetsController.onStateChanged(mTempInsets); + mInsetsController.onControlsChanged(mTempControls); + + mPendingAlwaysConsumeSystemBars = + (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; + } final int transformHint = SurfaceControl.rotationToBufferTransform( (mDisplayInstallOrientation + mDisplay.getRotation()) % 4); - final WindowConfiguration winConfig = getConfiguration().windowConfiguration; WindowLayout.computeSurfaceSize(mWindowAttributes, winConfig.getMaxBounds(), requestedWidth, requestedHeight, mTmpFrames.frame, mPendingDragResizing, mSurfaceSize); @@ -8142,24 +8202,10 @@ public final class ViewRootImpl implements ViewParent, destroySurface(); } - mPendingAlwaysConsumeSystemBars = - (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; - if (restore) { params.restore(); } - - if (mTranslator != null) { - mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); - mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame); - mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); - mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); - } setFrame(mTmpFrames.frame); - mWillMove = false; - mWillResize = false; - mInsetsController.onStateChanged(mTempInsets); - mInsetsController.onControlsChanged(mTempControls); return relayoutResult; } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 06588b2cbb6d..385a80d7c32c 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -336,6 +336,21 @@ public class WindowlessWindowManager implements IWindowSession { } @Override + public int updateVisibility(IWindow window, WindowManager.LayoutParams inAttrs, + int viewVisibility, MergedConfiguration outMergedConfiguration, + SurfaceControl outSurfaceControl, InsetsState outInsetsState, + InsetsSourceControl[] outActiveControls) { + // TODO(b/161810301): Finish the implementation. + return 0; + } + + @Override + public void updateLayout(IWindow window, WindowManager.LayoutParams inAttrs, int flags, + ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) { + // TODO(b/161810301): Finish the implementation. + } + + @Override public void prepareToReplaceWindows(android.os.IBinder appToken, boolean childrenOnly) { } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 9ad25ac8876f..f75a06d99d6c 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -116,6 +116,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { private float mLastReportedAnimatorScale; private String mPackageName; private String mRelayoutTag; + private String mUpdateViewVisibilityTag; + private String mUpdateWindowLayoutTag; private final InsetsVisibilities mDummyRequestedVisibilities = new InsetsVisibilities(); private final InsetsSourceControl[] mDummyControls = new InsetsSourceControl[0]; final boolean mSetsUnrestrictedKeepClearAreas; @@ -223,6 +225,27 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override + public int updateVisibility(IWindow client, WindowManager.LayoutParams attrs, + int viewVisibility, MergedConfiguration outMergedConfiguration, + SurfaceControl outSurfaceControl, InsetsState outInsetsState, + InsetsSourceControl[] outActiveControls) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mUpdateViewVisibilityTag); + int res = mService.updateViewVisibility(this, client, attrs, viewVisibility, + outMergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + return res; + } + + @Override + public void updateLayout(IWindow window, WindowManager.LayoutParams attrs, int flags, + ClientWindowFrames clientFrames, int requestedWidth, int requestedHeight) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mUpdateWindowLayoutTag); + mService.updateWindowLayout(this, window, attrs, flags, clientFrames, requestedWidth, + requestedHeight); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + + @Override public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) { mService.setWillReplaceWindows(appToken, childrenOnly); } @@ -689,6 +712,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { if (wpc != null) { mPackageName = wpc.mInfo.packageName; mRelayoutTag = "relayoutWindow: " + mPackageName; + mUpdateViewVisibilityTag = "updateVisibility: " + mPackageName; + mUpdateWindowLayoutTag = "updateLayout: " + mPackageName; } else { Slog.e(TAG_WM, "Unknown process pid=" + mPid); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 7165854ab68d..41215014f859 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2627,6 +2627,19 @@ public class WindowManagerService extends IWindowManager.Stub return result; } + int updateViewVisibility(Session session, IWindow client, LayoutParams attrs, + int viewVisibility, MergedConfiguration outMergedConfiguration, + SurfaceControl outSurfaceControl, InsetsState outInsetsState, + InsetsSourceControl[] outActiveControls) { + // TODO(b/161810301): Finish the implementation. + return 0; + } + + void updateWindowLayout(Session session, IWindow client, LayoutParams attrs, int flags, + ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) { + // TODO(b/161810301): Finish the implementation. + } + public boolean outOfMemoryWindow(Session session, IWindow client) { final long origId = Binder.clearCallingIdentity(); |