summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java6
-rw-r--r--services/core/java/com/android/server/wm/DisplayArea.java26
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java54
7 files changed, 109 insertions, 15 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
index 34bf9e0dd98f..2e5448a9e8d5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
@@ -18,6 +18,7 @@ package com.android.wm.shell;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
+import android.annotation.SuppressLint;
import android.app.WindowConfiguration;
import android.util.SparseArray;
import android.view.SurfaceControl;
@@ -29,6 +30,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.sysui.ShellInit;
import java.io.PrintWriter;
import java.util.List;
@@ -44,9 +46,14 @@ public class RootDisplayAreaOrganizer extends DisplayAreaOrganizer {
/** Display area leashes, which is mapped by display IDs. */
private final SparseArray<SurfaceControl> mLeashes = new SparseArray<>();
- public RootDisplayAreaOrganizer(Executor executor) {
+ public RootDisplayAreaOrganizer(@NonNull Executor executor, @NonNull ShellInit shellInit) {
super(executor);
- List<DisplayAreaAppearedInfo> infos = registerOrganizer(FEATURE_ROOT);
+ shellInit.addInitCallback(this::onInit, this);
+ }
+
+ @SuppressLint("MissingPermission") // Only called by SysUI.
+ private void onInit() {
+ final List<DisplayAreaAppearedInfo> infos = registerOrganizer(FEATURE_ROOT);
for (int i = infos.size() - 1; i >= 0; --i) {
onDisplayAreaAppeared(infos.get(i).getDisplayAreaInfo(), infos.get(i).getLeash());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index 38550b405c0e..ab61a48a715c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -18,6 +18,7 @@ package com.android.wm.shell;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
+import android.annotation.SuppressLint;
import android.annotation.UiContext;
import android.app.ResourcesManager;
import android.content.Context;
@@ -38,6 +39,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.sysui.ShellInit;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -69,10 +71,17 @@ public class RootTaskDisplayAreaOrganizer extends DisplayAreaOrganizer {
private final Context mContext;
- public RootTaskDisplayAreaOrganizer(Executor executor, Context context) {
+ public RootTaskDisplayAreaOrganizer(@NonNull Executor executor, @NonNull Context context,
+ @NonNull ShellInit shellInit) {
super(executor);
mContext = context;
- List<DisplayAreaAppearedInfo> infos = registerOrganizer(FEATURE_DEFAULT_TASK_CONTAINER);
+ shellInit.addInitCallback(this::onInit, this);
+ }
+
+ @SuppressLint("MissingPermission") // Only called by SysUI.
+ private void onInit() {
+ final List<DisplayAreaAppearedInfo> infos =
+ registerOrganizer(FEATURE_DEFAULT_TASK_CONTAINER);
for (int i = infos.size() - 1; i >= 0; --i) {
onDisplayAreaAppeared(infos.get(i).getDisplayAreaInfo(), infos.get(i).getLeash());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index e6d3abcc6e1d..c51af46accdb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -110,13 +110,13 @@ import com.android.wm.shell.unfold.UnfoldAnimationController;
import com.android.wm.shell.unfold.UnfoldTransitionHandler;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
-import java.util.Optional;
-
import dagger.BindsOptionalOf;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
+import java.util.Optional;
+
/**
* Provides basic dependencies from {@link com.android.wm.shell}, these dependencies are only
* accessible from components within the WM subcomponent (can be explicitly exposed to the
@@ -658,15 +658,15 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
static RootTaskDisplayAreaOrganizer provideRootTaskDisplayAreaOrganizer(
- @ShellMainThread ShellExecutor mainExecutor, Context context) {
- return new RootTaskDisplayAreaOrganizer(mainExecutor, context);
+ @ShellMainThread ShellExecutor mainExecutor, Context context, ShellInit shellInit) {
+ return new RootTaskDisplayAreaOrganizer(mainExecutor, context, shellInit);
}
@WMSingleton
@Provides
static RootDisplayAreaOrganizer provideRootDisplayAreaOrganizer(
- @ShellMainThread ShellExecutor mainExecutor) {
- return new RootDisplayAreaOrganizer(mainExecutor);
+ @ShellMainThread ShellExecutor mainExecutor, ShellInit shellInit) {
+ return new RootDisplayAreaOrganizer(mainExecutor, shellInit);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index c74b3f30e52d..0d9a9e9f07ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -277,7 +277,7 @@ public class Transitions implements RemoteCallable<Transitions>,
@NonNull ShellExecutor animExecutor) {
this(context, shellInit, shellController, organizer, pool, displayController, mainExecutor,
mainHandler, animExecutor, null,
- new RootTaskDisplayAreaOrganizer(mainExecutor, context));
+ new RootTaskDisplayAreaOrganizer(mainExecutor, context, shellInit));
}
public Transitions(@NonNull Context context,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index d5986780d5d8..ded851c12690 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -50,6 +50,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
@@ -92,6 +93,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayController;
@@ -145,7 +147,9 @@ public class ShellTransitionTests extends ShellTestCase {
final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
mMainHandler, mAnimExecutor);
- verify(shellInit, times(1)).addInitCallback(any(), eq(t));
+ // One from Transitions, one from RootTaskDisplayAreaOrganizer
+ verify(shellInit).addInitCallback(any(), eq(t));
+ verify(shellInit).addInitCallback(any(), isA(RootTaskDisplayAreaOrganizer.class));
}
@Test
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index f81e5d453434..df26b101a657 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -44,6 +44,7 @@ import android.util.proto.ProtoOutputStream;
import android.window.DisplayAreaInfo;
import android.window.IDisplayAreaOrganizer;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
@@ -79,6 +80,12 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
private final Configuration mTmpConfiguration = new Configuration();
/**
+ * Prevent duplicate calls to onDisplayAreaAppeared, or early call of onDisplayAreaInfoChanged.
+ */
+ @VisibleForTesting
+ boolean mDisplayAreaAppearedSent;
+
+ /**
* Whether this {@link DisplayArea} should ignore fixed-orientation request. If {@code true}, it
* can never specify orientation, but shows the fixed-orientation apps below it in the
* letterbox; otherwise, it rotates based on the fixed-orientation request.
@@ -582,18 +589,31 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
sendDisplayAreaVanished(lastOrganizer);
if (!skipDisplayAreaAppeared) {
sendDisplayAreaAppeared();
+ } else if (organizer != null) {
+ // Set as sent since the DisplayAreaAppearedInfo will be sent back when registered.
+ mDisplayAreaAppearedSent = true;
}
}
+ @VisibleForTesting
void sendDisplayAreaAppeared() {
- if (mOrganizer == null) return;
+ if (mOrganizer == null || mDisplayAreaAppearedSent) return;
mOrganizerController.onDisplayAreaAppeared(mOrganizer, this);
+ mDisplayAreaAppearedSent = true;
+ }
+
+ @VisibleForTesting
+ void sendDisplayAreaInfoChanged() {
+ if (mOrganizer == null || !mDisplayAreaAppearedSent) return;
+ mOrganizerController.onDisplayAreaInfoChanged(mOrganizer, this);
}
+ @VisibleForTesting
void sendDisplayAreaVanished(IDisplayAreaOrganizer organizer) {
- if (organizer == null) return;
+ if (organizer == null || !mDisplayAreaAppearedSent) return;
migrateToNewSurfaceControl(getSyncTransaction());
mOrganizerController.onDisplayAreaVanished(organizer, this);
+ mDisplayAreaAppearedSent = false;
}
@Override
@@ -603,7 +623,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
super.onConfigurationChanged(newParentConfig);
if (mOrganizer != null && getConfiguration().diff(mTmpConfiguration) != 0) {
- mOrganizerController.onDisplayAreaInfoChanged(mOrganizer, this);
+ sendDisplayAreaInfoChanged();
}
}
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 cd0389dce416..ba31944f412a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -46,10 +46,13 @@ 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.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -583,6 +586,7 @@ public class DisplayAreaTest extends WindowTestsBase {
final IDisplayAreaOrganizer mockDisplayAreaOrganizer = mock(IDisplayAreaOrganizer.class);
doReturn(mock(IBinder.class)).when(mockDisplayAreaOrganizer).asBinder();
displayArea.mOrganizer = mockDisplayAreaOrganizer;
+ displayArea.mDisplayAreaAppearedSent = true;
spyOn(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController);
mDisplayContent.addChild(displayArea, 0);
@@ -687,6 +691,56 @@ public class DisplayAreaTest extends WindowTestsBase {
assertEquals(parent.getChildAt(0), child);
}
+ @Test
+ public void testSetOrganizer() {
+ final TaskDisplayArea displayArea = createTaskDisplayArea(
+ mDisplayContent, mWm, "NewArea", FEATURE_VENDOR_FIRST);
+
+ assertNull(displayArea.mOrganizer);
+ assertFalse(displayArea.mDisplayAreaAppearedSent);
+
+ final IDisplayAreaOrganizer organizer = mock(IDisplayAreaOrganizer.class);
+ final DisplayAreaOrganizerController controller =
+ mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController;
+ spyOn(controller);
+ doNothing().when(controller).onDisplayAreaVanished(any(), any());
+
+ displayArea.setOrganizer(organizer);
+
+ assertEquals(organizer, displayArea.mOrganizer);
+ assertTrue(displayArea.mDisplayAreaAppearedSent);
+ verify(controller).onDisplayAreaAppeared(organizer, displayArea);
+
+ // No duplicated appeared sent.
+ clearInvocations(controller);
+ displayArea.sendDisplayAreaAppeared();
+
+ verify(controller, never()).onDisplayAreaAppeared(any(), any());
+
+ // Sent info changed after appeared.
+ displayArea.sendDisplayAreaInfoChanged();
+
+ verify(controller).onDisplayAreaInfoChanged(organizer, displayArea);
+
+ // Sent info vanished after appeared.
+ displayArea.setOrganizer(null);
+
+ verify(controller).onDisplayAreaVanished(organizer, displayArea);
+ assertNull(displayArea.mOrganizer);
+ assertFalse(displayArea.mDisplayAreaAppearedSent);
+
+ // No callback until appeared sent.
+ clearInvocations(controller);
+
+ displayArea.sendDisplayAreaAppeared();
+ displayArea.sendDisplayAreaInfoChanged();
+ displayArea.sendDisplayAreaVanished(organizer);
+
+ verify(controller, never()).onDisplayAreaAppeared(any(), any());
+ verify(controller, never()).onDisplayAreaInfoChanged(any(), any());
+ verify(controller, never()).onDisplayAreaVanished(any(), any());
+ }
+
private static class TestDisplayArea<T extends WindowContainer> extends DisplayArea<T> {
private TestDisplayArea(WindowManagerService wms, Rect bounds, String name) {
super(wms, ANY, name);