Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3a7c9a3 authored by Evan Rosky's avatar Evan Rosky Committed by Automerger Merge Worker
Browse files

Merge "Add leashes in launcher adapters in lieu of cross-process sync" into...

Merge "Add leashes in launcher adapters in lieu of cross-process sync" into sc-dev am: bd26d8f1 am: d293bd35

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14441864

Change-Id: Ic143e811c46ea8e47e50bd9668494217a8212974
parents d10323e0 d293bd35
Loading
Loading
Loading
Loading
+54 −24
Original line number Diff line number Diff line
@@ -22,6 +22,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_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;

import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
@@ -226,18 +227,11 @@ public class Transitions implements RemoteCallable<Transitions> {
    }

    /**
     * Reparents all participants into a shared parent and orders them based on: the global transit
     * type, their transit mode, and their destination z-order.
     * Sets up visibility/alpha/transforms to resemble the starting state of an animation.
     */
    private static void setupStartState(@NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
        boolean isOpening = isOpeningType(info.getType());
        if (info.getRootLeash().isValid()) {
            t.show(info.getRootLeash());
        }
        // Put animating stuff above this line and put static stuff below it.
        int zSplitLine = info.getChanges().size();
        // changes should be ordered top-to-bottom in z
        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final SurfaceControl leash = change.getLeash();
@@ -254,6 +248,52 @@ public class Transitions implements RemoteCallable<Transitions> {
                continue;
            }

            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
                t.show(leash);
                t.setMatrix(leash, 1, 0, 0, 1);
                if (isOpening
                        // If this is a transferred starting window, we want it immediately visible.
                        && (change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
                    t.setAlpha(leash, 0.f);
                    // fix alpha in finish transaction in case the animator itself no-ops.
                    finishT.setAlpha(leash, 1.f);
                }
            } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
                // Wallpaper is a bit of an anomaly: it's visibility is tied to other WindowStates.
                // As a result, we actually can't hide it's WindowToken because there may not be a
                // transition associated with it becoming visible again. Fortunately, since it is
                // always z-ordered to the back, we don't have to worry about it flickering to the
                // front during reparenting, so the hide here isn't necessary for it.
                if ((change.getFlags() & FLAG_IS_WALLPAPER) == 0) {
                    finishT.hide(leash);
                }
            }
        }
    }

    /**
     * Reparents all participants into a shared parent and orders them based on: the global transit
     * type, their transit mode, and their destination z-order.
     */
    private static void setupAnimHierarchy(@NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
        boolean isOpening = isOpeningType(info.getType());
        if (info.getRootLeash().isValid()) {
            t.show(info.getRootLeash());
        }
        // Put animating stuff above this line and put static stuff below it.
        int zSplitLine = info.getChanges().size();
        // changes should be ordered top-to-bottom in z
        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final SurfaceControl leash = change.getLeash();
            final int mode = info.getChanges().get(i).getMode();

            // Don't reparent anything that isn't independent within its parents
            if (!TransitionInfo.isIndependent(change, info)) {
                continue;
            }

            boolean hasParent = change.getParent() != null;

            if (!hasParent) {
@@ -263,24 +303,12 @@ public class Transitions implements RemoteCallable<Transitions> {
            }
            // Put all the OPEN/SHOW on top
            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
                t.show(leash);
                t.setMatrix(leash, 1, 0, 0, 1);
                if (isOpening) {
                    // put on top with 0 alpha
                    // put on top
                    t.setLayer(leash, zSplitLine + info.getChanges().size() - i);
                    if ((change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) {
                        // This received a transferred starting window, so make it immediately
                        // visible.
                        t.setAlpha(leash, 1.f);
                } else {
                        t.setAlpha(leash, 0.f);
                        // fix alpha in finish transaction in case the animator itself no-ops.
                        finishT.setAlpha(leash, 1.f);
                    }
                } else {
                    // put on bottom and leave it visible
                    // put on bottom
                    t.setLayer(leash, zSplitLine - i);
                    t.setAlpha(leash, 1.f);
                }
            } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
                if (isOpening) {
@@ -290,7 +318,7 @@ public class Transitions implements RemoteCallable<Transitions> {
                    // put on top
                    t.setLayer(leash, zSplitLine + info.getChanges().size() - i);
                }
            } else { // CHANGE
            } else { // CHANGE or other
                t.setLayer(leash, zSplitLine + info.getChanges().size() - i);
            }
        }
@@ -329,6 +357,8 @@ public class Transitions implements RemoteCallable<Transitions> {
        active.mInfo = info;
        active.mStartT = t;
        active.mFinishT = finishT;
        setupStartState(active.mInfo, active.mStartT, active.mFinishT);

        if (activeIdx > 0) {
            // This is now playing at the same time as an existing animation, so try merging it.
            attemptMergeTransition(mActiveTransitions.get(0), active);
@@ -357,7 +387,7 @@ public class Transitions implements RemoteCallable<Transitions> {
    }

    void playTransition(@NonNull ActiveTransition active) {
        setupStartState(active.mInfo, active.mStartT, active.mFinishT);
        setupAnimHierarchy(active.mInfo, active.mStartT, active.mFinishT);

        // If a handler already chose to run this animation, try delegating to it first.
        if (active.mHandler != null) {
+13 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import android.annotation.SuppressLint;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
@@ -158,10 +159,11 @@ public class RemoteAnimationAdapterCompat {
            public void startAnimation(IBinder token, TransitionInfo info,
                    SurfaceControl.Transaction t,
                    IRemoteTransitionFinishedCallback finishCallback) {
                final ArrayMap<SurfaceControl, SurfaceControl> leashMap = new ArrayMap<>();
                final RemoteAnimationTargetCompat[] appsCompat =
                        RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */);
                        RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */, t, leashMap);
                final RemoteAnimationTargetCompat[] wallpapersCompat =
                        RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */);
                        RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */, t, leashMap);
                // TODO(bc-unlock): Build wrapped object for non-apps target.
                final RemoteAnimationTargetCompat[] nonAppsCompat =
                        new RemoteAnimationTargetCompat[0];
@@ -211,7 +213,7 @@ public class RemoteAnimationAdapterCompat {
                    // Need to "boost" the closing things since that's what launcher expects.
                    for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                        final TransitionInfo.Change change = info.getChanges().get(i);
                        final SurfaceControl leash = change.getLeash();
                        final SurfaceControl leash = leashMap.get(change.getLeash());
                        final int mode = info.getChanges().get(i).getMode();
                        // Only deal with independent layers
                        if (!TransitionInfo.isIndependent(change, info)) continue;
@@ -227,14 +229,14 @@ public class RemoteAnimationAdapterCompat {
                    }
                } else {
                    if (launcherTask != null) {
                        counterLauncher.addChild(t, launcherTask.getLeash());
                        counterLauncher.addChild(t, leashMap.get(launcherTask.getLeash()));
                    }
                    if (wallpaper != null && rotateDelta != 0 && wallpaper.getParent() != null) {
                        counterWallpaper.setup(t, info.getChange(wallpaper.getParent()).getLeash(),
                                rotateDelta, displayW, displayH);
                        if (counterWallpaper.mSurface != null) {
                            t.setLayer(counterWallpaper.mSurface, -1);
                            counterWallpaper.addChild(t, wallpaper.getLeash());
                            counterWallpaper.addChild(t, leashMap.get(wallpaper.getLeash()));
                        }
                    }
                }
@@ -252,6 +254,12 @@ public class RemoteAnimationAdapterCompat {
                            for (int i = 0; i < info.getChanges().size(); ++i) {
                                info.getChanges().get(i).getLeash().release();
                            }
                            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
                            for (int i = 0; i < leashMap.size(); ++i) {
                                if (leashMap.keyAt(i) == leashMap.valueAt(i)) continue;
                                t.remove(leashMap.valueAt(i));
                            }
                            t.apply();
                            finishCallback.onTransitionFinished(null /* wct */);
                        } catch (RemoteException e) {
                            Log.e("ActivityOptionsCompat", "Failed to call app controlled animation"
+104 −4
Original line number Diff line number Diff line
@@ -17,11 +17,21 @@
package com.android.systemui.shared.system;

import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
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_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.WindowConfiguration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.WindowManager;
@@ -97,10 +107,94 @@ public class RemoteAnimationTargetCompat {
        }
    }

    public RemoteAnimationTargetCompat(TransitionInfo.Change change, int order) {

    /**
     * Almost a copy of Transitions#setupStartState.
     * TODO: remove when there is proper cross-process transaction sync.
     */
    @SuppressLint("NewApi")
    private static void setupLeash(@NonNull SurfaceControl leash,
            @NonNull TransitionInfo.Change change, int layer,
            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
        boolean isOpening = info.getType() == TRANSIT_OPEN || info.getType() == TRANSIT_TO_FRONT;
        // Put animating stuff above this line and put static stuff below it.
        int zSplitLine = info.getChanges().size();
        // changes should be ordered top-to-bottom in z
        final int mode = change.getMode();

        // Don't move anything that isn't independent within its parents
        if (!TransitionInfo.isIndependent(change, info)) {
            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT || mode == TRANSIT_CHANGE) {
                t.show(leash);
                t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
            }
            return;
        }

        boolean hasParent = change.getParent() != null;

        if (!hasParent) {
            t.reparent(leash, info.getRootLeash());
            t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x,
                    change.getStartAbsBounds().top - info.getRootOffset().y);
        }
        t.show(leash);
        // Put all the OPEN/SHOW on top
        if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
            if (isOpening) {
                t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
                if ((change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
                    // if transferred, it should be left visible.
                    t.setAlpha(leash, 0.f);
                }
            } else {
                // put on bottom and leave it visible
                t.setLayer(leash, zSplitLine - layer);
            }
        } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
            if (isOpening) {
                // put on bottom and leave visible
                t.setLayer(leash, zSplitLine - layer);
            } else {
                // put on top
                t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
            }
        } else { // CHANGE
            t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
        }
    }

    @SuppressLint("NewApi")
    private static SurfaceControl createLeash(TransitionInfo info, TransitionInfo.Change change,
            int order, SurfaceControl.Transaction t) {
        // TODO: once we can properly sync transactions across process, then get rid of this leash.
        if (change.getParent() != null && (change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
            // Special case for wallpaper atm. Normally these are left alone; but, a quirk of
            // making leashes means we have to handle them specially.
            return change.getLeash();
        }
        SurfaceControl leashSurface = new SurfaceControl.Builder()
                .setName(change.getLeash().toString() + "_transition-leash")
                .setContainerLayer().setParent(change.getParent() == null ? info.getRootLeash()
                        : info.getChange(change.getParent()).getLeash()).build();
        // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
        setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
        t.reparent(change.getLeash(), leashSurface);
        t.setAlpha(change.getLeash(), 1.0f);
        t.show(change.getLeash());
        t.setPosition(change.getLeash(), 0, 0);
        t.setLayer(change.getLeash(), 0);
        return leashSurface;
    }

    public RemoteAnimationTargetCompat(TransitionInfo.Change change, int order,
            TransitionInfo info, SurfaceControl.Transaction t) {
        taskId = change.getTaskInfo() != null ? change.getTaskInfo().taskId : -1;
        mode = newModeToLegacyMode(change.getMode());
        leash = new SurfaceControlCompat(change.getLeash());

        // TODO: once we can properly sync transactions across process, then get rid of this leash.
        leash = new SurfaceControlCompat(createLeash(info, change, order, t));

        isTranslucent = (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0
                || (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0;
        clipRect = null;
@@ -139,15 +233,21 @@ public class RemoteAnimationTargetCompat {
     *
     * @param wallpapers If true, this will return wallpaper targets; otherwise it returns
     *                   non-wallpaper targets.
     * @param leashMap Temporary map of change leash -> launcher leash. Is an output, so should be
     *                 populated by this function. If null, it is ignored.
     */
    public static RemoteAnimationTargetCompat[] wrap(TransitionInfo info, boolean wallpapers) {
    public static RemoteAnimationTargetCompat[] wrap(TransitionInfo info, boolean wallpapers,
            SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
        final ArrayList<RemoteAnimationTargetCompat> out = new ArrayList<>();
        for (int i = 0; i < info.getChanges().size(); i++) {
            boolean changeIsWallpaper =
                    (info.getChanges().get(i).getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0;
            if (wallpapers != changeIsWallpaper) continue;
            out.add(new RemoteAnimationTargetCompat(info.getChanges().get(i),
                    info.getChanges().size() - i));
                    info.getChanges().size() - i, info, t));
            if (leashMap == null) continue;
            leashMap.put(info.getChanges().get(i).getLeash(),
                    out.get(out.size() - 1).leash.mSurfaceControl);
        }
        return out.toArray(new RemoteAnimationTargetCompat[out.size()]);
    }
+26 −9
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.graphics.Rect;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
import android.view.IRecentsAnimationController;
import android.view.SurfaceControl;
@@ -108,10 +109,11 @@ public class RemoteTransitionCompat implements Parcelable {
            public void startAnimation(IBinder transition, TransitionInfo info,
                    SurfaceControl.Transaction t,
                    IRemoteTransitionFinishedCallback finishedCallback) {
                final ArrayMap<SurfaceControl, SurfaceControl> leashMap = new ArrayMap<>();
                final RemoteAnimationTargetCompat[] apps =
                        RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */);
                        RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */, t, leashMap);
                final RemoteAnimationTargetCompat[] wallpapers =
                        RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */);
                        RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */, t, leashMap);
                // TODO(b/177438007): Move this set-up logic into launcher's animation impl.
                mToken = transition;
                // This transition is for opening recents, so recents is on-top. We want to draw
@@ -120,7 +122,8 @@ public class RemoteTransitionCompat implements Parcelable {
                for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                    final TransitionInfo.Change change = info.getChanges().get(i);
                    if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) {
                        t.setLayer(change.getLeash(), info.getChanges().size() * 3 - i);
                        t.setLayer(leashMap.get(change.getLeash()),
                                info.getChanges().size() * 3 - i);
                        if (change.getTaskInfo() != null) {
                            pausingTask = change.getTaskInfo().token;
                        }
@@ -131,7 +134,8 @@ public class RemoteTransitionCompat implements Parcelable {
                    t.setAlpha(wallpapers[i].leash.mSurfaceControl, 1);
                }
                t.apply();
                mRecentsSession.setup(controller, info, finishedCallback, pausingTask);
                mRecentsSession.setup(controller, info, finishedCallback, pausingTask,
                        leashMap);
                recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0),
                        new Rect());
            }
@@ -173,9 +177,11 @@ public class RemoteTransitionCompat implements Parcelable {
        private WindowContainerToken mPausingTask = null;
        private TransitionInfo mInfo = null;
        private SurfaceControl mOpeningLeash = null;
        private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;

        void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info,
                IRemoteTransitionFinishedCallback finishCB, WindowContainerToken pausingTask) {
                IRemoteTransitionFinishedCallback finishCB, WindowContainerToken pausingTask,
                ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
            if (mInfo != null) {
                throw new IllegalStateException("Trying to run a new recents animation while"
                        + " recents is already active.");
@@ -184,6 +190,7 @@ public class RemoteTransitionCompat implements Parcelable {
            mInfo = info;
            mFinishCB = finishCB;
            mPausingTask = pausingTask;
            mLeashMap = leashMap;
        }

        @SuppressLint("NewApi")
@@ -211,11 +218,14 @@ public class RemoteTransitionCompat implements Parcelable {
            }
            // We are receiving a new opening task, so convert to onTaskAppeared.
            final int layer = mInfo.getChanges().size() * 3;
            t.reparent(mOpeningLeash, mInfo.getRootLeash());
            t.setLayer(mOpeningLeash, layer);
            t.hide(mOpeningLeash);
            final RemoteAnimationTargetCompat target = new RemoteAnimationTargetCompat(
                    openingTask, layer, mInfo, t);
            mLeashMap.put(mOpeningLeash, target.leash.mSurfaceControl);
            t.reparent(target.leash.mSurfaceControl, mInfo.getRootLeash());
            t.setLayer(target.leash.mSurfaceControl, layer);
            t.hide(target.leash.mSurfaceControl);
            t.apply();
            recents.onTaskAppeared(new RemoteAnimationTargetCompat(openingTask, layer));
            recents.onTaskAppeared(target);
            return true;
        }

@@ -272,6 +282,12 @@ public class RemoteTransitionCompat implements Parcelable {
            }
            // Release surface references now. This is apparently to free GPU
            // memory while doing quick operations (eg. during CTS).
            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            for (int i = 0; i < mLeashMap.size(); ++i) {
                if (mLeashMap.keyAt(i) == mLeashMap.valueAt(i)) continue;
                t.remove(mLeashMap.valueAt(i));
            }
            t.apply();
            for (int i = 0; i < mInfo.getChanges().size(); ++i) {
                mInfo.getChanges().get(i).getLeash().release();
            }
@@ -281,6 +297,7 @@ public class RemoteTransitionCompat implements Parcelable {
            mPausingTask = null;
            mInfo = null;
            mOpeningLeash = null;
            mLeashMap = null;
        }

        @Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
+11 −11
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ public class RemoteTransitionTest extends SysuiTestCase {
                .addChange(TRANSIT_CLOSE, 0 /* flags */)
                .addChange(TRANSIT_OPEN, FLAG_IS_WALLPAPER).build();
        // Check non-wallpaper extraction
        RemoteAnimationTargetCompat[] wrapped =
                RemoteAnimationTargetCompat.wrap(combined, false /* wallpapers */);
        RemoteAnimationTargetCompat[] wrapped = RemoteAnimationTargetCompat.wrap(combined,
                false /* wallpapers */, mock(SurfaceControl.Transaction.class), null /* leashes */);
        assertEquals(2, wrapped.length);
        int changeLayer = -1;
        int closeLayer = -1;
@@ -86,8 +86,8 @@ public class RemoteTransitionTest extends SysuiTestCase {
        assertTrue(closeLayer < changeLayer);

        // Check wallpaper extraction
        RemoteAnimationTargetCompat[] wallps =
                RemoteAnimationTargetCompat.wrap(combined, true /* wallpapers */);
        RemoteAnimationTargetCompat[] wallps = RemoteAnimationTargetCompat.wrap(combined,
                true /* wallpapers */, mock(SurfaceControl.Transaction.class), null /* leashes */);
        assertEquals(1, wallps.length);
        assertTrue(wallps[0].prefixOrderIndex < closeLayer);
        assertEquals(MODE_OPENING, wallps[0].mode);
@@ -95,16 +95,15 @@ public class RemoteTransitionTest extends SysuiTestCase {

    @Test
    public void testLegacyTargetWrapper() {
        TransitionInfo tinfo = new TransitionInfoBuilder(TRANSIT_CLOSE)
                .addChange(TRANSIT_CHANGE, FLAG_TRANSLUCENT).build();
        final TransitionInfo.Change change = tinfo.getChanges().get(0);
        final Rect endBounds = new Rect(40, 60, 140, 200);
        final TransitionInfo.Change change =
                new TransitionInfo.Change(null /* token */, null /* leash */);
        change.setTaskInfo(createTaskInfo(1 /* taskId */, ACTIVITY_TYPE_HOME));
        change.setMode(TRANSIT_CHANGE);
        change.setEndAbsBounds(endBounds);
        change.setEndRelOffset(0, 0);
        change.setFlags(FLAG_TRANSLUCENT);
        final RemoteAnimationTargetCompat wrapped =
                new RemoteAnimationTargetCompat(change, 0 /* order */);
        final RemoteAnimationTargetCompat wrapped = new RemoteAnimationTargetCompat(change,
                0 /* order */, tinfo, mock(SurfaceControl.Transaction.class));
        assertEquals(ACTIVITY_TYPE_HOME, wrapped.activityType);
        assertEquals(new Rect(0, 0, 100, 140), wrapped.localBounds);
        assertEquals(endBounds, wrapped.screenSpaceBounds);
@@ -122,7 +121,7 @@ public class RemoteTransitionTest extends SysuiTestCase {
        TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode,
                @TransitionInfo.ChangeFlags int flags) {
            final TransitionInfo.Change change =
                    new TransitionInfo.Change(null /* token */, null /* leash */);
                    new TransitionInfo.Change(null /* token */, createMockSurface(true));
            change.setMode(mode);
            change.setFlags(flags);
            mInfo.addChange(change);
@@ -138,6 +137,7 @@ public class RemoteTransitionTest extends SysuiTestCase {
        SurfaceControl sc = mock(SurfaceControl.class);
        if (valid) {
            doReturn(true).when(sc).isValid();
            doReturn("TestSurface").when(sc).toString();
        }
        return sc;
    }