Loading core/java/android/window/TransitionFilter.java +12 −0 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ public final class TransitionFilter implements Parcelable { /** If non-null, requires the change to specifically have or not-have a custom animation. */ public Boolean mCustomAnimation = null; public IBinder mTaskFragmentToken = null; public Requirement() { } Loading @@ -204,12 +205,19 @@ public final class TransitionFilter implements Parcelable { // 0: null, 1: false, 2: true final int customAnimRaw = in.readInt(); mCustomAnimation = customAnimRaw == 0 ? null : Boolean.valueOf(customAnimRaw == 2); mTaskFragmentToken = in.readStrongBinder(); } /** Go through changes and find if at-least one change matches this filter */ boolean matches(@NonNull TransitionInfo info) { for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (mTaskFragmentToken != null && !mTaskFragmentToken.equals(change.getTaskFragmentToken())) { continue; } if (mMustBeIndependent && !TransitionInfo.isIndependent(change, info)) { // Only look at independent animating windows. continue; Loading Loading @@ -313,6 +321,7 @@ public final class TransitionFilter implements Parcelable { dest.writeStrongBinder(mLaunchCookie); int customAnimRaw = mCustomAnimation == null ? 0 : (mCustomAnimation ? 2 : 1); dest.writeInt(customAnimRaw); dest.writeStrongBinder(mTaskFragmentToken); } @NonNull Loading Loading @@ -357,6 +366,9 @@ public final class TransitionFilter implements Parcelable { if (mCustomAnimation != null) { out.append(" customAnim=").append(mCustomAnimation.booleanValue()); } if (mTaskFragmentToken != null) { out.append(" taskFragmentToken=").append(mTaskFragmentToken); } out.append("}"); return out.toString(); } Loading core/java/android/window/TransitionInfo.java +25 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.view.Surface; Loading Loading @@ -681,6 +682,7 @@ public final class TransitionInfo implements Parcelable { private float mSnapshotLuma; private ComponentName mActivityComponent = null; private AnimationOptions mAnimationOptions = null; private IBinder mTaskFragmentToken = null; public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) { mContainer = container; Loading Loading @@ -712,6 +714,7 @@ public final class TransitionInfo implements Parcelable { mSnapshotLuma = in.readFloat(); mActivityComponent = in.readTypedObject(ComponentName.CREATOR); mAnimationOptions = in.readTypedObject(AnimationOptions.CREATOR); mTaskFragmentToken = in.readStrongBinder(); } private Change localRemoteCopy() { Loading @@ -737,6 +740,7 @@ public final class TransitionInfo implements Parcelable { out.mSnapshotLuma = mSnapshotLuma; out.mActivityComponent = mActivityComponent; out.mAnimationOptions = mAnimationOptions; out.mTaskFragmentToken = mTaskFragmentToken; return out; } Loading Loading @@ -854,6 +858,14 @@ public final class TransitionInfo implements Parcelable { mAnimationOptions = options; } /** * Sets the client-defined TaskFragment token. Only set this if the window is a * client-organized TaskFragment. */ public void setTaskFragmentToken(@Nullable IBinder token) { mTaskFragmentToken = token; } /** @return the container that is changing. May be null if non-remotable (eg. activity) */ @Nullable public WindowContainerToken getContainer() { Loading Loading @@ -1009,6 +1021,15 @@ public final class TransitionInfo implements Parcelable { return mAnimationOptions; } /** * Returns the client-defined TaskFragment token. {@code null} if this window is not a * client-organized TaskFragment. */ @Nullable public IBinder getTaskFragmentToken() { return mTaskFragmentToken; } /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { Loading @@ -1035,6 +1056,7 @@ public final class TransitionInfo implements Parcelable { dest.writeFloat(mSnapshotLuma); dest.writeTypedObject(mActivityComponent, flags); dest.writeTypedObject(mAnimationOptions, flags); dest.writeStrongBinder(mTaskFragmentToken); } @NonNull Loading Loading @@ -1110,6 +1132,9 @@ public final class TransitionInfo implements Parcelable { if (mAnimationOptions != null) { sb.append(" opt=").append(mAnimationOptions); } if (mTaskFragmentToken != null) { sb.append(" taskFragmentToken=").append(mTaskFragmentToken); } sb.append('}'); return sb.toString(); } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +29 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,35 @@ public class ShellTransitionTests extends ShellTestCase { assertFalse(filter.matches(openStd)); } @Test public void testTransitionFilterTaskFragmentToken() { final IBinder taskFragmentToken = new Binder(); TransitionFilter filter = new TransitionFilter(); filter.mRequirements = new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()}; filter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; filter.mRequirements[0].mTaskFragmentToken = taskFragmentToken; // Transition with the same token should match. final TransitionInfo infoHasTaskFragmentToken = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN, taskFragmentToken).build(); assertTrue(filter.matches(infoHasTaskFragmentToken)); // Transition with a different token should not match. final IBinder differentTaskFragmentToken = new Binder(); final TransitionInfo infoDifferentTaskFragmentToken = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN, differentTaskFragmentToken).build(); assertFalse(filter.matches(infoDifferentTaskFragmentToken)); // Transition without a token should not match. final TransitionInfo infoNoTaskFragmentToken = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN, createTaskInfo( 1, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD)).build(); assertFalse(filter.matches(infoNoTaskFragmentToken)); } @Test public void testTransitionFilterMultiRequirement() { // filter that requires at-least one opening and one closing app Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionInfoBuilder.java +17 −4 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static org.mockito.Mockito.mock; import android.annotation.Nullable; import android.app.ActivityManager; import android.content.ComponentName; import android.os.IBinder; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.TransitionInfo; Loading Loading @@ -51,21 +53,24 @@ public class TransitionInfoBuilder { } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @TransitionInfo.ChangeFlags int flags, ActivityManager.RunningTaskInfo taskInfo, ComponentName activityComponent) { @TransitionInfo.ChangeFlags int flags, @Nullable ActivityManager.RunningTaskInfo taskInfo, @Nullable ComponentName activityComponent, @Nullable IBinder taskFragmentToken) { final TransitionInfo.Change change = new TransitionInfo.Change( taskInfo != null ? taskInfo.token : null, createMockSurface(true /* valid */)); change.setMode(mode); change.setFlags(flags); change.setTaskInfo(taskInfo); change.setActivityComponent(activityComponent); change.setTaskFragmentToken(taskFragmentToken); return addChange(change); } /** Add a change to the TransitionInfo */ public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @TransitionInfo.ChangeFlags int flags, ActivityManager.RunningTaskInfo taskInfo) { return addChange(mode, flags, taskInfo, null /* activityComponent */); return addChange(mode, flags, taskInfo, null /* activityComponent */, null /* taskFragmentToken */); } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, Loading @@ -76,13 +81,21 @@ public class TransitionInfoBuilder { /** Add a change to the TransitionInfo */ public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, ComponentName activityComponent) { return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskinfo */, activityComponent); return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskinfo */, activityComponent, null /* taskFragmentToken */); } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode) { return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskInfo */); } /** Add a change with a TaskFragment token to the TransitionInfo */ public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @Nullable IBinder taskFragmentToken) { return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskInfo */, null /* activityComponent */, taskFragmentToken); } public TransitionInfoBuilder addChange(TransitionInfo.Change change) { change.setDisplayId(DISPLAY_ID, DISPLAY_ID); mInfo.addChange(change); Loading services/core/java/com/android/server/wm/Transition.java +3 −0 Original line number Diff line number Diff line Loading @@ -2925,6 +2925,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final TaskFragment taskFragment = target.asTaskFragment(); final boolean isEmbeddedTaskFragment = taskFragment != null && taskFragment.isEmbedded(); final IBinder taskFragmentToken = taskFragment != null ? taskFragment.getFragmentToken() : null; change.setTaskFragmentToken(taskFragmentToken); final ActivityRecord activityRecord = target.asActivityRecord(); if (task != null) { Loading Loading
core/java/android/window/TransitionFilter.java +12 −0 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ public final class TransitionFilter implements Parcelable { /** If non-null, requires the change to specifically have or not-have a custom animation. */ public Boolean mCustomAnimation = null; public IBinder mTaskFragmentToken = null; public Requirement() { } Loading @@ -204,12 +205,19 @@ public final class TransitionFilter implements Parcelable { // 0: null, 1: false, 2: true final int customAnimRaw = in.readInt(); mCustomAnimation = customAnimRaw == 0 ? null : Boolean.valueOf(customAnimRaw == 2); mTaskFragmentToken = in.readStrongBinder(); } /** Go through changes and find if at-least one change matches this filter */ boolean matches(@NonNull TransitionInfo info) { for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (mTaskFragmentToken != null && !mTaskFragmentToken.equals(change.getTaskFragmentToken())) { continue; } if (mMustBeIndependent && !TransitionInfo.isIndependent(change, info)) { // Only look at independent animating windows. continue; Loading Loading @@ -313,6 +321,7 @@ public final class TransitionFilter implements Parcelable { dest.writeStrongBinder(mLaunchCookie); int customAnimRaw = mCustomAnimation == null ? 0 : (mCustomAnimation ? 2 : 1); dest.writeInt(customAnimRaw); dest.writeStrongBinder(mTaskFragmentToken); } @NonNull Loading Loading @@ -357,6 +366,9 @@ public final class TransitionFilter implements Parcelable { if (mCustomAnimation != null) { out.append(" customAnim=").append(mCustomAnimation.booleanValue()); } if (mTaskFragmentToken != null) { out.append(" taskFragmentToken=").append(mTaskFragmentToken); } out.append("}"); return out.toString(); } Loading
core/java/android/window/TransitionInfo.java +25 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.view.Surface; Loading Loading @@ -681,6 +682,7 @@ public final class TransitionInfo implements Parcelable { private float mSnapshotLuma; private ComponentName mActivityComponent = null; private AnimationOptions mAnimationOptions = null; private IBinder mTaskFragmentToken = null; public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) { mContainer = container; Loading Loading @@ -712,6 +714,7 @@ public final class TransitionInfo implements Parcelable { mSnapshotLuma = in.readFloat(); mActivityComponent = in.readTypedObject(ComponentName.CREATOR); mAnimationOptions = in.readTypedObject(AnimationOptions.CREATOR); mTaskFragmentToken = in.readStrongBinder(); } private Change localRemoteCopy() { Loading @@ -737,6 +740,7 @@ public final class TransitionInfo implements Parcelable { out.mSnapshotLuma = mSnapshotLuma; out.mActivityComponent = mActivityComponent; out.mAnimationOptions = mAnimationOptions; out.mTaskFragmentToken = mTaskFragmentToken; return out; } Loading Loading @@ -854,6 +858,14 @@ public final class TransitionInfo implements Parcelable { mAnimationOptions = options; } /** * Sets the client-defined TaskFragment token. Only set this if the window is a * client-organized TaskFragment. */ public void setTaskFragmentToken(@Nullable IBinder token) { mTaskFragmentToken = token; } /** @return the container that is changing. May be null if non-remotable (eg. activity) */ @Nullable public WindowContainerToken getContainer() { Loading Loading @@ -1009,6 +1021,15 @@ public final class TransitionInfo implements Parcelable { return mAnimationOptions; } /** * Returns the client-defined TaskFragment token. {@code null} if this window is not a * client-organized TaskFragment. */ @Nullable public IBinder getTaskFragmentToken() { return mTaskFragmentToken; } /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { Loading @@ -1035,6 +1056,7 @@ public final class TransitionInfo implements Parcelable { dest.writeFloat(mSnapshotLuma); dest.writeTypedObject(mActivityComponent, flags); dest.writeTypedObject(mAnimationOptions, flags); dest.writeStrongBinder(mTaskFragmentToken); } @NonNull Loading Loading @@ -1110,6 +1132,9 @@ public final class TransitionInfo implements Parcelable { if (mAnimationOptions != null) { sb.append(" opt=").append(mAnimationOptions); } if (mTaskFragmentToken != null) { sb.append(" taskFragmentToken=").append(mTaskFragmentToken); } sb.append('}'); return sb.toString(); } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +29 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,35 @@ public class ShellTransitionTests extends ShellTestCase { assertFalse(filter.matches(openStd)); } @Test public void testTransitionFilterTaskFragmentToken() { final IBinder taskFragmentToken = new Binder(); TransitionFilter filter = new TransitionFilter(); filter.mRequirements = new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()}; filter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; filter.mRequirements[0].mTaskFragmentToken = taskFragmentToken; // Transition with the same token should match. final TransitionInfo infoHasTaskFragmentToken = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN, taskFragmentToken).build(); assertTrue(filter.matches(infoHasTaskFragmentToken)); // Transition with a different token should not match. final IBinder differentTaskFragmentToken = new Binder(); final TransitionInfo infoDifferentTaskFragmentToken = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN, differentTaskFragmentToken).build(); assertFalse(filter.matches(infoDifferentTaskFragmentToken)); // Transition without a token should not match. final TransitionInfo infoNoTaskFragmentToken = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN, createTaskInfo( 1, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD)).build(); assertFalse(filter.matches(infoNoTaskFragmentToken)); } @Test public void testTransitionFilterMultiRequirement() { // filter that requires at-least one opening and one closing app Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionInfoBuilder.java +17 −4 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static org.mockito.Mockito.mock; import android.annotation.Nullable; import android.app.ActivityManager; import android.content.ComponentName; import android.os.IBinder; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.TransitionInfo; Loading Loading @@ -51,21 +53,24 @@ public class TransitionInfoBuilder { } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @TransitionInfo.ChangeFlags int flags, ActivityManager.RunningTaskInfo taskInfo, ComponentName activityComponent) { @TransitionInfo.ChangeFlags int flags, @Nullable ActivityManager.RunningTaskInfo taskInfo, @Nullable ComponentName activityComponent, @Nullable IBinder taskFragmentToken) { final TransitionInfo.Change change = new TransitionInfo.Change( taskInfo != null ? taskInfo.token : null, createMockSurface(true /* valid */)); change.setMode(mode); change.setFlags(flags); change.setTaskInfo(taskInfo); change.setActivityComponent(activityComponent); change.setTaskFragmentToken(taskFragmentToken); return addChange(change); } /** Add a change to the TransitionInfo */ public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @TransitionInfo.ChangeFlags int flags, ActivityManager.RunningTaskInfo taskInfo) { return addChange(mode, flags, taskInfo, null /* activityComponent */); return addChange(mode, flags, taskInfo, null /* activityComponent */, null /* taskFragmentToken */); } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, Loading @@ -76,13 +81,21 @@ public class TransitionInfoBuilder { /** Add a change to the TransitionInfo */ public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, ComponentName activityComponent) { return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskinfo */, activityComponent); return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskinfo */, activityComponent, null /* taskFragmentToken */); } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode) { return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskInfo */); } /** Add a change with a TaskFragment token to the TransitionInfo */ public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @Nullable IBinder taskFragmentToken) { return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskInfo */, null /* activityComponent */, taskFragmentToken); } public TransitionInfoBuilder addChange(TransitionInfo.Change change) { change.setDisplayId(DISPLAY_ID, DISPLAY_ID); mInfo.addChange(change); Loading
services/core/java/com/android/server/wm/Transition.java +3 −0 Original line number Diff line number Diff line Loading @@ -2925,6 +2925,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final TaskFragment taskFragment = target.asTaskFragment(); final boolean isEmbeddedTaskFragment = taskFragment != null && taskFragment.isEmbedded(); final IBinder taskFragmentToken = taskFragment != null ? taskFragment.getFragmentToken() : null; change.setTaskFragmentToken(taskFragmentToken); final ActivityRecord activityRecord = target.asActivityRecord(); if (task != null) { Loading