Loading quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +98 −5 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import android.provider.Settings; import android.util.Pair; import android.util.Size; import android.view.CrossWindowBlurListeners; import android.view.IRemoteAnimationFinishedCallback; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; Loading @@ -114,6 +115,7 @@ import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.taskbar.LauncherTaskbarUIController; Loading Loading @@ -143,6 +145,9 @@ import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.WorkspaceRevealAnim; import com.android.quickstep.views.FloatingWidgetView; import com.android.quickstep.views.RecentsView; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DelegateLaunchAnimatorController; import com.android.systemui.animation.RemoteAnimationDelegate; import com.android.systemui.shared.system.BlurUtils; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.QuickStepContract; Loading Loading @@ -222,7 +227,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private RemoteAnimationProvider mRemoteAnimationProvider; // Strong refs to runners which are cleared when the launcher activity is destroyed private RemoteAnimationFactory mWallpaperOpenRunner; private RemoteAnimationFactory mAppLaunchRunner; private RemoteAnimationFactory mKeyguardGoingAwayRunner; private RemoteAnimationFactory mWallpaperOpenTransitionRunner; Loading Loading @@ -291,9 +295,18 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public ActivityOptionsWrapper getActivityLaunchOptions(View v) { boolean fromRecents = isLaunchingFromRecents(v, null /* targets */); RunnableList onEndCallback = new RunnableList(); mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback); RemoteAnimationFactory delegateRunner = new AppLaunchAnimationRunner(v, onEndCallback); ItemInfo tag = (ItemInfo) v.getTag(); if (tag != null && tag.shouldUseBackgroundAnimation()) { ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from(v, mStartingWindowListener); if (containerAnimationRunner != null) { delegateRunner = containerAnimationRunner; } } RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner( mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */); mHandler, delegateRunner, true /* startAtFrontOfQueue */); // Note that this duration is a guess as we do not know if the animation will be a // recents launch or not for sure until we know the opening app targets. Loading Loading @@ -1160,7 +1173,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // Also clear strong references to the runners registered with the remote animation // definition so we don't have to wait for the system gc mWallpaperOpenRunner = null; mAppLaunchRunner = null; mKeyguardGoingAwayRunner = null; } } Loading Loading @@ -1754,6 +1766,79 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } /** Remote animation runner to launch an app using System UI's animation library. */ private static class ContainerAnimationRunner implements RemoteAnimationFactory { /** The delegate runner that handles the actual animation. */ private final RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> mDelegate; private ContainerAnimationRunner( RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> delegate) { mDelegate = delegate; } @Nullable private static ContainerAnimationRunner from( View v, StartingWindowListener startingWindowListener) { View viewToUse = findViewWithBackground(v); if (viewToUse == null) { viewToUse = v; } // TODO(b/265134143): create a CUJ type for interaction jank monitoring. ActivityLaunchAnimator.Controller controllerDelegate = ActivityLaunchAnimator.Controller.fromView(viewToUse, null /* cujType */); if (controllerDelegate == null) { return null; } // This wrapper allows us to override the default value, telling the controller that the // current window is below the animating window. ActivityLaunchAnimator.Controller controller = new DelegateLaunchAnimatorController(controllerDelegate) { @Override public boolean isBelowAnimatingWindow() { return true; } }; ActivityLaunchAnimator.Callback callback = task -> ColorUtils.setAlphaComponent( startingWindowListener.getBackgroundColor(), 255); return new ContainerAnimationRunner( new ActivityLaunchAnimator.AnimationDelegate(controller, callback)); } /** Finds the closest parent of [view] (inclusive) with a background drawable. */ @Nullable private static View findViewWithBackground(View view) { View current = view; while (current.getBackground() == null) { if (!(current.getParent() instanceof View)) { return null; } current = (View) view.getParent(); } return current; } @Override public void onAnimationStart(int transit, RemoteAnimationTarget[] appTargets, RemoteAnimationTarget[] wallpaperTargets, RemoteAnimationTarget[] nonAppTargets, LauncherAnimationRunner.AnimationResult result) { mDelegate.onAnimationStart( transit, appTargets, wallpaperTargets, nonAppTargets, result); } @Override public void onAnimationCancelled(boolean isKeyguardOccluded) { mDelegate.onAnimationCancelled(isKeyguardOccluded); } } /** * Class that holds all the variables for the app open animation. */ Loading Loading @@ -1822,8 +1907,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } private static class StartingWindowListener extends IStartingWindowListener.Stub { private class StartingWindowListener extends IStartingWindowListener.Stub { private QuickstepTransitionManager mTransitionManager; private int mBackgroundColor; public void setTransitionManager(QuickstepTransitionManager transitionManager) { mTransitionManager = transitionManager; Loading @@ -1832,6 +1918,13 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onTaskLaunching(int taskId, int supportedType, int color) { mTransitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color)); mBackgroundColor = color; } public int getBackgroundColor() { return mBackgroundColor == Color.TRANSPARENT ? mLauncher.getScrimView().getBackgroundColor() : mBackgroundColor; } } Loading src/com/android/launcher3/LauncherSettings.java +14 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,20 @@ import com.android.launcher3.model.data.ItemInfo; */ public class LauncherSettings { /** * Types of animations. */ public static final class Animation { /** * The default animation for a given view/item info type. */ public static final int DEFAULT = 0; /** * An animation using the view's background. */ public static final int VIEW_BACKGROUND = 1; } /** * Favorites. */ Loading src/com/android/launcher3/config/FeatureFlags.java +1 −1 Original line number Diff line number Diff line Loading @@ -272,7 +272,7 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = new DeviceFlag( "ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION", false, "Enable option to launch search results using the new standardized transitions"); "Enable option to launch search results using the new view container transitions"); public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag( "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false, Loading src/com/android/launcher3/model/data/ItemInfo.java +18 −0 Original line number Diff line number Diff line Loading @@ -47,8 +47,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Animation; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Workspace; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.logger.LauncherAtom.AllAppsContainer; import com.android.launcher3.logger.LauncherAtom.ContainerInfo; Loading Loading @@ -93,6 +95,12 @@ public class ItemInfo { */ public int itemType; /** * One of {@link Animation#DEFAULT}, * {@link Animation#VIEW_BACKGROUND}. */ public int animationType = Animation.DEFAULT; /** * The id of the container that holds this item. For the desktop, this will be * {@link Favorites#CONTAINER_DESKTOP}. For the all applications folder it Loading Loading @@ -185,6 +193,7 @@ public class ItemInfo { rank = info.rank; screenId = info.screenId; itemType = info.itemType; animationType = info.animationType; container = info.container; user = info.user; contentDescription = info.contentDescription; Loading Loading @@ -297,6 +306,15 @@ public class ItemInfo { return container == CONTAINER_HOTSEAT_PREDICTION || container == CONTAINER_PREDICTION; } /** * Returns whether this item should use the background animation. */ public boolean shouldUseBackgroundAnimation() { return animationType == LauncherSettings.Animation.VIEW_BACKGROUND && FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get() && FeatureFlags.ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION.get(); } /** * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info. */ Loading src/com/android/launcher3/touch/ItemClickHandler.java +2 −1 Original line number Diff line number Diff line Loading @@ -343,7 +343,8 @@ public class ItemClickHandler { return; } } if (v != null && launcher.supportsAdaptiveIconAnimation(v)) { if (v != null && launcher.supportsAdaptiveIconAnimation(v) && !item.shouldUseBackgroundAnimation()) { // Preload the icon to reduce latency b/w swapping the floating view with the original. FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */); } Loading Loading
quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +98 −5 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import android.provider.Settings; import android.util.Pair; import android.util.Size; import android.view.CrossWindowBlurListeners; import android.view.IRemoteAnimationFinishedCallback; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; Loading @@ -114,6 +115,7 @@ import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.taskbar.LauncherTaskbarUIController; Loading Loading @@ -143,6 +145,9 @@ import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.WorkspaceRevealAnim; import com.android.quickstep.views.FloatingWidgetView; import com.android.quickstep.views.RecentsView; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DelegateLaunchAnimatorController; import com.android.systemui.animation.RemoteAnimationDelegate; import com.android.systemui.shared.system.BlurUtils; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.QuickStepContract; Loading Loading @@ -222,7 +227,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private RemoteAnimationProvider mRemoteAnimationProvider; // Strong refs to runners which are cleared when the launcher activity is destroyed private RemoteAnimationFactory mWallpaperOpenRunner; private RemoteAnimationFactory mAppLaunchRunner; private RemoteAnimationFactory mKeyguardGoingAwayRunner; private RemoteAnimationFactory mWallpaperOpenTransitionRunner; Loading Loading @@ -291,9 +295,18 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public ActivityOptionsWrapper getActivityLaunchOptions(View v) { boolean fromRecents = isLaunchingFromRecents(v, null /* targets */); RunnableList onEndCallback = new RunnableList(); mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback); RemoteAnimationFactory delegateRunner = new AppLaunchAnimationRunner(v, onEndCallback); ItemInfo tag = (ItemInfo) v.getTag(); if (tag != null && tag.shouldUseBackgroundAnimation()) { ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from(v, mStartingWindowListener); if (containerAnimationRunner != null) { delegateRunner = containerAnimationRunner; } } RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner( mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */); mHandler, delegateRunner, true /* startAtFrontOfQueue */); // Note that this duration is a guess as we do not know if the animation will be a // recents launch or not for sure until we know the opening app targets. Loading Loading @@ -1160,7 +1173,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // Also clear strong references to the runners registered with the remote animation // definition so we don't have to wait for the system gc mWallpaperOpenRunner = null; mAppLaunchRunner = null; mKeyguardGoingAwayRunner = null; } } Loading Loading @@ -1754,6 +1766,79 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } /** Remote animation runner to launch an app using System UI's animation library. */ private static class ContainerAnimationRunner implements RemoteAnimationFactory { /** The delegate runner that handles the actual animation. */ private final RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> mDelegate; private ContainerAnimationRunner( RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> delegate) { mDelegate = delegate; } @Nullable private static ContainerAnimationRunner from( View v, StartingWindowListener startingWindowListener) { View viewToUse = findViewWithBackground(v); if (viewToUse == null) { viewToUse = v; } // TODO(b/265134143): create a CUJ type for interaction jank monitoring. ActivityLaunchAnimator.Controller controllerDelegate = ActivityLaunchAnimator.Controller.fromView(viewToUse, null /* cujType */); if (controllerDelegate == null) { return null; } // This wrapper allows us to override the default value, telling the controller that the // current window is below the animating window. ActivityLaunchAnimator.Controller controller = new DelegateLaunchAnimatorController(controllerDelegate) { @Override public boolean isBelowAnimatingWindow() { return true; } }; ActivityLaunchAnimator.Callback callback = task -> ColorUtils.setAlphaComponent( startingWindowListener.getBackgroundColor(), 255); return new ContainerAnimationRunner( new ActivityLaunchAnimator.AnimationDelegate(controller, callback)); } /** Finds the closest parent of [view] (inclusive) with a background drawable. */ @Nullable private static View findViewWithBackground(View view) { View current = view; while (current.getBackground() == null) { if (!(current.getParent() instanceof View)) { return null; } current = (View) view.getParent(); } return current; } @Override public void onAnimationStart(int transit, RemoteAnimationTarget[] appTargets, RemoteAnimationTarget[] wallpaperTargets, RemoteAnimationTarget[] nonAppTargets, LauncherAnimationRunner.AnimationResult result) { mDelegate.onAnimationStart( transit, appTargets, wallpaperTargets, nonAppTargets, result); } @Override public void onAnimationCancelled(boolean isKeyguardOccluded) { mDelegate.onAnimationCancelled(isKeyguardOccluded); } } /** * Class that holds all the variables for the app open animation. */ Loading Loading @@ -1822,8 +1907,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } private static class StartingWindowListener extends IStartingWindowListener.Stub { private class StartingWindowListener extends IStartingWindowListener.Stub { private QuickstepTransitionManager mTransitionManager; private int mBackgroundColor; public void setTransitionManager(QuickstepTransitionManager transitionManager) { mTransitionManager = transitionManager; Loading @@ -1832,6 +1918,13 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onTaskLaunching(int taskId, int supportedType, int color) { mTransitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color)); mBackgroundColor = color; } public int getBackgroundColor() { return mBackgroundColor == Color.TRANSPARENT ? mLauncher.getScrimView().getBackgroundColor() : mBackgroundColor; } } Loading
src/com/android/launcher3/LauncherSettings.java +14 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,20 @@ import com.android.launcher3.model.data.ItemInfo; */ public class LauncherSettings { /** * Types of animations. */ public static final class Animation { /** * The default animation for a given view/item info type. */ public static final int DEFAULT = 0; /** * An animation using the view's background. */ public static final int VIEW_BACKGROUND = 1; } /** * Favorites. */ Loading
src/com/android/launcher3/config/FeatureFlags.java +1 −1 Original line number Diff line number Diff line Loading @@ -272,7 +272,7 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = new DeviceFlag( "ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION", false, "Enable option to launch search results using the new standardized transitions"); "Enable option to launch search results using the new view container transitions"); public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag( "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false, Loading
src/com/android/launcher3/model/data/ItemInfo.java +18 −0 Original line number Diff line number Diff line Loading @@ -47,8 +47,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Animation; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Workspace; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.logger.LauncherAtom.AllAppsContainer; import com.android.launcher3.logger.LauncherAtom.ContainerInfo; Loading Loading @@ -93,6 +95,12 @@ public class ItemInfo { */ public int itemType; /** * One of {@link Animation#DEFAULT}, * {@link Animation#VIEW_BACKGROUND}. */ public int animationType = Animation.DEFAULT; /** * The id of the container that holds this item. For the desktop, this will be * {@link Favorites#CONTAINER_DESKTOP}. For the all applications folder it Loading Loading @@ -185,6 +193,7 @@ public class ItemInfo { rank = info.rank; screenId = info.screenId; itemType = info.itemType; animationType = info.animationType; container = info.container; user = info.user; contentDescription = info.contentDescription; Loading Loading @@ -297,6 +306,15 @@ public class ItemInfo { return container == CONTAINER_HOTSEAT_PREDICTION || container == CONTAINER_PREDICTION; } /** * Returns whether this item should use the background animation. */ public boolean shouldUseBackgroundAnimation() { return animationType == LauncherSettings.Animation.VIEW_BACKGROUND && FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get() && FeatureFlags.ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION.get(); } /** * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info. */ Loading
src/com/android/launcher3/touch/ItemClickHandler.java +2 −1 Original line number Diff line number Diff line Loading @@ -343,7 +343,8 @@ public class ItemClickHandler { return; } } if (v != null && launcher.supportsAdaptiveIconAnimation(v)) { if (v != null && launcher.supportsAdaptiveIconAnimation(v) && !item.shouldUseBackgroundAnimation()) { // Preload the icon to reduce latency b/w swapping the floating view with the original. FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */); } Loading