Loading services/core/java/com/android/server/wm/AppTransitionController.java +34 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()) { Loading services/core/java/com/android/server/wm/AppWindowToken.java +12 −7 Original line number Diff line number Diff line Loading @@ -2705,15 +2705,20 @@ 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) { mTmpRect.setEmpty(); final Task task = getTask(); if (getDisplayContent().mAppTransitionController.isTransitWithinTask( getTransit(), task)) { task.getBounds(mTmpRect); } else { final TaskStack stack = getStack(); if (stack == null) { return; } mAnimationBoundsLayer = createAnimationBoundsLayer(t); // Set clip rect to stack bounds. mTmpRect.setEmpty(); stack.getBounds(mTmpRect); } mAnimationBoundsLayer = createAnimationBoundsLayer(t); // Crop to stack bounds. t.setWindowCrop(mAnimationBoundsLayer, mTmpRect); Loading services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); } } } Loading
services/core/java/com/android/server/wm/AppTransitionController.java +34 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()) { Loading
services/core/java/com/android/server/wm/AppWindowToken.java +12 −7 Original line number Diff line number Diff line Loading @@ -2705,15 +2705,20 @@ 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) { mTmpRect.setEmpty(); final Task task = getTask(); if (getDisplayContent().mAppTransitionController.isTransitWithinTask( getTransit(), task)) { task.getBounds(mTmpRect); } else { final TaskStack stack = getStack(); if (stack == null) { return; } mAnimationBoundsLayer = createAnimationBoundsLayer(t); // Set clip rect to stack bounds. mTmpRect.setEmpty(); stack.getBounds(mTmpRect); } mAnimationBoundsLayer = createAnimationBoundsLayer(t); // Crop to stack bounds. t.setWindowCrop(mAnimationBoundsLayer, mTmpRect); Loading
services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); } } }