From adb7e53532ca94d286a849e394ed39918cbc423d Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 22 Jul 2021 15:31:28 -0700 Subject: [PATCH] Add some more transition filter properties These are needed for keyguard transitions. The ones added are: A NOT requirement which will reject transitions with a matching change. The ability to match containers that aren't independent. Checks for global transition flags as well as individual change flags. Match only if container is a task. Bug: 191799478 Test: atest ShellTransitionTests Change-Id: I963c6c91cdfc0b71a75ba9656261bb0e237f11f1 --- core/java/android/view/WindowManager.java | 2 + .../java/android/window/TransitionFilter.java | 57 +++++++++++++++++-- .../transition/ShellTransitionTests.java | 21 +++++++ .../keyguard/KeyguardServiceWrapper.java | 2 +- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 8cc8866214475..eb410ab8c3ed2 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -943,6 +943,8 @@ public interface WindowManager extends ViewManager { case TRANSIT_KEYGUARD_GOING_AWAY: return "KEYGUARD_GOING_AWAY"; case TRANSIT_KEYGUARD_OCCLUDE: return "KEYGUARD_OCCLUDE"; case TRANSIT_KEYGUARD_UNOCCLUDE: return "KEYGUARD_UNOCCLUDE"; + case TRANSIT_PIP: return "PIP"; + case TRANSIT_WAKE: return "WAKE"; case TRANSIT_FIRST_CUSTOM: return "FIRST_CUSTOM"; default: if (type > TRANSIT_FIRST_CUSTOM) { diff --git a/core/java/android/window/TransitionFilter.java b/core/java/android/window/TransitionFilter.java index bb3f90b3a1d8c..34facc40d3988 100644 --- a/core/java/android/window/TransitionFilter.java +++ b/core/java/android/window/TransitionFilter.java @@ -27,6 +27,7 @@ import android.app.WindowConfiguration; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; +import android.view.WindowManager; /** * A parcelable filter that can be used for rerouting transitions to a remote. This is a local @@ -55,6 +56,9 @@ public final class TransitionFilter implements Parcelable { */ @Nullable public @TransitionType int[] mTypeSet = null; + /** All flags must be set on a transition. */ + public @WindowManager.TransitionFlags int mFlags = 0; + /** * A list of required changes. To pass, a transition must meet all requirements. */ @@ -65,6 +69,7 @@ public final class TransitionFilter implements Parcelable { private TransitionFilter(Parcel in) { mTypeSet = in.createIntArray(); + mFlags = in.readInt(); mRequirements = in.createTypedArray(Requirement.CREATOR); } @@ -81,10 +86,16 @@ public final class TransitionFilter implements Parcelable { } if (!typePass) return false; } + if ((info.getFlags() & mFlags) != mFlags) { + return false; + } // Make sure info meets all of the requirements. if (mRequirements != null) { for (int i = 0; i < mRequirements.length; ++i) { - if (!mRequirements[i].matches(info)) return false; + final boolean matches = mRequirements[i].matches(info); + if (matches == mRequirements[i].mNot) { + return false; + } } } return true; @@ -94,6 +105,7 @@ public final class TransitionFilter implements Parcelable { /** @hide */ public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeIntArray(mTypeSet); + dest.writeInt(mFlags); dest.writeTypedArray(mRequirements, flags); } @@ -123,10 +135,11 @@ public final class TransitionFilter implements Parcelable { sb.append("{types=["); if (mTypeSet != null) { for (int i = 0; i < mTypeSet.length; ++i) { - sb.append((i == 0 ? "" : ",") + mTypeSet[i]); + sb.append((i == 0 ? "" : ",") + WindowManager.transitTypeToString(mTypeSet[i])); } } - sb.append("] checks=["); + sb.append("] flags=0x" + Integer.toHexString(mFlags)); + sb.append(" checks=["); if (mRequirements != null) { for (int i = 0; i < mRequirements.length; ++i) { sb.append((i == 0 ? "" : ",") + mRequirements[i]); @@ -141,7 +154,21 @@ public final class TransitionFilter implements Parcelable { */ public static final class Requirement implements Parcelable { public int mActivityType = ACTIVITY_TYPE_UNDEFINED; + + /** This only matches if the change is independent of its parents. */ + public boolean mMustBeIndependent = true; + + /** If this matches, the parent filter will fail */ + public boolean mNot = false; + public int[] mModes = null; + + /** Matches only if all the flags here are set on the change. */ + public @TransitionInfo.ChangeFlags int mFlags = 0; + + /** If this needs to be a task. */ + public boolean mMustBeTask = false; + public @ContainerOrder int mOrder = CONTAINER_ORDER_ANY; public ComponentName mTopActivity; @@ -150,7 +177,11 @@ public final class TransitionFilter implements Parcelable { private Requirement(Parcel in) { mActivityType = in.readInt(); + mMustBeIndependent = in.readBoolean(); + mNot = in.readBoolean(); mModes = in.createIntArray(); + mFlags = in.readInt(); + mMustBeTask = in.readBoolean(); mOrder = in.readInt(); mTopActivity = in.readTypedObject(ComponentName.CREATOR); } @@ -159,7 +190,7 @@ public final class TransitionFilter implements Parcelable { boolean matches(@NonNull TransitionInfo info) { for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); - if (!TransitionInfo.isIndependent(change, info)) { + if (mMustBeIndependent && !TransitionInfo.isIndependent(change, info)) { // Only look at independent animating windows. continue; } @@ -183,6 +214,12 @@ public final class TransitionFilter implements Parcelable { } if (!pass) continue; } + if ((change.getFlags() & mFlags) != mFlags) { + continue; + } + if (mMustBeTask && change.getTaskInfo() == null) { + continue; + } return true; } return false; @@ -208,7 +245,11 @@ public final class TransitionFilter implements Parcelable { /** @hide */ public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mActivityType); + dest.writeBoolean(mMustBeIndependent); + dest.writeBoolean(mNot); dest.writeIntArray(mModes); + dest.writeInt(mFlags); + dest.writeBoolean(mMustBeTask); dest.writeInt(mOrder); dest.writeTypedObject(mTopActivity, flags); } @@ -236,7 +277,10 @@ public final class TransitionFilter implements Parcelable { @Override public String toString() { StringBuilder out = new StringBuilder(); - out.append("{atype=" + WindowConfiguration.activityTypeToString(mActivityType)); + out.append('{'); + if (mNot) out.append("NOT "); + out.append("atype=" + WindowConfiguration.activityTypeToString(mActivityType)); + out.append(" independent=" + mMustBeIndependent); out.append(" modes=["); if (mModes != null) { for (int i = 0; i < mModes.length; ++i) { @@ -244,8 +288,11 @@ public final class TransitionFilter implements Parcelable { } } out.append("]").toString(); + out.append(" flags=" + TransitionInfo.flagsToString(mFlags)); + out.append(" mustBeTask=" + mMustBeTask); out.append(" order=" + containerOrderToString(mOrder)); out.append(" topActivity=").append(mTopActivity); + out.append("}"); return out.toString(); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java index a2b1f6421f8da..21329c75ebb09 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java @@ -26,6 +26,7 @@ import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; +import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -274,6 +275,26 @@ public class ShellTransitionTests { assertTrue(filter.matches(openClose)); } + @Test + public void testTransitionFilterNotRequirement() { + // filter that requires one opening and NO translucent apps + TransitionFilter filter = new TransitionFilter(); + filter.mRequirements = new TransitionFilter.Requirement[]{ + new TransitionFilter.Requirement(), new TransitionFilter.Requirement()}; + filter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; + filter.mRequirements[1].mFlags = FLAG_TRANSLUCENT; + filter.mRequirements[1].mNot = true; + + final TransitionInfo openOnly = new TransitionInfoBuilder(TRANSIT_OPEN) + .addChange(TRANSIT_OPEN).build(); + assertTrue(filter.matches(openOnly)); + + final TransitionInfo openAndTranslucent = new TransitionInfoBuilder(TRANSIT_OPEN) + .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); + openAndTranslucent.getChanges().get(1).setFlags(FLAG_TRANSLUCENT); + assertFalse(filter.matches(openAndTranslucent)); + } + @Test public void testRegisteredRemoteTransition() { Transitions transitions = new Transitions(mOrganizer, mTransactionPool, mContext, diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 855a1ccc172d3..051f555fab951 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -276,4 +276,4 @@ public class KeyguardServiceWrapper implements IKeyguardService { public void dump(String prefix, PrintWriter pw) { mKeyguardStateMonitor.dump(prefix, pw); } -} \ No newline at end of file +}