Clean up task stack listeners

- Have shell provided a task stack listener that various controllers can
  add to, and remove registration from outside the controllers (this
  also removes methods on the interface exposed only for use from the
  task stack listeners)
- Move copy of InputConsumerController into shell (shared lib version
  can probably be refactored into use just by launcher for gesture nav)
- Hide remaining wm components that are exposed now that all the
  features are in the Shell

Bug: 169894807
Test: atest WMShellUnitTests WMShellTest
Test: Verify Pip/Split/One handed still behaves as expected
Change-Id: If0f50f6b701ac4b013a9e41fe6f88857ea35bf5b
This commit is contained in:
Winson Chung
2020-11-04 14:17:07 -08:00
parent 327ff53a39
commit e3d75ac262
23 changed files with 1211 additions and 282 deletions

View File

@@ -0,0 +1,258 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.common;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Tests for {@link com.android.wm.shell.common.TaskStackListenerImpl}.
*/
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class TaskStackListenerImplTest {
@Mock
private IActivityTaskManager mActivityTaskManager;
@Mock
private TaskStackListenerCallback mCallback;
@Mock
private TaskStackListenerCallback mOtherCallback;
private TaskStackListenerImpl mImpl;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mImpl = new TaskStackListenerImpl(mActivityTaskManager);
mImpl.setHandler(new ProxyToListenerImplHandler(mImpl));
mImpl.addListener(mCallback);
mImpl.addListener(mOtherCallback);
}
@Test
public void testAddRemoveMultipleListeners_ExpectRegisterUnregisterOnce()
throws RemoteException {
TaskStackListenerImpl impl = new TaskStackListenerImpl(mActivityTaskManager);
impl.setHandler(new ProxyToListenerImplHandler(impl));
reset(mActivityTaskManager);
impl.addListener(mCallback);
impl.addListener(mOtherCallback);
verify(mActivityTaskManager, times(1)).registerTaskStackListener(any());
impl.removeListener(mOtherCallback);
impl.removeListener(mCallback);
verify(mActivityTaskManager, times(1)).unregisterTaskStackListener(any());
}
@Test
public void testOnRecentTaskListUpdated() {
mImpl.onRecentTaskListUpdated();
verify(mCallback).onRecentTaskListUpdated();
verify(mOtherCallback).onRecentTaskListUpdated();
}
@Test
public void testOnRecentTaskListFrozenChanged() {
mImpl.onRecentTaskListFrozenChanged(true);
verify(mCallback).onRecentTaskListFrozenChanged(eq(true));
verify(mOtherCallback).onRecentTaskListFrozenChanged(eq(true));
}
@Test
public void testOnTaskStackChanged() {
mImpl.onTaskStackChanged();
verify(mCallback).onTaskStackChangedBackground();
verify(mCallback).onTaskStackChanged();
verify(mOtherCallback).onTaskStackChangedBackground();
verify(mOtherCallback).onTaskStackChanged();
}
@Test
public void testOnTaskProfileLocked() {
mImpl.onTaskProfileLocked(1, 2);
verify(mCallback).onTaskProfileLocked(eq(1), eq(2));
verify(mOtherCallback).onTaskProfileLocked(eq(1), eq(2));
}
@Test
public void testOnTaskDisplayChanged() {
mImpl.onTaskDisplayChanged(1, 2);
verify(mCallback).onTaskDisplayChanged(eq(1), eq(2));
verify(mOtherCallback).onTaskDisplayChanged(eq(1), eq(2));
}
@Test
public void testOnTaskCreated() {
mImpl.onTaskCreated(1, new ComponentName("a", "b"));
verify(mCallback).onTaskCreated(eq(1), eq(new ComponentName("a", "b")));
verify(mOtherCallback).onTaskCreated(eq(1), eq(new ComponentName("a", "b")));
}
@Test
public void testOnTaskRemoved() {
mImpl.onTaskRemoved(123);
verify(mCallback).onTaskRemoved(eq(123));
verify(mOtherCallback).onTaskRemoved(eq(123));
}
@Test
public void testOnTaskMovedToFront() {
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
mImpl.onTaskMovedToFront(info);
verify(mCallback).onTaskMovedToFront(eq(info));
verify(mOtherCallback).onTaskMovedToFront(eq(info));
}
@Test
public void testOnTaskDescriptionChanged() {
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
mImpl.onTaskDescriptionChanged(info);
verify(mCallback).onTaskDescriptionChanged(eq(info));
verify(mOtherCallback).onTaskDescriptionChanged(eq(info));
}
@Test
public void testOnTaskSnapshotChanged() {
ActivityManager.TaskSnapshot snapshot = mock(ActivityManager.TaskSnapshot.class);
mImpl.onTaskSnapshotChanged(123, snapshot);
verify(mCallback).onTaskSnapshotChanged(eq(123), eq(snapshot));
verify(mOtherCallback).onTaskSnapshotChanged(eq(123), eq(snapshot));
}
@Test
public void testOnBackPressedOnTaskRoot() {
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
mImpl.onBackPressedOnTaskRoot(info);
verify(mCallback).onBackPressedOnTaskRoot(eq(info));
verify(mOtherCallback).onBackPressedOnTaskRoot(eq(info));
}
@Test
public void testOnActivityRestartAttempt() {
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
mImpl.onActivityRestartAttempt(info, true, true, true);
verify(mCallback).onActivityRestartAttempt(eq(info), eq(true), eq(true), eq(true));
verify(mOtherCallback).onActivityRestartAttempt(eq(info), eq(true), eq(true), eq(true));
}
@Test
public void testOnActivityPinned() {
mImpl.onActivityPinned("abc", 1, 2, 3);
verify(mCallback).onActivityPinned(eq("abc"), eq(1), eq(2), eq(3));
verify(mOtherCallback).onActivityPinned(eq("abc"), eq(1), eq(2), eq(3));
}
@Test
public void testOnActivityUnpinned() {
mImpl.onActivityUnpinned();
verify(mCallback).onActivityUnpinned();
verify(mOtherCallback).onActivityUnpinned();
}
@Test
public void testOnActivityForcedResizable() {
mImpl.onActivityForcedResizable("abc", 1, 2);
verify(mCallback).onActivityForcedResizable(eq("abc"), eq(1), eq(2));
verify(mOtherCallback).onActivityForcedResizable(eq("abc"), eq(1), eq(2));
}
@Test
public void testOnActivityDismissingDockedStack() {
mImpl.onActivityDismissingDockedStack();
verify(mCallback).onActivityDismissingDockedStack();
verify(mOtherCallback).onActivityDismissingDockedStack();
}
@Test
public void testOnActivityLaunchOnSecondaryDisplayFailed() {
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
mImpl.onActivityLaunchOnSecondaryDisplayFailed(info, 1);
verify(mCallback).onActivityLaunchOnSecondaryDisplayFailed(eq(info));
verify(mOtherCallback).onActivityLaunchOnSecondaryDisplayFailed(eq(info));
}
@Test
public void testOnActivityLaunchOnSecondaryDisplayRerouted() {
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
mImpl.onActivityLaunchOnSecondaryDisplayRerouted(info, 1);
verify(mCallback).onActivityLaunchOnSecondaryDisplayRerouted(eq(info));
verify(mOtherCallback).onActivityLaunchOnSecondaryDisplayRerouted(eq(info));
}
@Test
public void testOnActivityRequestedOrientationChanged() {
mImpl.onActivityRequestedOrientationChanged(1, 2);
verify(mCallback).onActivityRequestedOrientationChanged(eq(1), eq(2));
verify(mOtherCallback).onActivityRequestedOrientationChanged(eq(1), eq(2));
}
@Test
public void testOnActivityRotation() {
mImpl.onActivityRotation(123);
verify(mCallback).onActivityRotation(eq(123));
verify(mOtherCallback).onActivityRotation(eq(123));
}
@Test
public void testOnSizeCompatModeActivityChanged() {
IBinder b = mock(IBinder.class);
mImpl.onSizeCompatModeActivityChanged(123, b);
verify(mCallback).onSizeCompatModeActivityChanged(eq(123), eq(b));
verify(mOtherCallback).onSizeCompatModeActivityChanged(eq(123), eq(b));
}
/**
* Handler that synchronously calls TaskStackListenerImpl#handleMessage() when it receives a
* message.
*/
private class ProxyToListenerImplHandler extends Handler {
public ProxyToListenerImplHandler(Callback callback) {
super(callback);
}
@Override
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
return mImpl.handleMessage(msg);
}
}
}

