diff options
4 files changed, 84 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 54ff6db99452..759b7fe054bc 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -504,6 +504,17 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { return false; } + @Override + void removeImmediately() { + setOrganizer(null); + super.removeImmediately(); + } + + @Override + DisplayArea getDisplayArea() { + return this; + } + /** * DisplayArea that contains WindowTokens, and orders them according to their type. */ @@ -584,11 +595,6 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { } } - @Override - DisplayArea getDisplayArea() { - return this; - } - /** * DisplayArea that can be dimmed. */ diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index acfe10a6a25a..2beb3780633e 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -21,6 +21,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_RUNTIME_TASK_CONTAINER import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.DisplayArea.Type.ANY; +import android.annotation.Nullable; import android.content.pm.ParceledListSlice; import android.os.Binder; import android.os.IBinder; @@ -77,6 +78,11 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl mService.enforceTaskPermission(func); } + @Nullable + IDisplayAreaOrganizer getOrganizerByFeature(int featureId) { + return mOrganizersByFeatureIds.get(featureId); + } + @Override public ParceledListSlice<DisplayAreaAppearedInfo> registerOrganizer( IDisplayAreaOrganizer organizer, int feature) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 23eab98a671a..e51d690cabed 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -213,6 +213,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManager.DisplayImePolicy; import android.view.WindowManagerPolicyConstants.PointerEventListener; +import android.window.IDisplayAreaOrganizer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; @@ -1074,6 +1075,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // Sets the display content for the children. onDisplayChanged(this); + updateDisplayAreaOrganizers(); mInputMonitor = new InputMonitor(mWmService, this); mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this); @@ -2712,6 +2714,30 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } /** + * Checks for all non-organized {@link DisplayArea}s for if there is any existing organizer for + * their features. If so, registers them with the matched organizer. + */ + @VisibleForTesting + void updateDisplayAreaOrganizers() { + if (!isTrusted()) { + // No need to update for untrusted display. + return; + } + forAllDisplayAreas(displayArea -> { + if (displayArea.isOrganized()) { + return; + } + // Check if we have a registered organizer for the DA feature. + final IDisplayAreaOrganizer organizer = + mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController + .getOrganizerByFeature(displayArea.mFeatureId); + if (organizer != null) { + displayArea.setOrganizer(organizer); + } + }); + } + + /** * Returns true if the input point is within an app window. */ boolean pointWithinAppWindow(int x, int y) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java index 89b962b96baf..d4c956db90a9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java @@ -43,11 +43,15 @@ import static com.android.server.wm.testing.Assert.assertThrows; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; import android.content.pm.ActivityInfo; import android.content.res.Configuration; @@ -57,6 +61,7 @@ import android.platform.test.annotations.Presubmit; import android.view.SurfaceControl; import android.view.View; import android.view.WindowManager; +import android.window.IDisplayAreaOrganizer; import com.google.android.collect.Lists; @@ -525,6 +530,42 @@ public class DisplayAreaTest extends WindowTestsBase { assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isEqualTo(tda); } + @Test + public void testDisplayContentUpdateDisplayAreaOrganizers_onDisplayAreaAppeared() { + final DisplayArea<WindowContainer> displayArea = new DisplayArea<>( + mWm, BELOW_TASKS, "NewArea", FEATURE_VENDOR_FIRST); + final IDisplayAreaOrganizer mockDisplayAreaOrganizer = mock(IDisplayAreaOrganizer.class); + spyOn(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController); + when(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController + .getOrganizerByFeature(FEATURE_VENDOR_FIRST)) + .thenReturn(mockDisplayAreaOrganizer); + + mDisplayContent.addChild(displayArea, 0); + mDisplayContent.updateDisplayAreaOrganizers(); + + assertEquals(mockDisplayAreaOrganizer, displayArea.mOrganizer); + verify(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController) + .onDisplayAreaAppeared( + eq(mockDisplayAreaOrganizer), + argThat(it -> it == displayArea && it.getSurfaceControl() != null)); + } + + @Test + public void testRemoveImmediately_onDisplayAreaVanished() { + final DisplayArea<WindowContainer> displayArea = new DisplayArea<>( + mWm, BELOW_TASKS, "NewArea", FEATURE_VENDOR_FIRST); + final IDisplayAreaOrganizer mockDisplayAreaOrganizer = mock(IDisplayAreaOrganizer.class); + displayArea.mOrganizer = mockDisplayAreaOrganizer; + spyOn(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController); + mDisplayContent.addChild(displayArea, 0); + + displayArea.removeImmediately(); + + assertNull(displayArea.mOrganizer); + verify(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController) + .onDisplayAreaVanished(mockDisplayAreaOrganizer, displayArea); + } + private static class TestDisplayArea<T extends WindowContainer> extends DisplayArea<T> { private TestDisplayArea(WindowManagerService wms, Rect bounds) { super(wms, ANY, "half display area"); |