Merge "Store desktop tasks per display id" into udc-dev
This commit is contained in:
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.TRANSIT_CHANGE;
|
||||
import static android.view.WindowManager.TRANSIT_NONE;
|
||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||
@@ -264,10 +265,10 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
/**
|
||||
* Show apps on desktop
|
||||
*/
|
||||
void showDesktopApps() {
|
||||
void showDesktopApps(int displayId) {
|
||||
// Bring apps to front, ignoring their visibility status to always ensure they are on top.
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
bringDesktopAppsToFront(wct);
|
||||
bringDesktopAppsToFront(displayId, wct);
|
||||
|
||||
if (!wct.isEmpty()) {
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
@@ -280,12 +281,12 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
}
|
||||
|
||||
/** Get number of tasks that are marked as visible */
|
||||
int getVisibleTaskCount() {
|
||||
return mDesktopModeTaskRepository.getVisibleTaskCount();
|
||||
int getVisibleTaskCount(int displayId) {
|
||||
return mDesktopModeTaskRepository.getVisibleTaskCount(displayId);
|
||||
}
|
||||
|
||||
private void bringDesktopAppsToFront(WindowContainerTransaction wct) {
|
||||
final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
|
||||
private void bringDesktopAppsToFront(int displayId, WindowContainerTransaction wct) {
|
||||
final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(displayId);
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
|
||||
|
||||
final List<RunningTaskInfo> taskInfos = new ArrayList<>();
|
||||
@@ -386,6 +387,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
@Override
|
||||
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
|
||||
@NonNull TransitionRequestInfo request) {
|
||||
RunningTaskInfo triggerTask = request.getTriggerTask();
|
||||
// Only do anything if we are in desktop mode and opening/moving-to-front a task/app in
|
||||
// freeform
|
||||
if (!DesktopModeStatus.isActive(mContext)) {
|
||||
@@ -399,16 +401,15 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
WindowManager.transitTypeToString(request.getType()));
|
||||
return null;
|
||||
}
|
||||
if (request.getTriggerTask() == null
|
||||
|| request.getTriggerTask().getWindowingMode() != WINDOWING_MODE_FREEFORM) {
|
||||
if (triggerTask == null || triggerTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "skip shell transition request: not freeform task");
|
||||
return null;
|
||||
}
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "handle shell transition request: %s", request);
|
||||
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
bringDesktopAppsToFront(wct);
|
||||
wct.reorder(request.getTriggerTask().token, true /* onTop */);
|
||||
bringDesktopAppsToFront(triggerTask.displayId, wct);
|
||||
wct.reorder(triggerTask.token, true /* onTop */);
|
||||
|
||||
return wct;
|
||||
}
|
||||
@@ -493,16 +494,18 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
mController = null;
|
||||
}
|
||||
|
||||
// TODO(b/278084491): pass in display id
|
||||
public void showDesktopApps() {
|
||||
executeRemoteCallWithTaskPermission(mController, "showDesktopApps",
|
||||
DesktopModeController::showDesktopApps);
|
||||
controller -> controller.showDesktopApps(DEFAULT_DISPLAY));
|
||||
}
|
||||
|
||||
// TODO(b/278084491): pass in display id
|
||||
@Override
|
||||
public int getVisibleTaskCount() throws RemoteException {
|
||||
int[] result = new int[1];
|
||||
executeRemoteCallWithTaskPermission(mController, "getVisibleTaskCount",
|
||||
controller -> result[0] = controller.getVisibleTaskCount(),
|
||||
controller -> result[0] = controller.getVisibleTaskCount(DEFAULT_DISPLAY),
|
||||
true /* blocking */
|
||||
);
|
||||
return result[0];
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.graphics.Region
|
||||
import android.util.ArrayMap
|
||||
import android.util.ArraySet
|
||||
import android.util.SparseArray
|
||||
import androidx.core.util.forEach
|
||||
import androidx.core.util.keyIterator
|
||||
import androidx.core.util.valueIterator
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.function.Consumer
|
||||
@@ -29,14 +31,18 @@ import java.util.function.Consumer
|
||||
*/
|
||||
class DesktopModeTaskRepository {
|
||||
|
||||
/**
|
||||
* Set of task ids that are marked as active in desktop mode.
|
||||
* Active tasks in desktop mode are freeform tasks that are visible or have been visible after
|
||||
* desktop mode was activated.
|
||||
* Task gets removed from this list when it vanishes. Or when desktop mode is turned off.
|
||||
*/
|
||||
private val activeTasks = ArraySet<Int>()
|
||||
private val visibleTasks = ArraySet<Int>()
|
||||
/** Task data that is tracked per display */
|
||||
private data class DisplayData(
|
||||
/**
|
||||
* Set of task ids that are marked as active in desktop mode. Active tasks in desktop mode
|
||||
* are freeform tasks that are visible or have been visible after desktop mode was
|
||||
* activated. Task gets removed from this list when it vanishes. Or when desktop mode is
|
||||
* turned off.
|
||||
*/
|
||||
val activeTasks: ArraySet<Int> = ArraySet(),
|
||||
val visibleTasks: ArraySet<Int> = ArraySet(),
|
||||
)
|
||||
|
||||
// Tasks currently in freeform mode, ordered from top to bottom (top is at index 0).
|
||||
private val freeformTasksInZOrder = mutableListOf<Int>()
|
||||
private val activeTasksListeners = ArraySet<ActiveTasksListener>()
|
||||
@@ -47,9 +53,22 @@ class DesktopModeTaskRepository {
|
||||
private var desktopGestureExclusionListener: Consumer<Region>? = null
|
||||
private var desktopGestureExclusionExecutor: Executor? = null
|
||||
|
||||
/**
|
||||
* Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository.
|
||||
*/
|
||||
private val displayData =
|
||||
object : SparseArray<DisplayData>() {
|
||||
/**
|
||||
* Get the [DisplayData] associated with this [displayId]
|
||||
*
|
||||
* Creates a new instance if one does not exist
|
||||
*/
|
||||
fun getOrCreate(displayId: Int): DisplayData {
|
||||
if (!contains(displayId)) {
|
||||
put(displayId, DisplayData())
|
||||
}
|
||||
return get(displayId)
|
||||
}
|
||||
}
|
||||
|
||||
/** Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository. */
|
||||
fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) {
|
||||
activeTasksListeners.add(activeTasksListener)
|
||||
}
|
||||
@@ -57,10 +76,17 @@ class DesktopModeTaskRepository {
|
||||
/**
|
||||
* Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not.
|
||||
*/
|
||||
fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) {
|
||||
visibleTasksListeners.put(visibleTasksListener, executor)
|
||||
executor.execute(
|
||||
Runnable { visibleTasksListener.onVisibilityChanged(visibleTasks.size > 0) })
|
||||
fun addVisibleTasksListener(
|
||||
visibleTasksListener: VisibleTasksListener,
|
||||
executor: Executor
|
||||
) {
|
||||
visibleTasksListeners[visibleTasksListener] = executor
|
||||
displayData.keyIterator().forEach { displayId ->
|
||||
val visibleTasks = getVisibleTaskCount(displayId)
|
||||
executor.execute {
|
||||
visibleTasksListener.onVisibilityChanged(displayId, visibleTasks > 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,14 +126,21 @@ class DesktopModeTaskRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a task with given [taskId] as active.
|
||||
* Mark a task with given [taskId] as active on given [displayId]
|
||||
*
|
||||
* @return `true` if the task was not active
|
||||
* @return `true` if the task was not active on given [displayId]
|
||||
*/
|
||||
fun addActiveTask(taskId: Int): Boolean {
|
||||
val added = activeTasks.add(taskId)
|
||||
fun addActiveTask(displayId: Int, taskId: Int): Boolean {
|
||||
// Check if task is active on another display, if so, remove it
|
||||
displayData.forEach { id, data ->
|
||||
if (id != displayId && data.activeTasks.remove(taskId)) {
|
||||
activeTasksListeners.onEach { it.onActiveTasksChanged(id) }
|
||||
}
|
||||
}
|
||||
|
||||
val added = displayData.getOrCreate(displayId).activeTasks.add(taskId)
|
||||
if (added) {
|
||||
activeTasksListeners.onEach { it.onActiveTasksChanged() }
|
||||
activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
|
||||
}
|
||||
return added
|
||||
}
|
||||
@@ -118,65 +151,93 @@ class DesktopModeTaskRepository {
|
||||
* @return `true` if the task was active
|
||||
*/
|
||||
fun removeActiveTask(taskId: Int): Boolean {
|
||||
val removed = activeTasks.remove(taskId)
|
||||
if (removed) {
|
||||
activeTasksListeners.onEach { it.onActiveTasksChanged() }
|
||||
var result = false
|
||||
displayData.forEach { displayId, data ->
|
||||
if (data.activeTasks.remove(taskId)) {
|
||||
activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return removed
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a task with the given [taskId] was marked as an active task
|
||||
*/
|
||||
fun isActiveTask(taskId: Int): Boolean {
|
||||
return activeTasks.contains(taskId)
|
||||
return displayData.valueIterator().asSequence().any { data ->
|
||||
data.activeTasks.contains(taskId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a task is visible.
|
||||
*/
|
||||
fun isVisibleTask(taskId: Int): Boolean {
|
||||
return visibleTasks.contains(taskId)
|
||||
return displayData.valueIterator().asSequence().any { data ->
|
||||
data.visibleTasks.contains(taskId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of the active tasks
|
||||
* Get a set of the active tasks for given [displayId]
|
||||
*/
|
||||
fun getActiveTasks(): ArraySet<Int> {
|
||||
return ArraySet(activeTasks)
|
||||
fun getActiveTasks(displayId: Int): ArraySet<Int> {
|
||||
return ArraySet(displayData[displayId]?.activeTasks)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of freeform tasks, ordered from top-bottom (top at index 0).
|
||||
*/
|
||||
// TODO(b/278084491): pass in display id
|
||||
fun getFreeformTasksInZOrder(): List<Int> {
|
||||
return freeformTasksInZOrder
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates whether a freeform task with this id is visible or not and notifies listeners.
|
||||
*
|
||||
* If the task was visible on a different display with a different displayId, it is removed from
|
||||
* the set of visible tasks on that display. Listeners will be notified.
|
||||
*/
|
||||
fun updateVisibleFreeformTasks(taskId: Int, visible: Boolean) {
|
||||
val prevCount: Int = visibleTasks.size
|
||||
fun updateVisibleFreeformTasks(displayId: Int, taskId: Int, visible: Boolean) {
|
||||
if (visible) {
|
||||
visibleTasks.add(taskId)
|
||||
} else {
|
||||
visibleTasks.remove(taskId)
|
||||
}
|
||||
if (prevCount == 0 && visibleTasks.size == 1 ||
|
||||
prevCount > 0 && visibleTasks.size == 0) {
|
||||
for ((listener, executor) in visibleTasksListeners) {
|
||||
executor.execute(
|
||||
Runnable { listener.onVisibilityChanged(visibleTasks.size > 0) })
|
||||
// Task is visible. Check if we need to remove it from any other display.
|
||||
val otherDisplays = displayData.keyIterator().asSequence().filter { it != displayId }
|
||||
for (otherDisplayId in otherDisplays) {
|
||||
if (displayData[otherDisplayId].visibleTasks.remove(taskId)) {
|
||||
// Task removed from other display, check if we should notify listeners
|
||||
if (displayData[otherDisplayId].visibleTasks.isEmpty()) {
|
||||
notifyVisibleTaskListeners(otherDisplayId, hasVisibleFreeformTasks = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val prevCount = getVisibleTaskCount(displayId)
|
||||
if (visible) {
|
||||
displayData.getOrCreate(displayId).visibleTasks.add(taskId)
|
||||
} else {
|
||||
displayData[displayId]?.visibleTasks?.remove(taskId)
|
||||
}
|
||||
val newCount = getVisibleTaskCount(displayId)
|
||||
// Check if count changed and if there was no tasks or this is the first task
|
||||
if (prevCount != newCount && (prevCount == 0 || newCount == 0)) {
|
||||
notifyVisibleTaskListeners(displayId, newCount > 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyVisibleTaskListeners(displayId: Int, hasVisibleFreeformTasks: Boolean) {
|
||||
visibleTasksListeners.forEach { (listener, executor) ->
|
||||
executor.execute { listener.onVisibilityChanged(displayId, hasVisibleFreeformTasks) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of tasks that are marked as visible
|
||||
* Get number of tasks that are marked as visible on given [displayId]
|
||||
*/
|
||||
fun getVisibleTaskCount(): Int {
|
||||
return visibleTasks.size
|
||||
fun getVisibleTaskCount(displayId: Int): Int {
|
||||
return displayData[displayId]?.visibleTasks?.size ?: 0
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +287,7 @@ class DesktopModeTaskRepository {
|
||||
* Called when the active tasks change in desktop mode.
|
||||
*/
|
||||
@JvmDefault
|
||||
fun onActiveTasksChanged() {}
|
||||
fun onActiveTasksChanged(displayId: Int) {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,6 +298,6 @@ class DesktopModeTaskRepository {
|
||||
* Called when the desktop starts or stops showing freeform tasks.
|
||||
*/
|
||||
@JvmDefault
|
||||
fun onVisibilityChanged(hasVisibleFreeformTasks: Boolean) {}
|
||||
fun onVisibilityChanged(displayId: Int, hasVisibleFreeformTasks: Boolean) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.graphics.Rect
|
||||
import android.graphics.Region
|
||||
import android.os.IBinder
|
||||
import android.os.SystemProperties
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import android.view.SurfaceControl
|
||||
import android.view.WindowManager.TRANSIT_CHANGE
|
||||
import android.view.WindowManager.TRANSIT_NONE
|
||||
@@ -97,10 +98,11 @@ class DesktopTasksController(
|
||||
}
|
||||
|
||||
/** Show all tasks, that are part of the desktop, on top of launcher */
|
||||
fun showDesktopApps() {
|
||||
fun showDesktopApps(displayId: Int) {
|
||||
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
|
||||
val wct = WindowContainerTransaction()
|
||||
bringDesktopAppsToFront(wct)
|
||||
// TODO(b/278084491): pass in display id
|
||||
bringDesktopAppsToFront(displayId, wct)
|
||||
|
||||
// Execute transaction if there are pending operations
|
||||
if (!wct.isEmpty) {
|
||||
@@ -114,8 +116,8 @@ class DesktopTasksController(
|
||||
}
|
||||
|
||||
/** Get number of tasks that are marked as visible */
|
||||
fun getVisibleTaskCount(): Int {
|
||||
return desktopModeTaskRepository.getVisibleTaskCount()
|
||||
fun getVisibleTaskCount(displayId: Int): Int {
|
||||
return desktopModeTaskRepository.getVisibleTaskCount(displayId)
|
||||
}
|
||||
|
||||
/** Move a task with given `taskId` to desktop */
|
||||
@@ -129,7 +131,7 @@ class DesktopTasksController(
|
||||
|
||||
val wct = WindowContainerTransaction()
|
||||
// Bring other apps to front first
|
||||
bringDesktopAppsToFront(wct)
|
||||
bringDesktopAppsToFront(task.displayId, wct)
|
||||
addMoveToDesktopChanges(wct, task.token)
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
|
||||
@@ -165,7 +167,7 @@ class DesktopTasksController(
|
||||
freeformBounds: Rect
|
||||
) {
|
||||
val wct = WindowContainerTransaction()
|
||||
bringDesktopAppsToFront(wct)
|
||||
bringDesktopAppsToFront(taskInfo.displayId, wct)
|
||||
addMoveToDesktopChanges(wct, taskInfo.getToken())
|
||||
wct.setBounds(taskInfo.token, freeformBounds)
|
||||
|
||||
@@ -244,9 +246,9 @@ class DesktopTasksController(
|
||||
?: WINDOWING_MODE_UNDEFINED
|
||||
}
|
||||
|
||||
private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
|
||||
private fun bringDesktopAppsToFront(displayId: Int, wct: WindowContainerTransaction) {
|
||||
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront")
|
||||
val activeTasks = desktopModeTaskRepository.getActiveTasks()
|
||||
val activeTasks = desktopModeTaskRepository.getActiveTasks(displayId)
|
||||
|
||||
// First move home to front and then other tasks on top of it
|
||||
moveHomeTaskToFront(wct)
|
||||
@@ -290,18 +292,17 @@ class DesktopTasksController(
|
||||
request: TransitionRequestInfo
|
||||
): WindowContainerTransaction? {
|
||||
// Check if we should skip handling this transition
|
||||
val task: RunningTaskInfo? = request.triggerTask
|
||||
val shouldHandleRequest =
|
||||
when {
|
||||
// Only handle open or to front transitions
|
||||
request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> false
|
||||
// Only handle when it is a task transition
|
||||
task == null -> false
|
||||
request.triggerTask == null -> false
|
||||
// Only handle standard type tasks
|
||||
task.activityType != ACTIVITY_TYPE_STANDARD -> false
|
||||
request.triggerTask.activityType != ACTIVITY_TYPE_STANDARD -> false
|
||||
// Only handle fullscreen or freeform tasks
|
||||
task.windowingMode != WINDOWING_MODE_FULLSCREEN &&
|
||||
task.windowingMode != WINDOWING_MODE_FREEFORM -> false
|
||||
request.triggerTask.windowingMode != WINDOWING_MODE_FULLSCREEN &&
|
||||
request.triggerTask.windowingMode != WINDOWING_MODE_FREEFORM -> false
|
||||
// Otherwise process it
|
||||
else -> true
|
||||
}
|
||||
@@ -310,10 +311,11 @@ class DesktopTasksController(
|
||||
return null
|
||||
}
|
||||
|
||||
val activeTasks = desktopModeTaskRepository.getActiveTasks()
|
||||
val task: RunningTaskInfo = request.triggerTask
|
||||
val activeTasks = desktopModeTaskRepository.getActiveTasks(task.displayId)
|
||||
|
||||
// Check if we should switch a fullscreen task to freeform
|
||||
if (task?.windowingMode == WINDOWING_MODE_FULLSCREEN) {
|
||||
if (task.windowingMode == WINDOWING_MODE_FULLSCREEN) {
|
||||
// If there are any visible desktop tasks, switch the task to freeform
|
||||
if (activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) {
|
||||
ProtoLog.d(
|
||||
@@ -329,7 +331,7 @@ class DesktopTasksController(
|
||||
}
|
||||
|
||||
// CHeck if we should switch a freeform task to fullscreen
|
||||
if (task?.windowingMode == WINDOWING_MODE_FREEFORM) {
|
||||
if (task.windowingMode == WINDOWING_MODE_FREEFORM) {
|
||||
// If no visible desktop tasks, switch this task to freeform as the transition came
|
||||
// outside of this controller
|
||||
if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) {
|
||||
@@ -559,20 +561,21 @@ class DesktopTasksController(
|
||||
controller = null
|
||||
}
|
||||
|
||||
// TODO(b/278084491): pass in display id
|
||||
override fun showDesktopApps() {
|
||||
ExecutorUtils.executeRemoteCallWithTaskPermission(
|
||||
controller,
|
||||
"showDesktopApps",
|
||||
Consumer(DesktopTasksController::showDesktopApps)
|
||||
)
|
||||
"showDesktopApps"
|
||||
) { c -> c.showDesktopApps(DEFAULT_DISPLAY) }
|
||||
}
|
||||
|
||||
// TODO(b/278084491): pass in display id
|
||||
override fun getVisibleTaskCount(): Int {
|
||||
val result = IntArray(1)
|
||||
ExecutorUtils.executeRemoteCallWithTaskPermission(
|
||||
controller,
|
||||
"getVisibleTaskCount",
|
||||
{ controller -> result[0] = controller.getVisibleTaskCount() },
|
||||
{ controller -> result[0] = controller.getVisibleTaskCount(DEFAULT_DISPLAY) },
|
||||
true /* blocking */
|
||||
)
|
||||
return result[0]
|
||||
|
||||
@@ -94,11 +94,12 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
|
||||
mDesktopModeTaskRepository.ifPresent(repository -> {
|
||||
repository.addOrMoveFreeformTaskToTop(taskInfo.taskId);
|
||||
if (taskInfo.isVisible) {
|
||||
if (repository.addActiveTask(taskInfo.taskId)) {
|
||||
if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
||||
"Adding active freeform task: #%d", taskInfo.taskId);
|
||||
}
|
||||
repository.updateVisibleFreeformTasks(taskInfo.taskId, true);
|
||||
repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
|
||||
true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -117,7 +118,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
||||
"Removing active freeform task: #%d", taskInfo.taskId);
|
||||
}
|
||||
repository.updateVisibleFreeformTasks(taskInfo.taskId, false);
|
||||
repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId, false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -137,12 +138,13 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
|
||||
if (DesktopModeStatus.isAnyEnabled()) {
|
||||
mDesktopModeTaskRepository.ifPresent(repository -> {
|
||||
if (taskInfo.isVisible) {
|
||||
if (repository.addActiveTask(taskInfo.taskId)) {
|
||||
if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
||||
"Adding active freeform task: #%d", taskInfo.taskId);
|
||||
}
|
||||
}
|
||||
repository.updateVisibleFreeformTasks(taskInfo.taskId, taskInfo.isVisible);
|
||||
repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
|
||||
taskInfo.isVisible);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActiveTasksChanged() {
|
||||
public void onActiveTasksChanged(int displayId) {
|
||||
notifyRecentTasksChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.TRANSIT_CHANGE;
|
||||
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||
import static android.view.WindowManager.TRANSIT_NONE;
|
||||
@@ -82,6 +83,8 @@ import java.util.Arrays;
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class DesktopModeControllerTest extends ShellTestCase {
|
||||
|
||||
private static final int SECOND_DISPLAY = 2;
|
||||
|
||||
@Mock
|
||||
private ShellController mShellController;
|
||||
@Mock
|
||||
@@ -248,22 +251,22 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
||||
public void testShowDesktopApps_allAppsInvisible_bringsToFront() {
|
||||
// Set up two active tasks on desktop, task2 is on top of task1.
|
||||
RunningTaskInfo freeformTask1 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(freeformTask1.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, freeformTask1.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(freeformTask1.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(
|
||||
freeformTask1.taskId, false /* visible */);
|
||||
DEFAULT_DISPLAY, freeformTask1.taskId, false /* visible */);
|
||||
RunningTaskInfo freeformTask2 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(freeformTask2.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, freeformTask2.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(freeformTask2.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(
|
||||
freeformTask2.taskId, false /* visible */);
|
||||
DEFAULT_DISPLAY, freeformTask2.taskId, false /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(freeformTask1.taskId)).thenReturn(
|
||||
freeformTask1);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(freeformTask2.taskId)).thenReturn(
|
||||
freeformTask2);
|
||||
|
||||
// Run show desktop apps logic
|
||||
mController.showDesktopApps();
|
||||
mController.showDesktopApps(DEFAULT_DISPLAY);
|
||||
|
||||
final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
|
||||
// Check wct has reorder calls
|
||||
@@ -283,17 +286,19 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
||||
@Test
|
||||
public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() {
|
||||
final RunningTaskInfo task1 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task1.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
|
||||
true /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(task1.taskId)).thenReturn(task1);
|
||||
final RunningTaskInfo task2 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task2.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
|
||||
true /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(task2.taskId)).thenReturn(task2);
|
||||
|
||||
mController.showDesktopApps();
|
||||
mController.showDesktopApps(DEFAULT_DISPLAY);
|
||||
|
||||
final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
|
||||
// Check wct has reorder calls
|
||||
@@ -312,17 +317,19 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
||||
@Test
|
||||
public void testShowDesktopApps_someAppsInvisible_reordersAll() {
|
||||
final RunningTaskInfo task1 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task1.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, false /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
|
||||
false /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(task1.taskId)).thenReturn(task1);
|
||||
final RunningTaskInfo task2 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task2.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
|
||||
true /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(task2.taskId)).thenReturn(task2);
|
||||
|
||||
mController.showDesktopApps();
|
||||
mController.showDesktopApps(DEFAULT_DISPLAY);
|
||||
|
||||
final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
|
||||
// Both tasks should be reordered to top, even if one was already visible.
|
||||
@@ -335,39 +342,88 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
||||
assertThat(op2.getContainer()).isEqualTo(task2.token.asBinder());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay() {
|
||||
RunningTaskInfo taskDefaultDisplay = createFreeformTask(DEFAULT_DISPLAY);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, taskDefaultDisplay.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskDefaultDisplay.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(
|
||||
DEFAULT_DISPLAY, taskDefaultDisplay.taskId, false /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(taskDefaultDisplay.taskId)).thenReturn(
|
||||
taskDefaultDisplay);
|
||||
|
||||
RunningTaskInfo taskSecondDisplay = createFreeformTask(SECOND_DISPLAY);
|
||||
mDesktopModeTaskRepository.addActiveTask(SECOND_DISPLAY, taskSecondDisplay.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskSecondDisplay.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(
|
||||
SECOND_DISPLAY, taskSecondDisplay.taskId, false /* visible */);
|
||||
when(mShellTaskOrganizer.getRunningTaskInfo(taskSecondDisplay.taskId)).thenReturn(
|
||||
taskSecondDisplay);
|
||||
|
||||
mController.showDesktopApps(DEFAULT_DISPLAY);
|
||||
|
||||
WindowContainerTransaction wct = getBringAppsToFrontTransaction();
|
||||
assertThat(wct.getHierarchyOps()).hasSize(1);
|
||||
HierarchyOp op = wct.getHierarchyOps().get(0);
|
||||
assertThat(op.getContainer()).isEqualTo(taskDefaultDisplay.token.asBinder());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVisibleTaskCount_noTasks_returnsZero() {
|
||||
assertThat(mController.getVisibleTaskCount()).isEqualTo(0);
|
||||
assertThat(mController.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVisibleTaskCount_twoTasks_bothVisible_returnsTwo() {
|
||||
RunningTaskInfo task1 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task1.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
|
||||
true /* visible */);
|
||||
|
||||
RunningTaskInfo task2 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task2.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
|
||||
true /* visible */);
|
||||
|
||||
assertThat(mController.getVisibleTaskCount()).isEqualTo(2);
|
||||
assertThat(mController.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVisibleTaskCount_twoTasks_oneVisible_returnsOne() {
|
||||
RunningTaskInfo task1 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task1.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
|
||||
true /* visible */);
|
||||
|
||||
RunningTaskInfo task2 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task2.taskId);
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, false /* visible */);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
|
||||
false /* visible */);
|
||||
|
||||
assertThat(mController.getVisibleTaskCount()).isEqualTo(1);
|
||||
assertThat(mController.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVisibleTaskCount_twoTasksVisibleOnDifferentDisplays_returnsOne() {
|
||||
RunningTaskInfo taskDefaultDisplay = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, taskDefaultDisplay.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskDefaultDisplay.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY,
|
||||
taskDefaultDisplay.taskId,
|
||||
true /* visible */);
|
||||
|
||||
RunningTaskInfo taskSecondDisplay = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(SECOND_DISPLAY, taskSecondDisplay.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskSecondDisplay.taskId);
|
||||
mDesktopModeTaskRepository.updateVisibleFreeformTasks(SECOND_DISPLAY,
|
||||
taskSecondDisplay.taskId,
|
||||
true /* visible */);
|
||||
|
||||
assertThat(mController.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
package com.android.wm.shell.desktopmode
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.wm.shell.ShellTestCase
|
||||
import com.android.wm.shell.TestShellExecutor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import junit.framework.Assert.fail
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@@ -41,8 +43,8 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
|
||||
repo.addActiveTask(1)
|
||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(1)
|
||||
assertThat(repo.isActiveTask(1)).isTrue()
|
||||
}
|
||||
|
||||
@@ -51,9 +53,9 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
|
||||
repo.addActiveTask(1)
|
||||
repo.addActiveTask(1)
|
||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -61,9 +63,22 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
|
||||
repo.addActiveTask(1)
|
||||
repo.addActiveTask(2)
|
||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(2)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 2)
|
||||
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addActiveTask_multipleDisplays_notifiesCorrectListener() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 2)
|
||||
repo.addActiveTask(SECOND_DISPLAY, taskId = 3)
|
||||
|
||||
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
|
||||
assertThat(listener.activeChangesOnSecondaryDisplay).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,10 +86,10 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
|
||||
repo.addActiveTask(1)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
repo.removeActiveTask(1)
|
||||
// Notify once for add and once for remove
|
||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(2)
|
||||
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
|
||||
assertThat(repo.isActiveTask(1)).isFalse()
|
||||
}
|
||||
|
||||
@@ -83,7 +98,17 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
repo.removeActiveTask(99)
|
||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(0)
|
||||
assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun remoteActiveTask_listenerForOtherDisplayNotNotified() {
|
||||
val listener = TestListener()
|
||||
repo.addActiveTaskListener(listener)
|
||||
repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
|
||||
repo.removeActiveTask(1)
|
||||
assertThat(listener.activeChangesOnSecondaryDisplay).isEqualTo(0)
|
||||
assertThat(repo.isActiveTask(1)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,14 +118,27 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
|
||||
@Test
|
||||
fun addListener_notifiesVisibleFreeformTask() {
|
||||
repo.updateVisibleFreeformTasks(1, true)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
val listener = TestVisibilityListener()
|
||||
val executor = TestShellExecutor()
|
||||
repo.addVisibleTasksListener(listener, executor)
|
||||
executor.flushAll()
|
||||
|
||||
assertThat(listener.hasVisibleFreeformTasks).isTrue()
|
||||
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(1)
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addListener_tasksOnDifferentDisplay_doesNotNotify() {
|
||||
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
|
||||
val listener = TestVisibilityListener()
|
||||
val executor = TestShellExecutor()
|
||||
repo.addVisibleTasksListener(listener, executor)
|
||||
executor.flushAll()
|
||||
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isFalse()
|
||||
// One call as adding listener notifies it
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,13 +146,61 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestVisibilityListener()
|
||||
val executor = TestShellExecutor()
|
||||
repo.addVisibleTasksListener(listener, executor)
|
||||
repo.updateVisibleFreeformTasks(1, true)
|
||||
repo.updateVisibleFreeformTasks(2, true)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
|
||||
executor.flushAll()
|
||||
|
||||
assertThat(listener.hasVisibleFreeformTasks).isTrue()
|
||||
// Equal to 2 because adding the listener notifies the current state
|
||||
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(2)
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateVisibleFreeformTasks_addVisibleTaskNotifiesListenerForThatDisplay() {
|
||||
val listener = TestVisibilityListener()
|
||||
val executor = TestShellExecutor()
|
||||
repo.addVisibleTasksListener(listener, executor)
|
||||
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
executor.flushAll()
|
||||
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
|
||||
assertThat(listener.hasVisibleTasksOnSecondaryDisplay).isFalse()
|
||||
assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(0)
|
||||
|
||||
repo.updateVisibleFreeformTasks(displayId = 1, taskId = 2, visible = true)
|
||||
executor.flushAll()
|
||||
|
||||
// Listener for secondary display is notified
|
||||
assertThat(listener.hasVisibleTasksOnSecondaryDisplay).isTrue()
|
||||
assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(1)
|
||||
// No changes to listener for default display
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateVisibleFreeformTasks_taskOnDefaultBecomesVisibleOnSecondDisplay_listenersNotified() {
|
||||
val listener = TestVisibilityListener()
|
||||
val executor = TestShellExecutor()
|
||||
repo.addVisibleTasksListener(listener, executor)
|
||||
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
executor.flushAll()
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
|
||||
|
||||
// Mark task 1 visible on secondary display
|
||||
repo.updateVisibleFreeformTasks(displayId = 1, taskId = 1, visible = true)
|
||||
executor.flushAll()
|
||||
|
||||
// Default display should have 2 calls
|
||||
// 1 - visible task added
|
||||
// 2 - visible task removed
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(2)
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isFalse()
|
||||
|
||||
// Secondary display should have 1 call for visible task added
|
||||
assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(1)
|
||||
assertThat(listener.hasVisibleTasksOnSecondaryDisplay).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -122,52 +208,83 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
val listener = TestVisibilityListener()
|
||||
val executor = TestShellExecutor()
|
||||
repo.addVisibleTasksListener(listener, executor)
|
||||
repo.updateVisibleFreeformTasks(1, true)
|
||||
repo.updateVisibleFreeformTasks(2, true)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
|
||||
executor.flushAll()
|
||||
|
||||
assertThat(listener.hasVisibleFreeformTasks).isTrue()
|
||||
repo.updateVisibleFreeformTasks(1, false)
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
|
||||
executor.flushAll()
|
||||
|
||||
// Equal to 2 because adding the listener notifies the current state
|
||||
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(2)
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
|
||||
|
||||
repo.updateVisibleFreeformTasks(2, false)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
|
||||
executor.flushAll()
|
||||
|
||||
assertThat(listener.hasVisibleFreeformTasks).isFalse()
|
||||
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(3)
|
||||
assertThat(listener.hasVisibleTasksOnDefaultDisplay).isFalse()
|
||||
assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getVisibleTaskCount() {
|
||||
// No tasks, count is 0
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
|
||||
// New task increments count to 1
|
||||
repo.updateVisibleFreeformTasks(taskId = 1, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
|
||||
|
||||
// Visibility update to same task does not increase count
|
||||
repo.updateVisibleFreeformTasks(taskId = 1, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
|
||||
|
||||
// Second task visible increments count
|
||||
repo.updateVisibleFreeformTasks(taskId = 2, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(2)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
|
||||
|
||||
// Hiding a task decrements count
|
||||
repo.updateVisibleFreeformTasks(taskId = 1, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
|
||||
|
||||
// Hiding all tasks leaves count at 0
|
||||
repo.updateVisibleFreeformTasks(taskId = 2, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount(displayId = 9)).isEqualTo(0)
|
||||
|
||||
// Hiding a not existing task, count remains at 0
|
||||
repo.updateVisibleFreeformTasks(taskId = 999, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 999, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getVisibleTaskCount_multipleDisplays() {
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
|
||||
|
||||
// New task on default display increments count for that display only
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
|
||||
assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
|
||||
|
||||
// New task on secondary display, increments count for that display only
|
||||
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 2, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
|
||||
assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
|
||||
|
||||
// Marking task visible on another display, updates counts for both displays
|
||||
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
|
||||
|
||||
// Marking task that is on secondary display, hidden on default display, does not affect
|
||||
// secondary display
|
||||
repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
|
||||
|
||||
// Hiding a task on that display, decrements count
|
||||
repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = false)
|
||||
assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -197,19 +314,40 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
||||
}
|
||||
|
||||
class TestListener : DesktopModeTaskRepository.ActiveTasksListener {
|
||||
var activeTaskChangedCalls = 0
|
||||
override fun onActiveTasksChanged() {
|
||||
activeTaskChangedCalls++
|
||||
var activeChangesOnDefaultDisplay = 0
|
||||
var activeChangesOnSecondaryDisplay = 0
|
||||
override fun onActiveTasksChanged(displayId: Int) {
|
||||
when (displayId) {
|
||||
DEFAULT_DISPLAY -> activeChangesOnDefaultDisplay++
|
||||
SECOND_DISPLAY -> activeChangesOnSecondaryDisplay++
|
||||
else -> fail("Active task listener received unexpected display id: $displayId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestVisibilityListener : DesktopModeTaskRepository.VisibleTasksListener {
|
||||
var hasVisibleFreeformTasks = false
|
||||
var visibleFreeformTaskChangedCalls = 0
|
||||
var hasVisibleTasksOnDefaultDisplay = false
|
||||
var hasVisibleTasksOnSecondaryDisplay = false
|
||||
|
||||
override fun onVisibilityChanged(hasVisibleTasks: Boolean) {
|
||||
hasVisibleFreeformTasks = hasVisibleTasks
|
||||
visibleFreeformTaskChangedCalls++
|
||||
var visibleChangesOnDefaultDisplay = 0
|
||||
var visibleChangesOnSecondaryDisplay = 0
|
||||
|
||||
override fun onVisibilityChanged(displayId: Int, hasVisibleFreeformTasks: Boolean) {
|
||||
when (displayId) {
|
||||
DEFAULT_DISPLAY -> {
|
||||
hasVisibleTasksOnDefaultDisplay = hasVisibleFreeformTasks
|
||||
visibleChangesOnDefaultDisplay++
|
||||
}
|
||||
SECOND_DISPLAY -> {
|
||||
hasVisibleTasksOnSecondaryDisplay = hasVisibleFreeformTasks
|
||||
visibleChangesOnSecondaryDisplay++
|
||||
}
|
||||
else -> fail("Visible task listener received unexpected display id: $displayId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SECOND_DISPLAY = 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
|
||||
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
|
||||
import android.os.Binder
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import android.view.WindowManager
|
||||
import android.view.WindowManager.TRANSIT_CHANGE
|
||||
import android.view.WindowManager.TRANSIT_NONE
|
||||
@@ -84,10 +85,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
@Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
|
||||
@Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
|
||||
|
||||
lateinit var mockitoSession: StaticMockitoSession
|
||||
lateinit var controller: DesktopTasksController
|
||||
lateinit var shellInit: ShellInit
|
||||
lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
|
||||
private lateinit var mockitoSession: StaticMockitoSession
|
||||
private lateinit var controller: DesktopTasksController
|
||||
private lateinit var shellInit: ShellInit
|
||||
private lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
|
||||
|
||||
// Mock running tasks are registered here so we can get the list from mock shell task organizer
|
||||
private val runningTasks = mutableListOf<RunningTaskInfo>()
|
||||
@@ -155,7 +156,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
markTaskHidden(task1)
|
||||
markTaskHidden(task2)
|
||||
|
||||
controller.showDesktopApps()
|
||||
controller.showDesktopApps(DEFAULT_DISPLAY)
|
||||
|
||||
val wct = getLatestWct(expectTransition = TRANSIT_NONE)
|
||||
assertThat(wct.hierarchyOps).hasSize(3)
|
||||
@@ -173,7 +174,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
markTaskVisible(task1)
|
||||
markTaskVisible(task2)
|
||||
|
||||
controller.showDesktopApps()
|
||||
controller.showDesktopApps(DEFAULT_DISPLAY)
|
||||
|
||||
val wct = getLatestWct(expectTransition = TRANSIT_NONE)
|
||||
assertThat(wct.hierarchyOps).hasSize(3)
|
||||
@@ -191,7 +192,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
markTaskHidden(task1)
|
||||
markTaskVisible(task2)
|
||||
|
||||
controller.showDesktopApps()
|
||||
controller.showDesktopApps(DEFAULT_DISPLAY)
|
||||
|
||||
val wct = getLatestWct(expectTransition = TRANSIT_NONE)
|
||||
assertThat(wct.hierarchyOps).hasSize(3)
|
||||
@@ -205,16 +206,34 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
fun showDesktopApps_noActiveTasks_reorderHomeToTop() {
|
||||
val homeTask = setUpHomeTask()
|
||||
|
||||
controller.showDesktopApps()
|
||||
controller.showDesktopApps(DEFAULT_DISPLAY)
|
||||
|
||||
val wct = getLatestWct(expectTransition = TRANSIT_NONE)
|
||||
assertThat(wct.hierarchyOps).hasSize(1)
|
||||
wct.assertReorderAt(index = 0, homeTask)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay() {
|
||||
val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
|
||||
val taskDefaultDisplay = setUpFreeformTask(DEFAULT_DISPLAY)
|
||||
setUpHomeTask(SECOND_DISPLAY)
|
||||
val taskSecondDisplay = setUpFreeformTask(SECOND_DISPLAY)
|
||||
markTaskHidden(taskDefaultDisplay)
|
||||
markTaskHidden(taskSecondDisplay)
|
||||
|
||||
controller.showDesktopApps(DEFAULT_DISPLAY)
|
||||
|
||||
val wct = getLatestWct(expectTransition = TRANSIT_NONE)
|
||||
assertThat(wct.hierarchyOps).hasSize(2)
|
||||
// Expect order to be from bottom: home, task
|
||||
wct.assertReorderAt(index = 0, homeTaskDefaultDisplay)
|
||||
wct.assertReorderAt(index = 1, taskDefaultDisplay)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getVisibleTaskCount_noTasks_returnsZero() {
|
||||
assertThat(controller.getVisibleTaskCount()).isEqualTo(0)
|
||||
assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -222,7 +241,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
setUpHomeTask()
|
||||
setUpFreeformTask().also(::markTaskVisible)
|
||||
setUpFreeformTask().also(::markTaskVisible)
|
||||
assertThat(controller.getVisibleTaskCount()).isEqualTo(2)
|
||||
assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -230,7 +249,15 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
setUpHomeTask()
|
||||
setUpFreeformTask().also(::markTaskVisible)
|
||||
setUpFreeformTask().also(::markTaskHidden)
|
||||
assertThat(controller.getVisibleTaskCount()).isEqualTo(1)
|
||||
assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getVisibleTaskCount_twoTasksVisibleOnDifferentDisplays_returnsOne() {
|
||||
setUpHomeTask()
|
||||
setUpFreeformTask(DEFAULT_DISPLAY).also(::markTaskVisible)
|
||||
setUpFreeformTask(SECOND_DISPLAY).also(::markTaskVisible)
|
||||
assertThat(controller.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -258,6 +285,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
controller.moveToDesktop(fullscreenTask)
|
||||
|
||||
with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
|
||||
// Operations should include home task, freeform task
|
||||
assertThat(hierarchyOps).hasSize(3)
|
||||
assertReorderSequence(homeTask, freeformTask, fullscreenTask)
|
||||
assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode)
|
||||
@@ -265,6 +293,28 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moveToDesktop_onlyFreeformTasksFromCurrentDisplayBroughtToFront() {
|
||||
setUpHomeTask(displayId = DEFAULT_DISPLAY)
|
||||
val freeformTaskDefault = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
|
||||
val fullscreenTaskDefault = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
|
||||
markTaskHidden(freeformTaskDefault)
|
||||
|
||||
val homeTaskSecond = setUpHomeTask(displayId = SECOND_DISPLAY)
|
||||
val freeformTaskSecond = setUpFreeformTask(displayId = SECOND_DISPLAY)
|
||||
markTaskHidden(freeformTaskSecond)
|
||||
|
||||
controller.moveToDesktop(fullscreenTaskDefault)
|
||||
|
||||
with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
|
||||
// Check that hierarchy operations do not include tasks from second display
|
||||
assertThat(hierarchyOps.map { it.container })
|
||||
.doesNotContain(homeTaskSecond.token.asBinder())
|
||||
assertThat(hierarchyOps.map { it.container })
|
||||
.doesNotContain(freeformTaskSecond.token.asBinder())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moveToFullscreen() {
|
||||
val task = setUpFreeformTask()
|
||||
@@ -280,6 +330,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
verifyWCTNotExecuted()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moveToFullscreen_secondDisplayTaskHasFreeform_secondDisplayNotAffected() {
|
||||
val taskDefaultDisplay = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
|
||||
val taskSecondDisplay = setUpFreeformTask(displayId = SECOND_DISPLAY)
|
||||
|
||||
controller.moveToFullscreen(taskDefaultDisplay)
|
||||
|
||||
with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
|
||||
assertThat(changes.keys).contains(taskDefaultDisplay.token.asBinder())
|
||||
assertThat(changes.keys).doesNotContain(taskSecondDisplay.token.asBinder())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getTaskWindowingMode() {
|
||||
val fullscreenTask = setUpFullscreenTask()
|
||||
@@ -323,6 +386,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleRequest_fullscreenTask_freeformTaskOnOtherDisplay_returnNull() {
|
||||
assumeTrue(ENABLE_SHELL_TRANSITIONS)
|
||||
|
||||
val fullscreenTaskDefaultDisplay = createFullscreenTask(displayId = DEFAULT_DISPLAY)
|
||||
createFreeformTask(displayId = SECOND_DISPLAY)
|
||||
|
||||
val result =
|
||||
controller.handleRequest(Binder(), createTransition(fullscreenTaskDefaultDisplay))
|
||||
assertThat(result).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleRequest_freeformTask_freeformVisible_returnNull() {
|
||||
assumeTrue(ENABLE_SHELL_TRANSITIONS)
|
||||
@@ -361,6 +436,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
.isEqualTo(WINDOWING_MODE_FULLSCREEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleRequest_freeformTask_freeformOnOtherDisplayOnly_returnSwitchToFullscreenWCT() {
|
||||
assumeTrue(ENABLE_SHELL_TRANSITIONS)
|
||||
|
||||
val taskDefaultDisplay = createFreeformTask(displayId = DEFAULT_DISPLAY)
|
||||
createFreeformTask(displayId = SECOND_DISPLAY)
|
||||
|
||||
val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay))
|
||||
assertThat(result?.changes?.get(taskDefaultDisplay.token.asBinder())?.windowingMode)
|
||||
.isEqualTo(WINDOWING_MODE_FULLSCREEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleRequest_notOpenOrToFrontTransition_returnNull() {
|
||||
assumeTrue(ENABLE_SHELL_TRANSITIONS)
|
||||
@@ -400,35 +487,43 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull()
|
||||
}
|
||||
|
||||
private fun setUpFreeformTask(): RunningTaskInfo {
|
||||
val task = createFreeformTask()
|
||||
private fun setUpFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
|
||||
val task = createFreeformTask(displayId)
|
||||
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
|
||||
desktopModeTaskRepository.addActiveTask(task.taskId)
|
||||
desktopModeTaskRepository.addActiveTask(displayId, task.taskId)
|
||||
desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId)
|
||||
runningTasks.add(task)
|
||||
return task
|
||||
}
|
||||
|
||||
private fun setUpHomeTask(): RunningTaskInfo {
|
||||
val task = createHomeTask()
|
||||
private fun setUpHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
|
||||
val task = createHomeTask(displayId)
|
||||
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
|
||||
runningTasks.add(task)
|
||||
return task
|
||||
}
|
||||
|
||||
private fun setUpFullscreenTask(): RunningTaskInfo {
|
||||
val task = createFullscreenTask()
|
||||
private fun setUpFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
|
||||
val task = createFullscreenTask(displayId)
|
||||
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
|
||||
runningTasks.add(task)
|
||||
return task
|
||||
}
|
||||
|
||||
private fun markTaskVisible(task: RunningTaskInfo) {
|
||||
desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = true)
|
||||
desktopModeTaskRepository.updateVisibleFreeformTasks(
|
||||
task.displayId,
|
||||
task.taskId,
|
||||
visible = true
|
||||
)
|
||||
}
|
||||
|
||||
private fun markTaskHidden(task: RunningTaskInfo) {
|
||||
desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = false)
|
||||
desktopModeTaskRepository.updateVisibleFreeformTasks(
|
||||
task.displayId,
|
||||
task.taskId,
|
||||
visible = false
|
||||
)
|
||||
}
|
||||
|
||||
private fun getLatestWct(
|
||||
@@ -457,6 +552,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
): TransitionRequestInfo {
|
||||
return TransitionRequestInfo(type, task, null /* remoteTransition */)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SECOND_DISPLAY = 2
|
||||
}
|
||||
}
|
||||
|
||||
private fun WindowContainerTransaction.assertReorderAt(index: Int, task: RunningTaskInfo) {
|
||||
|
||||
@@ -21,14 +21,17 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
|
||||
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
|
||||
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
|
||||
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import com.android.wm.shell.TestRunningTaskInfoBuilder
|
||||
|
||||
class DesktopTestHelpers {
|
||||
companion object {
|
||||
/** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
|
||||
@JvmStatic
|
||||
fun createFreeformTask(): RunningTaskInfo {
|
||||
@JvmOverloads
|
||||
fun createFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
|
||||
return TestRunningTaskInfoBuilder()
|
||||
.setDisplayId(displayId)
|
||||
.setToken(MockToken().token())
|
||||
.setActivityType(ACTIVITY_TYPE_STANDARD)
|
||||
.setWindowingMode(WINDOWING_MODE_FREEFORM)
|
||||
@@ -38,8 +41,10 @@ class DesktopTestHelpers {
|
||||
|
||||
/** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
|
||||
@JvmStatic
|
||||
fun createFullscreenTask(): RunningTaskInfo {
|
||||
@JvmOverloads
|
||||
fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
|
||||
return TestRunningTaskInfoBuilder()
|
||||
.setDisplayId(displayId)
|
||||
.setToken(MockToken().token())
|
||||
.setActivityType(ACTIVITY_TYPE_STANDARD)
|
||||
.setWindowingMode(WINDOWING_MODE_FULLSCREEN)
|
||||
@@ -49,8 +54,10 @@ class DesktopTestHelpers {
|
||||
|
||||
/** Create a new home task */
|
||||
@JvmStatic
|
||||
fun createHomeTask(): RunningTaskInfo {
|
||||
@JvmOverloads
|
||||
fun createHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
|
||||
return TestRunningTaskInfoBuilder()
|
||||
.setDisplayId(displayId)
|
||||
.setToken(MockToken().token())
|
||||
.setActivityType(ACTIVITY_TYPE_HOME)
|
||||
.setWindowingMode(WINDOWING_MODE_FULLSCREEN)
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.os.IBinder;
|
||||
import android.view.Display;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -347,12 +348,16 @@ public final class WMShell implements
|
||||
void initDesktopMode(DesktopMode desktopMode) {
|
||||
desktopMode.addVisibleTasksListener(
|
||||
new DesktopModeTaskRepository.VisibleTasksListener() {
|
||||
@Override
|
||||
public void onVisibilityChanged(boolean hasFreeformTasks) {
|
||||
mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, hasFreeformTasks)
|
||||
.commitUpdate(mDisplayTracker.getDefaultDisplayId());
|
||||
}
|
||||
}, mSysUiMainExecutor);
|
||||
@Override
|
||||
public void onVisibilityChanged(int displayId, boolean hasFreeformTasks) {
|
||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||
mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE,
|
||||
hasFreeformTasks)
|
||||
.commitUpdate(mDisplayTracker.getDefaultDisplayId());
|
||||
}
|
||||
// TODO(b/278084491): update sysui state for changes on other displays
|
||||
}
|
||||
}, mSysUiMainExecutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user