Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +35 −0 Original line number Diff line number Diff line Loading @@ -46,7 +46,9 @@ import com.android.wm.shell.shared.desktopmode.DesktopState; import com.android.wm.shell.sysui.ShellInit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /** Loading Loading @@ -114,6 +116,30 @@ public class DisplayController { return mDisplayManager.getDisplay(displayId); } /** * Gets the uniqueId associated with the provided displayId, if it is associated with one. */ @Nullable public String getDisplayUniqueId(int displayId) { final DisplayRecord r = mDisplays.get(displayId); return r != null ? r.mUniqueId : null; } /** * Gets a map of all displays by uniqueId from DisplayManager. */ @Nullable public Map<String, Integer> getAllDisplaysByUniqueId() { HashMap<String, Integer> map = new HashMap<>(); for (int i = 0; i < mDisplays.size(); i++) { final String uniqueId = mDisplays.valueAt(i).mUniqueId; if (uniqueId != null) { map.put(uniqueId, mDisplays.keyAt(i)); } } return map; } /** * Returns true if the display with the given displayId is part of the topology. */ Loading Loading @@ -218,6 +244,10 @@ public class DisplayController { final DisplayRecord record = new DisplayRecord(displayId, hasStatusAndNavBars); DisplayLayout displayLayout = record.createLayout(context, display); record.setDisplayLayout(context, displayLayout); final String uniqueId = display.getUniqueId(); if (uniqueId != null) { record.setUniqueId(uniqueId); } mDisplays.put(displayId, record); for (int i = 0; i < mDisplayChangedListeners.size(); ++i) { mDisplayChangedListeners.get(i).onDisplayAdded(displayId); Loading Loading @@ -383,6 +413,7 @@ public class DisplayController { private class DisplayRecord { private final int mDisplayId; private String mUniqueId; private Context mContext; private DisplayLayout mDisplayLayout; private InsetsState mInsetsState = new InsetsState(); Loading Loading @@ -428,6 +459,10 @@ public class DisplayController { mDisplayLayout.setInsets(mContext.getResources(), mInsetsState); } private void setUniqueId(String uniqueId) { mUniqueId = uniqueId; } private void setInsets(InsetsState state) { mInsetsState = state; mDisplayLayout.setInsets(mContext.getResources(), state); Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +3 −2 Original line number Diff line number Diff line Loading @@ -1781,9 +1781,10 @@ public abstract class WMShellModule { DesktopPersistentRepository desktopPersistentRepository, @ShellMainThread CoroutineScope mainScope, DesktopConfig desktopConfig, DesktopState desktopState) { DesktopState desktopState, DisplayController displayController) { return new DesktopRepositoryInitializerImpl(context, desktopPersistentRepository, mainScope, desktopConfig, desktopState); mainScope, desktopConfig, desktopState, displayController); } @WMSingleton Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +24 −7 Original line number Diff line number Diff line Loading @@ -620,7 +620,11 @@ class DesktopTasksController( if (deskId == null) { logW("Failed to add desk in displayId=%d for userId=%d", displayId, userId) } else { repository.addDesk(displayId = displayId, deskId = deskId) repository.addDesk( displayId = displayId, deskId = deskId, uniqueDisplayId = displayController.getDisplayUniqueId(displayId), ) onResult(deskId) if (activateDesk) { activateDesk(deskId = deskId, userId = userId, enterReason = enterReason) Loading @@ -638,7 +642,11 @@ class DesktopTasksController( logW("Failed to add desk in displayId=%d for userId=%d", displayId, userId) return null } repository.addDesk(displayId = displayId, deskId = deskId) repository.addDesk( displayId = displayId, deskId = deskId, uniqueDisplayId = displayController.getDisplayUniqueId(displayId), ) return deskId } Loading Loading @@ -748,7 +756,7 @@ class DesktopTasksController( destinationDisplayId: Int, ): RunOnTransitStart { logD( "onDisplayDisconnect: disconnectedDisplayId=$disconnectedDisplayId, " + "addOnDisplayDisconnectChanges: disconnectedDisplayId=$disconnectedDisplayId, " + "destinationDisplayId=$destinationDisplayId" ) val runOnTransitStartList = mutableListOf<RunOnTransitStart>() Loading @@ -762,7 +770,7 @@ class DesktopTasksController( val destDisplayLayout = displayController.getDisplayLayout(destinationDisplayId) if (destDisplayLayout == null) { logE( "onDisplayDisconnect: no display layout found for " + "addOnDisplayDisconnectChanges: no display layout found for " + "destinationDisplayId=$destinationDisplayId" ) } Loading Loading @@ -817,7 +825,11 @@ class DesktopTasksController( val deskTasks = desktopRepository.getActiveTaskIdsInDesk(deskId) // Remove desk if it's empty. if (deskTasks.isEmpty()) { logD("onDisplayDisconnect: removing empty desk=%d of user=%d", deskId, userId) logD( "handleExtendedModeDisconnect: removing empty desk=%d of user=%d", deskId, userId, ) desksOrganizer.removeDesk(wct, deskId, userId) runOnTransitStartList.add { transition -> desksTransitionObserver.addPendingTransition( Loading @@ -835,7 +847,8 @@ class DesktopTasksController( } } else { logD( "onDisplayDisconnect: reparenting desk=%d to display=%d for user=%d", "handleExtendedModeDisconnect: " + "reparenting desk=%d to display=%d for user=%d", deskId, destinationDisplayId, userId, Loading @@ -856,6 +869,8 @@ class DesktopTasksController( userId = userId, deskId = deskId, displayId = destinationDisplayId, uniqueDisplayId = displayController.getDisplayUniqueId(destinationDisplayId), ) ) } Loading Loading @@ -1279,6 +1294,7 @@ class DesktopTasksController( .apply { launchWindowingMode = WINDOWING_MODE_FREEFORM launchBounds = getInitialBounds(displayLayout, task, deskId) launchDisplayId = targetDisplayId } .toBundle(), ) Loading Loading @@ -2911,7 +2927,8 @@ class DesktopTasksController( wct.reorder(runningTaskInfo.token, /* onTop= */ true) } else if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // Task is not running, start it wct.startTask(taskId, createActivityOptionsForStartTask().toBundle()) val startDesk = repository.getDefaultDeskId(displayId) ?: INVALID_DESK_ID wct.startTask(taskId, createActivityOptionsForStartTask(startDesk).toBundle()) } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/data/Desk.kt +2 −2 Original line number Diff line number Diff line Loading @@ -51,10 +51,10 @@ data class Desk( var topTransparentFullscreenTaskData: TopTransparentFullscreenTaskData? = null, var leftTiledTaskId: Int? = null, var rightTiledTaskId: Int? = null, // The display's unique id that will remain the same across reboots. var uniqueDisplayId: String? = null, ) { // TODO: b/417907552 - Add these variables to persistent repository. // The display's unique id that will remain the same across reboots. var uniqueDisplayId: String? = null // Bounds of tasks in this desk mapped to their respective task ids. Used for reconnect. var boundsByTaskId: MutableMap<Int, Rect> = mutableMapOf() Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/data/DesktopRepository.kt +20 −13 Original line number Diff line number Diff line Loading @@ -254,10 +254,10 @@ class DesktopRepository( } /** Adds the given desk under the given display. */ fun addDesk(displayId: Int, deskId: Int) { fun addDesk(displayId: Int, deskId: Int, uniqueDisplayId: String? = null) { logD("addDesk for displayId=%d and deskId=%d", displayId, deskId) val couldCreateDesk = canCreateDesks() desktopData.createDesk(displayId, deskId) desktopData.createDesk(displayId, deskId, uniqueDisplayId) val canCreateDesk = canCreateDesks() deskChangeListeners.forEach { (listener, executor) -> executor.execute { Loading @@ -270,12 +270,13 @@ class DesktopRepository( } /** Update the data to reflect a desk changing displays. */ fun onDeskDisplayChanged(deskId: Int, newDisplayId: Int) { fun onDeskDisplayChanged(deskId: Int, newDisplayId: Int, newUniqueDisplayId: String?) { val couldCreateDesk = canCreateDesks() val desk = desktopData.getDesk(deskId)?.deepCopy() ?: error("Expected to find desk with id: $deskId") desk.displayId = newDisplayId desk.uniqueDisplayId = newUniqueDisplayId // TODO: b/412484513 - consider de-duping unnecessary updates to listeners, such as the one // made here by |removeDesk| that will be reverted at the end of this method. removeDesk(deskId) Loading Loading @@ -1231,12 +1232,13 @@ class DesktopRepository( "Use updatePersistentRepository() instead.", ReplaceWith("updatePersistentRepository()"), ) private suspend fun updatePersistentRepositoryForDesk(desk: Desk) = private suspend fun updatePersistentRepositoryForDesk(desk: Desk): Unit = traceSection("DesktopRepository#updatePersistentRepositoryForDesk") { try { persistentRepository.addOrUpdateDesktop( userId = userId, desktopId = desk.deskId, uniqueDisplayId = desk.uniqueDisplayId, visibleTasks = desk.visibleTasks, minimizedTasks = desk.minimizedTasks, freeformTasksInZOrder = desk.freeformTasksInZOrder, Loading Loading @@ -1353,7 +1355,7 @@ class DesktopRepository( /** An interface for the desktop hierarchy's data managed by this repository. */ private interface DesktopData { /** Creates a desk record. */ fun createDesk(displayId: Int, deskId: Int) fun createDesk(displayId: Int, deskId: Int, uniqueDisplayId: String?) /** Adds an existing desk to a specific display */ fun addDesk(displayId: Int, desk: Desk) Loading Loading @@ -1428,16 +1430,19 @@ class DesktopRepository( private val deskByDisplayId = object : SparseArray<Desk>() { /** Gets [Desk] for existing [displayId] or creates a new one. */ fun getOrCreate(displayId: Int): Desk = fun getOrCreate(displayId: Int, uniqueDisplayId: String? = null): Desk = this[displayId] ?: Desk(deskId = displayId, displayId = displayId).also { this[displayId] = it } ?: Desk( deskId = displayId, displayId = displayId, uniqueDisplayId = uniqueDisplayId, ) .also { this[displayId] = it } } override fun createDesk(displayId: Int, deskId: Int) { override fun createDesk(displayId: Int, deskId: Int, uniqueDisplayId: String?) { check(displayId == deskId) { "Display and desk ids must match" } deskByDisplayId.getOrCreate(displayId) deskByDisplayId.getOrCreate(displayId, uniqueDisplayId) } override fun addDesk(displayId: Int, desk: Desk) { Loading Loading @@ -1513,14 +1518,16 @@ class DesktopRepository( private class MultiDesktopData : DesktopData { private val desktopDisplays = SparseArray<DesktopDisplay>() override fun createDesk(displayId: Int, deskId: Int) { override fun createDesk(displayId: Int, deskId: Int, uniqueDisplayId: String?) { val display = desktopDisplays[displayId] ?: DesktopDisplay(displayId).also { desktopDisplays[displayId] = it } check(display.orderedDesks.none { desk -> desk.deskId == deskId }) { "Attempting to create desk#$deskId that already exists in display#$displayId" } display.orderedDesks.add(Desk(deskId = deskId, displayId = displayId)) display.orderedDesks.add( Desk(deskId = deskId, displayId = displayId, uniqueDisplayId = uniqueDisplayId) ) } override fun addDesk(displayId: Int, desk: Desk) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +35 −0 Original line number Diff line number Diff line Loading @@ -46,7 +46,9 @@ import com.android.wm.shell.shared.desktopmode.DesktopState; import com.android.wm.shell.sysui.ShellInit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /** Loading Loading @@ -114,6 +116,30 @@ public class DisplayController { return mDisplayManager.getDisplay(displayId); } /** * Gets the uniqueId associated with the provided displayId, if it is associated with one. */ @Nullable public String getDisplayUniqueId(int displayId) { final DisplayRecord r = mDisplays.get(displayId); return r != null ? r.mUniqueId : null; } /** * Gets a map of all displays by uniqueId from DisplayManager. */ @Nullable public Map<String, Integer> getAllDisplaysByUniqueId() { HashMap<String, Integer> map = new HashMap<>(); for (int i = 0; i < mDisplays.size(); i++) { final String uniqueId = mDisplays.valueAt(i).mUniqueId; if (uniqueId != null) { map.put(uniqueId, mDisplays.keyAt(i)); } } return map; } /** * Returns true if the display with the given displayId is part of the topology. */ Loading Loading @@ -218,6 +244,10 @@ public class DisplayController { final DisplayRecord record = new DisplayRecord(displayId, hasStatusAndNavBars); DisplayLayout displayLayout = record.createLayout(context, display); record.setDisplayLayout(context, displayLayout); final String uniqueId = display.getUniqueId(); if (uniqueId != null) { record.setUniqueId(uniqueId); } mDisplays.put(displayId, record); for (int i = 0; i < mDisplayChangedListeners.size(); ++i) { mDisplayChangedListeners.get(i).onDisplayAdded(displayId); Loading Loading @@ -383,6 +413,7 @@ public class DisplayController { private class DisplayRecord { private final int mDisplayId; private String mUniqueId; private Context mContext; private DisplayLayout mDisplayLayout; private InsetsState mInsetsState = new InsetsState(); Loading Loading @@ -428,6 +459,10 @@ public class DisplayController { mDisplayLayout.setInsets(mContext.getResources(), mInsetsState); } private void setUniqueId(String uniqueId) { mUniqueId = uniqueId; } private void setInsets(InsetsState state) { mInsetsState = state; mDisplayLayout.setInsets(mContext.getResources(), state); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +3 −2 Original line number Diff line number Diff line Loading @@ -1781,9 +1781,10 @@ public abstract class WMShellModule { DesktopPersistentRepository desktopPersistentRepository, @ShellMainThread CoroutineScope mainScope, DesktopConfig desktopConfig, DesktopState desktopState) { DesktopState desktopState, DisplayController displayController) { return new DesktopRepositoryInitializerImpl(context, desktopPersistentRepository, mainScope, desktopConfig, desktopState); mainScope, desktopConfig, desktopState, displayController); } @WMSingleton Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +24 −7 Original line number Diff line number Diff line Loading @@ -620,7 +620,11 @@ class DesktopTasksController( if (deskId == null) { logW("Failed to add desk in displayId=%d for userId=%d", displayId, userId) } else { repository.addDesk(displayId = displayId, deskId = deskId) repository.addDesk( displayId = displayId, deskId = deskId, uniqueDisplayId = displayController.getDisplayUniqueId(displayId), ) onResult(deskId) if (activateDesk) { activateDesk(deskId = deskId, userId = userId, enterReason = enterReason) Loading @@ -638,7 +642,11 @@ class DesktopTasksController( logW("Failed to add desk in displayId=%d for userId=%d", displayId, userId) return null } repository.addDesk(displayId = displayId, deskId = deskId) repository.addDesk( displayId = displayId, deskId = deskId, uniqueDisplayId = displayController.getDisplayUniqueId(displayId), ) return deskId } Loading Loading @@ -748,7 +756,7 @@ class DesktopTasksController( destinationDisplayId: Int, ): RunOnTransitStart { logD( "onDisplayDisconnect: disconnectedDisplayId=$disconnectedDisplayId, " + "addOnDisplayDisconnectChanges: disconnectedDisplayId=$disconnectedDisplayId, " + "destinationDisplayId=$destinationDisplayId" ) val runOnTransitStartList = mutableListOf<RunOnTransitStart>() Loading @@ -762,7 +770,7 @@ class DesktopTasksController( val destDisplayLayout = displayController.getDisplayLayout(destinationDisplayId) if (destDisplayLayout == null) { logE( "onDisplayDisconnect: no display layout found for " + "addOnDisplayDisconnectChanges: no display layout found for " + "destinationDisplayId=$destinationDisplayId" ) } Loading Loading @@ -817,7 +825,11 @@ class DesktopTasksController( val deskTasks = desktopRepository.getActiveTaskIdsInDesk(deskId) // Remove desk if it's empty. if (deskTasks.isEmpty()) { logD("onDisplayDisconnect: removing empty desk=%d of user=%d", deskId, userId) logD( "handleExtendedModeDisconnect: removing empty desk=%d of user=%d", deskId, userId, ) desksOrganizer.removeDesk(wct, deskId, userId) runOnTransitStartList.add { transition -> desksTransitionObserver.addPendingTransition( Loading @@ -835,7 +847,8 @@ class DesktopTasksController( } } else { logD( "onDisplayDisconnect: reparenting desk=%d to display=%d for user=%d", "handleExtendedModeDisconnect: " + "reparenting desk=%d to display=%d for user=%d", deskId, destinationDisplayId, userId, Loading @@ -856,6 +869,8 @@ class DesktopTasksController( userId = userId, deskId = deskId, displayId = destinationDisplayId, uniqueDisplayId = displayController.getDisplayUniqueId(destinationDisplayId), ) ) } Loading Loading @@ -1279,6 +1294,7 @@ class DesktopTasksController( .apply { launchWindowingMode = WINDOWING_MODE_FREEFORM launchBounds = getInitialBounds(displayLayout, task, deskId) launchDisplayId = targetDisplayId } .toBundle(), ) Loading Loading @@ -2911,7 +2927,8 @@ class DesktopTasksController( wct.reorder(runningTaskInfo.token, /* onTop= */ true) } else if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // Task is not running, start it wct.startTask(taskId, createActivityOptionsForStartTask().toBundle()) val startDesk = repository.getDefaultDeskId(displayId) ?: INVALID_DESK_ID wct.startTask(taskId, createActivityOptionsForStartTask(startDesk).toBundle()) } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/data/Desk.kt +2 −2 Original line number Diff line number Diff line Loading @@ -51,10 +51,10 @@ data class Desk( var topTransparentFullscreenTaskData: TopTransparentFullscreenTaskData? = null, var leftTiledTaskId: Int? = null, var rightTiledTaskId: Int? = null, // The display's unique id that will remain the same across reboots. var uniqueDisplayId: String? = null, ) { // TODO: b/417907552 - Add these variables to persistent repository. // The display's unique id that will remain the same across reboots. var uniqueDisplayId: String? = null // Bounds of tasks in this desk mapped to their respective task ids. Used for reconnect. var boundsByTaskId: MutableMap<Int, Rect> = mutableMapOf() Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/data/DesktopRepository.kt +20 −13 Original line number Diff line number Diff line Loading @@ -254,10 +254,10 @@ class DesktopRepository( } /** Adds the given desk under the given display. */ fun addDesk(displayId: Int, deskId: Int) { fun addDesk(displayId: Int, deskId: Int, uniqueDisplayId: String? = null) { logD("addDesk for displayId=%d and deskId=%d", displayId, deskId) val couldCreateDesk = canCreateDesks() desktopData.createDesk(displayId, deskId) desktopData.createDesk(displayId, deskId, uniqueDisplayId) val canCreateDesk = canCreateDesks() deskChangeListeners.forEach { (listener, executor) -> executor.execute { Loading @@ -270,12 +270,13 @@ class DesktopRepository( } /** Update the data to reflect a desk changing displays. */ fun onDeskDisplayChanged(deskId: Int, newDisplayId: Int) { fun onDeskDisplayChanged(deskId: Int, newDisplayId: Int, newUniqueDisplayId: String?) { val couldCreateDesk = canCreateDesks() val desk = desktopData.getDesk(deskId)?.deepCopy() ?: error("Expected to find desk with id: $deskId") desk.displayId = newDisplayId desk.uniqueDisplayId = newUniqueDisplayId // TODO: b/412484513 - consider de-duping unnecessary updates to listeners, such as the one // made here by |removeDesk| that will be reverted at the end of this method. removeDesk(deskId) Loading Loading @@ -1231,12 +1232,13 @@ class DesktopRepository( "Use updatePersistentRepository() instead.", ReplaceWith("updatePersistentRepository()"), ) private suspend fun updatePersistentRepositoryForDesk(desk: Desk) = private suspend fun updatePersistentRepositoryForDesk(desk: Desk): Unit = traceSection("DesktopRepository#updatePersistentRepositoryForDesk") { try { persistentRepository.addOrUpdateDesktop( userId = userId, desktopId = desk.deskId, uniqueDisplayId = desk.uniqueDisplayId, visibleTasks = desk.visibleTasks, minimizedTasks = desk.minimizedTasks, freeformTasksInZOrder = desk.freeformTasksInZOrder, Loading Loading @@ -1353,7 +1355,7 @@ class DesktopRepository( /** An interface for the desktop hierarchy's data managed by this repository. */ private interface DesktopData { /** Creates a desk record. */ fun createDesk(displayId: Int, deskId: Int) fun createDesk(displayId: Int, deskId: Int, uniqueDisplayId: String?) /** Adds an existing desk to a specific display */ fun addDesk(displayId: Int, desk: Desk) Loading Loading @@ -1428,16 +1430,19 @@ class DesktopRepository( private val deskByDisplayId = object : SparseArray<Desk>() { /** Gets [Desk] for existing [displayId] or creates a new one. */ fun getOrCreate(displayId: Int): Desk = fun getOrCreate(displayId: Int, uniqueDisplayId: String? = null): Desk = this[displayId] ?: Desk(deskId = displayId, displayId = displayId).also { this[displayId] = it } ?: Desk( deskId = displayId, displayId = displayId, uniqueDisplayId = uniqueDisplayId, ) .also { this[displayId] = it } } override fun createDesk(displayId: Int, deskId: Int) { override fun createDesk(displayId: Int, deskId: Int, uniqueDisplayId: String?) { check(displayId == deskId) { "Display and desk ids must match" } deskByDisplayId.getOrCreate(displayId) deskByDisplayId.getOrCreate(displayId, uniqueDisplayId) } override fun addDesk(displayId: Int, desk: Desk) { Loading Loading @@ -1513,14 +1518,16 @@ class DesktopRepository( private class MultiDesktopData : DesktopData { private val desktopDisplays = SparseArray<DesktopDisplay>() override fun createDesk(displayId: Int, deskId: Int) { override fun createDesk(displayId: Int, deskId: Int, uniqueDisplayId: String?) { val display = desktopDisplays[displayId] ?: DesktopDisplay(displayId).also { desktopDisplays[displayId] = it } check(display.orderedDesks.none { desk -> desk.deskId == deskId }) { "Attempting to create desk#$deskId that already exists in display#$displayId" } display.orderedDesks.add(Desk(deskId = deskId, displayId = displayId)) display.orderedDesks.add( Desk(deskId = deskId, displayId = displayId, uniqueDisplayId = uniqueDisplayId) ) } override fun addDesk(displayId: Int, desk: Desk) { Loading