View File

@@ -33,6 +33,7 @@ import android.view.Display;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.Before;
import org.junit.Ignore;
@@ -64,6 +65,8 @@ public class OneHandedControllerTest extends OneHandedTestCase {
OneHandedTimeoutHandler mMockTimeoutHandler;
@Mock
IOverlayManager mMockOverlayManager;
@Mock
TaskStackListenerImpl mMockTaskStackListener;
@Before
public void setUp() throws Exception {
@@ -76,7 +79,8 @@ public class OneHandedControllerTest extends OneHandedTestCase {
mMockTouchHandler,
mMockTutorialHandler,
mMockGestureHandler,
mMockOverlayManager);
mMockOverlayManager,
mMockTaskStackListener);
mOneHandedController = Mockito.spy(oneHandedController);
mTimeoutHandler = Mockito.spy(OneHandedTimeoutHandler.get());

View File

@@ -25,6 +25,7 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.Before;
import org.junit.Test;
@@ -47,6 +48,8 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
@Mock
IOverlayManager mMockOverlayManager;
@Mock
TaskStackListenerImpl mMockTaskStackListener;
@Before
public void setUp() {
@@ -60,7 +63,8 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
mTouchHandler,
mTutorialHandler,
mGestureHandler,
mMockOverlayManager);
mMockOverlayManager,
mMockTaskStackListener);
}
@Test

View File

@@ -39,6 +39,7 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
@@ -68,6 +69,7 @@ public class PipControllerTest extends ShellTestCase {
@Mock private PipTouchHandler mMockPipTouchHandler;
@Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper;
@Mock private PipBoundsState mMockPipBoundsState;
@Mock private TaskStackListenerImpl mMockTaskStackListener;
@Mock private ShellExecutor mMockExecutor;
@Before
@@ -76,7 +78,8 @@ public class PipControllerTest extends ShellTestCase {
mPipController = new PipController(mContext, mMockDisplayController,
mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState,
mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer,
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor);
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockTaskStackListener,
mMockExecutor);
doAnswer(invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
@@ -108,7 +111,8 @@ public class PipControllerTest extends ShellTestCase {
assertNull(PipController.create(spyContext, mMockDisplayController,
mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState,
mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer,
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor));
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockTaskStackListener,
mMockExecutor));
}
@Test