Loading services/core/java/com/android/server/wm/OverlayHost.java 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.wm; import android.content.res.Configuration; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import java.util.ArrayList; /** * Utility class to assist WindowContainer in the hosting of * SurfacePackage based overlays. Manages overlays inside * one parent control, and manages the lifetime of that parent control * in order to obscure details from WindowContainer. * * Also handles multiplexing of event dispatch and tracking of overlays * to make things easier for WindowContainer. */ class OverlayHost { // Lazily initialized when required SurfaceControl mSurfaceControl; final ArrayList<SurfaceControlViewHost.SurfacePackage> mOverlays = new ArrayList<>(); final WindowManagerService mWmService; OverlayHost(WindowManagerService wms) { mWmService = wms; } void requireOverlaySurfaceControl() { if (mSurfaceControl == null) { final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(null) .setContainerLayer() .setHidden(true) .setName("Overlay Host Leash"); mSurfaceControl = b.build(); } } void setParent(SurfaceControl.Transaction t, SurfaceControl newParent) { if (mSurfaceControl == null) { return; } t.reparent(mSurfaceControl, newParent); if (newParent != null) { t.show(mSurfaceControl); } else { t.hide(mSurfaceControl); } } void setLayer(SurfaceControl.Transaction t, int layer) { if (mSurfaceControl != null) { t.setLayer(mSurfaceControl, layer); } } void addOverlay(SurfaceControlViewHost.SurfacePackage p, SurfaceControl currentParent) { requireOverlaySurfaceControl(); mOverlays.add(p); SurfaceControl.Transaction t = mWmService.mTransactionFactory.get(); t.reparent(p.getSurfaceControl(), mSurfaceControl) .show(p.getSurfaceControl()); setParent(t,currentParent); t.apply(); } boolean removeOverlay(SurfaceControlViewHost.SurfacePackage p) { final SurfaceControl.Transaction t = mWmService.mTransactionFactory.get(); for (int i = mOverlays.size() - 1; i >= 0; i--) { SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i); if (l.getSurfaceControl().isSameSurface(p.getSurfaceControl())) { mOverlays.remove(i); t.reparent(l.getSurfaceControl(), null); l.release(); } } t.apply(); return mOverlays.size() > 0; } void dispatchConfigurationChanged(Configuration c) { for (int i = mOverlays.size() - 1; i >= 0; i--) { SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i); try { l.getRemoteInterface().onConfigurationChanged(c); } catch (Exception e) { removeOverlay(l); } } } private void dispatchDetachedFromWindow() { for (int i = mOverlays.size() - 1; i >= 0; i--) { SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i); try { l.getRemoteInterface().onDispatchDetachedFromWindow(); } catch (Exception e) { // Oh well we are tearing down anyway. } l.release(); } } void release() { dispatchDetachedFromWindow(); mOverlays.clear(); final SurfaceControl.Transaction t = mWmService.mTransactionFactory.get(); t.remove(mSurfaceControl).apply(); mSurfaceControl = null; } } services/core/java/com/android/server/wm/Task.java +15 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,8 @@ import static com.android.server.wm.TaskProto.SURFACE_HEIGHT; import static com.android.server.wm.TaskProto.SURFACE_WIDTH; import static com.android.server.wm.TaskProto.TASK_FRAGMENT; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; Loading Loading @@ -609,6 +611,8 @@ class Task extends TaskFragment { */ ActivityRecord mChildPipActivity; boolean mLastSurfaceShowing = true; private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent, Intent _affinityIntent, String _affinity, String _rootAffinity, ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset, Loading Loading @@ -3308,6 +3312,17 @@ class Task extends TaskFragment { if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) { scheduleAnimation(); } // We intend to let organizer manage task visibility but it doesn't // have enough information until we finish shell transitions. // In the mean time we do an easy fix here. final boolean show = isVisible() || isAnimating(TRANSITION | PARENTS); if (mSurfaceControl != null) { if (show != mLastSurfaceShowing) { getSyncTransaction().setVisibility(mSurfaceControl, show); } } mLastSurfaceShowing = show; } @Override Loading services/core/java/com/android/server/wm/WindowContainer.java +32 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import android.view.MagnificationSpec; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceControl.Builder; import android.view.SurfaceSession; import android.view.TaskTransitionSpec; Loading Loading @@ -312,6 +313,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< private final List<WindowContainerListener> mListeners = new ArrayList<>(); private OverlayHost mOverlayHost; WindowContainer(WindowManagerService wms) { mWmService = wms; mTransitionController = mWmService.mAtmService.getTransitionController(); Loading Loading @@ -341,6 +344,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< super.onConfigurationChanged(newParentConfig); updateSurfacePositionNonOrganized(); scheduleAnimation(); if (mOverlayHost != null) { mOverlayHost.dispatchConfigurationChanged(getConfiguration()); } } void reparent(WindowContainer newParent, int position) { Loading Loading @@ -487,6 +493,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< t.reparent(sc, mSurfaceControl); } } if (mOverlayHost != null) { mOverlayHost.setParent(t, mSurfaceControl); } scheduleAnimation(); } Loading Loading @@ -632,6 +643,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< mLastSurfacePosition.set(0, 0); scheduleAnimation(); } if (mOverlayHost != null) { mOverlayHost.release(); mOverlayHost = null; } // This must happen after updating the surface so that sync transactions can be handled // properly. Loading Loading @@ -2308,6 +2323,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< wc.assignLayer(t, layer++); } } if (mOverlayHost != null) { mOverlayHost.setLayer(t, layer++); } } void assignChildLayers() { Loading Loading @@ -3570,4 +3588,18 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type, @Nullable AnimationAdapter snapshotAnim); } void addOverlay(SurfaceControlViewHost.SurfacePackage overlay) { if (mOverlayHost == null) { mOverlayHost = new OverlayHost(mWmService); } mOverlayHost.addOverlay(overlay, mSurfaceControl); } void removeOverlay(SurfaceControlViewHost.SurfacePackage overlay) { if (mOverlayHost != null && !mOverlayHost.removeOverlay(overlay)) { mOverlayHost.release(); mOverlayHost = null; } } } services/core/java/com/android/server/wm/WindowManagerInternal.java +13 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.view.IWindow; import android.view.InputChannel; import android.view.MagnificationSpec; import android.view.RemoteAnimationTarget; import android.view.SurfaceControlViewHost; import android.view.WindowInfo; import android.view.WindowManager.DisplayImePolicy; Loading Loading @@ -767,4 +768,16 @@ public abstract class WindowManagerInternal { * {@code false} otherwise. */ public abstract boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken); /** * Internal methods for other parts of SystemServer to manage * SurfacePackage based overlays on tasks. * * Callers prepare a view hierarchy with SurfaceControlViewHost * and send the package to WM here. The remote view hierarchy will receive * configuration change, lifecycle events, etc, forwarded over the * ISurfaceControlViewHost interface inside the SurfacePackage. */ public abstract void addTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay); public abstract void removeTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay); } services/core/java/com/android/server/wm/WindowManagerService.java +23 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ import android.view.RemoteAnimationAdapter; import android.view.ScrollCaptureResponse; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceSession; import android.view.TaskTransitionSpec; import android.view.View; Loading Loading @@ -7910,6 +7911,28 @@ public class WindowManagerService extends IWindowManager.Stub public boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) { return WindowManagerService.this.shouldRestoreImeVisibility(imeTargetWindowToken); } @Override public void addTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay) { synchronized (mGlobalLock) { final Task task = mRoot.getRootTask(taskId); if (task == null) { throw new IllegalArgumentException("no task with taskId" + taskId); } task.addOverlay(overlay); } } @Override public void removeTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay) { synchronized (mGlobalLock) { final Task task = mRoot.getRootTask(taskId); if (task == null) { throw new IllegalArgumentException("no task with taskId" + taskId); } task.removeOverlay(overlay); } } } void registerAppFreezeListener(AppFreezeListener listener) { Loading Loading
services/core/java/com/android/server/wm/OverlayHost.java 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.wm; import android.content.res.Configuration; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import java.util.ArrayList; /** * Utility class to assist WindowContainer in the hosting of * SurfacePackage based overlays. Manages overlays inside * one parent control, and manages the lifetime of that parent control * in order to obscure details from WindowContainer. * * Also handles multiplexing of event dispatch and tracking of overlays * to make things easier for WindowContainer. */ class OverlayHost { // Lazily initialized when required SurfaceControl mSurfaceControl; final ArrayList<SurfaceControlViewHost.SurfacePackage> mOverlays = new ArrayList<>(); final WindowManagerService mWmService; OverlayHost(WindowManagerService wms) { mWmService = wms; } void requireOverlaySurfaceControl() { if (mSurfaceControl == null) { final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(null) .setContainerLayer() .setHidden(true) .setName("Overlay Host Leash"); mSurfaceControl = b.build(); } } void setParent(SurfaceControl.Transaction t, SurfaceControl newParent) { if (mSurfaceControl == null) { return; } t.reparent(mSurfaceControl, newParent); if (newParent != null) { t.show(mSurfaceControl); } else { t.hide(mSurfaceControl); } } void setLayer(SurfaceControl.Transaction t, int layer) { if (mSurfaceControl != null) { t.setLayer(mSurfaceControl, layer); } } void addOverlay(SurfaceControlViewHost.SurfacePackage p, SurfaceControl currentParent) { requireOverlaySurfaceControl(); mOverlays.add(p); SurfaceControl.Transaction t = mWmService.mTransactionFactory.get(); t.reparent(p.getSurfaceControl(), mSurfaceControl) .show(p.getSurfaceControl()); setParent(t,currentParent); t.apply(); } boolean removeOverlay(SurfaceControlViewHost.SurfacePackage p) { final SurfaceControl.Transaction t = mWmService.mTransactionFactory.get(); for (int i = mOverlays.size() - 1; i >= 0; i--) { SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i); if (l.getSurfaceControl().isSameSurface(p.getSurfaceControl())) { mOverlays.remove(i); t.reparent(l.getSurfaceControl(), null); l.release(); } } t.apply(); return mOverlays.size() > 0; } void dispatchConfigurationChanged(Configuration c) { for (int i = mOverlays.size() - 1; i >= 0; i--) { SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i); try { l.getRemoteInterface().onConfigurationChanged(c); } catch (Exception e) { removeOverlay(l); } } } private void dispatchDetachedFromWindow() { for (int i = mOverlays.size() - 1; i >= 0; i--) { SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i); try { l.getRemoteInterface().onDispatchDetachedFromWindow(); } catch (Exception e) { // Oh well we are tearing down anyway. } l.release(); } } void release() { dispatchDetachedFromWindow(); mOverlays.clear(); final SurfaceControl.Transaction t = mWmService.mTransactionFactory.get(); t.remove(mSurfaceControl).apply(); mSurfaceControl = null; } }
services/core/java/com/android/server/wm/Task.java +15 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,8 @@ import static com.android.server.wm.TaskProto.SURFACE_HEIGHT; import static com.android.server.wm.TaskProto.SURFACE_WIDTH; import static com.android.server.wm.TaskProto.TASK_FRAGMENT; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; Loading Loading @@ -609,6 +611,8 @@ class Task extends TaskFragment { */ ActivityRecord mChildPipActivity; boolean mLastSurfaceShowing = true; private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent, Intent _affinityIntent, String _affinity, String _rootAffinity, ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset, Loading Loading @@ -3308,6 +3312,17 @@ class Task extends TaskFragment { if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) { scheduleAnimation(); } // We intend to let organizer manage task visibility but it doesn't // have enough information until we finish shell transitions. // In the mean time we do an easy fix here. final boolean show = isVisible() || isAnimating(TRANSITION | PARENTS); if (mSurfaceControl != null) { if (show != mLastSurfaceShowing) { getSyncTransaction().setVisibility(mSurfaceControl, show); } } mLastSurfaceShowing = show; } @Override Loading
services/core/java/com/android/server/wm/WindowContainer.java +32 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import android.view.MagnificationSpec; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceControl.Builder; import android.view.SurfaceSession; import android.view.TaskTransitionSpec; Loading Loading @@ -312,6 +313,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< private final List<WindowContainerListener> mListeners = new ArrayList<>(); private OverlayHost mOverlayHost; WindowContainer(WindowManagerService wms) { mWmService = wms; mTransitionController = mWmService.mAtmService.getTransitionController(); Loading Loading @@ -341,6 +344,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< super.onConfigurationChanged(newParentConfig); updateSurfacePositionNonOrganized(); scheduleAnimation(); if (mOverlayHost != null) { mOverlayHost.dispatchConfigurationChanged(getConfiguration()); } } void reparent(WindowContainer newParent, int position) { Loading Loading @@ -487,6 +493,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< t.reparent(sc, mSurfaceControl); } } if (mOverlayHost != null) { mOverlayHost.setParent(t, mSurfaceControl); } scheduleAnimation(); } Loading Loading @@ -632,6 +643,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< mLastSurfacePosition.set(0, 0); scheduleAnimation(); } if (mOverlayHost != null) { mOverlayHost.release(); mOverlayHost = null; } // This must happen after updating the surface so that sync transactions can be handled // properly. Loading Loading @@ -2308,6 +2323,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< wc.assignLayer(t, layer++); } } if (mOverlayHost != null) { mOverlayHost.setLayer(t, layer++); } } void assignChildLayers() { Loading Loading @@ -3570,4 +3588,18 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type, @Nullable AnimationAdapter snapshotAnim); } void addOverlay(SurfaceControlViewHost.SurfacePackage overlay) { if (mOverlayHost == null) { mOverlayHost = new OverlayHost(mWmService); } mOverlayHost.addOverlay(overlay, mSurfaceControl); } void removeOverlay(SurfaceControlViewHost.SurfacePackage overlay) { if (mOverlayHost != null && !mOverlayHost.removeOverlay(overlay)) { mOverlayHost.release(); mOverlayHost = null; } } }
services/core/java/com/android/server/wm/WindowManagerInternal.java +13 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.view.IWindow; import android.view.InputChannel; import android.view.MagnificationSpec; import android.view.RemoteAnimationTarget; import android.view.SurfaceControlViewHost; import android.view.WindowInfo; import android.view.WindowManager.DisplayImePolicy; Loading Loading @@ -767,4 +768,16 @@ public abstract class WindowManagerInternal { * {@code false} otherwise. */ public abstract boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken); /** * Internal methods for other parts of SystemServer to manage * SurfacePackage based overlays on tasks. * * Callers prepare a view hierarchy with SurfaceControlViewHost * and send the package to WM here. The remote view hierarchy will receive * configuration change, lifecycle events, etc, forwarded over the * ISurfaceControlViewHost interface inside the SurfacePackage. */ public abstract void addTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay); public abstract void removeTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay); }
services/core/java/com/android/server/wm/WindowManagerService.java +23 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ import android.view.RemoteAnimationAdapter; import android.view.ScrollCaptureResponse; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceSession; import android.view.TaskTransitionSpec; import android.view.View; Loading Loading @@ -7910,6 +7911,28 @@ public class WindowManagerService extends IWindowManager.Stub public boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) { return WindowManagerService.this.shouldRestoreImeVisibility(imeTargetWindowToken); } @Override public void addTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay) { synchronized (mGlobalLock) { final Task task = mRoot.getRootTask(taskId); if (task == null) { throw new IllegalArgumentException("no task with taskId" + taskId); } task.addOverlay(overlay); } } @Override public void removeTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay) { synchronized (mGlobalLock) { final Task task = mRoot.getRootTask(taskId); if (task == null) { throw new IllegalArgumentException("no task with taskId" + taskId); } task.removeOverlay(overlay); } } } void registerAppFreezeListener(AppFreezeListener listener) { Loading