Merge "Track visible tasks in DesktopModeController and add a listener" into tm-qpr-dev am: 731095e5cf

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19957743

Change-Id: Icfd2f80f0eaf4aec3771a39e17f19d7e0f8924d0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Mady Mellor
2022-10-24 17:21:45 +00:00
committed by Automerger Merge Worker
9 changed files with 210 additions and 22 deletions

View File

@@ -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);
} }

View File

@@ -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);
});
}
} }
/** /**

View File

@@ -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) {}
} }
} }

View File

@@ -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));
} }
} }

View File

@@ -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));
} }
/** /**

View File

@@ -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++
}
}
} }

View File

@@ -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();
} }

View File

@@ -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) {

View File

@@ -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));
}
} }