Merge "Add nav bar case to RemoteAnimationTarget of non-app window" into sc-dev

This commit is contained in:
Shawn Lin
2021-03-05 03:50:41 +00:00
committed by Android (Google) Code Review
9 changed files with 270 additions and 22 deletions

View File

@@ -31,6 +31,7 @@ import static android.view.RemoteAnimationTargetProto.START_BOUNDS;
import static android.view.RemoteAnimationTargetProto.START_LEASH;
import static android.view.RemoteAnimationTargetProto.TASK_ID;
import static android.view.RemoteAnimationTargetProto.WINDOW_CONFIGURATION;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import android.annotation.IntDef;
import android.app.PictureInPictureParams;
@@ -195,12 +196,30 @@ public class RemoteAnimationTarget implements Parcelable {
*/
public PictureInPictureParams pictureInPictureParams;
/**
* The {@link android.view.WindowManager.LayoutParams.WindowType} of this window. It's only used
* for non-app window.
*/
public final @WindowManager.LayoutParams.WindowType int windowType;
public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
Rect localBounds, Rect screenSpaceBounds,
WindowConfiguration windowConfig, boolean isNotInRecents,
SurfaceControl startLeash, Rect startBounds,
PictureInPictureParams pictureInPictureParams) {
this(taskId, mode, leash, isTranslucent, clipRect, contentInsets, prefixOrderIndex,
position, localBounds, screenSpaceBounds, windowConfig, isNotInRecents, startLeash,
startBounds, pictureInPictureParams, INVALID_WINDOW_TYPE);
}
public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
Rect localBounds, Rect screenSpaceBounds,
WindowConfiguration windowConfig, boolean isNotInRecents,
SurfaceControl startLeash, Rect startBounds,
PictureInPictureParams pictureInPictureParams,
@WindowManager.LayoutParams.WindowType int windowType) {
this.mode = mode;
this.taskId = taskId;
this.leash = leash;
@@ -217,6 +236,7 @@ public class RemoteAnimationTarget implements Parcelable {
this.startLeash = startLeash;
this.startBounds = startBounds == null ? null : new Rect(startBounds);
this.pictureInPictureParams = pictureInPictureParams;
this.windowType = windowType;
}
public RemoteAnimationTarget(Parcel in) {
@@ -236,6 +256,7 @@ public class RemoteAnimationTarget implements Parcelable {
startLeash = in.readTypedObject(SurfaceControl.CREATOR);
startBounds = in.readTypedObject(Rect.CREATOR);
pictureInPictureParams = in.readTypedObject(PictureInPictureParams.CREATOR);
windowType = in.readInt();
}
@Override
@@ -261,6 +282,7 @@ public class RemoteAnimationTarget implements Parcelable {
dest.writeTypedObject(startLeash, 0 /* flags */);
dest.writeTypedObject(startBounds, 0 /* flags */);
dest.writeTypedObject(pictureInPictureParams, 0 /* flags */);
dest.writeInt(windowType);
}
public void dump(PrintWriter pw, String prefix) {
@@ -274,6 +296,7 @@ public class RemoteAnimationTarget implements Parcelable {
pw.print(" sourceContainerBounds="); sourceContainerBounds.printShortString(pw);
pw.print(" screenSpaceBounds="); screenSpaceBounds.printShortString(pw);
pw.print(" localBounds="); localBounds.printShortString(pw);
pw.print(" windowType="); pw.print(windowType);
pw.println();
pw.print(prefix); pw.print("windowConfiguration="); pw.println(windowConfiguration);
pw.print(prefix); pw.print("leash="); pw.println(leash);

View File

@@ -16,6 +16,8 @@
package com.android.systemui.shared.system;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import android.app.PictureInPictureParams;
import android.app.WindowConfiguration;
import android.graphics.Point;
@@ -44,6 +46,9 @@ public class RemoteAnimationTargetCompat {
public static final int ACTIVITY_TYPE_ASSISTANT = WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
public final int activityType;
public static final int TYPE_NAVIGATION_BAR = WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
public final int windowType;
public final int taskId;
public final SurfaceControlCompat leash;
public final boolean isTranslucent;
@@ -74,6 +79,7 @@ public class RemoteAnimationTargetCompat {
contentInsets = app.contentInsets;
activityType = app.windowConfiguration.getActivityType();
pictureInPictureParams = app.pictureInPictureParams;
windowType = app.windowType;
mStartLeash = app.startLeash;
}
@@ -114,6 +120,7 @@ public class RemoteAnimationTargetCompat {
activityType = ACTIVITY_TYPE_UNDEFINED;
}
pictureInPictureParams = null;
windowType = INVALID_WINDOW_TYPE;
mStartLeash = null;
}

View File

@@ -1305,7 +1305,7 @@ public class AppTransition implements Dump {
if (isTransitionSet()) {
clear();
mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
mRemoteAnimationController = new RemoteAnimationController(mService,
mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent,
remoteAnimationAdapter, mHandler);
}
}

View File

@@ -16,6 +16,12 @@
package com.android.server.wm;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_FRONT;
import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
@@ -26,6 +32,7 @@ import android.os.SystemClock;
import android.util.proto.ProtoOutputStream;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.WindowManager;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
@@ -35,7 +42,7 @@ import java.util.ArrayList;
class NonAppWindowAnimationAdapter implements AnimationAdapter {
private final WindowState mWindow;
private final WindowContainer mWindow;
private RemoteAnimationTarget mTarget;
private SurfaceControl mCapturedLeash;
@@ -47,22 +54,43 @@ class NonAppWindowAnimationAdapter implements AnimationAdapter {
return false;
}
NonAppWindowAnimationAdapter(WindowState w,
long durationHint, long statusBarTransitionDelay) {
NonAppWindowAnimationAdapter(WindowContainer w, long durationHint,
long statusBarTransitionDelay) {
mWindow = w;
mDurationHint = durationHint;
mStatusBarTransitionDelay = statusBarTransitionDelay;
}
static RemoteAnimationTarget[] startNonAppWindowAnimations(WindowManagerService service,
DisplayContent displayContent, @WindowManager.TransitionOldType int transit,
long durationHint, long statusBarTransitionDelay) {
final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
if (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY
|| transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
startNonAppWindowAnimationsForKeyguardExit(
service, durationHint, statusBarTransitionDelay, targets);
} else if (transit == TRANSIT_OLD_TASK_OPEN || transit == TRANSIT_OLD_TASK_TO_FRONT
|| transit == TRANSIT_OLD_WALLPAPER_CLOSE) {
final boolean shouldAttachNavBarToApp =
displayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
&& service.getRecentsAnimationController() == null
&& displayContent.getFixedRotationAnimationController() == null;
if (shouldAttachNavBarToApp) {
startNavigationBarWindowAnimation(
displayContent, durationHint, statusBarTransitionDelay, targets);
}
}
return targets.toArray(new RemoteAnimationTarget[targets.size()]);
}
/**
* Creates and starts remote animations for all the visible non app windows.
*
* @return RemoteAnimationTarget[] targets for all the visible non app windows
*/
public static RemoteAnimationTarget[] startNonAppWindowAnimationsForKeyguardExit(
WindowManagerService service, long durationHint, long statusBarTransitionDelay) {
final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
private static void startNonAppWindowAnimationsForKeyguardExit(WindowManagerService service,
long durationHint, long statusBarTransitionDelay,
ArrayList<RemoteAnimationTarget> targets) {
final WindowManagerPolicy policy = service.mPolicy;
service.mRoot.forAllWindows(nonAppWindow -> {
if (nonAppWindow.mActivityRecord == null && policy.canBeHiddenByKeyguardLw(nonAppWindow)
@@ -74,7 +102,22 @@ class NonAppWindowAnimationAdapter implements AnimationAdapter {
targets.add(nonAppAdapter.createRemoteAnimationTarget());
}
}, true /* traverseTopToBottom */);
return targets.toArray(new RemoteAnimationTarget[targets.size()]);
}
/**
* Creates and starts remote animation for the navigation bar windows.
*
* @return RemoteAnimationTarget[] targets for all the visible non app windows
*/
private static void startNavigationBarWindowAnimation(DisplayContent displayContent,
long durationHint, long statusBarTransitionDelay,
ArrayList<RemoteAnimationTarget> targets) {
final WindowState navWindow = displayContent.getDisplayPolicy().getNavigationBar();
final NonAppWindowAnimationAdapter nonAppAdapter = new NonAppWindowAnimationAdapter(
navWindow.mToken, durationHint, statusBarTransitionDelay);
navWindow.mToken.startAnimation(navWindow.mToken.getPendingTransaction(),
nonAppAdapter, false /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION);
targets.add(nonAppAdapter.createRemoteAnimationTarget());
}
/**
@@ -84,7 +127,7 @@ class NonAppWindowAnimationAdapter implements AnimationAdapter {
mTarget = new RemoteAnimationTarget(-1, -1, getLeash(), false,
new Rect(), null, mWindow.getPrefixOrderIndex(), mWindow.getLastSurfacePosition(),
mWindow.getBounds(), null, mWindow.getWindowConfiguration(), true, null, null,
null);
null, mWindow.getWindowType());
return mTarget;
}
@@ -120,8 +163,8 @@ class NonAppWindowAnimationAdapter implements AnimationAdapter {
@Override
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.print("token=");
pw.println(mWindow.mToken);
pw.print("window=");
pw.println(mWindow);
if (mTarget != null) {
pw.print(prefix);
pw.println("Target:");

View File

@@ -16,9 +16,6 @@
package com.android.server.wm;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
@@ -60,6 +57,7 @@ class RemoteAnimationController implements DeathRecipient {
private static final long TIMEOUT_MS = 2000;
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
private final RemoteAnimationAdapter mRemoteAnimationAdapter;
private final ArrayList<RemoteAnimationRecord> mPendingAnimations = new ArrayList<>();
private final ArrayList<WallpaperAnimationAdapter> mPendingWallpaperAnimations =
@@ -72,9 +70,10 @@ class RemoteAnimationController implements DeathRecipient {
private boolean mCanceled;
private boolean mLinkedToDeathOfRunner;
RemoteAnimationController(WindowManagerService service,
RemoteAnimationController(WindowManagerService service, DisplayContent displayContent,
RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) {
mService = service;
mDisplayContent = displayContent;
mRemoteAnimationAdapter = remoteAnimationAdapter;
mHandler = handler;
}
@@ -221,12 +220,11 @@ class RemoteAnimationController implements DeathRecipient {
private RemoteAnimationTarget[] createNonAppWindowAnimations(
@WindowManager.TransitionOldType int transit) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createNonAppWindowAnimations()");
return (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY
|| transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER)
? NonAppWindowAnimationAdapter.startNonAppWindowAnimationsForKeyguardExit(mService,
return NonAppWindowAnimationAdapter.startNonAppWindowAnimations(mService,
mDisplayContent,
transit,
mRemoteAnimationAdapter.getDuration(),
mRemoteAnimationAdapter.getStatusBarTransitionDelay())
: new RemoteAnimationTarget[0];
mRemoteAnimationAdapter.getStatusBarTransitionDelay());
}
private void onAnimationFinished() {

View File

@@ -29,6 +29,7 @@ import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.UserHandle.USER_NULL;
import static android.view.SurfaceControl.Transaction;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
@@ -3304,4 +3305,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
mListeners.remove(listener);
unregisterConfigurationChangeListener(listener);
}
@WindowManager.LayoutParams.WindowType int getWindowType() {
return INVALID_WINDOW_TYPE;
}
}

View File

@@ -5777,4 +5777,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
outSize.inset(-attrs.surfaceInsets.left, -attrs.surfaceInsets.top,
-attrs.surfaceInsets.right, -attrs.surfaceInsets.bottom);
}
@Override
@WindowManager.LayoutParams.WindowType int getWindowType() {
return mAttrs.type;
}
}

View File

@@ -764,4 +764,9 @@ class WindowToken extends WindowContainer<WindowState> {
forAllWindows(WindowState::clearFrozenInsetsState, true /* traverseTopToBottom */);
}
}
@Override
@WindowManager.LayoutParams.WindowType int getWindowType() {
return windowType;
}
}

View File

@@ -18,11 +18,13 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -35,7 +37,9 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITIO
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -94,7 +98,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50, true /* changeNeedsSnapshot */);
mAdapter.setCallingPidUid(123, 456);
runWithScissors(mWm.mH, () -> mHandler = new TestHandler(null, mClock), 0);
mController = new RemoteAnimationController(mWm, mAdapter, mHandler);
mController = new RemoteAnimationController(mWm, mDisplayContent, mAdapter, mHandler);
}
private WindowState createAppOverlayWindow() {
@@ -520,6 +524,164 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
}
}
@Test
public void testNonAppTarget_sendNavBar() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mDisplayContent.mOpeningApps.add(win.mActivityRecord);
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs);
final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
spyOn(policy);
doReturn(true).when(policy).shouldAttachNavBarToAppDuringTransition();
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
win.mActivityRecord, new Point(50, 100), null,
new Rect(50, 100, 150, 150), null).mAdapter;
adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
mFinishedCallback);
mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(),
finishedCaptor.capture());
boolean containNavTarget = false;
for (int i = 0; i < nonAppsCaptor.getValue().length; i++) {
if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) {
containNavTarget = true;
break;
}
}
assertTrue(containNavTarget);
}
@Test
public void testNonAppTarget_notSendNavBar_notAttachToApp() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mDisplayContent.mOpeningApps.add(win.mActivityRecord);
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs);
final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
spyOn(policy);
doReturn(false).when(policy).shouldAttachNavBarToAppDuringTransition();
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
win.mActivityRecord, new Point(50, 100), null,
new Rect(50, 100, 150, 150), null).mAdapter;
adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
mFinishedCallback);
mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(),
finishedCaptor.capture());
boolean containNavTarget = false;
for (int i = 0; i < nonAppsCaptor.getValue().length; i++) {
if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) {
containNavTarget = true;
break;
}
}
assertFalse(containNavTarget);
}
@Test
public void testNonAppTarget_notSendNavBar_controlledByFixedRotation() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mDisplayContent.mOpeningApps.add(win.mActivityRecord);
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs);
final FixedRotationAnimationController mockController =
mock(FixedRotationAnimationController.class);
doReturn(mockController).when(mDisplayContent).getFixedRotationAnimationController();
final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
spyOn(policy);
doReturn(true).when(policy).shouldAttachNavBarToAppDuringTransition();
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
win.mActivityRecord, new Point(50, 100), null,
new Rect(50, 100, 150, 150), null).mAdapter;
adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
mFinishedCallback);
mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(),
finishedCaptor.capture());
boolean containNavTarget = false;
for (int i = 0; i < nonAppsCaptor.getValue().length; i++) {
if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) {
containNavTarget = true;
break;
}
}
assertFalse(containNavTarget);
}
@Test
public void testNonAppTarget_notSendNavBar_controlledByRecents() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mDisplayContent.mOpeningApps.add(win.mActivityRecord);
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs);
final RecentsAnimationController mockController =
mock(RecentsAnimationController.class);
doReturn(mockController).when(mWm).getRecentsAnimationController();
final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
spyOn(policy);
doReturn(true).when(policy).shouldAttachNavBarToAppDuringTransition();
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
win.mActivityRecord, new Point(50, 100), null,
new Rect(50, 100, 150, 150), null).mAdapter;
adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
mFinishedCallback);
mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(),
finishedCaptor.capture());
boolean containNavTarget = false;
for (int i = 0; i < nonAppsCaptor.getValue().length; i++) {
if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) {
containNavTarget = true;
break;
}
}
assertFalse(containNavTarget);
}
private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
verify(binder, atLeast(0)).asBinder();
verifyNoMoreInteractions(binder);