Merge "Clip transition animations within a task to the task"

This commit is contained in:
Evan Rosky
2019-03-20 21:18:02 +00:00
committed by Android (Google) Code Review
3 changed files with 70 additions and 7 deletions

View File

@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_ACTIVITY_RELAUNCH;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
@@ -638,6 +639,39 @@ public class AppTransitionController {
return transit;
}
/**
* Identifies whether the current transition occurs within a single task or not. This is used
* to determine whether animations should be clipped to the task bounds instead of stack bounds.
*/
@VisibleForTesting
boolean isTransitWithinTask(int transit, Task task) {
if (task == null
|| !mDisplayContent.mChangingApps.isEmpty()) {
// if there is no task, then we can't constrain to the task.
// if anything is changing, it can animate outside its task.
return false;
}
if (!(transit == TRANSIT_ACTIVITY_OPEN
|| transit == TRANSIT_ACTIVITY_CLOSE
|| transit == TRANSIT_ACTIVITY_RELAUNCH)) {
// only activity-level transitions will be within-task.
return false;
}
// check that all components are in the task.
for (AppWindowToken activity : mDisplayContent.mOpeningApps) {
Task activityTask = activity.getTask();
if (activityTask != task) {
return false;
}
}
for (AppWindowToken activity : mDisplayContent.mClosingApps) {
if (activity.getTask() != task) {
return false;
}
}
return true;
}
private boolean canBeWallpaperTarget(ArraySet<AppWindowToken> apps) {
for (int i = apps.size() - 1; i >= 0; i--) {
if (apps.valueAt(i).windowsCanBeWallpaperTarget()) {

View File

@@ -2705,16 +2705,21 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
// If the animation needs to be cropped then an animation bounds layer is created as a child
// of the pinned stack or animation layer. The leash is then reparented to this new layer.
if (mNeedsAnimationBoundsLayer) {
final TaskStack stack = getStack();
if (stack == null) {
return;
mTmpRect.setEmpty();
final Task task = getTask();
if (getDisplayContent().mAppTransitionController.isTransitWithinTask(
getTransit(), task)) {
task.getBounds(mTmpRect);
} else {
final TaskStack stack = getStack();
if (stack == null) {
return;
}
// Set clip rect to stack bounds.
stack.getBounds(mTmpRect);
}
mAnimationBoundsLayer = createAnimationBoundsLayer(t);
// Set clip rect to stack bounds.
mTmpRect.setEmpty();
stack.getBounds(mTmpRect);
// Crop to stack bounds.
t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);

View File

@@ -17,12 +17,16 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
import android.view.WindowManager;
@@ -95,4 +99,24 @@ public class AppTransitionControllerTest extends WindowTestsBase {
TRANSIT_TASK_CHANGE_WINDOWING_MODE));
}
}
@Test
public void testTransitWithinTask() {
synchronized (mWm.mGlobalLock) {
final AppWindowToken opening = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
opening.setFillsParent(false);
final AppWindowToken closing = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
closing.setFillsParent(false);
Task task = opening.getTask();
mDisplayContent.mOpeningApps.add(opening);
mDisplayContent.mClosingApps.add(closing);
assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
closing.getTask().removeChild(closing);
task.addChild(closing, 0);
assertTrue(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_TASK_OPEN, task));
}
}
}