Merge "Track visible tasks in DesktopModeController and add a listener" into tm-qpr-dev
This commit is contained in:
@@ -18,9 +18,21 @@ package com.android.wm.shell.desktopmode;
|
|||||||
|
|
||||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to interact with desktop mode feature in shell.
|
* Interface to interact with desktop mode feature in shell.
|
||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
public interface DesktopMode {
|
public interface DesktopMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a listener to find out about changes in the visibility of freeform tasks.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
* @param callbackExecutor the executor to call the listener on.
|
||||||
|
*/
|
||||||
|
void addListener(DesktopModeTaskRepository.VisibleTasksListener listener,
|
||||||
|
Executor callbackExecutor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.android.wm.shell.transition.Transitions;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles windowing changes when desktop mode system setting changes
|
* Handles windowing changes when desktop mode system setting changes
|
||||||
@@ -132,6 +133,17 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
return new IDesktopModeImpl(this);
|
return new IDesktopModeImpl(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a listener to find out about changes in the visibility of freeform tasks.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
* @param callbackExecutor the executor to call the listener on.
|
||||||
|
*/
|
||||||
|
public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener,
|
||||||
|
Executor callbackExecutor) {
|
||||||
|
mDesktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void updateDesktopModeActive(boolean active) {
|
void updateDesktopModeActive(boolean active) {
|
||||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active);
|
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active);
|
||||||
@@ -293,7 +305,14 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private final class DesktopModeImpl implements DesktopMode {
|
private final class DesktopModeImpl implements DesktopMode {
|
||||||
// Do nothing
|
|
||||||
|
@Override
|
||||||
|
public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener,
|
||||||
|
Executor callbackExecutor) {
|
||||||
|
mMainExecutor.execute(() -> {
|
||||||
|
DesktopModeController.this.addListener(listener, callbackExecutor);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.desktopmode
|
package com.android.wm.shell.desktopmode
|
||||||
|
|
||||||
|
import android.util.ArrayMap
|
||||||
import android.util.ArraySet
|
import android.util.ArraySet
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track of task data related to desktop mode.
|
* Keeps track of task data related to desktop mode.
|
||||||
@@ -30,20 +32,39 @@ class DesktopModeTaskRepository {
|
|||||||
* Task gets removed from this list when it vanishes. Or when desktop mode is turned off.
|
* Task gets removed from this list when it vanishes. Or when desktop mode is turned off.
|
||||||
*/
|
*/
|
||||||
private val activeTasks = ArraySet<Int>()
|
private val activeTasks = ArraySet<Int>()
|
||||||
private val listeners = ArraySet<Listener>()
|
private val visibleTasks = ArraySet<Int>()
|
||||||
|
private val activeTasksListeners = ArraySet<ActiveTasksListener>()
|
||||||
|
// Track visible tasks separately because a task may be part of the desktop but not visible.
|
||||||
|
private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a [Listener] to be notified of updates to the repository.
|
* Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository.
|
||||||
*/
|
*/
|
||||||
fun addListener(listener: Listener) {
|
fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) {
|
||||||
listeners.add(listener)
|
activeTasksListeners.add(activeTasksListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a previously registered [Listener]
|
* Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not.
|
||||||
*/
|
*/
|
||||||
fun removeListener(listener: Listener) {
|
fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) {
|
||||||
listeners.remove(listener)
|
visibleTasksListeners.put(visibleTasksListener, executor)
|
||||||
|
executor.execute(
|
||||||
|
Runnable { visibleTasksListener.onVisibilityChanged(visibleTasks.size > 0) })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a previously registered [ActiveTasksListener]
|
||||||
|
*/
|
||||||
|
fun removeActiveTasksListener(activeTasksListener: ActiveTasksListener) {
|
||||||
|
activeTasksListeners.remove(activeTasksListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a previously registered [VisibleTasksListener]
|
||||||
|
*/
|
||||||
|
fun removeVisibleTasksListener(visibleTasksListener: VisibleTasksListener) {
|
||||||
|
visibleTasksListeners.remove(visibleTasksListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,7 +73,7 @@ class DesktopModeTaskRepository {
|
|||||||
fun addActiveTask(taskId: Int) {
|
fun addActiveTask(taskId: Int) {
|
||||||
val added = activeTasks.add(taskId)
|
val added = activeTasks.add(taskId)
|
||||||
if (added) {
|
if (added) {
|
||||||
listeners.onEach { it.onActiveTasksChanged() }
|
activeTasksListeners.onEach { it.onActiveTasksChanged() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +83,7 @@ class DesktopModeTaskRepository {
|
|||||||
fun removeActiveTask(taskId: Int) {
|
fun removeActiveTask(taskId: Int) {
|
||||||
val removed = activeTasks.remove(taskId)
|
val removed = activeTasks.remove(taskId)
|
||||||
if (removed) {
|
if (removed) {
|
||||||
listeners.onEach { it.onActiveTasksChanged() }
|
activeTasksListeners.onEach { it.onActiveTasksChanged() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,9 +102,43 @@ class DesktopModeTaskRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines interface for classes that can listen to changes in repository state.
|
* Updates whether a freeform task with this id is visible or not and notifies listeners.
|
||||||
*/
|
*/
|
||||||
interface Listener {
|
fun updateVisibleFreeformTasks(taskId: Int, visible: Boolean) {
|
||||||
fun onActiveTasksChanged()
|
val prevCount: Int = visibleTasks.size
|
||||||
|
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) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines interface for classes that can listen to changes for active tasks in desktop mode.
|
||||||
|
*/
|
||||||
|
interface ActiveTasksListener {
|
||||||
|
/**
|
||||||
|
* Called when the active tasks change in desktop mode.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun onActiveTasksChanged() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines interface for classes that can listen to changes for visible tasks in desktop mode.
|
||||||
|
*/
|
||||||
|
interface VisibleTasksListener {
|
||||||
|
/**
|
||||||
|
* Called when the desktop starts or stops showing freeform tasks.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun onVisibilityChanged(hasVisibleFreeformTasks: Boolean) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
|
|||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
||||||
"Adding active freeform task: #%d", taskInfo.taskId);
|
"Adding active freeform task: #%d", taskInfo.taskId);
|
||||||
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId));
|
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId));
|
||||||
|
mDesktopModeTaskRepository.ifPresent(
|
||||||
|
it -> it.updateVisibleFreeformTasks(taskInfo.taskId, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +105,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
|
|||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
|
||||||
"Removing active freeform task: #%d", taskInfo.taskId);
|
"Removing active freeform task: #%d", taskInfo.taskId);
|
||||||
mDesktopModeTaskRepository.ifPresent(it -> it.removeActiveTask(taskInfo.taskId));
|
mDesktopModeTaskRepository.ifPresent(it -> it.removeActiveTask(taskInfo.taskId));
|
||||||
|
mDesktopModeTaskRepository.ifPresent(
|
||||||
|
it -> it.updateVisibleFreeformTasks(taskInfo.taskId, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
|
if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||||
@@ -124,6 +128,8 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
|
|||||||
"Adding active freeform task: #%d", taskInfo.taskId);
|
"Adding active freeform task: #%d", taskInfo.taskId);
|
||||||
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId));
|
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId));
|
||||||
}
|
}
|
||||||
|
mDesktopModeTaskRepository.ifPresent(
|
||||||
|
it -> it.updateVisibleFreeformTasks(taskInfo.taskId, taskInfo.isVisible));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ import java.util.function.Consumer;
|
|||||||
* Manages the recent task list from the system, caching it as necessary.
|
* Manages the recent task list from the system, caching it as necessary.
|
||||||
*/
|
*/
|
||||||
public class RecentTasksController implements TaskStackListenerCallback,
|
public class RecentTasksController implements TaskStackListenerCallback,
|
||||||
RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.Listener {
|
RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.ActiveTasksListener {
|
||||||
private static final String TAG = RecentTasksController.class.getSimpleName();
|
private static final String TAG = RecentTasksController.class.getSimpleName();
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -147,7 +147,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
this::createExternalInterface, this);
|
this::createExternalInterface, this);
|
||||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||||
mTaskStackListener.addListener(this);
|
mTaskStackListener.addListener(this);
|
||||||
mDesktopModeTaskRepository.ifPresent(it -> it.addListener(this));
|
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTaskListener(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.wm.shell.desktopmode
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.wm.shell.ShellTestCase
|
import com.android.wm.shell.ShellTestCase
|
||||||
|
import com.android.wm.shell.TestShellExecutor
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -38,7 +39,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun addActiveTask_listenerNotifiedAndTaskIsActive() {
|
fun addActiveTask_listenerNotifiedAndTaskIsActive() {
|
||||||
val listener = TestListener()
|
val listener = TestListener()
|
||||||
repo.addListener(listener)
|
repo.addActiveTaskListener(listener)
|
||||||
|
|
||||||
repo.addActiveTask(1)
|
repo.addActiveTask(1)
|
||||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
|
assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
|
||||||
@@ -48,7 +49,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun addActiveTask_sameTaskDoesNotNotify() {
|
fun addActiveTask_sameTaskDoesNotNotify() {
|
||||||
val listener = TestListener()
|
val listener = TestListener()
|
||||||
repo.addListener(listener)
|
repo.addActiveTaskListener(listener)
|
||||||
|
|
||||||
repo.addActiveTask(1)
|
repo.addActiveTask(1)
|
||||||
repo.addActiveTask(1)
|
repo.addActiveTask(1)
|
||||||
@@ -58,7 +59,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun addActiveTask_multipleTasksAddedNotifiesForEach() {
|
fun addActiveTask_multipleTasksAddedNotifiesForEach() {
|
||||||
val listener = TestListener()
|
val listener = TestListener()
|
||||||
repo.addListener(listener)
|
repo.addActiveTaskListener(listener)
|
||||||
|
|
||||||
repo.addActiveTask(1)
|
repo.addActiveTask(1)
|
||||||
repo.addActiveTask(2)
|
repo.addActiveTask(2)
|
||||||
@@ -68,7 +69,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun removeActiveTask_listenerNotifiedAndTaskNotActive() {
|
fun removeActiveTask_listenerNotifiedAndTaskNotActive() {
|
||||||
val listener = TestListener()
|
val listener = TestListener()
|
||||||
repo.addListener(listener)
|
repo.addActiveTaskListener(listener)
|
||||||
|
|
||||||
repo.addActiveTask(1)
|
repo.addActiveTask(1)
|
||||||
repo.removeActiveTask(1)
|
repo.removeActiveTask(1)
|
||||||
@@ -80,7 +81,7 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun removeActiveTask_removeNotExistingTaskDoesNotNotify() {
|
fun removeActiveTask_removeNotExistingTaskDoesNotNotify() {
|
||||||
val listener = TestListener()
|
val listener = TestListener()
|
||||||
repo.addListener(listener)
|
repo.addActiveTaskListener(listener)
|
||||||
repo.removeActiveTask(99)
|
repo.removeActiveTask(99)
|
||||||
assertThat(listener.activeTaskChangedCalls).isEqualTo(0)
|
assertThat(listener.activeTaskChangedCalls).isEqualTo(0)
|
||||||
}
|
}
|
||||||
@@ -90,10 +91,69 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() {
|
|||||||
assertThat(repo.isActiveTask(99)).isFalse()
|
assertThat(repo.isActiveTask(99)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestListener : DesktopModeTaskRepository.Listener {
|
@Test
|
||||||
|
fun addListener_notifiesVisibleFreeformTask() {
|
||||||
|
repo.updateVisibleFreeformTasks(1, true)
|
||||||
|
val listener = TestVisibilityListener()
|
||||||
|
val executor = TestShellExecutor()
|
||||||
|
repo.addVisibleTasksListener(listener, executor)
|
||||||
|
executor.flushAll()
|
||||||
|
|
||||||
|
assertThat(listener.hasVisibleFreeformTasks).isTrue()
|
||||||
|
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateVisibleFreeformTasks_addVisibleTasksNotifiesListener() {
|
||||||
|
val listener = TestVisibilityListener()
|
||||||
|
val executor = TestShellExecutor()
|
||||||
|
repo.addVisibleTasksListener(listener, executor)
|
||||||
|
repo.updateVisibleFreeformTasks(1, true)
|
||||||
|
repo.updateVisibleFreeformTasks(2, true)
|
||||||
|
executor.flushAll()
|
||||||
|
|
||||||
|
assertThat(listener.hasVisibleFreeformTasks).isTrue()
|
||||||
|
// Equal to 2 because adding the listener notifies the current state
|
||||||
|
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateVisibleFreeformTasks_removeVisibleTasksNotifiesListener() {
|
||||||
|
val listener = TestVisibilityListener()
|
||||||
|
val executor = TestShellExecutor()
|
||||||
|
repo.addVisibleTasksListener(listener, executor)
|
||||||
|
repo.updateVisibleFreeformTasks(1, true)
|
||||||
|
repo.updateVisibleFreeformTasks(2, true)
|
||||||
|
executor.flushAll()
|
||||||
|
|
||||||
|
assertThat(listener.hasVisibleFreeformTasks).isTrue()
|
||||||
|
repo.updateVisibleFreeformTasks(1, false)
|
||||||
|
executor.flushAll()
|
||||||
|
|
||||||
|
// Equal to 2 because adding the listener notifies the current state
|
||||||
|
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(2)
|
||||||
|
|
||||||
|
repo.updateVisibleFreeformTasks(2, false)
|
||||||
|
executor.flushAll()
|
||||||
|
|
||||||
|
assertThat(listener.hasVisibleFreeformTasks).isFalse()
|
||||||
|
assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestListener : DesktopModeTaskRepository.ActiveTasksListener {
|
||||||
var activeTaskChangedCalls = 0
|
var activeTaskChangedCalls = 0
|
||||||
override fun onActiveTasksChanged() {
|
override fun onActiveTasksChanged() {
|
||||||
activeTaskChangedCalls++
|
activeTaskChangedCalls++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestVisibilityListener : DesktopModeTaskRepository.VisibleTasksListener {
|
||||||
|
var hasVisibleFreeformTasks = false
|
||||||
|
var visibleFreeformTaskChangedCalls = 0
|
||||||
|
|
||||||
|
override fun onVisibilityChanged(hasVisibleTasks: Boolean) {
|
||||||
|
hasVisibleFreeformTasks = hasVisibleTasks
|
||||||
|
visibleFreeformTaskChangedCalls++
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,9 @@ public class QuickStepContract {
|
|||||||
public static final int SYSUI_STATE_IMMERSIVE_MODE = 1 << 24;
|
public static final int SYSUI_STATE_IMMERSIVE_MODE = 1 << 24;
|
||||||
// The voice interaction session window is showing
|
// The voice interaction session window is showing
|
||||||
public static final int SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 25;
|
public static final int SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 25;
|
||||||
|
// Freeform windows are showing in desktop mode
|
||||||
|
public static final int SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE = 1 << 26;
|
||||||
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({SYSUI_STATE_SCREEN_PINNING,
|
@IntDef({SYSUI_STATE_SCREEN_PINNING,
|
||||||
@@ -137,7 +140,8 @@ public class QuickStepContract {
|
|||||||
SYSUI_STATE_BACK_DISABLED,
|
SYSUI_STATE_BACK_DISABLED,
|
||||||
SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED,
|
SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED,
|
||||||
SYSUI_STATE_IMMERSIVE_MODE,
|
SYSUI_STATE_IMMERSIVE_MODE,
|
||||||
SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING
|
SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING,
|
||||||
|
SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE
|
||||||
})
|
})
|
||||||
public @interface SystemUiStateFlags {}
|
public @interface SystemUiStateFlags {}
|
||||||
|
|
||||||
@@ -173,6 +177,8 @@ public class QuickStepContract {
|
|||||||
? "bubbles_mange_menu_expanded" : "");
|
? "bubbles_mange_menu_expanded" : "");
|
||||||
str.add((flags & SYSUI_STATE_IMMERSIVE_MODE) != 0 ? "immersive_mode" : "");
|
str.add((flags & SYSUI_STATE_IMMERSIVE_MODE) != 0 ? "immersive_mode" : "");
|
||||||
str.add((flags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0 ? "vis_win_showing" : "");
|
str.add((flags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0 ? "vis_win_showing" : "");
|
||||||
|
str.add((flags & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0
|
||||||
|
? "freeform_active_in_desktop_mode" : "");
|
||||||
return str.toString();
|
return str.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_B
|
|||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
|
||||||
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
||||||
@@ -55,6 +56,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.tracing.ProtoTracer;
|
import com.android.systemui.tracing.ProtoTracer;
|
||||||
import com.android.systemui.tracing.nano.SystemUiTraceProto;
|
import com.android.systemui.tracing.nano.SystemUiTraceProto;
|
||||||
|
import com.android.wm.shell.desktopmode.DesktopMode;
|
||||||
|
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
||||||
import com.android.wm.shell.floating.FloatingTasks;
|
import com.android.wm.shell.floating.FloatingTasks;
|
||||||
import com.android.wm.shell.nano.WmShellTraceProto;
|
import com.android.wm.shell.nano.WmShellTraceProto;
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
import com.android.wm.shell.onehanded.OneHanded;
|
||||||
@@ -111,6 +114,7 @@ public final class WMShell implements
|
|||||||
private final Optional<SplitScreen> mSplitScreenOptional;
|
private final Optional<SplitScreen> mSplitScreenOptional;
|
||||||
private final Optional<OneHanded> mOneHandedOptional;
|
private final Optional<OneHanded> mOneHandedOptional;
|
||||||
private final Optional<FloatingTasks> mFloatingTasksOptional;
|
private final Optional<FloatingTasks> mFloatingTasksOptional;
|
||||||
|
private final Optional<DesktopMode> mDesktopModeOptional;
|
||||||
|
|
||||||
private final CommandQueue mCommandQueue;
|
private final CommandQueue mCommandQueue;
|
||||||
private final ConfigurationController mConfigurationController;
|
private final ConfigurationController mConfigurationController;
|
||||||
@@ -173,6 +177,7 @@ public final class WMShell implements
|
|||||||
Optional<SplitScreen> splitScreenOptional,
|
Optional<SplitScreen> splitScreenOptional,
|
||||||
Optional<OneHanded> oneHandedOptional,
|
Optional<OneHanded> oneHandedOptional,
|
||||||
Optional<FloatingTasks> floatingTasksOptional,
|
Optional<FloatingTasks> floatingTasksOptional,
|
||||||
|
Optional<DesktopMode> desktopMode,
|
||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
ConfigurationController configurationController,
|
ConfigurationController configurationController,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
@@ -194,6 +199,7 @@ public final class WMShell implements
|
|||||||
mPipOptional = pipOptional;
|
mPipOptional = pipOptional;
|
||||||
mSplitScreenOptional = splitScreenOptional;
|
mSplitScreenOptional = splitScreenOptional;
|
||||||
mOneHandedOptional = oneHandedOptional;
|
mOneHandedOptional = oneHandedOptional;
|
||||||
|
mDesktopModeOptional = desktopMode;
|
||||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||||
mProtoTracer = protoTracer;
|
mProtoTracer = protoTracer;
|
||||||
mUserTracker = userTracker;
|
mUserTracker = userTracker;
|
||||||
@@ -219,6 +225,7 @@ public final class WMShell implements
|
|||||||
mPipOptional.ifPresent(this::initPip);
|
mPipOptional.ifPresent(this::initPip);
|
||||||
mSplitScreenOptional.ifPresent(this::initSplitScreen);
|
mSplitScreenOptional.ifPresent(this::initSplitScreen);
|
||||||
mOneHandedOptional.ifPresent(this::initOneHanded);
|
mOneHandedOptional.ifPresent(this::initOneHanded);
|
||||||
|
mDesktopModeOptional.ifPresent(this::initDesktopMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -326,6 +333,16 @@ public final class WMShell implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initDesktopMode(DesktopMode desktopMode) {
|
||||||
|
desktopMode.addListener(new DesktopModeTaskRepository.VisibleTasksListener() {
|
||||||
|
@Override
|
||||||
|
public void onVisibilityChanged(boolean hasFreeformTasks) {
|
||||||
|
mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, hasFreeformTasks)
|
||||||
|
.commitUpdate(DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
}, mSysUiMainExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToProto(SystemUiTraceProto proto) {
|
public void writeToProto(SystemUiTraceProto proto) {
|
||||||
if (proto.wmShell == null) {
|
if (proto.wmShell == null) {
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.tracing.ProtoTracer;
|
import com.android.systemui.tracing.ProtoTracer;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
|
import com.android.wm.shell.desktopmode.DesktopMode;
|
||||||
|
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
||||||
import com.android.wm.shell.floating.FloatingTasks;
|
import com.android.wm.shell.floating.FloatingTasks;
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
import com.android.wm.shell.onehanded.OneHanded;
|
||||||
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
||||||
@@ -49,6 +51,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link WMShell}.
|
* Tests for {@link WMShell}.
|
||||||
@@ -76,12 +79,14 @@ public class WMShellTest extends SysuiTestCase {
|
|||||||
@Mock UserTracker mUserTracker;
|
@Mock UserTracker mUserTracker;
|
||||||
@Mock ShellExecutor mSysUiMainExecutor;
|
@Mock ShellExecutor mSysUiMainExecutor;
|
||||||
@Mock FloatingTasks mFloatingTasks;
|
@Mock FloatingTasks mFloatingTasks;
|
||||||
|
@Mock DesktopMode mDesktopMode;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip),
|
mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip),
|
||||||
Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mFloatingTasks),
|
Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mFloatingTasks),
|
||||||
|
Optional.of(mDesktopMode),
|
||||||
mCommandQueue, mConfigurationController, mKeyguardStateController,
|
mCommandQueue, mConfigurationController, mKeyguardStateController,
|
||||||
mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState, mProtoTracer,
|
mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState, mProtoTracer,
|
||||||
mWakefulnessLifecycle, mUserTracker, mSysUiMainExecutor);
|
mWakefulnessLifecycle, mUserTracker, mSysUiMainExecutor);
|
||||||
@@ -103,4 +108,12 @@ public class WMShellTest extends SysuiTestCase {
|
|||||||
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
|
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
|
||||||
verify(mOneHanded).registerEventCallback(any(OneHandedEventCallback.class));
|
verify(mOneHanded).registerEventCallback(any(OneHandedEventCallback.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initDesktopMode_registersListener() {
|
||||||
|
mWMShell.initDesktopMode(mDesktopMode);
|
||||||
|
verify(mDesktopMode).addListener(
|
||||||
|
any(DesktopModeTaskRepository.VisibleTasksListener.class),
|
||||||
|
any(Executor.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user