diff --git a/lint-baseline-launcher3.xml b/lint-baseline-launcher3.xml index 469ad942d9..e77c88926d 100644 --- a/lint-baseline-launcher3.xml +++ b/lint-baseline-launcher3.xml @@ -573,4 +573,15 @@ column="42"/> + + + + diff --git a/quickstep/protos_overrides/launcher_atom_extension.proto b/quickstep/protos_overrides/launcher_atom_extension.proto index 6253b41aac..d2dc0cb745 100644 --- a/quickstep/protos_overrides/launcher_atom_extension.proto +++ b/quickstep/protos_overrides/launcher_atom_extension.proto @@ -26,6 +26,7 @@ message ExtendedContainers { oneof Container{ DeviceSearchResultContainer device_search_result_container = 1; + CorrectedDeviceSearchResultContainer corrected_device_search_result_container = 2; } } @@ -33,3 +34,9 @@ message ExtendedContainers { message DeviceSearchResultContainer{ optional int32 query_length = 1; } + +// Represents on-device search result container with results from spell-corrected query. +message CorrectedDeviceSearchResultContainer{ + optional int32 query_length = 1; +} + diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back_left_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_back_left.xml similarity index 82% rename from quickstep/res/drawable/gesture_tutorial_motion_back_left_dark_mode.xml rename to quickstep/res/drawable/gesture_tutorial_motion_back_left.xml index f5ad56916b..a6860fac64 100644 --- a/quickstep/res/drawable/gesture_tutorial_motion_back_left_dark_mode.xml +++ b/quickstep/res/drawable/gesture_tutorial_motion_back_left.xml @@ -1,306 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -313,11 +21,11 @@ @@ -330,11 +38,11 @@ @@ -347,11 +55,11 @@ @@ -364,11 +72,11 @@ @@ -381,11 +89,11 @@ @@ -398,11 +106,11 @@ @@ -415,11 +123,11 @@ @@ -432,11 +140,11 @@ @@ -449,11 +157,11 @@ @@ -466,11 +174,11 @@ @@ -483,11 +191,11 @@ @@ -500,11 +208,11 @@ @@ -517,11 +225,11 @@ @@ -530,203 +238,486 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -973,7 +814,7 @@ @@ -1090,104 +931,104 @@ android:viewportWidth="412"> - - + + - - - - - + android:translateX="-17.875" + android:translateY="322.017"> + android:translateX="123.282" + android:translateY="129.757"> + android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back_right_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_back_right.xml similarity index 82% rename from quickstep/res/drawable/gesture_tutorial_motion_back_right_dark_mode.xml rename to quickstep/res/drawable/gesture_tutorial_motion_back_right.xml index b898dc17a6..b368d9d045 100644 --- a/quickstep/res/drawable/gesture_tutorial_motion_back_right_dark_mode.xml +++ b/quickstep/res/drawable/gesture_tutorial_motion_back_right.xml @@ -1,306 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -313,11 +21,11 @@ @@ -330,11 +38,11 @@ @@ -347,11 +55,11 @@ @@ -364,11 +72,11 @@ @@ -381,11 +89,11 @@ @@ -398,11 +106,11 @@ @@ -415,11 +123,11 @@ @@ -432,11 +140,11 @@ @@ -449,11 +157,11 @@ @@ -466,11 +174,11 @@ @@ -483,11 +191,11 @@ @@ -500,11 +208,11 @@ @@ -517,11 +225,11 @@ @@ -530,203 +238,486 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -973,7 +814,7 @@ @@ -1090,104 +931,104 @@ android:viewportWidth="412"> - - + + - - - - - + android:translateX="-17.875" + android:translateY="322.017"> + android:translateX="565.282" + android:translateY="129.757"> + android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 4eb2d53b46..ef96c963bd 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -423,7 +423,7 @@ public abstract class BaseQuickstepLauncher extends Launcher public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) { ActivityOptionsWrapper activityOptions = mAppTransitionManager.hasControlRemoteAppTransitionPermission() - ? mAppTransitionManager.getActivityLaunchOptions(this, v) + ? mAppTransitionManager.getActivityLaunchOptions(v) : super.getActivityLaunchOptions(v, item); if (mLastTouchUpTime > 0) { ActivityOptionsCompat.setLauncherSourceInfo( diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java index 1090099d2f..661053af18 100644 --- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java +++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java @@ -36,26 +36,48 @@ import androidx.annotation.UiThread; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import java.lang.ref.WeakReference; + +/** + * This class is needed to wrap any animation runner that is a part of the + * RemoteAnimationDefinition: + * - Launcher creates a new instance of the LauncherAppTransitionManagerImpl whenever it is + * created, which in turn registers a new definition + * - When the definition is registered, window manager retains a strong binder reference to the + * runner passed in + * - If the Launcher activity is recreated, the new definition registered will replace the old + * reference in the system's activity record, but until the system server is GC'd, the binder + * reference will still exist, which references the runner in the Launcher process, which + * references the (old) Launcher activity through this class + * + * Instead we make the runner provided to the definition static only holding a weak reference to + * the runner implementation. When this animation manager is destroyed, we remove the Launcher + * reference to the runner, leaving only the weak ref from the runner. + */ @TargetApi(Build.VERSION_CODES.P) -public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat { +public class LauncherAnimationRunner implements RemoteAnimationRunnerCompat { + + private static final RemoteAnimationFactory DEFAULT_FACTORY = + (transit, appTargets, wallpaperTargets, nonAppTargets, result) -> + result.setAnimation(null, null); private final Handler mHandler; private final boolean mStartAtFrontOfQueue; + private final WeakReference mFactory; + private AnimationResult mAnimationResult; /** * @param startAtFrontOfQueue If true, the animation start will be posted at the front of the * queue to minimize latency. */ - public LauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue) { + public LauncherAnimationRunner(Handler handler, RemoteAnimationFactory factory, + boolean startAtFrontOfQueue) { mHandler = handler; + mFactory = new WeakReference<>(factory); mStartAtFrontOfQueue = startAtFrontOfQueue; } - public Handler getHandler() { - return mHandler; - } - // Called only in S+ platform @BinderThread public void onAnimationStart( @@ -67,7 +89,7 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo Runnable r = () -> { finishExistingAnimation(); mAnimationResult = new AnimationResult(() -> mAnimationResult = null, runnable); - onCreateAnimation(transit, appTargets, wallpaperTargets, nonAppTargets, + getFactory().onCreateAnimation(transit, appTargets, wallpaperTargets, nonAppTargets, mAnimationResult); }; if (mStartAtFrontOfQueue) { @@ -92,17 +114,11 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo onAnimationStart(appTargets, new RemoteAnimationTargetCompat[0], runnable); } - /** - * Called on the UI thread when the animation targets are received. The implementation must - * call {@link AnimationResult#setAnimation} with the target animation to be run. - */ - @UiThread - public abstract void onCreateAnimation( - int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, - AnimationResult result); + + private RemoteAnimationFactory getFactory() { + RemoteAnimationFactory factory = mFactory.get(); + return factory != null ? factory : DEFAULT_FACTORY; + } @UiThread private void finishExistingAnimation() { @@ -118,7 +134,10 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo @BinderThread @Override public void onAnimationCancelled() { - postAsyncCallback(mHandler, this::finishExistingAnimation); + postAsyncCallback(mHandler, () -> { + finishExistingAnimation(); + getFactory().onAnimationCancelled(); + }); } public static final class AnimationResult { @@ -153,7 +172,6 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo @UiThread public void setAnimation(AnimatorSet animation, Context context) { setAnimation(animation, context, null, true); - } /** @@ -198,4 +216,28 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo } } } + + /** + * Used with LauncherAnimationRunner as an interface for the runner to call back to the + * implementation. + */ + @FunctionalInterface + public interface RemoteAnimationFactory { + + /** + * Called on the UI thread when the animation targets are received. The implementation must + * call {@link AnimationResult#setAnimation} with the target animation to be run. + */ + void onCreateAnimation(int transit, + RemoteAnimationTargetCompat[] appTargets, + RemoteAnimationTargetCompat[] wallpaperTargets, + RemoteAnimationTargetCompat[] nonAppTargets, + LauncherAnimationRunner.AnimationResult result); + + /** + * Called when the animation is cancelled. This can happen with or without + * the create being called. + */ + default void onAnimationCancelled() { } + } } diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 2d1e304325..a07f27f6fe 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -79,6 +79,7 @@ import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; +import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.icons.FastBitmapDrawable; @@ -197,11 +198,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private RemoteAnimationProvider mRemoteAnimationProvider; // Strong refs to runners which are cleared when the launcher activity is destroyed - private WrappedAnimationRunnerImpl mWallpaperOpenRunner; - private WrappedAnimationRunnerImpl mAppLaunchRunner; - private WrappedAnimationRunnerImpl mKeyguardGoingAwayRunner; + private RemoteAnimationFactory mWallpaperOpenRunner; + private RemoteAnimationFactory mAppLaunchRunner; + private RemoteAnimationFactory mKeyguardGoingAwayRunner; - private WrappedAnimationRunnerImpl mWallpaperOpenTransitionRunner; + private RemoteAnimationFactory mWallpaperOpenTransitionRunner; private RemoteTransitionCompat mLauncherOpenTransition; private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() { @@ -257,11 +258,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @return ActivityOptions with remote animations that controls how the window of the opening * targets are displayed. */ - public ActivityOptionsWrapper getActivityLaunchOptions(Launcher launcher, View v) { + public ActivityOptionsWrapper getActivityLaunchOptions(View v) { boolean fromRecents = isLaunchingFromRecents(v, null /* targets */); RunnableList onEndCallback = new RunnableList(); - mAppLaunchRunner = new AppLaunchAnimationRunner(mHandler, v, onEndCallback); - RemoteAnimationRunnerCompat runner = new WrappedLauncherAnimationRunner<>( + mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback); + RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner( mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */); // Note that this duration is a guess as we do not know if the animation will be a @@ -1006,7 +1007,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN, WindowManagerWrapper.ACTIVITY_TYPE_STANDARD, new RemoteAnimationAdapterCompat( - new WrappedLauncherAnimationRunner<>(mHandler, mWallpaperOpenRunner, + new LauncherAnimationRunner(mHandler, mWallpaperOpenRunner, false /* startAtFrontOfQueue */), CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */)); @@ -1015,7 +1016,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener definition.addRemoteAnimation( WindowManagerWrapper.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, new RemoteAnimationAdapterCompat( - new WrappedLauncherAnimationRunner<>( + new LauncherAnimationRunner( mHandler, mKeyguardGoingAwayRunner, true /* startAtFrontOfQueue */), CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */)); @@ -1035,7 +1036,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener if (hasControlRemoteAppTransitionPermission()) { mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */); mLauncherOpenTransition = RemoteAnimationAdapterCompat.buildRemoteTransition( - new WrappedLauncherAnimationRunner<>(mHandler, mWallpaperOpenTransitionRunner, + new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner, false /* startAtFrontOfQueue */)); mLauncherOpenTransition.addHomeOpenCheck(); SystemUiProxy.INSTANCE.getNoCreate().registerRemoteTransition(mLauncherOpenTransition); @@ -1093,7 +1094,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @return Runner that plays when user goes to Launcher * ie. pressing home, swiping up from nav bar. */ - WrappedAnimationRunnerImpl createWallpaperOpenRunner(boolean fromUnlock) { + RemoteAnimationFactory createWallpaperOpenRunner(boolean fromUnlock) { return new WallpaperOpenLauncherAnimationRunner(mHandler, fromUnlock); } @@ -1243,7 +1244,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Remote animation runner for animation from the app to Launcher, including recents. */ - protected class WallpaperOpenLauncherAnimationRunner implements WrappedAnimationRunnerImpl { + protected class WallpaperOpenLauncherAnimationRunner implements RemoteAnimationFactory { private final Handler mHandler; private final boolean mFromUnlock; @@ -1331,17 +1332,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Remote animation runner for animation to launch an app. */ - private class AppLaunchAnimationRunner implements WrappedAnimationRunnerImpl { + private class AppLaunchAnimationRunner implements RemoteAnimationFactory { - private static final String TRANSITION_LAUNCH_FROM_RECENTS = "transition:LaunchFromRecents"; - private static final String TRANSITION_LAUNCH_FROM_ICON = "transition:LaunchFromIcon"; - - private final Handler mHandler; private final View mV; private final RunnableList mOnEndCallback; - AppLaunchAnimationRunner(Handler handler, View v, RunnableList onEndCallback) { - mHandler = handler; + AppLaunchAnimationRunner(View v, RunnableList onEndCallback) { mV = v; mOnEndCallback = onEndCallback; } @@ -1385,6 +1381,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy, skipFirstFrame); } + + @Override + public void onAnimationCancelled() { + mOnEndCallback.executeAllAndDestroy(); + } } /** diff --git a/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java b/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java deleted file mode 100644 index 16727ecfda..0000000000 --- a/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3; - -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; - -/** - * Used with WrappedLauncherAnimationRunner as an interface for the runner to call back to the - * implementation. - */ -public interface WrappedAnimationRunnerImpl { - - void onCreateAnimation(int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, - LauncherAnimationRunner.AnimationResult result); -} diff --git a/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java deleted file mode 100644 index fcf9857649..0000000000 --- a/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3; - -import android.os.Handler; - -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; - -import java.lang.ref.WeakReference; - -/** - * This class is needed to wrap any animation runner that is a part of the - * RemoteAnimationDefinition: - * - Launcher creates a new instance of the LauncherAppTransitionManagerImpl whenever it is - * created, which in turn registers a new definition - * - When the definition is registered, window manager retains a strong binder reference to the - * runner passed in - * - If the Launcher activity is recreated, the new definition registered will replace the old - * reference in the system's activity record, but until the system server is GC'd, the binder - * reference will still exist, which references the runner in the Launcher process, which - * references the (old) Launcher activity through this class - * - * Instead we make the runner provided to the definition static only holding a weak reference to - * the runner implementation. When this animation manager is destroyed, we remove the Launcher - * reference to the runner, leaving only the weak ref from the runner. - */ -public class WrappedLauncherAnimationRunner - extends LauncherAnimationRunner { - private WeakReference mImpl; - - public WrappedLauncherAnimationRunner( - Handler handler, R animationRunnerImpl, boolean startAtFrontOfQueue) { - super(handler, startAtFrontOfQueue); - mImpl = new WeakReference<>(animationRunnerImpl); - } - - @Override - public void onCreateAnimation(int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, - AnimationResult result) { - R animationRunnerImpl = mImpl.get(); - if (animationRunnerImpl != null) { - animationRunnerImpl.onCreateAnimation(transit, appTargets, wallpaperTargets, - nonAppTargets, result); - } else { - result.setAnimation(null, null); - } - } -} diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index e6333d196b..4503e308e6 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.os.IBinder; import android.util.FloatProperty; +import android.view.CrossWindowBlurListeners; import android.view.SurfaceControl; import android.view.View; import android.view.ViewRootImpl; @@ -41,6 +42,8 @@ import com.android.launcher3.states.StateAnimationConfig; import com.android.systemui.shared.system.BlurUtils; import com.android.systemui.shared.system.WallpaperManagerCompat; +import java.util.function.Consumer; + /** * Controls blur and wallpaper zoom, for the Launcher surface only. */ @@ -96,11 +99,17 @@ public class DepthController implements StateHandler, } }; + private final Consumer mCrossWindowBlurListener = (enabled) -> { + mCrossWindowBlursEnabled = enabled; + dispatchTransactionSurface(); + }; + private final Launcher mLauncher; /** * Blur radius when completely zoomed out, in pixels. */ private int mMaxBlurRadius; + private boolean mCrossWindowBlursEnabled; private WallpaperManagerCompat mWallpaperManager; private SurfaceControl mSurface; /** @@ -123,6 +132,7 @@ public class DepthController implements StateHandler, mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius); mWallpaperManager = new WallpaperManagerCompat(mLauncher); } + if (mLauncher.getRootView() != null && mOnAttachListener == null) { mOnAttachListener = new View.OnAttachStateChangeListener() { @Override @@ -132,13 +142,20 @@ public class DepthController implements StateHandler, if (windowToken != null) { mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth); } + CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(), + mCrossWindowBlurListener); } @Override public void onViewDetachedFromWindow(View view) { + CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener); } }; mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener); + if (mLauncher.getRootView().isAttachedToWindow()) { + CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(), + mCrossWindowBlurListener); + } } } @@ -220,7 +237,8 @@ public class DepthController implements StateHandler, boolean isOverview = mLauncher.isInState(LauncherState.OVERVIEW); boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview; - int blur = opaque || isOverview ? 0 : (int) (mDepth * mMaxBlurRadius); + int blur = opaque || isOverview || !mCrossWindowBlursEnabled + ? 0 : (int) (mDepth * mMaxBlurRadius); new SurfaceControl.Transaction() .setBackgroundBlurRadius(mSurface, blur) .setOpaque(mSurface, opaque) diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index d15113184d..c2c721adf8 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -26,6 +26,7 @@ import android.util.Log; import android.util.Pair; import android.view.View; import android.widget.RemoteViews; +import android.window.SplashScreen; import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogManager; @@ -56,7 +57,7 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler { } Pair options = remoteResponse.getLaunchOptions(view); ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager() - .getActivityLaunchOptions(mLauncher, hostView); + .getActivityLaunchOptions(hostView); if (Utilities.ATLEAST_S && !pendingIntent.isActivity()) { // In the event this pending intent eventually launches an activity, i.e. a trampoline, // use the Quickstep transition animation. @@ -70,6 +71,7 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler { } } activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); Object itemInfo = hostView.getTag(); if (itemInfo instanceof ItemInfo) { mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options); diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index 3d66823c98..fa5ab1cb7b 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -49,9 +49,8 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAnimationRunner; import com.android.launcher3.LauncherAnimationRunner.AnimationResult; +import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory; import com.android.launcher3.R; -import com.android.launcher3.WrappedAnimationRunnerImpl; -import com.android.launcher3.WrappedLauncherAnimationRunner; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; @@ -109,7 +108,7 @@ public final class RecentsActivity extends StatefulActivity { private StateManager mStateManager; // Strong refs to runners which are cleared when the activity is destroyed - private WrappedAnimationRunnerImpl mActivityLaunchAnimationRunner; + private RemoteAnimationFactory mActivityLaunchAnimationRunner; /** * Init drag layer and overview panel views. @@ -206,19 +205,25 @@ public final class RecentsActivity extends StatefulActivity { final TaskView taskView = (TaskView) v; RunnableList onEndCallback = new RunnableList(); - mActivityLaunchAnimationRunner = (int transit, - RemoteAnimationTargetCompat[] appTargets, + mActivityLaunchAnimationRunner = new RemoteAnimationFactory() { + @Override + public void onCreateAnimation(int transit, RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, - AnimationResult result) -> { - AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets, - wallpaperTargets, nonAppTargets); - anim.addListener(resetStateListener()); - result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy, - true /* skipFirstFrame */); + RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) { + AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets, + wallpaperTargets, nonAppTargets); + anim.addListener(resetStateListener()); + result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy, + true /* skipFirstFrame */); + } + + @Override + public void onAnimationCancelled() { + onEndCallback.executeAllAndDestroy(); + } }; - final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner<>( + final LauncherAnimationRunner wrapper = new LauncherAnimationRunner( mUiHandler, mActivityLaunchAnimationRunner, true /* startAtFrontOfQueue */); RemoteAnimationAdapterCompat adapterCompat = new RemoteAnimationAdapterCompat( wrapper, RECENTS_LAUNCH_DURATION, @@ -263,6 +268,7 @@ public final class RecentsActivity extends StatefulActivity { // onActivityStart callback. mFallbackRecentsView.setContentAlpha(1); super.onStart(); + mFallbackRecentsView.updateLocusId(); } @Override @@ -271,6 +277,7 @@ public final class RecentsActivity extends StatefulActivity { // Workaround for b/78520668, explicitly trim memory once UI is hidden onTrimMemory(TRIM_MEMORY_UI_HIDDEN); + mFallbackRecentsView.updateLocusId(); } @Override @@ -362,34 +369,37 @@ public final class RecentsActivity extends StatefulActivity { } private void startHomeInternal() { - WrappedLauncherAnimationRunner runner = new WrappedLauncherAnimationRunner( - getMainThreadHandler(), this::onCreateAnimationToHome, true); + LauncherAnimationRunner runner = new LauncherAnimationRunner( + getMainThreadHandler(), mAnimationToHomeFactory, true); RemoteAnimationAdapterCompat adapterCompat = new RemoteAnimationAdapterCompat(runner, HOME_APPEAR_DURATION, 0); startActivity(createHomeIntent(), ActivityOptionsCompat.makeRemoteAnimation(adapterCompat).toBundle()); } - private void onCreateAnimationToHome( - int transit, RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) { - AnimatorPlaybackController controller = getStateManager() - .createAnimationToNewWorkspace(RecentsState.BG_LAUNCHER, HOME_APPEAR_DURATION); - controller.dispatchOnStart(); + private final RemoteAnimationFactory mAnimationToHomeFactory = + new RemoteAnimationFactory() { + @Override + public void onCreateAnimation(int transit, RemoteAnimationTargetCompat[] appTargets, + RemoteAnimationTargetCompat[] wallpaperTargets, + RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) { + AnimatorPlaybackController controller = getStateManager() + .createAnimationToNewWorkspace(RecentsState.BG_LAUNCHER, HOME_APPEAR_DURATION); + controller.dispatchOnStart(); - RemoteAnimationTargets targets = new RemoteAnimationTargets( - appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING); - for (RemoteAnimationTargetCompat app : targets.apps) { - new Transaction().setAlpha(app.leash.getSurfaceControl(), 1).apply(); + RemoteAnimationTargets targets = new RemoteAnimationTargets( + appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING); + for (RemoteAnimationTargetCompat app : targets.apps) { + new Transaction().setAlpha(app.leash.getSurfaceControl(), 1).apply(); + } + AnimatorSet anim = new AnimatorSet(); + anim.play(controller.getAnimationPlayer()); + anim.setDuration(HOME_APPEAR_DURATION); + result.setAnimation(anim, RecentsActivity.this, + () -> getStateManager().goToState(RecentsState.HOME, false), + true /* skipFirstFrame */); } - AnimatorSet anim = new AnimatorSet(); - anim.play(controller.getAnimationPlayer()); - anim.setDuration(HOME_APPEAR_DURATION); - result.setAnimation(anim, this, - () -> getStateManager().goToState(RecentsState.HOME, false), - true /* skipFirstFrame */); - } + }; @Override protected void collectStateHandlers(List out) { diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java index 32f4c58d7f..9b6afd6a97 100644 --- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java @@ -29,12 +29,8 @@ public class BackGestureTutorialFragment extends TutorialFragment { @Override Integer getFeedbackVideoResId(boolean forDarkMode) { return mTutorialType == TutorialType.RIGHT_EDGE_BACK_NAVIGATION - ? (forDarkMode - ? R.drawable.gesture_tutorial_motion_back_right_dark_mode - : R.drawable.gesture_tutorial_motion_back_right_light_mode) - : (forDarkMode - ? R.drawable.gesture_tutorial_motion_back_left_dark_mode - : R.drawable.gesture_tutorial_motion_back_left_light_mode); + ? R.drawable.gesture_tutorial_motion_back_right + : R.drawable.gesture_tutorial_motion_back_left; } @Nullable diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index 719cb0a032..b1c9ed0361 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -151,6 +151,7 @@ public class StatsLogCompatManager extends StatsLogManager { private Optional mToState = Optional.empty(); private Optional mEditText = Optional.empty(); private SliceItem mSliceItem; + private LauncherAtom.Slice mSlice; StatsCompatLogger(Context context) { mContext = context; @@ -193,7 +194,7 @@ public class StatsLogCompatManager extends StatsLogManager { @Override public StatsLogger withContainerInfo(ContainerInfo containerInfo) { checkState(mItemInfo == DEFAULT_ITEM_INFO, - "ItemInfo and ContainerInfo are mutual exclusive; cannot log both."); + "ItemInfo and ContainerInfo are mutual exclusive; cannot log both."); this.mContainerInfo = Optional.of(containerInfo); return this; } @@ -218,9 +219,21 @@ public class StatsLogCompatManager extends StatsLogManager { @Override public StatsLogger withSliceItem(@NonNull SliceItem sliceItem) { + checkState(mItemInfo == DEFAULT_ITEM_INFO && mSlice == null, + "ItemInfo, Slice and SliceItem are mutual exclusive; cannot set more than one" + + " of them."); this.mSliceItem = checkNotNull(sliceItem, "expected valid sliceItem but received null"); - checkState(mItemInfo == DEFAULT_ITEM_INFO, - "ItemInfo and SliceItem are mutual exclusive; cannot log both."); + return this; + } + + @Override + public StatsLogger withSlice(LauncherAtom.Slice slice) { + checkState(mItemInfo == DEFAULT_ITEM_INFO && mSliceItem == null, + "ItemInfo, Slice and SliceItem are mutual exclusive; cannot set more than one" + + " of them."); + checkNotNull(slice, "expected valid slice but received null"); + checkNotNull(slice.getUri(), "expected valid slice uri but received null"); + this.mSlice = slice; return this; } @@ -231,13 +244,16 @@ public class StatsLogCompatManager extends StatsLogManager { } LauncherAppState appState = LauncherAppState.getInstanceNoCreate(); - if (mSliceItem != null) { + if (mSlice == null && mSliceItem != null) { + mSlice = LauncherAtom.Slice.newBuilder().setUri( + mSliceItem.getSlice().getUri().toString()).build(); + } + + if (mSlice != null) { Executors.MODEL_EXECUTOR.execute( () -> { LauncherAtom.ItemInfo.Builder itemInfoBuilder = - LauncherAtom.ItemInfo.newBuilder().setSlice( - LauncherAtom.Slice.newBuilder().setUri( - mSliceItem.getSlice().getUri().toString())); + LauncherAtom.ItemInfo.newBuilder().setSlice(mSlice); mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo); write(event, applyOverwrites(itemInfoBuilder.build())); }); diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java index 5c6da1611f..98dbd47ba4 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java +++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java @@ -21,15 +21,14 @@ import android.content.Context; import android.os.Handler; import com.android.launcher3.LauncherAnimationRunner; -import com.android.launcher3.WrappedAnimationRunnerImpl; -import com.android.launcher3.WrappedLauncherAnimationRunner; +import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; public abstract class RemoteAnimationProvider { - WrappedAnimationRunnerImpl mAnimationRunner; + RemoteAnimationFactory mAnimationRunner; public abstract AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets); @@ -37,7 +36,7 @@ public abstract class RemoteAnimationProvider { ActivityOptions toActivityOptions(Handler handler, long duration, Context context) { mAnimationRunner = (transit, appTargets, wallpaperTargets, nonApps, result) -> result.setAnimation(createWindowAnimation(appTargets, wallpaperTargets), context); - final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner( + final LauncherAnimationRunner wrapper = new LauncherAnimationRunner( handler, mAnimationRunner, false /* startAtFrontOfQueue */); return ActivityOptionsCompat.makeRemoteAnimation( new RemoteAnimationAdapterCompat(wrapper, duration, 0)); diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 3d33e57a36..a147b6808c 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -41,9 +41,8 @@ import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.LauncherAnimationRunner; +import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory; import com.android.launcher3.R; -import com.android.launcher3.WrappedAnimationRunnerImpl; -import com.android.launcher3.WrappedLauncherAnimationRunner; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskAnimationManager; @@ -101,14 +100,14 @@ public class SplitSelectStateController { return; } // Assume initial mInitialTaskId is for top/left part of screen - WrappedAnimationRunnerImpl initialSplitRunnerWrapped = new SplitLaunchAnimationRunner( + RemoteAnimationFactory initialSplitRunnerWrapped = new SplitLaunchAnimationRunner( mInitialTaskView, 0); - WrappedAnimationRunnerImpl secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner( + RemoteAnimationFactory secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner( taskView, 1); - RemoteAnimationRunnerCompat initialSplitRunner = new WrappedLauncherAnimationRunner( + RemoteAnimationRunnerCompat initialSplitRunner = new LauncherAnimationRunner( new Handler(Looper.getMainLooper()), initialSplitRunnerWrapped, true /* startAtFrontOfQueue */); - RemoteAnimationRunnerCompat secondarySplitRunner = new WrappedLauncherAnimationRunner( + RemoteAnimationRunnerCompat secondarySplitRunner = new LauncherAnimationRunner( new Handler(Looper.getMainLooper()), secondarySplitRunnerWrapped, true /* startAtFrontOfQueue */); ActivityOptions initialOptions = ActivityOptionsCompat.makeRemoteAnimation( @@ -192,7 +191,7 @@ public class SplitSelectStateController { * LEGACY * Remote animation runner for animation to launch an app. */ - private class SplitLaunchAnimationRunner implements WrappedAnimationRunnerImpl { + private class SplitLaunchAnimationRunner implements RemoteAnimationFactory { private final TaskView mV; private final int mTargetState; diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 4332c76648..9c207891ac 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -62,6 +62,7 @@ import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.content.LocusId; import android.content.res.Configuration; import android.graphics.BlendMode; import android.graphics.Canvas; @@ -74,6 +75,7 @@ import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; +import android.os.Bundle; import android.os.UserHandle; import android.text.Layout; import android.text.StaticLayout; @@ -883,7 +885,7 @@ public abstract class RecentsView { - UI_HELPER_EXECUTOR.getHandler().postDelayed(() -> - ActivityManagerWrapper.getInstance().removeTask( - dismissedTaskId), REMOVE_TASK_WAIT_FOR_APP_STOP_MS); - }); + if (LIVE_TILE.get() && dismissedTaskView.isRunningTask()) { + finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, + () -> removeTaskInternal(dismissedTaskId)); + } else { + removeTaskInternal(dismissedTaskId); + } mActivity.getStatsLogManager().logger() .withItemInfo(dismissedTaskView.getItemInfo()) .log(LAUNCHER_TASK_DISMISS_SWIPE_UP); @@ -2472,6 +2475,12 @@ public abstract class RecentsView ActivityManagerWrapper.getInstance().removeTask(dismissedTaskId), + REMOVE_TASK_WAIT_FOR_APP_STOP_MS); + } + /** * @return {@code true} if one of the task thumbnails would intersect/overlap with the * {@link #mSplitPlaceholderView} @@ -3923,4 +3932,19 @@ public abstract class RecentsView mActivity.setLocusContext(id, Bundle.EMPTY)); + } } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 8b6410508f..57cc79c8e4 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -545,7 +545,13 @@ public class TaskView extends FrameLayout implements Reusable { mIsClickableAsLiveTile = false; RecentsView recentsView = getRecentsView(); - RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet(); + final RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet(); + if (targets == null) { + // If the recents animation is cancelled somehow between the parent if block and + // here, try to launch the task as a non live tile task. + launcherNonLiveTileTask(); + return; + } AnimatorSet anim = new AnimatorSet(); TaskViewUtils.composeRecentsLaunchAnimator( @@ -567,17 +573,21 @@ public class TaskView extends FrameLayout implements Reusable { }); anim.start(); } else { - if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) { - // User tapped to select second split screen app - getRecentsView().confirmSplitSelect(this); - } else { - launchTaskAnimated(); - } + launcherNonLiveTileTask(); } mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo()) .log(LAUNCHER_TASK_LAUNCH_TAP); } + private void launcherNonLiveTileTask() { + if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) { + // User tapped to select second split screen app + getRecentsView().confirmSplitSelect(this); + } else { + launchTaskAnimated(); + } + } + /** * Starts the task associated with this view and animates the startup. * @return CompletionStage to indicate the animation completion or null if the launch failed. diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index 9630d274df..a683d01f6c 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -107,7 +107,7 @@ public class FallbackRecentsTest { mOrderSensitiveRules = RuleChain .outerRule(new NavigationModeSwitchRule(mLauncher)) - .around(new FailureWatcher(mDevice)); + .around(new FailureWatcher(mDevice, mLauncher)); mOtherLauncherActivity = context.getPackageManager().queryIntentActivities( getHomeIntentInPackage(context), diff --git a/res/color-night-v31/folder_background_dark.xml b/res/color-night-v31/folder_background_dark.xml new file mode 100644 index 0000000000..a5bd6367d5 --- /dev/null +++ b/res/color-night-v31/folder_background_dark.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-night-v31/popup_color_first.xml b/res/color-night-v31/popup_color_first.xml new file mode 100644 index 0000000000..ba7412859c --- /dev/null +++ b/res/color-night-v31/popup_color_first.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-night-v31/popup_color_second.xml b/res/color-night-v31/popup_color_second.xml new file mode 100644 index 0000000000..efc620532a --- /dev/null +++ b/res/color-night-v31/popup_color_second.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-night-v31/popup_color_third.xml b/res/color-night-v31/popup_color_third.xml new file mode 100644 index 0000000000..591c7ede34 --- /dev/null +++ b/res/color-night-v31/popup_color_third.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-v31/folder_background_light.xml b/res/color-v31/folder_background_light.xml new file mode 100644 index 0000000000..e3c7e7dab1 --- /dev/null +++ b/res/color-v31/folder_background_light.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-v31/popup_color_first.xml b/res/color-v31/popup_color_first.xml new file mode 100644 index 0000000000..28d9155f5e --- /dev/null +++ b/res/color-v31/popup_color_first.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-v31/popup_color_second.xml b/res/color-v31/popup_color_second.xml new file mode 100644 index 0000000000..dec562c046 --- /dev/null +++ b/res/color-v31/popup_color_second.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-v31/popup_color_third.xml b/res/color-v31/popup_color_third.xml new file mode 100644 index 0000000000..582232c536 --- /dev/null +++ b/res/color-v31/popup_color_third.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color/popup_color_first.xml b/res/color/popup_color_first.xml new file mode 100644 index 0000000000..d9999a20c8 --- /dev/null +++ b/res/color/popup_color_first.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/res/color/popup_color_second.xml b/res/color/popup_color_second.xml new file mode 100644 index 0000000000..d9999a20c8 --- /dev/null +++ b/res/color/popup_color_second.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/res/color/popup_color_third.xml b/res/color/popup_color_third.xml new file mode 100644 index 0000000000..d7e9e794e2 --- /dev/null +++ b/res/color/popup_color_third.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/res/drawable/work_apps_toggle_background.xml b/res/drawable/work_apps_toggle_background.xml index b7115f86b5..a47c8fef7c 100644 --- a/res/drawable/work_apps_toggle_background.xml +++ b/res/drawable/work_apps_toggle_background.xml @@ -18,14 +18,18 @@ - + - + diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml index dca3e79c62..1b4f3b984e 100644 --- a/res/layout/widgets_full_sheet.xml +++ b/res/layout/widgets_full_sheet.xml @@ -33,6 +33,8 @@ android:layout_height="match_parent" android:gravity="center" android:visibility="gone" + android:fontFamily="sans-serif-medium" + android:textSize="20sp" tools:text="No widgets available" /> diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml index 97feb23745..919f1b27cf 100644 --- a/res/layout/work_apps_edu.xml +++ b/res/layout/work_apps_edu.xml @@ -42,7 +42,7 @@