Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt +53 −2 Original line number Diff line number Diff line Loading @@ -15,10 +15,15 @@ */ package com.android.wm.shell.splitscreen import android.app.ActivityManager import android.hardware.display.DisplayManager import android.view.Display import android.view.Display.DEFAULT_DISPLAY import android.view.SurfaceControl import android.window.TransitionInfo import com.android.internal.protolog.ProtoLog import com.android.window.flags.Flags import com.android.wm.shell.common.split.SplitLayout import com.android.wm.shell.protolog.ShellProtoLogGroup Loading Loading @@ -94,7 +99,8 @@ class SplitMultiDisplayHelper(private val displayManager: DisplayManager) { * @return The root task info, or null if not found. */ fun getDisplayRootTaskInfo(displayId: Int): ActivityManager.RunningTaskInfo? { return displayTaskMap[displayId]?.rootTaskInfo val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY return displayTaskMap[targetDisplayId]?.rootTaskInfo } /** Loading @@ -107,7 +113,52 @@ class SplitMultiDisplayHelper(private val displayManager: DisplayManager) { displayId: Int, rootTaskInfo: ActivityManager.RunningTaskInfo? ) { val hierarchy = displayTaskMap.computeIfAbsent(displayId) { SplitTaskHierarchy() } val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY val hierarchy = displayTaskMap.computeIfAbsent(targetDisplayId) { SplitTaskHierarchy() } hierarchy.rootTaskInfo = rootTaskInfo } fun getDisplayRootTaskLeash(displayId: Int): SurfaceControl? { val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY return displayTaskMap[targetDisplayId]?.rootTaskLeash } fun setDisplayRootTaskLeash( displayId: Int, leash: SurfaceControl? ) { val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY val hierarchy = displayTaskMap.computeIfAbsent(targetDisplayId) { SplitTaskHierarchy() } hierarchy.rootTaskLeash = leash } companion object { /** * Returns the display ID associated with the first change in the given [TransitionInfo]. * It prioritize the end display ID of the change. If the end display ID is invalid, fall back * to the start display ID. If TransitionInfo has no changes, or if the first change has both * invalid end display ID and invalid start display ID, this method returns DEFAULT_DISPLAY. * * @param info the [TransitionInfo] containing transition changes * @return a valid display ID, or DEFAULT_DISPLAY as a fallback */ @JvmStatic fun getTransitionDisplayId(info: TransitionInfo): Int { if (!Flags.enableMultiDisplaySplit()) ( return DEFAULT_DISPLAY ) if (info.changes.isEmpty()) { return DEFAULT_DISPLAY } // TODO: b/393217881 - take in a specific change instead of the first change for // multi display split related tasks. val change: TransitionInfo.Change = info.changes.first() var displayId = change.endDisplayId if (displayId == Display.INVALID_DISPLAY) { displayId = change.startDisplayId } return if (displayId != Display.INVALID_DISPLAY) displayId else DEFAULT_DISPLAY } } } No newline at end of file libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +132 −55 File changed.Preview size limit exceeded, changes collapsed. Show changes libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +7 −4 Original line number Diff line number Diff line Loading @@ -80,14 +80,17 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { @StageType private final int mId; /** Callback interface for listening to changes in a split-screen stage. */ public interface StageListenerCallbacks { void onRootTaskAppeared(); /** Called when the root task on current display appears. */ void onRootTaskAppeared(ActivityManager.RunningTaskInfo taskInfo); void onStageVisibilityChanged(StageTaskListener stageTaskListener); void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present, boolean visible); void onRootTaskVanished(); /** Called when the root task on current display vanishes. */ void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo); void onNoLongerSupportMultiWindow(StageTaskListener stageTaskListener, ActivityManager.RunningTaskInfo taskInfo); Loading Loading @@ -220,7 +223,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { mRootTaskInfo.configuration, mIconProvider); mHasRootTask = true; mCallbacks.onRootTaskAppeared(); mCallbacks.onRootTaskAppeared(taskInfo); if (mVisible != mRootTaskInfo.isVisible) { mVisible = mRootTaskInfo.isVisible; mCallbacks.onStageVisibilityChanged(this); Loading Loading @@ -281,7 +284,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { mHasRootTask = false; mVisible = false; mHasChildren = false; mCallbacks.onRootTaskVanished(); mCallbacks.onRootTaskVanished(taskInfo); mRootTaskInfo = null; mRootLeash = null; mSyncQueue.runInSync(t -> { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt +3 −0 Original line number Diff line number Diff line Loading @@ -21,9 +21,11 @@ import android.hardware.display.DisplayManager import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.window.flags.Flags.enableMultiDisplaySplit import com.android.wm.shell.ShellTestCase import com.android.wm.shell.common.split.SplitLayout import com.google.common.truth.Truth.assertThat import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -52,6 +54,7 @@ class SplitMultiDisplayHelperTests : ShellTestCase() { @Before fun setUp() { assumeTrue(enableMultiDisplaySplit()) MockitoAnnotations.initMocks(this) mockDisplay1 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: mock(Display::class.java) mockDisplay2 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY + 1) ?: mock(Display::class.java) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java +1 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.app.ActivityManager; import android.os.SystemProperties; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; Loading Loading @@ -116,7 +115,7 @@ public final class StageTaskListenerTests extends ShellTestCase { @Test public void testRootTaskAppeared() { assertThat(mStageTaskListener.mRootTaskInfo.taskId).isEqualTo(mRootTask.taskId); verify(mCallbacks).onRootTaskAppeared(); verify(mCallbacks).onRootTaskAppeared(mRootTask); verify(mCallbacks, never()).onStageVisibilityChanged(mStageTaskListener); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt +53 −2 Original line number Diff line number Diff line Loading @@ -15,10 +15,15 @@ */ package com.android.wm.shell.splitscreen import android.app.ActivityManager import android.hardware.display.DisplayManager import android.view.Display import android.view.Display.DEFAULT_DISPLAY import android.view.SurfaceControl import android.window.TransitionInfo import com.android.internal.protolog.ProtoLog import com.android.window.flags.Flags import com.android.wm.shell.common.split.SplitLayout import com.android.wm.shell.protolog.ShellProtoLogGroup Loading Loading @@ -94,7 +99,8 @@ class SplitMultiDisplayHelper(private val displayManager: DisplayManager) { * @return The root task info, or null if not found. */ fun getDisplayRootTaskInfo(displayId: Int): ActivityManager.RunningTaskInfo? { return displayTaskMap[displayId]?.rootTaskInfo val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY return displayTaskMap[targetDisplayId]?.rootTaskInfo } /** Loading @@ -107,7 +113,52 @@ class SplitMultiDisplayHelper(private val displayManager: DisplayManager) { displayId: Int, rootTaskInfo: ActivityManager.RunningTaskInfo? ) { val hierarchy = displayTaskMap.computeIfAbsent(displayId) { SplitTaskHierarchy() } val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY val hierarchy = displayTaskMap.computeIfAbsent(targetDisplayId) { SplitTaskHierarchy() } hierarchy.rootTaskInfo = rootTaskInfo } fun getDisplayRootTaskLeash(displayId: Int): SurfaceControl? { val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY return displayTaskMap[targetDisplayId]?.rootTaskLeash } fun setDisplayRootTaskLeash( displayId: Int, leash: SurfaceControl? ) { val targetDisplayId = if (Flags.enableMultiDisplaySplit()) displayId else DEFAULT_DISPLAY val hierarchy = displayTaskMap.computeIfAbsent(targetDisplayId) { SplitTaskHierarchy() } hierarchy.rootTaskLeash = leash } companion object { /** * Returns the display ID associated with the first change in the given [TransitionInfo]. * It prioritize the end display ID of the change. If the end display ID is invalid, fall back * to the start display ID. If TransitionInfo has no changes, or if the first change has both * invalid end display ID and invalid start display ID, this method returns DEFAULT_DISPLAY. * * @param info the [TransitionInfo] containing transition changes * @return a valid display ID, or DEFAULT_DISPLAY as a fallback */ @JvmStatic fun getTransitionDisplayId(info: TransitionInfo): Int { if (!Flags.enableMultiDisplaySplit()) ( return DEFAULT_DISPLAY ) if (info.changes.isEmpty()) { return DEFAULT_DISPLAY } // TODO: b/393217881 - take in a specific change instead of the first change for // multi display split related tasks. val change: TransitionInfo.Change = info.changes.first() var displayId = change.endDisplayId if (displayId == Display.INVALID_DISPLAY) { displayId = change.startDisplayId } return if (displayId != Display.INVALID_DISPLAY) displayId else DEFAULT_DISPLAY } } } No newline at end of file
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +132 −55 File changed.Preview size limit exceeded, changes collapsed. Show changes
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +7 −4 Original line number Diff line number Diff line Loading @@ -80,14 +80,17 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { @StageType private final int mId; /** Callback interface for listening to changes in a split-screen stage. */ public interface StageListenerCallbacks { void onRootTaskAppeared(); /** Called when the root task on current display appears. */ void onRootTaskAppeared(ActivityManager.RunningTaskInfo taskInfo); void onStageVisibilityChanged(StageTaskListener stageTaskListener); void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present, boolean visible); void onRootTaskVanished(); /** Called when the root task on current display vanishes. */ void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo); void onNoLongerSupportMultiWindow(StageTaskListener stageTaskListener, ActivityManager.RunningTaskInfo taskInfo); Loading Loading @@ -220,7 +223,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { mRootTaskInfo.configuration, mIconProvider); mHasRootTask = true; mCallbacks.onRootTaskAppeared(); mCallbacks.onRootTaskAppeared(taskInfo); if (mVisible != mRootTaskInfo.isVisible) { mVisible = mRootTaskInfo.isVisible; mCallbacks.onStageVisibilityChanged(this); Loading Loading @@ -281,7 +284,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { mHasRootTask = false; mVisible = false; mHasChildren = false; mCallbacks.onRootTaskVanished(); mCallbacks.onRootTaskVanished(taskInfo); mRootTaskInfo = null; mRootLeash = null; mSyncQueue.runInSync(t -> { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt +3 −0 Original line number Diff line number Diff line Loading @@ -21,9 +21,11 @@ import android.hardware.display.DisplayManager import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.window.flags.Flags.enableMultiDisplaySplit import com.android.wm.shell.ShellTestCase import com.android.wm.shell.common.split.SplitLayout import com.google.common.truth.Truth.assertThat import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -52,6 +54,7 @@ class SplitMultiDisplayHelperTests : ShellTestCase() { @Before fun setUp() { assumeTrue(enableMultiDisplaySplit()) MockitoAnnotations.initMocks(this) mockDisplay1 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: mock(Display::class.java) mockDisplay2 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY + 1) ?: mock(Display::class.java) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java +1 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.app.ActivityManager; import android.os.SystemProperties; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; Loading Loading @@ -116,7 +115,7 @@ public final class StageTaskListenerTests extends ShellTestCase { @Test public void testRootTaskAppeared() { assertThat(mStageTaskListener.mRootTaskInfo.taskId).isEqualTo(mRootTask.taskId); verify(mCallbacks).onRootTaskAppeared(); verify(mCallbacks).onRootTaskAppeared(mRootTask); verify(mCallbacks, never()).onStageVisibilityChanged(mStageTaskListener); } Loading