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

Commit 27c8c5ec authored by Evan Rosky's avatar Evan Rosky
Browse files

Fix graphical glitches on keyguard-unlock with PIP

Since keyguard animations sync transactions to view rendering,
it's possible for them to apply changes after the finishtransaction,
so wrap containers in leashes so that we can just detach them.

Also, remove the single-task-opening restriction now that keyguard
animations support multiple tasks.

Bug: 278886491
Test: app in pip, turn screen off, turn screen on+unlock.
Change-Id: Iea2fc2d5ae16c59e7983b87fea2cd62d327f4ac9
parent 8020b8b6
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -252,11 +252,20 @@ public class TransitionUtil {
    public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
            TransitionInfo info, SurfaceControl.Transaction t,
            @Nullable ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
        return newTarget(change, order, false /* forceTranslucent */, info, t, leashMap);
    }

    /**
     * Creates a new RemoteAnimationTarget from the provided change info
     */
    public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
            boolean forceTranslucent, TransitionInfo info, SurfaceControl.Transaction t,
            @Nullable ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
        final SurfaceControl leash = createLeash(info, change, order, t);
        if (leashMap != null) {
            leashMap.put(change.getLeash(), leash);
        }
        return newTarget(change, order, leash);
        return newTarget(change, order, leash, forceTranslucent);
    }

    /**
@@ -264,6 +273,14 @@ public class TransitionUtil {
     */
    public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
            SurfaceControl leash) {
        return newTarget(change, order, leash, false /* forceTranslucent */);
    }

    /**
     * Creates a new RemoteAnimationTarget from the provided change and leash
     */
    public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
            SurfaceControl leash, boolean forceTranslucent) {
        if (isDividerBar(change)) {
            return getDividerTarget(change, leash);
        }
@@ -293,7 +310,7 @@ public class TransitionUtil {
                // TODO: once we can properly sync transactions across process,
                // then get rid of this leash.
                leash,
                (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0,
                forceTranslucent || (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0,
                null,
                // TODO(shell-transitions): we need to send content insets? evaluate how its used.
                new Rect(0, 0, 0, 0),
+15 −37
Original line number Diff line number Diff line
@@ -44,8 +44,6 @@ import android.app.ActivityTaskManager;
import android.app.Service;
import android.app.WindowConfiguration;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -81,6 +79,7 @@ import com.android.systemui.SystemUIApplication;
import com.android.systemui.settings.DisplayTracker;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.util.TransitionUtil;

import java.util.ArrayList;

@@ -109,7 +108,8 @@ public class KeyguardService extends Service {
        }
    }

    private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers) {
    private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
            SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
        final ArrayList<RemoteAnimationTarget> out = new ArrayList<>();
        for (int i = 0; i < info.getChanges().size(); i++) {
            boolean changeIsWallpaper =
@@ -119,32 +119,14 @@ public class KeyguardService extends Service {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
            final int taskId = taskInfo != null ? change.getTaskInfo().taskId : -1;
            boolean isNotInRecents;
            WindowConfiguration windowConfiguration = null;
            if (taskInfo != null) {
                if (taskInfo.getConfiguration() != null) {
                    windowConfiguration =
                            change.getTaskInfo().getConfiguration().windowConfiguration;
                }
                isNotInRecents = !change.getTaskInfo().isRunning;
            } else {
                isNotInRecents = true;
            }
            Rect localBounds = new Rect(change.getEndAbsBounds());
            localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y);

            final RemoteAnimationTarget target = new RemoteAnimationTarget(
                    taskId,
                    newModeToLegacyMode(change.getMode()),
                    change.getLeash(),
                    (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0
                            || (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
                    null /* clipRect */,
                    new Rect(0, 0, 0, 0) /* contentInsets */,

            final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
                    // wallpapers go into the "below" layer space
                    info.getChanges().size() - i,
                    new Point(), localBounds, new Rect(change.getEndAbsBounds()),
                    windowConfiguration, isNotInRecents, null /* startLeash */,
                    change.getStartAbsBounds(), taskInfo, false /* allowEnterPip */);
                    // keyguard treats wallpaper as translucent
                    (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
                    info, t, leashMap);

            // Use hasAnimatingParent to mark the anything below root task
            if (taskId != -1 && change.getParent() != null) {
                final TransitionInfo.Change parentChange = info.getChange(change.getParent());
@@ -182,31 +164,27 @@ public class KeyguardService extends Service {
        return new IRemoteTransition.Stub() {
            final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
                    new ArrayMap<>();
            private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>();

            @Override
            public void startAnimation(IBinder transition, TransitionInfo info,
                    SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
                    throws RemoteException {
                Slog.d(TAG, "Starts IRemoteAnimationRunner: info=" + info);
                final RemoteAnimationTarget[] apps = wrap(info, false /* wallpapers */);
                final RemoteAnimationTarget[] wallpapers = wrap(info, true /* wallpapers */);
                final RemoteAnimationTarget[] apps =
                        wrap(info, false /* wallpapers */, t, mLeashMap);
                final RemoteAnimationTarget[] wallpapers =
                        wrap(info, true /* wallpapers */, t, mLeashMap);
                final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];

                // Sets the alpha to 0 for the opening root task for fade in animation. And since
                // the fade in animation can only apply on the first opening app, so set alpha to 1
                // for anything else.
                boolean foundOpening = false;
                for (RemoteAnimationTarget target : apps) {
                    if (target.taskId != -1
                            && target.mode == RemoteAnimationTarget.MODE_OPENING
                            && !target.hasAnimatingParent) {
                        if (foundOpening) {
                            Log.w(TAG, "More than one opening target");
                            t.setAlpha(target.leash, 1.0f);
                            continue;
                        }
                        t.setAlpha(target.leash, 0.0f);
                        foundOpening = true;
                    } else {
                        t.setAlpha(target.leash, 1.0f);
                    }