Allow non-resizable apps in split-screen (7/n)
Add interface for SizeCompatUIController in WM shell to use when refactoring SizeCompatModeActivityController from system UI. Bug: 176061101 Bug: 178327644 Test: atest WMShellUnitTests:ShellTaskOrganizerTests Change-Id: I37f72396e1769b7773722be6575506fc430b2739
This commit is contained in:
@@ -336,6 +336,23 @@ public class TaskInfo {
|
||||
&& isVisible == that.isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if parameters that are important for size compat have changed.
|
||||
* @hide
|
||||
*/
|
||||
public boolean equalsForSizeCompat(@Nullable TaskInfo that) {
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
return displayId == that.displayId
|
||||
&& taskId == that.taskId
|
||||
&& topActivityInSizeCompat == that.topActivityInSizeCompat
|
||||
// TopActivityToken and bounds are important if top activity is in size compat
|
||||
&& (!topActivityInSizeCompat || topActivityToken.equals(that.topActivityToken))
|
||||
&& (!topActivityInSizeCompat || configuration.windowConfiguration.getBounds()
|
||||
.equals(that.configuration.windowConfiguration.getBounds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the TaskInfo from a parcel.
|
||||
*/
|
||||
|
||||
@@ -106,5 +106,4 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
public String toString() {
|
||||
return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import androidx.annotation.Nullable;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.sizecompatui.SizeCompatUI;
|
||||
import com.android.wm.shell.startingsurface.StartingSurfaceDrawer;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -102,18 +103,31 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
private final Object mLock = new Object();
|
||||
private final StartingSurfaceDrawer mStartingSurfaceDrawer;
|
||||
|
||||
/**
|
||||
* In charge of showing size compat UI. Can be {@code null} if device doesn't support size
|
||||
* compat.
|
||||
*/
|
||||
@Nullable
|
||||
private final SizeCompatUI mSizeCompatUI;
|
||||
|
||||
public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context) {
|
||||
this(null, mainExecutor, context);
|
||||
this(null /* taskOrganizerController */, mainExecutor, context, null /* sizeCompatUI */);
|
||||
}
|
||||
|
||||
public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context, @Nullable
|
||||
SizeCompatUI sizeCompatUI) {
|
||||
this(null /* taskOrganizerController */, mainExecutor, context, sizeCompatUI);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController, ShellExecutor mainExecutor,
|
||||
Context context) {
|
||||
Context context, @Nullable SizeCompatUI sizeCompatUI) {
|
||||
super(taskOrganizerController, mainExecutor);
|
||||
// TODO(b/131727939) temporarily live here, the starting surface drawer should be controlled
|
||||
// by a controller, that class should be create while porting
|
||||
// ActivityRecord#addStartingWindow to WMShell.
|
||||
mStartingSurfaceDrawer = new StartingSurfaceDrawer(context, mainExecutor);
|
||||
mSizeCompatUI = sizeCompatUI;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,6 +269,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
if (listener != null) {
|
||||
listener.onTaskAppeared(info.getTaskInfo(), info.getLeash());
|
||||
}
|
||||
notifySizeCompatUI(info.getTaskInfo(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -270,6 +285,10 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
if (!updated && newListener != null) {
|
||||
newListener.onTaskInfoChanged(taskInfo);
|
||||
}
|
||||
if (updated || !taskInfo.equalsForSizeCompat(data.getTaskInfo())) {
|
||||
// Notify the size compat UI if the listener or task info changed.
|
||||
notifySizeCompatUI(taskInfo, newListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,6 +313,8 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
if (listener != null) {
|
||||
listener.onTaskVanished(taskInfo);
|
||||
}
|
||||
// Pass null for listener to remove the size compat UI on this task if there is any.
|
||||
notifySizeCompatUI(taskInfo, null /* taskListener */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,6 +341,34 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies {@link SizeCompatUI} about the size compat info changed on the give Task to update
|
||||
* the UI accordingly.
|
||||
*
|
||||
* @param taskInfo the new Task info
|
||||
* @param taskListener listener to handle the Task Surface placement. {@code null} if task is
|
||||
* vanished.
|
||||
*/
|
||||
private void notifySizeCompatUI(RunningTaskInfo taskInfo, @Nullable TaskListener taskListener) {
|
||||
if (mSizeCompatUI == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The task is vanished, notify to remove size compat UI on this Task if there is any.
|
||||
if (taskListener == null) {
|
||||
mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId,
|
||||
null /* taskConfig */, null /* sizeCompatActivity*/,
|
||||
null /* taskListener */);
|
||||
return;
|
||||
}
|
||||
|
||||
mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId,
|
||||
taskInfo.configuration.windowConfiguration.getBounds(),
|
||||
// null if the top activity not in size compat.
|
||||
taskInfo.topActivityInSizeCompat ? taskInfo.topActivityToken : null,
|
||||
taskListener);
|
||||
}
|
||||
|
||||
private TaskListener getTaskListener(RunningTaskInfo runningTaskInfo) {
|
||||
return getTaskListener(runningTaskInfo, false /*removeLaunchCookieIfNeeded*/);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,14 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchVisibilityChanged(int displayId, boolean isShowing) {
|
||||
synchronized (mPositionProcessors) {
|
||||
for (ImePositionProcessor pp : mPositionProcessors) {
|
||||
pp.onImeVisibilityChanged(displayId, isShowing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an {@link ImePositionProcessor} to be called during ime position updates.
|
||||
*/
|
||||
@@ -212,7 +220,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
|
||||
return;
|
||||
}
|
||||
|
||||
mImeShowing = insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME);
|
||||
updateImeVisibility(insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME));
|
||||
|
||||
final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
|
||||
final Rect newFrame = newSource.getFrame();
|
||||
@@ -371,7 +379,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
|
||||
seek = true;
|
||||
}
|
||||
mAnimationDirection = show ? DIRECTION_SHOW : DIRECTION_HIDE;
|
||||
mImeShowing = show;
|
||||
updateImeVisibility(show);
|
||||
mAnimation = ValueAnimator.ofFloat(startY, endY);
|
||||
mAnimation.setDuration(
|
||||
show ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS);
|
||||
@@ -455,6 +463,13 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
|
||||
}
|
||||
}
|
||||
|
||||
private void updateImeVisibility(boolean isShowing) {
|
||||
if (mImeShowing != isShowing) {
|
||||
mImeShowing = isShowing;
|
||||
dispatchVisibilityChanged(mDisplayId, isShowing);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@BinderThread
|
||||
public class DisplayWindowInsetsControllerImpl
|
||||
@@ -563,6 +578,15 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
|
||||
default void onImeEndPositioning(int displayId, boolean cancel,
|
||||
SurfaceControl.Transaction t) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IME visibility changed.
|
||||
*
|
||||
* @param isShowing {@code true} if the IME is shown.
|
||||
*/
|
||||
default void onImeVisibilityChanged(int displayId, boolean isShowing) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public IInputMethodManager getImms() {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.sizecompatui;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||
|
||||
/**
|
||||
* Interface to engage size compat mode UI.
|
||||
*/
|
||||
@ExternalThread
|
||||
public interface SizeCompatUI {
|
||||
/**
|
||||
* Called when the Task info changed. Creates and updates the restart button if there is an
|
||||
* activity in size compat, or removes the restart button if there is no size compat activity.
|
||||
*
|
||||
* @param displayId display the task and activity are in.
|
||||
* @param taskId task the activity is in.
|
||||
* @param taskBounds task bounds to place the restart button in.
|
||||
* @param sizeCompatActivity the size compat activity in the task. Can be {@code null} if the
|
||||
* top activity in this Task is not in size compat.
|
||||
* @param taskListener listener to handle the Task Surface placement.
|
||||
*/
|
||||
void onSizeCompatInfoChanged(int displayId, int taskId, @Nullable Rect taskBounds,
|
||||
@Nullable IBinder sizeCompatActivity,
|
||||
@Nullable ShellTaskOrganizer.TaskListener taskListener);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.sizecompatui;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayImeController;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
|
||||
/**
|
||||
* Shows a restart-activity button on Task when the foreground activity is in size compatibility
|
||||
* mode.
|
||||
*/
|
||||
public class SizeCompatUIController implements DisplayController.OnDisplaysChangedListener,
|
||||
DisplayImeController.ImePositionProcessor {
|
||||
private static final String TAG = "SizeCompatUI";
|
||||
|
||||
@VisibleForTesting
|
||||
final SizeCompatUI mImpl = new SizeCompatUIImpl();
|
||||
private final Context mContext;
|
||||
private final ShellExecutor mMainExecutor;
|
||||
private final DisplayController mDisplayController;
|
||||
private final DisplayImeController mImeController;
|
||||
|
||||
/** Creates the {@link SizeCompatUIController}. */
|
||||
public static SizeCompatUI create(Context context,
|
||||
DisplayController displayController,
|
||||
DisplayImeController imeController,
|
||||
ShellExecutor mainExecutor) {
|
||||
return new SizeCompatUIController(context, displayController, imeController, mainExecutor)
|
||||
.mImpl;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SizeCompatUIController(Context context,
|
||||
DisplayController displayController,
|
||||
DisplayImeController imeController,
|
||||
ShellExecutor mainExecutor) {
|
||||
mContext = context;
|
||||
mMainExecutor = mainExecutor;
|
||||
mDisplayController = displayController;
|
||||
mImeController = imeController;
|
||||
mDisplayController.addDisplayWindowListener(this);
|
||||
mImeController.addPositionProcessor(this);
|
||||
}
|
||||
|
||||
private void onSizeCompatInfoChanged(int displayId, int taskId, @Nullable Rect taskBounds,
|
||||
@Nullable IBinder sizeCompatActivity,
|
||||
@Nullable ShellTaskOrganizer.TaskListener taskListener) {
|
||||
// TODO need to deduplicate task info changed
|
||||
}
|
||||
|
||||
// TODO move from SizeCompatModeActivityController from system UI.
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImeVisibilityChanged(int displayId, boolean isShowing) {
|
||||
}
|
||||
|
||||
private class SizeCompatUIImpl implements SizeCompatUI {
|
||||
@Override
|
||||
public void onSizeCompatInfoChanged(int displayId, int taskId, @Nullable Rect taskBounds,
|
||||
@Nullable IBinder sizeCompatActivity,
|
||||
@Nullable ShellTaskOrganizer.TaskListener taskListener) {
|
||||
mMainExecutor.execute(() ->
|
||||
SizeCompatUIController.this.onSizeCompatInfoChanged(displayId, taskId,
|
||||
taskBounds, sizeCompatActivity, taskListener));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package com.android.wm.shell;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
|
||||
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
|
||||
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW;
|
||||
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
|
||||
|
||||
@@ -48,6 +51,7 @@ import androidx.test.filters.SmallTest;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.common.TransactionPool;
|
||||
import com.android.wm.shell.sizecompatui.SizeCompatUI;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -59,6 +63,9 @@ import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests for the shell task organizer.
|
||||
*
|
||||
* Build/Install/Run:
|
||||
* atest WMShellUnitTests:ShellTaskOrganizerTests
|
||||
*/
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -68,6 +75,8 @@ public class ShellTaskOrganizerTests {
|
||||
private ITaskOrganizerController mTaskOrganizerController;
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private SizeCompatUI mSizeCompatUI;
|
||||
|
||||
ShellTaskOrganizer mOrganizer;
|
||||
private final SyncTransactionQueue mSyncTransactionQueue = mock(SyncTransactionQueue.class);
|
||||
@@ -102,7 +111,8 @@ public class ShellTaskOrganizerTests {
|
||||
doReturn(ParceledListSlice.<TaskAppearedInfo>emptyList())
|
||||
.when(mTaskOrganizerController).registerTaskOrganizer(any());
|
||||
} catch (RemoteException e) {}
|
||||
mOrganizer = spy(new ShellTaskOrganizer(mTaskOrganizerController, mTestExecutor, mContext));
|
||||
mOrganizer = spy(new ShellTaskOrganizer(mTaskOrganizerController, mTestExecutor, mContext,
|
||||
mSizeCompatUI));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -257,6 +267,39 @@ public class ShellTaskOrganizerTests {
|
||||
assertTrue(mwListener.appeared.contains(task2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnSizeCompatActivityChanged() {
|
||||
final RunningTaskInfo taskInfo1 = createTaskInfo(12, WINDOWING_MODE_FULLSCREEN);
|
||||
taskInfo1.displayId = DEFAULT_DISPLAY;
|
||||
taskInfo1.topActivityToken = mock(IBinder.class);
|
||||
taskInfo1.topActivityInSizeCompat = false;
|
||||
final TrackingTaskListener taskListener = new TrackingTaskListener();
|
||||
mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
|
||||
mOrganizer.onTaskAppeared(taskInfo1, null);
|
||||
|
||||
// sizeCompatActivity is null if top activity is not in size compat.
|
||||
verify(mSizeCompatUI).onSizeCompatInfoChanged(taskInfo1.displayId, taskInfo1.taskId,
|
||||
taskInfo1.configuration.windowConfiguration.getBounds(),
|
||||
null /* sizeCompatActivity*/ , taskListener);
|
||||
|
||||
// sizeCompatActivity is non-null if top activity is in size compat.
|
||||
final RunningTaskInfo taskInfo2 =
|
||||
createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
|
||||
taskInfo2.displayId = taskInfo1.displayId;
|
||||
taskInfo2.topActivityToken = taskInfo1.topActivityToken;
|
||||
taskInfo2.topActivityInSizeCompat = true;
|
||||
mOrganizer.onTaskInfoChanged(taskInfo2);
|
||||
verify(mSizeCompatUI).onSizeCompatInfoChanged(taskInfo1.displayId, taskInfo1.taskId,
|
||||
taskInfo1.configuration.windowConfiguration.getBounds(),
|
||||
taskInfo1.topActivityToken,
|
||||
taskListener);
|
||||
|
||||
mOrganizer.onTaskVanished(taskInfo1);
|
||||
verify(mSizeCompatUI).onSizeCompatInfoChanged(taskInfo1.displayId, taskInfo1.taskId,
|
||||
null /* taskConfig */, null /* sizeCompatActivity*/,
|
||||
null /* taskListener */);
|
||||
}
|
||||
|
||||
private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) {
|
||||
RunningTaskInfo taskInfo = new RunningTaskInfo();
|
||||
taskInfo.taskId = taskId;
|
||||
|
||||
@@ -71,6 +71,8 @@ import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
|
||||
import com.android.wm.shell.pip.PipUiEventLogger;
|
||||
import com.android.wm.shell.pip.phone.PipAppOpsListener;
|
||||
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
||||
import com.android.wm.shell.sizecompatui.SizeCompatUI;
|
||||
import com.android.wm.shell.sizecompatui.SizeCompatUIController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
@@ -293,8 +295,8 @@ public abstract class WMShellBaseModule {
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static ShellTaskOrganizer provideShellTaskOrganizer(@ShellMainThread ShellExecutor mainExecutor,
|
||||
Context context) {
|
||||
return new ShellTaskOrganizer(mainExecutor, context);
|
||||
Context context, SizeCompatUI sizeCompatUI) {
|
||||
return new ShellTaskOrganizer(mainExecutor, context, sizeCompatUI);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
@@ -380,8 +382,7 @@ public abstract class WMShellBaseModule {
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static FullscreenTaskListener provideFullscreenTaskListener(
|
||||
SyncTransactionQueue syncQueue) {
|
||||
static FullscreenTaskListener provideFullscreenTaskListener(SyncTransactionQueue syncQueue) {
|
||||
return new FullscreenTaskListener(syncQueue);
|
||||
}
|
||||
|
||||
@@ -392,4 +393,12 @@ public abstract class WMShellBaseModule {
|
||||
@ShellAnimationThread ShellExecutor animExecutor) {
|
||||
return new Transitions(organizer, pool, mainExecutor, animExecutor);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static SizeCompatUI provideSizeCompatUI(Context context, DisplayController displayController,
|
||||
DisplayImeController imeController, @ShellMainThread ShellExecutor mainExecutor) {
|
||||
return SizeCompatUIController.create(context, displayController, imeController,
|
||||
mainExecutor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.wmshell;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -41,7 +40,6 @@ import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.onehanded.OneHandedGestureHandler;
|
||||
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -51,6 +49,12 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Tests for {@link WMShell}.
|
||||
*
|
||||
* Build/Install/Run:
|
||||
* atest SystemUITests:WMShellTest
|
||||
*/
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class WMShellTest extends SysuiTestCase {
|
||||
|
||||
Reference in New Issue
Block a user