From 27c8c5ec7d7d1723b2a43253c03c2fc1c7f02739 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 11 May 2023 18:32:55 -0700 Subject: [PATCH] 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 --- .../android/wm/shell/util/TransitionUtil.java | 21 +++++++- .../systemui/keyguard/KeyguardService.java | 50 ++++++------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java index 402b0ce7c87cb..a33317ee66d70 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java @@ -252,11 +252,20 @@ public class TransitionUtil { public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order, TransitionInfo info, SurfaceControl.Transaction t, @Nullable ArrayMap 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 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), diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 8b6bd24861173..8af7c3486fb1c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -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 leashMap) { final ArrayList 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 mFinishCallbacks = new ArrayMap<>(); + private final ArrayMap 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); }