Loading core/java/android/view/WindowlessWindowLayout.java +32 −3 Original line number Diff line number Diff line Loading @@ -16,13 +16,19 @@ package android.view; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import android.app.WindowConfiguration.WindowingMode; import android.graphics.Rect; import android.view.WindowInsets.Type.InsetsType; import android.window.ClientWindowFrames; // TODO(b/262891212) use the real WindowLayout and remove WindowlessWindowLayout /** * Computes window frames for the windowless window. * * @hide */ public class WindowlessWindowLayout extends WindowLayout { Loading @@ -32,9 +38,32 @@ public class WindowlessWindowLayout extends WindowLayout { Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode, int requestedWidth, int requestedHeight, @InsetsType int requestedVisibleTypes, float compatScale, ClientWindowFrames frames) { if (frames.attachedFrame == null) { frames.frame.set(0, 0, attrs.width, attrs.height); frames.displayFrame.set(frames.frame); frames.parentFrame.set(frames.frame); frames.displayFrame.set(frames.frame); return; } final int height = calculateLength(attrs.height, requestedHeight, frames.attachedFrame.height()); final int width = calculateLength(attrs.width, requestedWidth, frames.attachedFrame.width()); Gravity.apply(attrs.gravity, width, height, frames.attachedFrame, (int) (attrs.x + attrs.horizontalMargin), (int) (attrs.y + attrs.verticalMargin), frames.frame); frames.displayFrame.set(frames.frame); frames.parentFrame.set(frames.attachedFrame); } private static int calculateLength(int attrLength, int requestedLength, int parentLength) { if (attrLength == MATCH_PARENT) { return parentLength; } if (attrLength == WRAP_CONTENT) { return requestedLength; } return attrLength; } } core/java/android/view/WindowlessWindowManager.java +69 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.view; import android.annotation.Nullable; import android.app.WindowConfiguration; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; Loading Loading @@ -53,13 +54,21 @@ public class WindowlessWindowManager implements IWindowSession { IBinder mInputChannelToken; Region mInputRegion; IWindow mClient; State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IBinder inputChannelToken, IWindow client) { SurfaceControl mLeash; Rect mFrame; Rect mAttachedFrame; State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IBinder inputChannelToken, IWindow client, SurfaceControl leash, Rect frame, Rect attachedFrame) { mSurfaceControl = sc; mParams.copyFrom(p); mDisplayId = displayId; mInputChannelToken = inputChannelToken; mClient = client; mLeash = leash; mFrame = frame; mAttachedFrame = attachedFrame; } }; Loading @@ -85,6 +94,7 @@ public class WindowlessWindowManager implements IWindowSession { private InsetsState mInsetsState; private final ClientWindowFrames mTmpFrames = new ClientWindowFrames(); private final MergedConfiguration mTmpConfig = new MergedConfiguration(); private final WindowlessWindowLayout mLayout = new WindowlessWindowLayout(); public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface, IBinder hostInputToken) { Loading Loading @@ -137,8 +147,15 @@ public class WindowlessWindowManager implements IWindowSession { } } protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { b.setParent(mRootSurface); protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { // If this is the first window, the state map is empty and the parent surface is the // root. Otherwise, the parent surface is in the state map. synchronized (this) { if (mStateForWindow.isEmpty()) { return mRootSurface; } return mStateForWindow.get(attrs.token).mLeash; } } /** Loading @@ -150,13 +167,20 @@ public class WindowlessWindowManager implements IWindowSession { InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame, float[] outSizeCompatScale) { final SurfaceControl.Builder b = new SurfaceControl.Builder(mSurfaceSession) final SurfaceControl leash = new SurfaceControl.Builder(mSurfaceSession) .setName(attrs.getTitle().toString() + "Leash") .setCallsite("WindowlessWindowManager.addToDisplay") .setParent(getParentSurface(window, attrs)) .build(); final SurfaceControl sc = new SurfaceControl.Builder(mSurfaceSession) .setFormat(attrs.format) .setBLASTLayer() .setName(attrs.getTitle().toString()) .setCallsite("WindowlessWindowManager.addToDisplay"); attachToParentSurface(window, b); final SurfaceControl sc = b.build(); .setCallsite("WindowlessWindowManager.addToDisplay") .setHidden(false) .setParent(leash) .build(); if (((attrs.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0)) { Loading @@ -178,11 +202,22 @@ public class WindowlessWindowManager implements IWindowSession { } final State state = new State(sc, attrs, displayId, outInputChannel != null ? outInputChannel.getToken() : null, window); outInputChannel != null ? outInputChannel.getToken() : null, window, leash, /* frame= */ new Rect(), /* attachedFrame= */ null); Rect parentFrame = null; synchronized (this) { State parentState = mStateForWindow.get(attrs.token); if (parentState != null) { parentFrame = parentState.mFrame; } mStateForWindow.put(window.asBinder(), state); } state.mAttachedFrame = parentFrame; if (parentFrame == null) { outAttachedFrame.set(0, 0, -1, -1); } else { outAttachedFrame.set(parentFrame); } outSizeCompatScale[0] = 1f; final int res = WindowManagerGlobal.ADD_OKAY | WindowManagerGlobal.ADD_FLAG_APP_VISIBLE | Loading Loading @@ -227,6 +262,7 @@ public class WindowlessWindowManager implements IWindowSession { "Invalid window token (never added or removed already)"); } removeSurface(state.mSurfaceControl); removeSurface(state.mLeash); } /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */ Loading Loading @@ -301,6 +337,7 @@ public class WindowlessWindowManager implements IWindowSession { "Invalid window token (never added or removed already)"); } SurfaceControl sc = state.mSurfaceControl; SurfaceControl leash = state.mLeash; SurfaceControl.Transaction t = new SurfaceControl.Transaction(); int attrChanges = 0; Loading @@ -309,21 +346,37 @@ public class WindowlessWindowManager implements IWindowSession { } WindowManager.LayoutParams attrs = state.mParams; ClientWindowFrames frames = new ClientWindowFrames(); frames.attachedFrame = state.mAttachedFrame; mLayout.computeFrames(attrs, null, null, null, WindowConfiguration.WINDOWING_MODE_UNDEFINED, requestedWidth, requestedHeight, 0, 0, frames); state.mFrame.set(frames.frame); if (outFrames != null) { outFrames.frame.set(frames.frame); outFrames.parentFrame.set(frames.parentFrame); outFrames.displayFrame.set(frames.displayFrame); } t.setPosition(leash, frames.frame.left, frames.frame.top); t.setWindowCrop(leash, frames.frame.width(), frames.frame.height()); if (viewFlags == View.VISIBLE) { t.setOpaque(sc, isOpaque(attrs)).show(sc).apply(); // TODO(b/262892794) ViewRootImpl modifies the app's rendering SurfaceControl // opaqueness. We shouldn't need to modify opaqueness for this SurfaceControl here or // in the real WindowManager. t.setOpaque(sc, isOpaque(attrs)).show(leash).apply(); if (outSurfaceControl != null) { outSurfaceControl.copyFrom(sc, "WindowlessWindowManager.relayout"); } } else { t.hide(sc).apply(); t.hide(leash).apply(); if (outSurfaceControl != null) { outSurfaceControl.release(); } } if (outFrames != null) { outFrames.frame.set(0, 0, attrs.width, attrs.height); outFrames.displayFrame.set(outFrames.frame); } if (outMergedConfiguration != null) { outMergedConfiguration.setConfiguration(mConfiguration, mConfiguration); Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +4 −2 Original line number Diff line number Diff line Loading @@ -306,7 +306,9 @@ public class SystemWindows { } } protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { @Override protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { SurfaceControl leash = new SurfaceControl.Builder(new SurfaceSession()) .setContainerLayer() .setName("SystemWindowLeash") Loading @@ -316,7 +318,7 @@ public class SystemWindows { synchronized (this) { mLeashForWindow.put(window.asBinder(), leash); } b.setParent(leash); return leash; } @Override Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ public class SplitDecorManager extends WindowlessWindowManager { } @Override protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { // Can't set position for the ViewRootImpl SC directly. Create a leash to manipulate later. final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession()) .setContainerLayer() Loading @@ -101,7 +101,7 @@ public class SplitDecorManager extends WindowlessWindowManager { .setParent(mHostLeash) .setCallsite("SplitDecorManager#attachToParentSurface"); mIconLeash = builder.build(); b.setParent(mIconLeash); return mIconLeash; } /** Inflates split decor surface on the root surface. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { } @Override protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { // Can't set position for the ViewRootImpl SC directly. Create a leash to manipulate later. final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession()) .setContainerLayer() Loading @@ -103,7 +103,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { mParentContainerCallbacks.attachToParentSurface(builder); mLeash = builder.build(); mParentContainerCallbacks.onLeashReady(mLeash); b.setParent(mLeash); return mLeash; } /** Inflates {@link DividerView} on to the root surface. */ Loading Loading
core/java/android/view/WindowlessWindowLayout.java +32 −3 Original line number Diff line number Diff line Loading @@ -16,13 +16,19 @@ package android.view; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import android.app.WindowConfiguration.WindowingMode; import android.graphics.Rect; import android.view.WindowInsets.Type.InsetsType; import android.window.ClientWindowFrames; // TODO(b/262891212) use the real WindowLayout and remove WindowlessWindowLayout /** * Computes window frames for the windowless window. * * @hide */ public class WindowlessWindowLayout extends WindowLayout { Loading @@ -32,9 +38,32 @@ public class WindowlessWindowLayout extends WindowLayout { Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode, int requestedWidth, int requestedHeight, @InsetsType int requestedVisibleTypes, float compatScale, ClientWindowFrames frames) { if (frames.attachedFrame == null) { frames.frame.set(0, 0, attrs.width, attrs.height); frames.displayFrame.set(frames.frame); frames.parentFrame.set(frames.frame); frames.displayFrame.set(frames.frame); return; } final int height = calculateLength(attrs.height, requestedHeight, frames.attachedFrame.height()); final int width = calculateLength(attrs.width, requestedWidth, frames.attachedFrame.width()); Gravity.apply(attrs.gravity, width, height, frames.attachedFrame, (int) (attrs.x + attrs.horizontalMargin), (int) (attrs.y + attrs.verticalMargin), frames.frame); frames.displayFrame.set(frames.frame); frames.parentFrame.set(frames.attachedFrame); } private static int calculateLength(int attrLength, int requestedLength, int parentLength) { if (attrLength == MATCH_PARENT) { return parentLength; } if (attrLength == WRAP_CONTENT) { return requestedLength; } return attrLength; } }
core/java/android/view/WindowlessWindowManager.java +69 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.view; import android.annotation.Nullable; import android.app.WindowConfiguration; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; Loading Loading @@ -53,13 +54,21 @@ public class WindowlessWindowManager implements IWindowSession { IBinder mInputChannelToken; Region mInputRegion; IWindow mClient; State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IBinder inputChannelToken, IWindow client) { SurfaceControl mLeash; Rect mFrame; Rect mAttachedFrame; State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IBinder inputChannelToken, IWindow client, SurfaceControl leash, Rect frame, Rect attachedFrame) { mSurfaceControl = sc; mParams.copyFrom(p); mDisplayId = displayId; mInputChannelToken = inputChannelToken; mClient = client; mLeash = leash; mFrame = frame; mAttachedFrame = attachedFrame; } }; Loading @@ -85,6 +94,7 @@ public class WindowlessWindowManager implements IWindowSession { private InsetsState mInsetsState; private final ClientWindowFrames mTmpFrames = new ClientWindowFrames(); private final MergedConfiguration mTmpConfig = new MergedConfiguration(); private final WindowlessWindowLayout mLayout = new WindowlessWindowLayout(); public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface, IBinder hostInputToken) { Loading Loading @@ -137,8 +147,15 @@ public class WindowlessWindowManager implements IWindowSession { } } protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { b.setParent(mRootSurface); protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { // If this is the first window, the state map is empty and the parent surface is the // root. Otherwise, the parent surface is in the state map. synchronized (this) { if (mStateForWindow.isEmpty()) { return mRootSurface; } return mStateForWindow.get(attrs.token).mLeash; } } /** Loading @@ -150,13 +167,20 @@ public class WindowlessWindowManager implements IWindowSession { InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame, float[] outSizeCompatScale) { final SurfaceControl.Builder b = new SurfaceControl.Builder(mSurfaceSession) final SurfaceControl leash = new SurfaceControl.Builder(mSurfaceSession) .setName(attrs.getTitle().toString() + "Leash") .setCallsite("WindowlessWindowManager.addToDisplay") .setParent(getParentSurface(window, attrs)) .build(); final SurfaceControl sc = new SurfaceControl.Builder(mSurfaceSession) .setFormat(attrs.format) .setBLASTLayer() .setName(attrs.getTitle().toString()) .setCallsite("WindowlessWindowManager.addToDisplay"); attachToParentSurface(window, b); final SurfaceControl sc = b.build(); .setCallsite("WindowlessWindowManager.addToDisplay") .setHidden(false) .setParent(leash) .build(); if (((attrs.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0)) { Loading @@ -178,11 +202,22 @@ public class WindowlessWindowManager implements IWindowSession { } final State state = new State(sc, attrs, displayId, outInputChannel != null ? outInputChannel.getToken() : null, window); outInputChannel != null ? outInputChannel.getToken() : null, window, leash, /* frame= */ new Rect(), /* attachedFrame= */ null); Rect parentFrame = null; synchronized (this) { State parentState = mStateForWindow.get(attrs.token); if (parentState != null) { parentFrame = parentState.mFrame; } mStateForWindow.put(window.asBinder(), state); } state.mAttachedFrame = parentFrame; if (parentFrame == null) { outAttachedFrame.set(0, 0, -1, -1); } else { outAttachedFrame.set(parentFrame); } outSizeCompatScale[0] = 1f; final int res = WindowManagerGlobal.ADD_OKAY | WindowManagerGlobal.ADD_FLAG_APP_VISIBLE | Loading Loading @@ -227,6 +262,7 @@ public class WindowlessWindowManager implements IWindowSession { "Invalid window token (never added or removed already)"); } removeSurface(state.mSurfaceControl); removeSurface(state.mLeash); } /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */ Loading Loading @@ -301,6 +337,7 @@ public class WindowlessWindowManager implements IWindowSession { "Invalid window token (never added or removed already)"); } SurfaceControl sc = state.mSurfaceControl; SurfaceControl leash = state.mLeash; SurfaceControl.Transaction t = new SurfaceControl.Transaction(); int attrChanges = 0; Loading @@ -309,21 +346,37 @@ public class WindowlessWindowManager implements IWindowSession { } WindowManager.LayoutParams attrs = state.mParams; ClientWindowFrames frames = new ClientWindowFrames(); frames.attachedFrame = state.mAttachedFrame; mLayout.computeFrames(attrs, null, null, null, WindowConfiguration.WINDOWING_MODE_UNDEFINED, requestedWidth, requestedHeight, 0, 0, frames); state.mFrame.set(frames.frame); if (outFrames != null) { outFrames.frame.set(frames.frame); outFrames.parentFrame.set(frames.parentFrame); outFrames.displayFrame.set(frames.displayFrame); } t.setPosition(leash, frames.frame.left, frames.frame.top); t.setWindowCrop(leash, frames.frame.width(), frames.frame.height()); if (viewFlags == View.VISIBLE) { t.setOpaque(sc, isOpaque(attrs)).show(sc).apply(); // TODO(b/262892794) ViewRootImpl modifies the app's rendering SurfaceControl // opaqueness. We shouldn't need to modify opaqueness for this SurfaceControl here or // in the real WindowManager. t.setOpaque(sc, isOpaque(attrs)).show(leash).apply(); if (outSurfaceControl != null) { outSurfaceControl.copyFrom(sc, "WindowlessWindowManager.relayout"); } } else { t.hide(sc).apply(); t.hide(leash).apply(); if (outSurfaceControl != null) { outSurfaceControl.release(); } } if (outFrames != null) { outFrames.frame.set(0, 0, attrs.width, attrs.height); outFrames.displayFrame.set(outFrames.frame); } if (outMergedConfiguration != null) { outMergedConfiguration.setConfiguration(mConfiguration, mConfiguration); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +4 −2 Original line number Diff line number Diff line Loading @@ -306,7 +306,9 @@ public class SystemWindows { } } protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { @Override protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { SurfaceControl leash = new SurfaceControl.Builder(new SurfaceSession()) .setContainerLayer() .setName("SystemWindowLeash") Loading @@ -316,7 +318,7 @@ public class SystemWindows { synchronized (this) { mLeashForWindow.put(window.asBinder(), leash); } b.setParent(leash); return leash; } @Override Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ public class SplitDecorManager extends WindowlessWindowManager { } @Override protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { // Can't set position for the ViewRootImpl SC directly. Create a leash to manipulate later. final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession()) .setContainerLayer() Loading @@ -101,7 +101,7 @@ public class SplitDecorManager extends WindowlessWindowManager { .setParent(mHostLeash) .setCallsite("SplitDecorManager#attachToParentSurface"); mIconLeash = builder.build(); b.setParent(mIconLeash); return mIconLeash; } /** Inflates split decor surface on the root surface. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { } @Override protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) { protected SurfaceControl getParentSurface(IWindow window, WindowManager.LayoutParams attrs) { // Can't set position for the ViewRootImpl SC directly. Create a leash to manipulate later. final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession()) .setContainerLayer() Loading @@ -103,7 +103,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { mParentContainerCallbacks.attachToParentSurface(builder); mLeash = builder.build(); mParentContainerCallbacks.onLeashReady(mLeash); b.setParent(mLeash); return mLeash; } /** Inflates {@link DividerView} on to the root surface. */ Loading