Merge "Fix bubble tx when the bar is collapsed" into main
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index bca7494..5413601 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -20,7 +20,7 @@
aconfig_declarations {
name: "com_android_launcher3_flags",
package: "com.android.launcher3",
- container: "system_ext",
+ container: "system",
srcs: ["**/*.aconfig"],
}
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 0da2df1..f877fd8 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -1,5 +1,5 @@
package: "com.android.launcher3"
-container: "system_ext"
+container: "system"
flag {
name: "enable_expanding_pause_work_button"
@@ -388,3 +388,13 @@
description: "Refactor grid migration such that the code is simpler to understand and update"
bug: "358399271"
}
+
+flag {
+ name: "accessibility_scroll_on_allapps"
+ namespace: "launcher"
+ description: "Scroll to item position if accessibility focused"
+ bug: "265392261"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/aconfig/launcher_overview.aconfig b/aconfig/launcher_overview.aconfig
index 23733a4..853faf8 100644
--- a/aconfig/launcher_overview.aconfig
+++ b/aconfig/launcher_overview.aconfig
@@ -1,5 +1,5 @@
package: "com.android.launcher3"
-container: "system_ext"
+container: "system"
flag {
name: "enable_grid_only_overview"
diff --git a/aconfig/launcher_search.aconfig b/aconfig/launcher_search.aconfig
index b98eee6..72f654e 100644
--- a/aconfig/launcher_search.aconfig
+++ b/aconfig/launcher_search.aconfig
@@ -1,5 +1,5 @@
package: "com.android.launcher3"
-container: "system_ext"
+container: "system"
flag {
name: "enable_private_space"
diff --git a/quickstep/Android.bp b/quickstep/Android.bp
index 4c724dc..2ef9f82 100644
--- a/quickstep/Android.bp
+++ b/quickstep/Android.bp
@@ -64,3 +64,11 @@
"tests/multivalentScreenshotTests/src/**/*.kt",
],
}
+
+filegroup {
+ name: "launcher3-quickstep-testing",
+ path: "testing",
+ srcs: [
+ "testing/**/*.kt",
+ ],
+}
diff --git a/quickstep/dagger/LauncherAppComponent.java b/quickstep/dagger/LauncherAppComponent.java
index dab2582..bd6008e 100644
--- a/quickstep/dagger/LauncherAppComponent.java
+++ b/quickstep/dagger/LauncherAppComponent.java
@@ -16,15 +16,16 @@
package com.android.launcher3.dagger;
-import dagger.Component;
-import javax.inject.Singleton;
+import com.android.quickstep.dagger.QuickStepModule;
+
+import dagger.Component;
/**
* Root component for Dagger injection for Launcher Quickstep.
*/
-@Singleton
-@Component
+@LauncherAppSingleton
+@Component(modules = QuickStepModule.class)
public interface LauncherAppComponent extends LauncherBaseAppComponent {
/** Builder for quickstep LauncherAppComponent. */
@Component.Builder
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 29d214d..e691663 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -89,7 +89,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"أحسنت"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"الدليل التوجيهي <xliff:g id="CURRENT">%1$d</xliff:g> من إجمالي <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"اكتملت عملية الإعداد"</string>
- <string name="allset_hint" msgid="459504134589971527">"يمكنك التمرير سريعًا إلى الأعلى للانتقال إلى الشاشة الرئيسية"</string>
+ <string name="allset_hint" msgid="459504134589971527">"مرّر سريعًا للأعلى للانتقال إلى الشاشة الرئيسية"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"انقر على زر الشاشة الرئيسية للانتقال إلى الشاشة الرئيسية."</string>
<string name="allset_description_generic" msgid="5385500062202019855">"يمكنك الآن بدء استخدام <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"الجهاز"</string>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 98f46ac..04e7f6e 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -92,7 +92,7 @@
<string name="allset_hint" msgid="459504134589971527">"Башкы бетке өтүү үчүн экранды өйдө сүрүңүз"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Башкы экранга өтүү үчүн башкы бет баскычын таптап коюңуз"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"<xliff:g id="DEVICE">%1$s</xliff:g> колдоно берсеңиз болот"</string>
- <string name="default_device_name" msgid="6660656727127422487">"түзмөк"</string>
+ <string name="default_device_name" msgid="6660656727127422487">"Түзмөктү"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Өтүү аракетинин системалык параметрлери"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Бөлүшүү"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 4054eb7..2722ca9 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -93,7 +93,7 @@
<string name="allset_button_hint" msgid="2395219947744706291">"Нажмите кнопку главного экрана, чтобы открыть его."</string>
<string name="allset_description_generic" msgid="5385500062202019855">"Теперь вы можете использовать <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
<string name="default_device_name" msgid="6660656727127422487">"устройство"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Системные настройки навигации"</annotation></string>
+ <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Настройки навигации в системе"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Поделиться"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="action_split" msgid="2098009717623550676">"Разделить"</string>
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index e940553..a63ba0f 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -26,7 +26,6 @@
import android.animation.AnimatorSet;
import android.content.Context;
import android.os.Handler;
-import android.os.RemoteException;
import android.util.Log;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.RemoteAnimationTarget;
@@ -210,7 +209,7 @@
* animation finished runnable.
*/
@Override
- public void onAnimationFinished() throws RemoteException {
+ public void onAnimationFinished() {
mASyncFinishRunnable.run();
}
}
@@ -240,12 +239,5 @@
@Override
@UiThread
default void onAnimationCancelled() {}
-
- /**
- * Returns whether this animation factory supports a tightly coupled return animation.
- */
- default boolean supportsReturnTransition() {
- return false;
- }
}
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java b/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java
index 962fd91..1161720 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java
@@ -15,10 +15,19 @@
*/
package com.android.launcher3;
+import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
+
import android.view.KeyEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.LinearSmoothScroller;
+import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
+import com.android.launcher3.allapps.AllAppsRecyclerView;
+import com.android.launcher3.allapps.SearchRecyclerView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -26,14 +35,61 @@
import java.util.List;
public class QuickstepAccessibilityDelegate extends LauncherAccessibilityDelegate {
+ private QuickstepLauncher mLauncher;
public QuickstepAccessibilityDelegate(QuickstepLauncher launcher) {
super(launcher);
+ mLauncher = launcher;
mActions.put(PIN_PREDICTION, new LauncherAction(
PIN_PREDICTION, R.string.pin_prediction, KeyEvent.KEYCODE_P));
}
@Override
+ public void onPopulateAccessibilityEvent(View view, AccessibilityEvent event) {
+ super.onPopulateAccessibilityEvent(view, event);
+ // Scroll to the position if focused view in main allapps list and not completely visible.
+ scrollToPositionIfNeeded(view);
+ }
+
+ private void scrollToPositionIfNeeded(View view) {
+ if (!Flags.accessibilityScrollOnAllapps()) {
+ return;
+ }
+ AllAppsRecyclerView contentView = mLauncher.getAppsView().getActiveRecyclerView();
+ if (contentView instanceof SearchRecyclerView) {
+ return;
+ }
+ LinearLayoutManager layoutManager = (LinearLayoutManager) contentView.getLayoutManager();
+ if (layoutManager == null) {
+ return;
+ }
+ RecyclerView.ViewHolder vh = contentView.findContainingViewHolder(view);
+ if (vh == null) {
+ return;
+ }
+ int itemPosition = vh.getBindingAdapterPosition();
+ if (itemPosition == NO_POSITION) {
+ return;
+ }
+ int firstCompletelyVisible = layoutManager.findFirstCompletelyVisibleItemPosition();
+ int lastCompletelyVisible = layoutManager.findLastCompletelyVisibleItemPosition();
+ boolean itemCompletelyVisible = firstCompletelyVisible <= itemPosition
+ && lastCompletelyVisible >= itemPosition;
+ if (itemCompletelyVisible) {
+ return;
+ }
+ RecyclerView.SmoothScroller smoothScroller =
+ new LinearSmoothScroller(mLauncher.asContext()) {
+ @Override
+ protected int getVerticalSnapPreference() {
+ return LinearSmoothScroller.SNAP_TO_ANY;
+ }
+ };
+ smoothScroller.setTargetPosition(itemPosition);
+ layoutManager.startSmoothScroll(smoothScroller);
+ }
+
+ @Override
protected void getSupportedActions(View host, ItemInfo item, List<LauncherAction> out) {
if (host instanceof PredictedAppIcon && !((PredictedAppIcon) host).isPinned()) {
out.add(new LauncherAction(PIN_PREDICTION, R.string.pin_prediction,
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index e51c956..a64936d 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -46,17 +46,12 @@
import static com.android.launcher3.Flags.enableContainerReturnAnimations;
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.mapBoundToRange;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_BACK_SWIPE_HOME_ANIMATION;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH;
-import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.testing.shared.TestProtocol.WALLPAPER_OPEN_ANIMATION_FINISHED_MESSAGE;
import static com.android.launcher3.util.DisplayController.isTransientTaskbar;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -89,7 +84,6 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
@@ -116,6 +110,7 @@
import android.view.animation.PathInterpolator;
import android.window.RemoteTransition;
import android.window.TransitionFilter;
+import android.window.WindowAnimationState;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -138,16 +133,17 @@
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DynamicResource;
-import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.StableViewInfo;
import com.android.launcher3.views.FloatingIconView;
-import com.android.launcher3.views.ScrimView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.quickstep.LauncherBackAnimationController;
import com.android.quickstep.RemoteAnimationTargets;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskViewUtils;
+import com.android.quickstep.util.AlreadyStartedBackAnimState;
+import com.android.quickstep.util.AnimatorBackState;
+import com.android.quickstep.util.BackAnimState;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
@@ -174,6 +170,7 @@
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@@ -182,9 +179,6 @@
*/
public class QuickstepTransitionManager implements OnDeviceProfileChangeListener {
- private static final String TRANSITION_COOKIE_PREFIX =
- "com.android.launcher3.QuickstepTransitionManager_activityLaunch";
-
private static final boolean ENABLE_SHELL_STARTING_SURFACE =
SystemProperties.getBoolean("persist.debug.shell_starting_surface", true);
@@ -258,7 +252,6 @@
// 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;
private RemoteTransition mLauncherOpenTransition;
@@ -327,7 +320,7 @@
* @return ActivityOptions with remote animations that controls how the window of the opening
* targets are displayed.
*/
- public ActivityOptionsWrapper getActivityLaunchOptions(View v) {
+ public ActivityOptionsWrapper getActivityLaunchOptions(View v, ItemInfo itemInfo) {
boolean fromRecents = isLaunchingFromRecents(v, null /* targets */);
RunnableList onEndCallback = new RunnableList();
@@ -354,14 +347,7 @@
IRemoteCallback endCallback = completeRunnableListCallback(onEndCallback);
options.setOnAnimationAbortListener(endCallback);
options.setOnAnimationFinishedListener(endCallback);
-
- IBinder cookie = mAppLaunchRunner.supportsReturnTransition()
- ? ((ContainerAnimationRunner) mAppLaunchRunner).getCookie() : null;
- addLaunchCookie(cookie, (ItemInfo) v.getTag(), options);
-
- // Register the return animation so it can be triggered on back from the app to home.
- maybeRegisterAppReturnTransition(v);
-
+ options.setLaunchCookie(StableViewInfo.toLaunchCookie(itemInfo));
return new ActivityOptionsWrapper(options, onEndCallback);
}
@@ -374,21 +360,9 @@
ItemInfo tag = (ItemInfo) v.getTag();
ContainerAnimationRunner containerRunner = null;
if (tag != null && tag.shouldUseBackgroundAnimation()) {
- // The cookie should only override the default used by launcher if container return
- // animations are enabled.
- ActivityTransitionAnimator.TransitionCookie cookie =
- checkReturnAnimationsFlags()
- ? new ActivityTransitionAnimator.TransitionCookie(
- TRANSITION_COOKIE_PREFIX + tag.id)
- : null;
- ContainerAnimationRunner launchAnimationRunner =
- ContainerAnimationRunner.fromView(
- v, cookie, true /* forLaunch */, mLauncher, mStartingWindowListener,
- onEndCallback);
-
- if (launchAnimationRunner != null) {
- containerRunner = launchAnimationRunner;
- }
+ containerRunner = ContainerAnimationRunner.fromView(
+ v, true /* forLaunch */, mLauncher, mStartingWindowListener, onEndCallback,
+ null /* windowState */);
}
mAppLaunchRunner = containerRunner != null
@@ -398,51 +372,6 @@
}
/**
- * If container return animations are enabled and the current launch runner is itself a
- * {@link ContainerAnimationRunner}, registers a matching return animation that de-registers
- * itself after it has run once or is made obsolete by the view going away.
- */
- private void maybeRegisterAppReturnTransition(View v) {
- if (!checkReturnAnimationsFlags() || !mAppLaunchRunner.supportsReturnTransition()) {
- return;
- }
-
- ActivityTransitionAnimator.TransitionCookie cookie =
- ((ContainerAnimationRunner) mAppLaunchRunner).getCookie();
- RunnableList onEndCallback = new RunnableList();
- ContainerAnimationRunner runner =
- ContainerAnimationRunner.fromView(
- v, cookie, false /* forLaunch */, mLauncher, mStartingWindowListener,
- onEndCallback);
- RemoteTransition transition =
- new RemoteTransition(
- new LauncherAnimationRunner(
- mHandler, runner, true /* startAtFrontOfQueue */
- ).toRemoteTransition()
- );
-
- SystemUiProxy.INSTANCE.get(mLauncher).registerRemoteTransition(
- transition, ContainerAnimationRunner.buildBackToHomeFilter(cookie, mLauncher));
- ContainerAnimationRunner.setUpRemoteAnimationCleanup(
- v, transition, onEndCallback, mLauncher);
- }
-
- /**
- * Adds a new launch cookie for the activity launch if supported.
- * Prioritizes the explicitly provided cookie, falling back on extracting one from the given
- * {@link ItemInfo} if necessary.
- */
- private void addLaunchCookie(IBinder cookie, ItemInfo info, ActivityOptions options) {
- if (cookie == null) {
- cookie = mLauncher.getLaunchCookie(info);
- }
-
- if (cookie != null) {
- options.setLaunchCookie(cookie);
- }
- }
-
- /**
* Whether the launch is a recents app transition and we should do a launch animation
* from the recents view. Note that if the remote animation targets are not provided, this
* may not always be correct as we may resolve the opening app to a task when the animation
@@ -667,34 +596,11 @@
launcherAnimator.play(scaleAnim);
});
- final boolean scrimEnabled = ENABLE_SCRIM_FOR_APP_LAUNCH.get();
- if (scrimEnabled) {
- int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
- int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0);
- int[] colors = isAppOpening
- ? new int[]{scrimColorTrans, scrimColor}
- : new int[]{scrimColor, scrimColorTrans};
- ScrimView scrimView = mLauncher.getScrimView();
- if (scrimView.getBackground() instanceof ColorDrawable) {
- scrimView.setBackgroundColor(colors[0]);
-
- ObjectAnimator scrim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
- colors);
- scrim.setDuration(CONTENT_SCRIM_DURATION);
- scrim.setInterpolator(DECELERATE_1_5);
-
- launcherAnimator.play(scrim);
- }
- }
-
endListener = () -> {
viewsToAnimate.forEach(view -> {
SCALE_PROPERTY.set(view, 1f);
view.setLayerType(View.LAYER_TYPE_NONE, null);
});
- if (scrimEnabled) {
- mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
- }
mLauncher.resumeExpensiveViewUpdates();
};
}
@@ -1203,24 +1109,13 @@
* additional animations.
*/
private void addRemoteAnimations(RemoteAnimationDefinition definition) {
- mWallpaperOpenRunner = createWallpaperOpenRunner(false /* fromUnlock */);
+ mWallpaperOpenRunner = new WallpaperOpenLauncherAnimationRunner();
definition.addRemoteAnimation(WindowManager.TRANSIT_OLD_WALLPAPER_OPEN,
WindowConfiguration.ACTIVITY_TYPE_STANDARD,
new RemoteAnimationAdapter(
new LauncherAnimationRunner(mHandler, mWallpaperOpenRunner,
false /* startAtFrontOfQueue */),
CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
-
- if (KEYGUARD_ANIMATION.get()) {
- mKeyguardGoingAwayRunner = createWallpaperOpenRunner(true /* fromUnlock */);
- definition.addRemoteAnimation(
- WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
- new RemoteAnimationAdapter(
- new LauncherAnimationRunner(
- mHandler, mKeyguardGoingAwayRunner,
- true /* startAtFrontOfQueue */),
- CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
- }
}
/**
@@ -1232,7 +1127,7 @@
return;
}
- mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */);
+ mWallpaperOpenTransitionRunner = new WallpaperOpenLauncherAnimationRunner();
mLauncherOpenTransition = new RemoteTransition(
new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner,
false /* startAtFrontOfQueue */).toRemoteTransition(),
@@ -1287,7 +1182,6 @@
// definition so we don't have to wait for the system gc
mWallpaperOpenRunner = null;
mAppLaunchRunner = null;
- mKeyguardGoingAwayRunner = null;
}
protected void unregisterRemoteTransitions() {
@@ -1345,41 +1239,6 @@
return false;
}
- /**
- * @return Runner that plays when user goes to Launcher
- * ie. pressing home, swiping up from nav bar.
- */
- RemoteAnimationFactory createWallpaperOpenRunner(boolean fromUnlock) {
- return new WallpaperOpenLauncherAnimationRunner(fromUnlock);
- }
-
- /**
- * Animator that controls the transformations of the windows when unlocking the device.
- */
- private Animator getUnlockWindowAnimator(RemoteAnimationTarget[] appTargets,
- RemoteAnimationTarget[] wallpaperTargets) {
- SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer);
- ValueAnimator unlockAnimator = ValueAnimator.ofFloat(0, 1);
- unlockAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS);
- float cornerRadius = mDeviceProfile.isMultiWindowMode ? 0 :
- QuickStepContract.getWindowCornerRadius(mLauncher);
- unlockAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- SurfaceTransaction transaction = new SurfaceTransaction();
- for (int i = appTargets.length - 1; i >= 0; i--) {
- RemoteAnimationTarget target = appTargets[i];
- transaction.forSurface(target.leash)
- .setAlpha(1f)
- .setWindowCrop(target.screenSpaceBounds)
- .setCornerRadius(cornerRadius);
- }
- surfaceApplier.scheduleApply(transaction);
- }
- });
- return unlockAnimator;
- }
-
private static int getRotationChange(RemoteAnimationTarget[] appTargets) {
int rotationChange = 0;
for (RemoteAnimationTarget target : appTargets) {
@@ -1433,20 +1292,12 @@
// Find the associated item info for the launch cookie (if available), note that predicted
// apps actually have an id of -1, so use another default id here
- final ArrayList<IBinder> launchCookies = runningTaskTarget.taskInfo.launchCookies == null
- ? new ArrayList<>()
+ final List<IBinder> launchCookies = runningTaskTarget.taskInfo.launchCookies == null
+ ? Collections.EMPTY_LIST
: runningTaskTarget.taskInfo.launchCookies;
- int launchCookieItemId = NO_MATCHING_ID;
- for (IBinder cookie : launchCookies) {
- Integer itemId = ObjectWrapper.unwrap(cookie);
- if (itemId != null) {
- launchCookieItemId = itemId;
- break;
- }
- }
-
- return mLauncher.getFirstMatchForAppClose(launchCookieItemId, packageName,
+ return mLauncher.getFirstMatchForAppClose(
+ StableViewInfo.fromLaunchCookies(launchCookies), packageName,
UserHandle.of(runningTaskTarget.taskInfo.userId), true /* supportsAllAppsState */);
}
@@ -1698,20 +1549,48 @@
* Creates the {@link RectFSpringAnim} and {@link AnimatorSet} required to animate
* the transition.
*/
- public Pair<RectFSpringAnim, AnimatorSet> createWallpaperOpenAnimations(
+ @NonNull
+ public BackAnimState createWallpaperOpenAnimations(
RemoteAnimationTarget[] appTargets,
- RemoteAnimationTarget[] wallpaperTargets,
- boolean fromUnlock,
+ RemoteAnimationTarget[] wallpapers,
+ RemoteAnimationTarget[] nonAppTargets,
RectF startRect,
float startWindowCornerRadius,
boolean fromPredictiveBack) {
+ View launcherView = findLauncherView(appTargets);
+ if (checkReturnAnimationsFlags()
+ && launcherView != null
+ && launcherView.getTag() instanceof ItemInfo info
+ && info.shouldUseBackgroundAnimation()) {
+ // Try to create a return animation
+ RunnableList onEndCallback = new RunnableList();
+ WindowAnimationState windowState = new WindowAnimationState();
+ windowState.bounds = startRect;
+ windowState.bottomLeftRadius = windowState.bottomRightRadius =
+ windowState.topLeftRadius = windowState.topRightRadius =
+ startWindowCornerRadius;
+ ContainerAnimationRunner runner = ContainerAnimationRunner.fromView(
+ launcherView, false /* forLaunch */, mLauncher, mStartingWindowListener,
+ onEndCallback, windowState);
+ if (runner != null) {
+ runner.startAnimation(TRANSIT_CLOSE,
+ appTargets, wallpapers, nonAppTargets,
+ new IRemoteAnimationFinishedCallback.Stub() {
+ @Override
+ public void onAnimationFinished() {
+ onEndCallback.executeAllAndDestroy();
+ }
+ });
+ return new AlreadyStartedBackAnimState(onEndCallback);
+ }
+ }
+
AnimatorSet anim = new AnimatorSet();
RectFSpringAnim rectFSpringAnim = null;
final boolean launcherIsForceInvisibleOrOpening = mLauncher.isForceInvisible()
|| launcherIsATargetWithMode(appTargets, MODE_OPENING);
- View launcherView = findLauncherView(appTargets);
boolean playFallBackAnimation = (launcherView == null
&& launcherIsForceInvisibleOrOpening)
|| mLauncher.getWorkspace().isOverlayShown()
@@ -1719,10 +1598,7 @@
boolean playWorkspaceReveal = !fromPredictiveBack;
boolean skipAllAppsScale = false;
- if (fromUnlock) {
- anim.play(getUnlockWindowAnimator(appTargets, wallpaperTargets));
- } else if (ENABLE_BACK_SWIPE_HOME_ANIMATION.get()
- && !playFallBackAnimation) {
+ if (!playFallBackAnimation) {
PointF velocity;
if (enableScalingRevealHomeAnimation()) {
velocity = new PointF();
@@ -1814,7 +1690,7 @@
}
}
- return new Pair(rectFSpringAnim, anim);
+ return new AnimatorBackState(rectFSpringAnim, anim);
}
public static int getTaskbarToHomeDuration() {
@@ -1834,12 +1710,6 @@
*/
protected class WallpaperOpenLauncherAnimationRunner implements RemoteAnimationFactory {
- private final boolean mFromUnlock;
-
- public WallpaperOpenLauncherAnimationRunner(boolean fromUnlock) {
- mFromUnlock = fromUnlock;
- }
-
@Override
public void onAnimationStart(int transit,
RemoteAnimationTarget[] appTargets,
@@ -1870,14 +1740,14 @@
}
}
- Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
- appTargets, wallpaperTargets, mFromUnlock, resolveRectF,
+ BackAnimState bankAnimState = createWallpaperOpenAnimations(
+ appTargets, wallpaperTargets, nonAppTargets, resolveRectF,
QuickStepContract.getWindowCornerRadius(mLauncher),
false /* fromPredictiveBack */);
TaskViewUtils.createSplitAuxiliarySurfacesAnimator(nonAppTargets, false, null);
mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
- result.setAnimation(pair.second, mLauncher);
+ bankAnimState.applyToAnimationResult(result, mLauncher);
}
}
@@ -1945,29 +1815,19 @@
/** The delegate runner that handles the actual animation. */
private final RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> mDelegate;
- @Nullable
- private final ActivityTransitionAnimator.TransitionCookie mCookie;
-
private ContainerAnimationRunner(
- RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> delegate,
- ActivityTransitionAnimator.TransitionCookie cookie) {
+ RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> delegate) {
mDelegate = delegate;
- mCookie = cookie;
- }
-
- @Nullable
- ActivityTransitionAnimator.TransitionCookie getCookie() {
- return mCookie;
}
@Nullable
static ContainerAnimationRunner fromView(
View v,
- ActivityTransitionAnimator.TransitionCookie cookie,
boolean forLaunch,
Launcher launcher,
StartingWindowListener startingWindowListener,
- RunnableList onEndCallback) {
+ RunnableList onEndCallback,
+ @Nullable WindowAnimationState windowState) {
if (!forLaunch && !checkReturnAnimationsFlags()) {
throw new IllegalStateException(
"forLaunch cannot be false when the enableContainerReturnAnimations or "
@@ -1977,7 +1837,7 @@
// First the controller is created. This is used by the runner to animate the
// origin/target view.
ActivityTransitionAnimator.Controller controller =
- buildController(v, cookie, forLaunch);
+ buildController(v, forLaunch, windowState);
if (controller == null) {
return null;
}
@@ -2002,8 +1862,7 @@
return new ContainerAnimationRunner(
new ActivityTransitionAnimator.AnimationDelegate(
- MAIN_EXECUTOR, controller, callback, listener),
- cookie);
+ MAIN_EXECUTOR, controller, callback, listener));
}
/**
@@ -2013,7 +1872,7 @@
*/
@Nullable
private static ActivityTransitionAnimator.Controller buildController(
- View v, ActivityTransitionAnimator.TransitionCookie cookie, boolean isLaunching) {
+ View v, boolean isLaunching, @Nullable WindowAnimationState windowState) {
View viewToUse = findLaunchableViewWithBackground(v);
if (viewToUse == null) {
return null;
@@ -2044,8 +1903,8 @@
@Nullable
@Override
- public ActivityTransitionAnimator.TransitionCookie getTransitionCookie() {
- return cookie;
+ public WindowAnimationState getWindowAnimatorState() {
+ return windowState;
}
};
}
@@ -2059,81 +1918,26 @@
View view) {
View current = view;
while (current.getBackground() == null || !(current instanceof LaunchableView)) {
- if (!(current.getParent() instanceof View)) {
+ if (current.getParent() instanceof View v) {
+ current = v;
+ } else {
return null;
}
-
- current = (View) current.getParent();
}
-
return (T) current;
}
- /**
- * Builds the filter used by WM Shell to match app closing transitions (only back, no home
- * button/gesture) to the given launch cookie.
- */
- static TransitionFilter buildBackToHomeFilter(
- ActivityTransitionAnimator.TransitionCookie cookie, Launcher launcher) {
- // Closing activity must include the cookie in its list of launch cookies.
- TransitionFilter.Requirement appRequirement = new TransitionFilter.Requirement();
- appRequirement.mActivityType = ACTIVITY_TYPE_STANDARD;
- appRequirement.mLaunchCookie = cookie;
- appRequirement.mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
- // Opening activity must be Launcher.
- TransitionFilter.Requirement launcherRequirement = new TransitionFilter.Requirement();
- launcherRequirement.mActivityType = ACTIVITY_TYPE_HOME;
- launcherRequirement.mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
- launcherRequirement.mTopActivity = launcher.getComponentName();
- // Transition types CLOSE and TO_BACK match the back button/gesture but not the home
- // button/gesture.
- TransitionFilter filter = new TransitionFilter();
- filter.mTypeSet = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
- filter.mRequirements =
- new TransitionFilter.Requirement[]{appRequirement, launcherRequirement};
- return filter;
- }
-
- /**
- * Creates various conditions to ensure that the given transition is cleaned up correctly
- * when necessary:
- * - if the transition has run, it is the callback that unregisters it;
- * - if the associated view is detached before the transition has had an opportunity to run,
- * a {@link View.OnAttachStateChangeListener} allows us to do the same (and removes
- * itself).
- */
- static void setUpRemoteAnimationCleanup(
- View v, RemoteTransition transition, RunnableList callback, Launcher launcher) {
- View.OnAttachStateChangeListener listener = new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(@NonNull View v) {}
-
- @Override
- public void onViewDetachedFromWindow(@NonNull View v) {
- SystemUiProxy.INSTANCE.get(launcher)
- .unregisterRemoteTransition(transition);
- v.removeOnAttachStateChangeListener(this);
- }
- };
-
- // Remove the animation as soon as it has run once.
- callback.add(() -> {
- SystemUiProxy.INSTANCE.get(launcher).unregisterRemoteTransition(transition);
- if (v != null) {
- v.removeOnAttachStateChangeListener(listener);
- }
- });
-
- // Remove the animation when the view is detached from the hierarchy.
- // This is so that if back is not invoked (e.g. if we go back home through the home
- // gesture) we don't have obsolete transitions staying registered.
- v.addOnAttachStateChangeListener(listener);
- }
-
@Override
public void onAnimationStart(int transit, RemoteAnimationTarget[] appTargets,
RemoteAnimationTarget[] wallpaperTargets, RemoteAnimationTarget[] nonAppTargets,
LauncherAnimationRunner.AnimationResult result) {
+ startAnimation(
+ transit, appTargets, wallpaperTargets, nonAppTargets, result);
+ }
+
+ public void startAnimation(int transit, RemoteAnimationTarget[] appTargets,
+ RemoteAnimationTarget[] wallpaperTargets, RemoteAnimationTarget[] nonAppTargets,
+ IRemoteAnimationFinishedCallback result) {
mDelegate.onAnimationStart(
transit, appTargets, wallpaperTargets, nonAppTargets, result);
}
@@ -2142,11 +1946,6 @@
public void onAnimationCancelled() {
mDelegate.onAnimationCancelled();
}
-
- @Override
- public boolean supportsReturnTransition() {
- return true;
- }
}
/**
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
index 50e8e5e..955388d 100644
--- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -41,6 +41,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.dragndrop.SimpleDragLayer;
+import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetPredictionsRequester;
import com.android.launcher3.model.WidgetsModel;
@@ -107,6 +108,7 @@
private SimpleDragLayer<WidgetPickerActivity> mDragLayer;
private WidgetsModel mModel;
private LauncherAppState mApp;
+ private StringCache mStringCache;
private WidgetPredictionsRequester mWidgetPredictionsRequester;
private final WidgetPickerDataProvider mWidgetPickerDataProvider =
new WidgetPickerDataProvider();
@@ -287,6 +289,11 @@
MODEL_EXECUTOR.execute(() -> {
LauncherAppState app = LauncherAppState.getInstance(this);
mModel.update(app, null);
+
+ StringCache stringCache = new StringCache();
+ stringCache.loadStrings(this);
+
+ bindStringCache(stringCache);
bindWidgets(mModel.getWidgetsByPackageItem());
// Open sheet once widgets are available, so that it doesn't interrupt the open
// animation.
@@ -299,6 +306,10 @@
});
}
+ private void bindStringCache(final StringCache stringCache) {
+ MAIN_EXECUTOR.execute(() -> mStringCache = stringCache);
+ }
+
private void bindWidgets(Map<PackageItemInfo, List<WidgetItem>> widgets) {
WidgetsListBaseEntriesBuilder builder = new WidgetsListBaseEntriesBuilder(
mApp.getContext());
@@ -336,6 +347,12 @@
}
}
+ @Nullable
+ @Override
+ public StringCache getStringCache() {
+ return mStringCache;
+ }
+
/**
* Animation callback for different predictive back animation states for the widget picker.
*/
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index e31b1d4..f29980b 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -17,10 +17,10 @@
import static android.view.View.VISIBLE;
-import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY;
+import android.content.Context;
import android.os.Debug;
import android.util.Log;
import android.view.View;
@@ -30,14 +30,18 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.GestureState;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.fallback.RecentsState;
import com.android.wm.shell.desktopmode.IDesktopTaskListener;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
+import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
@@ -49,7 +53,6 @@
private static final String TAG = "DesktopVisController";
private static final boolean DEBUG = false;
- private final Launcher mLauncher;
private final Set<DesktopVisibilityListener> mDesktopVisibilityListeners = new HashSet<>();
private final Set<TaskbarDesktopModeListener> mTaskbarDesktopModeListeners = new HashSet<>();
@@ -61,23 +64,43 @@
@Nullable
private DesktopTaskListenerImpl mDesktopTaskListener;
- public DesktopVisibilityController(Launcher launcher) {
- mLauncher = launcher;
+ @Nullable
+ private Context mContext;
+
+ public DesktopVisibilityController(@NonNull Context context) {
+ setContext(context);
}
- /**
- * Register a listener with System UI to receive updates about desktop tasks state
- */
- public void registerSystemUiListener() {
- mDesktopTaskListener = new DesktopTaskListenerImpl(this, mLauncher.getDisplayId());
- SystemUiProxy.INSTANCE.get(mLauncher).setDesktopTaskListener(mDesktopTaskListener);
+ /** Sets the context and re-registers the System Ui listener */
+ private void setContext(@Nullable Context context) {
+ unregisterSystemUiListener();
+ mContext = context;
+ registerSystemUiListener();
+ }
+
+ /** Register a listener with System UI to receive updates about desktop tasks state */
+ private void registerSystemUiListener() {
+ if (mContext == null) {
+ return;
+ }
+ if (mDesktopTaskListener != null) {
+ return;
+ }
+ mDesktopTaskListener = new DesktopTaskListenerImpl(this, mContext.getDisplayId());
+ SystemUiProxy.INSTANCE.get(mContext).setDesktopTaskListener(mDesktopTaskListener);
}
/**
* Clear listener from System UI that was set with {@link #registerSystemUiListener()}
*/
- public void unregisterSystemUiListener() {
- SystemUiProxy.INSTANCE.get(mLauncher).setDesktopTaskListener(null);
+ private void unregisterSystemUiListener() {
+ if (mContext == null) {
+ return;
+ }
+ if (mDesktopTaskListener == null) {
+ return;
+ }
+ SystemUiProxy.INSTANCE.get(mContext).setDesktopTaskListener(null);
mDesktopTaskListener.release();
mDesktopTaskListener = null;
}
@@ -126,6 +149,9 @@
* it.
*/
public void setVisibleDesktopTasksCount(int visibleTasksCount) {
+ if (mContext == null) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "setVisibleDesktopTasksCount: visibleTasksCount=" + visibleTasksCount
+ " currentValue=" + mVisibleDesktopTasksCount);
@@ -141,7 +167,7 @@
notifyDesktopVisibilityListeners(areDesktopTasksVisibleNow);
}
- if (!WALLPAPER_ACTIVITY.isEnabled(mLauncher) && wasVisible != isVisible) {
+ if (!WALLPAPER_ACTIVITY.isEnabled(mContext) && wasVisible != isVisible) {
// TODO: b/333533253 - Remove after flag rollout
if (mVisibleDesktopTasksCount > 0) {
setLauncherViewsVisibility(View.INVISIBLE);
@@ -160,19 +186,33 @@
}
}
+ public void onLauncherStateChanged(LauncherState state) {
+ onLauncherStateChanged(
+ state, state == LauncherState.BACKGROUND_APP, state.isRecentsViewVisible);
+ }
+
+ public void onLauncherStateChanged(RecentsState state) {
+ onLauncherStateChanged(
+ state, state == RecentsState.BACKGROUND_APP, state.isRecentsViewVisible());
+ }
+
/**
* Process launcher state change and update launcher view visibility based on desktop state
*/
- public void onLauncherStateChanged(LauncherState state) {
+ public void onLauncherStateChanged(
+ BaseState<?> state, boolean isBackgroundAppState, boolean isRecentsViewVisible) {
if (DEBUG) {
Log.d(TAG, "onLauncherStateChanged: newState=" + state);
}
- setBackgroundStateEnabled(state == BACKGROUND_APP);
+ setBackgroundStateEnabled(isBackgroundAppState);
// Desktop visibility tracks overview and background state separately
- setOverviewStateEnabled(state != BACKGROUND_APP && state.isRecentsViewVisible);
+ setOverviewStateEnabled(!isBackgroundAppState && isRecentsViewVisible);
}
private void setOverviewStateEnabled(boolean overviewStateEnabled) {
+ if (mContext == null) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "setOverviewStateEnabled: enabled=" + overviewStateEnabled
+ " currentValue=" + mInOverviewState);
@@ -185,7 +225,7 @@
notifyDesktopVisibilityListeners(areDesktopTasksVisibleNow);
}
- if (WALLPAPER_ACTIVITY.isEnabled(mLauncher)) {
+ if (WALLPAPER_ACTIVITY.isEnabled(mContext)) {
return;
}
// TODO: b/333533253 - Clean up after flag rollout
@@ -203,13 +243,16 @@
}
private void notifyDesktopVisibilityListeners(boolean areDesktopTasksVisible) {
+ if (mContext == null) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "notifyDesktopVisibilityListeners: visible=" + areDesktopTasksVisible);
}
for (DesktopVisibilityListener listener : mDesktopVisibilityListeners) {
listener.onDesktopVisibilityChanged(areDesktopTasksVisible);
}
- DisplayController.handleInfoChangeForDesktopMode(mLauncher);
+ DisplayController.handleInfoChangeForDesktopMode(mContext);
}
private void notifyTaskbarDesktopModeListeners(boolean doesAnyTaskRequireTaskbarRounding) {
@@ -295,22 +338,32 @@
* TODO: b/333533253 - Remove after flag rollout
*/
private void setLauncherViewsVisibility(int visibility) {
- if (WALLPAPER_ACTIVITY.isEnabled(mLauncher)) {
+ if (mContext == null) {
+ return;
+ }
+ if (WALLPAPER_ACTIVITY.isEnabled(mContext)) {
return;
}
if (DEBUG) {
Log.d(TAG, "setLauncherViewsVisibility: visibility=" + visibility + " "
+ Debug.getCaller());
}
- View workspaceView = mLauncher.getWorkspace();
- if (workspaceView != null) {
- workspaceView.setVisibility(visibility);
+ if (!(mContext instanceof ActivityContext activity)) {
+ return;
}
- View dragLayer = mLauncher.getDragLayer();
+ View dragLayer = activity.getDragLayer();
if (dragLayer != null) {
dragLayer.setVisibility(visibility);
}
- if (mLauncher instanceof QuickstepLauncher ql && ql.getTaskbarUIController() != null
+ if (!(activity instanceof Launcher launcher)) {
+ return;
+ }
+ View workspaceView = launcher.getWorkspace();
+ if (workspaceView != null) {
+ workspaceView.setVisibility(visibility);
+ }
+ if (launcher instanceof QuickstepLauncher ql
+ && ql.getTaskbarUIController() != null
&& mVisibleDesktopTasksCount != 0) {
ql.getTaskbarUIController().onLauncherVisibilityChanged(visibility == VISIBLE);
}
@@ -320,7 +373,10 @@
* TODO: b/333533253 - Remove after flag rollout
*/
private void markLauncherPaused() {
- if (WALLPAPER_ACTIVITY.isEnabled(mLauncher)) {
+ if (mContext == null) {
+ return;
+ }
+ if (WALLPAPER_ACTIVITY.isEnabled(mContext)) {
return;
}
if (DEBUG) {
@@ -337,7 +393,10 @@
* TODO: b/333533253 - Remove after flag rollout
*/
private void markLauncherResumed() {
- if (WALLPAPER_ACTIVITY.isEnabled(mLauncher)) {
+ if (mContext == null) {
+ return;
+ }
+ if (WALLPAPER_ACTIVITY.isEnabled(mContext)) {
return;
}
if (DEBUG) {
@@ -353,6 +412,22 @@
}
}
+ public void onDestroy() {
+ setContext(null);
+ }
+
+ public void dumpLogs(String prefix, PrintWriter pw) {
+ pw.println(prefix + "DesktopVisibilityController:");
+
+ pw.println(prefix + "\tmDesktopVisibilityListeners=" + mDesktopVisibilityListeners);
+ pw.println(prefix + "\tmVisibleDesktopTasksCount=" + mVisibleDesktopTasksCount);
+ pw.println(prefix + "\tmInOverviewState=" + mInOverviewState);
+ pw.println(prefix + "\tmBackgroundStateEnabled=" + mBackgroundStateEnabled);
+ pw.println(prefix + "\tmGestureInProgress=" + mGestureInProgress);
+ pw.println(prefix + "\tmDesktopTaskListener=" + mDesktopTaskListener);
+ pw.println(prefix + "\tmContext=" + mContext);
+ }
+
/** A listener for when the user enters/exits Desktop Mode. */
public interface DesktopVisibilityListener {
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index 06d9ee6..929e793 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -70,7 +70,6 @@
@Override
protected void init(TaskbarControllers taskbarControllers) {
super.init(taskbarControllers);
-
mRecentsActivity.setTaskbarUIController(this);
mRecentsActivity.getStateManager().addStateListener(mStateListener);
}
@@ -78,6 +77,7 @@
@Override
protected void onDestroy() {
super.onDestroy();
+ getRecentsView().setTaskLaunchListener(null);
mRecentsActivity.setTaskbarUIController(null);
mRecentsActivity.getStateManager().removeStateListener(mStateListener);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index e4cc6bb..ea432f3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -23,9 +23,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.R;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
@@ -116,10 +114,8 @@
mQuickSwitchViewController = new KeyboardQuickSwitchViewController(
mControllers, overlayContext, keyboardQuickSwitchView, mControllerCallbacks);
- DesktopVisibilityController desktopController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
final boolean onDesktop =
- desktopController != null && desktopController.areDesktopTasksVisible();
+ mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible();
if (mModel.isTaskListValid(mTaskListChangeId)) {
// When we are opening the KQS with no focus override, check if the first task is
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 69da7b6..5513599 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -38,14 +38,12 @@
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.quickstep.HomeVisibilityState;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.GroupTask;
@@ -128,8 +126,8 @@
@Override
protected void onDestroy() {
- super.onDestroy();
onLauncherVisibilityChanged(false);
+ super.onDestroy();
mTaskbarLauncherStateController.onDestroy();
mLauncher.setTaskbarUIController(null);
@@ -235,11 +233,8 @@
return null;
}
- DesktopVisibilityController desktopController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
if (!WALLPAPER_ACTIVITY.isEnabled(mLauncher)
- && desktopController != null
- && desktopController.areDesktopTasksVisible()) {
+ && mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()) {
// TODO: b/333533253 - Remove after flag rollout
isVisible = false;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index ec710c5..fabf3a5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -94,6 +94,7 @@
// States that affect whether region sampling is enabled or not
private boolean mIsStashed;
private boolean mIsLumaSamplingEnabled;
+ private boolean mIsAppTransitionPending;
private boolean mTaskbarHidden;
private float mTranslationYForSwipe;
@@ -267,6 +268,11 @@
updateSamplingState();
}
+ public void setIsAppTransitionPending(boolean pending) {
+ mIsAppTransitionPending = pending;
+ updateSamplingState();
+ }
+
private void updateSamplingState() {
updateRegionSamplingWindowVisibility();
if (shouldSample()) {
@@ -278,7 +284,7 @@
}
private boolean shouldSample() {
- return mIsStashed && mIsLumaSamplingEnabled;
+ return mIsStashed && mIsLumaSamplingEnabled && !mIsAppTransitionPending;
}
protected void updateStashedHandleHintScale() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 5f733b0..a1cd7f7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -37,6 +37,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN;
+import static com.android.launcher3.taskbar.TaskbarStashController.SHOULD_BUBBLES_FOLLOW_DEFAULT_VALUE;
import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
@@ -100,6 +101,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.AutohideSuspendFlag;
import com.android.launcher3.taskbar.TaskbarTranslationController.TransitionCallback;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
@@ -140,7 +142,6 @@
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.NavHandle;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SystemUiProxy;
@@ -223,7 +224,8 @@
public TaskbarActivityContext(Context windowContext,
@Nullable Context navigationBarPanelContext, DeviceProfile launcherDp,
TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
- unfoldTransitionProgressProvider) {
+ unfoldTransitionProgressProvider,
+ @NonNull DesktopVisibilityController desktopVisibilityController) {
super(windowContext);
mNavigationBarPanelContext = navigationBarPanelContext;
@@ -336,17 +338,13 @@
new VoiceInteractionWindowController(this),
new TaskbarTranslationController(this),
new TaskbarSpringOnStashController(this),
- new TaskbarRecentAppsController(
- this,
- RecentsModel.INSTANCE.get(this),
- LauncherActivityInterface.INSTANCE::getDesktopVisibilityController),
+ new TaskbarRecentAppsController(this, RecentsModel.INSTANCE.get(this)),
TaskbarEduTooltipController.newInstance(this),
new KeyboardQuickSwitchController(),
- new TaskbarPinningController(this, () ->
- DisplayController.isInDesktopMode(this)),
+ new TaskbarPinningController(this),
bubbleControllersOptional,
- new TaskbarDesktopModeController(
- LauncherActivityInterface.INSTANCE::getDesktopVisibilityController));
+ new TaskbarDesktopModeController(desktopVisibilityController));
+
mLauncherPrefs = LauncherPrefs.get(this);
}
@@ -914,11 +912,16 @@
mControllers.navbarButtonsViewController.transitionTo(barMode, animate);
}
+ public void appTransitionPending(boolean pending) {
+ mControllers.stashedHandleViewController.setIsAppTransitionPending(pending);
+ }
+
/**
* Called when this instance of taskbar is no longer needed
*/
public void onDestroy() {
mIsDestroyed = true;
+ mTaskbarFeatureEvaluator.onDestroy();
setUIController(TaskbarUIController.DEFAULT);
mControllers.onDestroy();
if (!enableTaskbarNoRecreate() && !ENABLE_TASKBAR_NAVBAR_UNIFICATION) {
@@ -1203,14 +1206,21 @@
mControllers.uiController.startSplitSelection(splitSelectSource);
}
+ boolean areDesktopTasksVisible() {
+ return mControllers != null
+ && mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible();
+ }
+
protected void onTaskbarIconClicked(View view) {
TaskbarUIController taskbarUIController = mControllers.uiController;
RecentsView recents = taskbarUIController.getRecentsView();
boolean shouldCloseAllOpenViews = true;
Object tag = view.getTag();
if (tag instanceof GroupTask groupTask) {
- handleGroupTaskLaunch(groupTask, /* remoteTransition = */ null,
- DisplayController.isInDesktopMode(this));
+ handleGroupTaskLaunch(
+ groupTask,
+ /* remoteTransition= */ null,
+ areDesktopTasksVisible());
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
} else if (tag instanceof FolderInfo) {
// Tapping an expandable folder icon on Taskbar
@@ -1541,10 +1551,12 @@
/**
* Called when we want to unstash taskbar when user performs swipes up gesture.
+ * @param delayTaskbarBackground whether we will delay the taskbar background animation
*/
- public void onSwipeToUnstashTaskbar() {
+ public void onSwipeToUnstashTaskbar(boolean delayTaskbarBackground) {
boolean wasStashed = mControllers.taskbarStashController.isStashed();
- mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(/* stash= */ false);
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(/* stash= */ false,
+ SHOULD_BUBBLES_FOLLOW_DEFAULT_VALUE, delayTaskbarBackground);
boolean isStashed = mControllers.taskbarStashController.isStashed();
if (isStashed != wasStashed) {
VibratorWrapper.INSTANCE.get(this).vibrateForTaskbarUnstash();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
index 4ac7514..d6ce3a4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
@@ -102,7 +102,7 @@
shadowAlpha = LIGHT_THEME_SHADOW_ALPHA
}
- if (DisplayController.isInDesktopMode(context)) {
+ if (context.areDesktopTasksVisible()) {
fullCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
cornerRadius = fullCornerRadius
} else {
@@ -200,7 +200,7 @@
mapRange(
scale,
0f,
- res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin).toFloat()
+ res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin).toFloat(),
)
.toInt()
shadowBlur =
@@ -245,7 +245,7 @@
-mapRange(
1f - progress,
0f,
- if (isAnimatingPinning) 0f else stashedHandleHeight / 2f
+ if (isAnimatingPinning) 0f else stashedHandleHeight / 2f,
)
// Draw shadow.
@@ -255,7 +255,7 @@
shadowBlur,
0f,
keyShadowDistance,
- setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
+ setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha)),
)
strokePaint.alpha = (paint.alpha * strokeAlpha) / 255
@@ -263,7 +263,7 @@
transientBackgroundBounds.left + halfWidthDelta + hotseatOffsetLeft,
bottom - newBackgroundHeight + hotseatOffsetTop,
transientBackgroundBounds.right - halfWidthDelta + hotseatOffsetRight,
- bottom + hotseatOffsetBottom
+ bottom + hotseatOffsetBottom,
)
val horizontalInset = fullWidth * widthInsetPercentage
lastDrawnTransientRect.inset(horizontalInset, 0f)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 34ab9f0..56fd2bb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -25,7 +25,6 @@
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
import com.android.launcher3.taskbar.bubbles.BubbleControllers;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
-import com.android.launcher3.util.DisplayController;
import com.android.systemui.shared.rotation.RotationButtonController;
import java.io.PrintWriter;
@@ -194,13 +193,17 @@
voiceInteractionWindowController
};
- if (DisplayController.isInDesktopMode(taskbarActivityContext)) {
+ if (taskbarDesktopModeController.getAreDesktopTasksVisible()) {
mCornerRoundness.updateValue(taskbarDesktopModeController.getTaskbarCornerRoundness(
mSharedState.showCornerRadiusInDesktopMode));
} else {
mCornerRoundness.updateValue(TaskbarBackgroundRenderer.MAX_ROUNDNESS);
}
+ onPostInit();
+ }
+ @VisibleForTesting
+ public void onPostInit() {
mAreAllControllersInitialized = true;
for (Runnable postInitCallback : mPostInitCallbacks) {
postInitCallback.run();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt
index a376531..47a35c5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDesktopModeController.kt
@@ -22,18 +22,18 @@
/** Handles Taskbar in Desktop Windowing mode. */
class TaskbarDesktopModeController(
- private val desktopVisibilityControllerProvider: () -> DesktopVisibilityController?
+ private val desktopVisibilityController: DesktopVisibilityController
) : TaskbarDesktopModeListener {
private lateinit var taskbarControllers: TaskbarControllers
private lateinit var taskbarSharedState: TaskbarSharedState
- private val desktopVisibilityController: DesktopVisibilityController?
- get() = desktopVisibilityControllerProvider()
+ val areDesktopTasksVisible: Boolean
+ get() = desktopVisibilityController.areDesktopTasksVisible()
fun init(controllers: TaskbarControllers, sharedState: TaskbarSharedState) {
taskbarControllers = controllers
taskbarSharedState = sharedState
- desktopVisibilityController?.registerTaskbarDesktopModeListener(this)
+ desktopVisibilityController.registerTaskbarDesktopModeListener(this)
}
override fun onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding: Boolean) {
@@ -50,5 +50,5 @@
}
}
- fun onDestroy() = desktopVisibilityController?.unregisterTaskbarDesktopModeListener(this)
+ fun onDestroy() = desktopVisibilityController.unregisterTaskbarDesktopModeListener(this)
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 5bbf4b2..fc307b2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -74,14 +74,12 @@
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.views.BubbleTextHolder;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LogUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
@@ -344,12 +342,9 @@
protected void callOnDragStart() {
super.callOnDragStart();
// TODO(297921594) clean it up when taskbar to desktop drag is implemented.
- DesktopVisibilityController desktopController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
-
// Pre-drag has ended, start the global system drag.
- if (mDisallowGlobalDrag || (desktopController != null
- && desktopController.areDesktopTasksVisible())) {
+ if (mDisallowGlobalDrag
+ || mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()) {
AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
return;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 63fae8c..6c6bd71 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -48,7 +48,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationController;
@@ -375,7 +374,7 @@
private void updateOverviewDragState(LauncherState launcherState) {
boolean disallowLongClick =
FeatureFlags.enableSplitContextually()
- ? mLauncher.isSplitSelectionActive()
+ ? mLauncher.isSplitSelectionActive() || mIsAnimatingToLauncher
: launcherState == LauncherState.OVERVIEW_SPLIT_SELECT;
com.android.launcher3.taskbar.Utilities.setOverviewDragState(
mControllers, launcherState.disallowTaskbarGlobalDrag(),
@@ -463,7 +462,8 @@
controllers.bubbleStashController.setBubblesShowingOnOverview(onOverview);
});
- mControllers.taskbarStashController.updateStateForFlag(FLAG_IN_OVERVIEW,
+ TaskbarStashController stashController = mControllers.taskbarStashController;
+ stashController.updateStateForFlag(FLAG_IN_OVERVIEW,
mLauncherState == LauncherState.OVERVIEW);
AnimatorSet animatorSet = new AnimatorSet();
@@ -495,8 +495,6 @@
public void onAnimationStart(Animator animation) {
mIsAnimatingToLauncher = isInLauncher;
- TaskbarStashController stashController =
- mControllers.taskbarStashController;
if (DEBUG) {
Log.d(TAG, "onAnimationStart - FLAG_IN_APP: " + !isInLauncher);
}
@@ -512,6 +510,8 @@
// Handle closing open popups when going home/overview
handleOpenFloatingViews = true;
+ } else {
+ stashController.applyState();
}
if (handleOpenFloatingViews && isInLauncher) {
@@ -592,7 +592,8 @@
float cornerRoundness = isInLauncher ? 0 : 1;
- if (DisplayController.isInDesktopMode(mLauncher) && mControllers.getSharedState() != null) {
+ if (mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()
+ && mControllers.getSharedState() != null) {
cornerRoundness =
mControllers.taskbarDesktopModeController.getTaskbarCornerRoundness(
mControllers.getSharedState().showCornerRadiusInDesktopMode);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 8c87fa6..1b4db7a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -60,6 +60,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks;
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
@@ -209,12 +210,14 @@
}
};
+ @NonNull private final DesktopVisibilityController mDesktopVisibilityController;
+
@SuppressLint("WrongConstant")
public TaskbarManager(
Context context,
AllAppsActionManager allAppsActionManager,
- TaskbarNavButtonCallbacks navCallbacks) {
-
+ TaskbarNavButtonCallbacks navCallbacks,
+ @NonNull DesktopVisibilityController desktopVisibilityController) {
Display display =
context.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
mContext = context.createWindowContext(display,
@@ -224,6 +227,7 @@
mNavigationBarPanelContext = ENABLE_TASKBAR_NAVBAR_UNIFICATION
? context.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null)
: null;
+ mDesktopVisibilityController = desktopVisibilityController;
if (enableTaskbarNoRecreate()) {
mWindowManager = mContext.getSystemService(WindowManager.class);
mTaskbarRootLayout = new FrameLayout(mContext) {
@@ -470,7 +474,7 @@
if (enableTaskbarNoRecreate() || mTaskbarActivityContext == null) {
mTaskbarActivityContext = new TaskbarActivityContext(mContext,
mNavigationBarPanelContext, dp, mNavButtonController,
- mUnfoldProgressProvider);
+ mUnfoldProgressProvider, mDesktopVisibilityController);
} else {
mTaskbarActivityContext.updateDeviceProfile(dp);
}
@@ -549,7 +553,15 @@
public void transitionTo(@BarTransitions.TransitionMode int barMode,
boolean animate) {
- mTaskbarActivityContext.transitionTo(barMode, animate);
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.transitionTo(barMode, animate);
+ }
+ }
+
+ public void appTransitionPending(boolean pending) {
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.appTransitionPending(pending);
+ }
}
private boolean isTaskbarEnabled(DeviceProfile deviceProfile) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
index 6c9cc64..1867cd0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
@@ -32,10 +32,8 @@
import java.io.PrintWriter
/** Controls taskbar pinning through a popup view. */
-class TaskbarPinningController(
- private val context: TaskbarActivityContext,
- private val isInDesktopModeProvider: () -> Boolean,
-) : TaskbarControllers.LoggableTaskbarController {
+class TaskbarPinningController(private val context: TaskbarActivityContext) :
+ TaskbarControllers.LoggableTaskbarController {
private lateinit var controllers: TaskbarControllers
private lateinit var taskbarSharedState: TaskbarSharedState
@@ -58,7 +56,7 @@
return
}
val shouldPinTaskbar =
- if (isInDesktopModeProvider()) {
+ if (controllers.taskbarDesktopModeController.areDesktopTasksVisible) {
!launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)
} else {
!launcherPrefs.get(TASKBAR_PINNING)
@@ -119,7 +117,7 @@
dragLayerController.taskbarBackgroundProgress.animateToValue(animateToValue),
taskbarViewController.taskbarIconTranslationYForPinning.animateToValue(animateToValue),
taskbarViewController.taskbarIconScaleForPinning.animateToValue(animateToValue),
- taskbarViewController.taskbarIconTranslationXForPinning.animateToValue(animateToValue)
+ taskbarViewController.taskbarIconTranslationXForPinning.animateToValue(animateToValue),
)
animatorSet.interpolator = Interpolators.EMPHASIZED
@@ -134,10 +132,10 @@
@VisibleForTesting
fun recreateTaskbarAndUpdatePinningValue() {
updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(false)
- if (isInDesktopModeProvider()) {
+ if (controllers.taskbarDesktopModeController.areDesktopTasksVisible) {
launcherPrefs.put(
TASKBAR_PINNING_IN_DESKTOP_MODE,
- !launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)
+ !launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE),
)
} else {
launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING))
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 332eb95..2cee77d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -189,7 +189,7 @@
// here will reflect in the popup
ArrayList<SystemShortcut.Factory> shortcuts = new ArrayList<>();
shortcuts.add(APP_INFO);
- if (!mControllers.taskbarRecentAppsController.isInDesktopMode()) {
+ if (!mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()) {
shortcuts.addAll(mControllers.uiController.getSplitMenuOptions().toList());
}
if (com.android.wm.shell.Flags.enableBubbleAnything()) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
index 737d031..72bdafe 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
@@ -21,7 +21,6 @@
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.TaskItemInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
-import com.android.launcher3.statehandlers.DesktopVisibilityController
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
import com.android.launcher3.util.CancellableTask
import com.android.quickstep.RecentsModel
@@ -36,13 +35,8 @@
* - When in Fullscreen mode: show the N most recent Tasks
* - When in Desktop Mode: show the currently running (open) Tasks
*/
-class TaskbarRecentAppsController(
- context: Context,
- private val recentsModel: RecentsModel,
- // Pass a provider here instead of the actual DesktopVisibilityController instance since that
- // instance might not be available when this constructor is called.
- private val desktopVisibilityControllerProvider: () -> DesktopVisibilityController?,
-) : LoggableTaskbarController {
+class TaskbarRecentAppsController(context: Context, private val recentsModel: RecentsModel) :
+ LoggableTaskbarController {
var canShowRunningApps =
DesktopModeStatus.canEnterDesktopMode(context) &&
@@ -78,19 +72,16 @@
var shownTasks: List<GroupTask> = emptyList()
private set
- private val desktopVisibilityController: DesktopVisibilityController?
- get() = desktopVisibilityControllerProvider()
-
- val isInDesktopMode: Boolean
- get() = desktopVisibilityController?.areDesktopTasksVisible() ?: false
-
val runningTaskIds: Set<Int>
/**
* Returns the task IDs of apps that should be indicated as "running" to the user.
* Specifically, we return all the open tasks if we are in Desktop mode, else emptySet().
*/
get() {
- if (!canShowRunningApps || !isInDesktopMode) {
+ if (
+ !canShowRunningApps ||
+ !controllers.taskbarDesktopModeController.areDesktopTasksVisible
+ ) {
return emptySet()
}
val tasks = desktopTask?.tasks ?: return emptySet()
@@ -102,7 +93,10 @@
* Returns the task IDs for the tasks that should be indicated as "minimized" to the user.
*/
get() {
- if (!canShowRunningApps || !isInDesktopMode) {
+ if (
+ !canShowRunningApps ||
+ !controllers.taskbarDesktopModeController.areDesktopTasksVisible
+ ) {
return emptySet()
}
val desktopTasks = desktopTask?.tasks ?: return emptySet()
@@ -124,7 +118,7 @@
controllers = taskbarControllers
if (canShowRunningApps || canShowRecentApps) {
recentsModel.registerRecentTasksChangedListener(recentTasksChangedListener)
- reloadRecentTasksIfNeeded()
+ controllers.runAfterInit { reloadRecentTasksIfNeeded() }
}
}
@@ -137,8 +131,10 @@
/** Called to update hotseatItems, in order to de-dupe them from Recent/Running tasks later. */
fun updateHotseatItemInfos(hotseatItems: Array<ItemInfo?>): Array<ItemInfo?> {
// Ignore predicted apps - we show running or recent apps instead.
+ val areDesktopTasksVisible = controllers.taskbarDesktopModeController.areDesktopTasksVisible
val removePredictions =
- (isInDesktopMode && canShowRunningApps) || (!isInDesktopMode && canShowRecentApps)
+ (areDesktopTasksVisible && canShowRunningApps) ||
+ (!areDesktopTasksVisible && canShowRecentApps)
if (!removePredictions) {
shownHotseatItems = hotseatItems.filterNotNull()
onRecentsOrHotseatChanged()
@@ -150,11 +146,11 @@
.filter { itemInfo -> !itemInfo.isPredictedItem }
.toMutableList()
- if (isInDesktopMode && canShowRunningApps) {
+ if (areDesktopTasksVisible && canShowRunningApps) {
shownHotseatItems =
updateHotseatItemsFromRunningTasks(
getOrderedAndWrappedDesktopTasks(),
- shownHotseatItems
+ shownHotseatItems,
)
}
@@ -199,7 +195,7 @@
val oldShownTasks = shownTasks
orderedRunningTaskIds = updateOrderedRunningTaskIds()
shownTasks =
- if (isInDesktopMode) {
+ if (controllers.taskbarDesktopModeController.areDesktopTasksVisible) {
computeShownRunningTasks()
} else {
computeShownRecentTasks()
@@ -281,7 +277,7 @@
private fun dedupeHotseatTasks(
groupTasks: List<GroupTask>,
- shownHotseatItems: List<ItemInfo>
+ shownHotseatItems: List<ItemInfo>,
): List<GroupTask> {
val hotseatPackages = shownHotseatItems.map { item -> item.targetPackage }
return groupTasks.filter { groupTask ->
@@ -296,7 +292,7 @@
*/
private fun updateHotseatItemsFromRunningTasks(
groupTasks: List<GroupTask>,
- shownHotseatItems: List<ItemInfo>
+ shownHotseatItems: List<ItemInfo>,
): List<ItemInfo> =
shownHotseatItems.map { itemInfo ->
if (itemInfo is TaskItemInfo) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 60e65b3..2c2f65d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -63,10 +63,8 @@
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.SystemUiFlagUtils;
@@ -84,6 +82,11 @@
private static final String TAG = "TaskbarStashController";
private static final boolean DEBUG = false;
+ /**
+ * Def. value for @param shouldBubblesFollow in
+ * {@link #updateAndAnimateTransientTaskbar(boolean)} */
+ public static boolean SHOULD_BUBBLES_FOLLOW_DEFAULT_VALUE = true;
+
public static final int FLAG_IN_APP = 1 << 0;
public static final int FLAG_STASHED_IN_APP_SYSUI = 1 << 1; // shade open, ...
public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 2; // setup wizard and AllSetActivity
@@ -96,6 +99,8 @@
public static final int FLAG_STASHED_SYSUI = 1 << 9; // app pinning,...
public static final int FLAG_STASHED_DEVICE_LOCKED = 1 << 10; // device is locked: keyguard, ...
public static final int FLAG_IN_OVERVIEW = 1 << 11; // launcher is in overview
+ // An internal no-op flag to determine whether we should delay the taskbar background animation
+ private static final int FLAG_DELAY_TASKBAR_BG_TAG = 1 << 12;
// If any of these flags are enabled, isInApp should return true.
private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -491,9 +496,17 @@
/**
* Stash or unstashes the transient taskbar, using the default TASKBAR_STASH_DURATION.
* If bubble bar exists, it will match taskbars stashing behavior.
+ * Will not delay taskbar background by default.
*/
public void updateAndAnimateTransientTaskbar(boolean stash) {
- updateAndAnimateTransientTaskbar(stash, /* shouldBubblesFollow= */ true);
+ updateAndAnimateTransientTaskbar(stash, SHOULD_BUBBLES_FOLLOW_DEFAULT_VALUE, false);
+ }
+
+ /**
+ * Stash or unstashes the transient taskbar, using the default TASKBAR_STASH_DURATION.
+ */
+ public void updateAndAnimateTransientTaskbar(boolean stash, boolean shouldBubblesFollow) {
+ updateAndAnimateTransientTaskbar(stash, shouldBubblesFollow, false);
}
/**
@@ -501,28 +514,47 @@
*
* @param stash whether transient taskbar should be stashed.
* @param shouldBubblesFollow whether bubbles should match taskbars behavior.
+ * @param delayTaskbarBackground whether we will delay the taskbar background animation
*/
- public void updateAndAnimateTransientTaskbar(boolean stash, boolean shouldBubblesFollow) {
+ public void updateAndAnimateTransientTaskbar(boolean stash, boolean shouldBubblesFollow,
+ boolean delayTaskbarBackground) {
if (!DisplayController.isTransientTaskbar(mActivity)) {
return;
}
- if (
- stash
- && !mControllers.taskbarAutohideSuspendController
- .isSuspendedForTransientTaskbarInLauncher()
- && mControllers.taskbarAutohideSuspendController
- .isTransientTaskbarStashingSuspended()) {
+ if (stash
+ && !mControllers.taskbarAutohideSuspendController
+ .isSuspendedForTransientTaskbarInLauncher()
+ && mControllers.taskbarAutohideSuspendController
+ .isTransientTaskbarStashingSuspended()) {
// Avoid stashing if autohide is currently suspended.
return;
}
+ boolean shouldApplyState = false;
+
+ if (delayTaskbarBackground) {
+ mControllers.taskbarStashController.updateStateForFlag(FLAG_DELAY_TASKBAR_BG_TAG, true);
+ shouldApplyState = true;
+ }
+
if (hasAnyFlag(FLAG_STASHED_IN_APP_AUTO) != stash) {
mTaskbarSharedState.taskbarWasStashedAuto = stash;
updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, stash);
+ shouldApplyState = true;
+ }
+
+ if (shouldApplyState) {
applyState();
}
+ // Effectively a no-opp to remove the tag.
+ if (delayTaskbarBackground) {
+ mControllers.taskbarStashController.updateStateForFlag(FLAG_DELAY_TASKBAR_BG_TAG,
+ false);
+ mControllers.taskbarStashController.applyState(0);
+ }
+
mControllers.bubbleControllers.ifPresent(controllers -> {
if (shouldBubblesFollow) {
final boolean willStash = mIsStashedPredicate.test(mState);
@@ -576,6 +608,7 @@
/* isStashed= */ mActivity.isPhoneMode(),
placeholderDuration,
TRANSITION_UNSTASH_SUW_MANUAL,
+ /* skipTaskbarBackgroundDelay */ false,
/* jankTag= */ "SUW_MANUAL");
animation.addListener(AnimatorListeners.forEndCallback(
() -> mControllers.taskbarViewController.setDeferUpdatesForSUW(false)));
@@ -585,13 +618,14 @@
/**
* Create a stash animation and save to {@link #mAnimator}.
*
- * @param isStashed whether it's a stash animation or an unstash animation
- * @param duration duration of the animation
- * @param animationType what transition type to play.
- * @param jankTag tag to be used in jank monitor trace.
+ * @param isStashed whether it's a stash animation or an unstash animation
+ * @param duration duration of the animation
+ * @param animationType what transition type to play.
+ * @param shouldDelayBackground whether we should delay the taskbar bg animation
+ * @param jankTag tag to be used in jank monitor trace.
*/
private void createAnimToIsStashed(boolean isStashed, long duration,
- @StashAnimation int animationType, String jankTag) {
+ @StashAnimation int animationType, boolean shouldDelayBackground, String jankTag) {
if (animationType == TRANSITION_UNSTASH_SUW_MANUAL && isStashed) {
// The STASH_ANIMATION_SUW_MANUAL must only be used during an unstash animation.
Log.e(TAG, "Illegal arguments:Using TRANSITION_UNSTASH_SUW_MANUAL to stash taskbar");
@@ -629,7 +663,8 @@
}
if (isTransientTaskbar) {
- createTransientAnimToIsStashed(mAnimator, isStashed, duration, animationType);
+ createTransientAnimToIsStashed(mAnimator, isStashed, duration,
+ shouldDelayBackground, animationType);
} else {
createAnimToIsStashed(mAnimator, isStashed, duration, stashTranslation, animationType);
}
@@ -735,7 +770,7 @@
}
private void createTransientAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
- @StashAnimation int animationType) {
+ boolean shouldDelayBackground, @StashAnimation int animationType) {
// Target values of the properties this is going to set
final float backgroundOffsetTarget = isStashed ? 1 : 0;
final float iconAlphaTarget = isStashed ? 0 : 1;
@@ -786,7 +821,10 @@
backgroundAndHandleAlphaStartDelay,
backgroundAndHandleAlphaDuration, LINEAR);
- if (enableScalingRevealHomeAnimation() && !isStashed) {
+
+ if (enableScalingRevealHomeAnimation()
+ && !isStashed
+ && shouldDelayBackground) {
play(as, getTaskbarBackgroundAnimatorWhenNotGoingHome(duration),
0, 0, LINEAR);
as.addListener(AnimatorListeners.forEndCallback(
@@ -1079,10 +1117,9 @@
}
// Do not stash if hardware keyboard is attached, in 3 button nav and desktop windowing mode
- DesktopVisibilityController visibilityController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
- if (visibilityController != null && mActivity.isHardwareKeyboard()
- && mActivity.isThreeButtonNav() && visibilityController.areDesktopTasksVisible()) {
+ if (mActivity.isHardwareKeyboard()
+ && mActivity.isThreeButtonNav()
+ && mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()) {
return false;
}
@@ -1137,6 +1174,10 @@
TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR,
!hasAnyFlag(FLAG_STASHED_IN_APP_AUTO));
}
+ if (hasAnyFlag(changedFlags, FLAG_IN_OVERVIEW | FLAG_IN_APP)) {
+ mControllers.runAfterInit(() -> mControllers.taskbarInsetsController
+ .onTaskbarOrBubblebarWindowHeightOrInsetsChanged());
+ }
mActivity.applyForciblyShownFlagWhileTransientTaskbarUnstashed(!isStashedInApp());
}
@@ -1176,6 +1217,12 @@
* Clean up on destroy from TaskbarControllers
*/
public void onDestroy() {
+ // If the controller is destroyed before the animation finishes, we cancel the animation
+ // so that we don't finish the CUJ.
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ mAnimator = null;
+ }
UI_HELPER_EXECUTOR.execute(
() -> mAccessibilityManager.unregisterSystemAction(SYSTEM_ACTION_ID_TASKBAR));
}
@@ -1339,8 +1386,9 @@
mIsStashed = isStashed;
mLastStartedTransitionType = animationType;
+ boolean shouldDelayBackground = hasAnyFlag(FLAG_DELAY_TASKBAR_BG_TAG);
// This sets mAnimator.
- createAnimToIsStashed(mIsStashed, duration, animationType,
+ createAnimToIsStashed(mIsStashed, duration, animationType, shouldDelayBackground,
computeTaskbarJankMonitorTag(changedFlags));
return mAnimator;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarThresholdUtils.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarThresholdUtils.java
index 5b6fbef..17516f3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarThresholdUtils.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarThresholdUtils.java
@@ -25,7 +25,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
/**
* Utility class that contains the different taskbar thresholds logic.
@@ -39,10 +38,6 @@
private static int getThreshold(Resources r, DeviceProfile dp, int thresholdDimen,
int multiplierDimen) {
- if (!FeatureFlags.ENABLE_DYNAMIC_TASKBAR_THRESHOLDS.get()) {
- return r.getDimensionPixelSize(thresholdDimen);
- }
-
float landscapeScreenHeight = dp.isLandscape ? dp.heightPx : dp.widthPx;
float screenPart = (landscapeScreenHeight * SCREEN_UNITS);
float defaultDp = dpiFromPx(screenPart, DisplayMetrics.DENSITY_DEVICE_STABLE);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index aa3e6bf..292b9ed 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -206,7 +206,8 @@
mModelCallbacks.init(controllers);
if (mActivity.isUserSetupComplete() && sEnableModelLoadingForTests) {
// Only load the callbacks if user setup is completed
- LauncherAppState.getInstance(mActivity).getModel().addCallbacksAndLoad(mModelCallbacks);
+ controllers.runAfterInit(() -> LauncherAppState.getInstance(mActivity).getModel()
+ .addCallbacksAndLoad(mModelCallbacks));
}
mTaskbarNavButtonTranslationY =
controllers.navbarButtonsViewController.getTaskbarNavButtonTranslationY();
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
index 25939e1..f08318e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
@@ -71,6 +71,27 @@
}
}
+ /**
+ * Scale of the background in the x direction. Pivot is at the left edge if [anchorLeft] is
+ * `true` and at the right edge if it is `false`
+ */
+ var scaleX: Float = 1f
+ set(value) {
+ if (field != value) {
+ field = value
+ invalidateSelf()
+ }
+ }
+
+ /** Scale of the background in the y direction. Pivot is at the bottom edge. */
+ var scaleY: Float = 1f
+ set(value) {
+ if (field != value) {
+ field = value
+ invalidateSelf()
+ }
+ }
+
init {
val res = context.resources
// configure fill paint
@@ -123,13 +144,17 @@
)
// Create background path
val backgroundPath = Path()
- val topOffset = backgroundHeight - bounds.height().toFloat()
+ val scaledBackgroundHeight = backgroundHeight * scaleY
+ val scaledWidth = width * scaleX
+ val topOffset = scaledBackgroundHeight - bounds.height().toFloat()
val radius = backgroundHeight / 2f
- val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - width)
- val right = bounds.left + (if (anchorLeft) width else bounds.width().toFloat())
- val top = bounds.top - topOffset + arrowVisibleHeight
- val bottom = bounds.top + bounds.height().toFloat()
+ val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - scaledWidth)
+ val right = bounds.left + (if (anchorLeft) scaledWidth else bounds.width().toFloat())
+ // Calculate top with scaled heights for background and arrow to align with stash handle
+ val top = bounds.bottom - scaledBackgroundHeight + getScaledArrowVisibleHeight()
+ val bottom = bounds.bottom.toFloat()
+
backgroundPath.addRoundRect(left, top, right, bottom, radius, radius, Path.Direction.CW)
addArrowPathIfNeeded(backgroundPath, topOffset)
@@ -142,19 +167,20 @@
private fun addArrowPathIfNeeded(sourcePath: Path, topOffset: Float) {
if (!showingArrow || arrowHeightFraction <= 0) return
val arrowPath = Path()
+ val scaledHeight = getScaledArrowHeight()
RoundedArrowDrawable.addDownPointingRoundedTriangleToPath(
arrowWidth,
- arrowHeight,
+ scaledHeight,
arrowTipRadius,
arrowPath
)
// flip it horizontally
val pathTransform = Matrix()
- pathTransform.setRotate(180f, arrowWidth * 0.5f, arrowHeight * 0.5f)
+ pathTransform.setRotate(180f, arrowWidth * 0.5f, scaledHeight * 0.5f)
arrowPath.transform(pathTransform)
// shift to arrow position
val arrowStart = bounds.left + arrowPositionX - (arrowWidth / 2f)
- val arrowTop = (1 - arrowHeightFraction) * arrowVisibleHeight - topOffset
+ val arrowTop = (1 - arrowHeightFraction) * getScaledArrowVisibleHeight() - topOffset
arrowPath.offset(arrowStart, arrowTop)
// union with rectangle
sourcePath.op(arrowPath, Path.Op.UNION)
@@ -183,6 +209,7 @@
fun setBackgroundHeight(newHeight: Float) {
backgroundHeight = newHeight
+ invalidateSelf()
}
/**
@@ -199,6 +226,14 @@
invalidateSelf()
}
+ private fun getScaledArrowHeight(): Float {
+ return arrowHeight * scaleY
+ }
+
+ private fun getScaledArrowVisibleHeight(): Float {
+ return max(0f, getScaledArrowHeight() - (arrowHeight - arrowVisibleHeight))
+ }
+
companion object {
private const val DARK_THEME_STROKE_ALPHA = 51
private const val LIGHT_THEME_STROKE_ALPHA = 41
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 8ab1ae7..c005640 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -187,6 +187,9 @@
private BubbleView mDismissedByDragBubbleView;
private float mAlphaDuringDrag = 1f;
+ /** Additional translation in the y direction that is applied to each bubble */
+ private float mBubbleOffsetY;
+
private Controller mController;
private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED;
@@ -205,7 +208,6 @@
public BubbleBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- setAlpha(0);
setVisibility(INVISIBLE);
mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap);
mBubbleBarPadding = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
@@ -306,6 +308,46 @@
}
/**
+ * Set scale for bubble bar background in x direction
+ */
+ public void setBackgroundScaleX(float scaleX) {
+ mBubbleBarBackground.setScaleX(scaleX);
+ }
+
+ /**
+ * Set scale for bubble bar background in y direction
+ */
+ public void setBackgroundScaleY(float scaleY) {
+ mBubbleBarBackground.setScaleY(scaleY);
+ }
+
+ /**
+ * Set alpha for bubble views
+ */
+ public void setBubbleAlpha(float alpha) {
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).setAlpha(alpha);
+ }
+ }
+
+ /**
+ * Set alpha for bar background
+ */
+ public void setBackgroundAlpha(float alpha) {
+ mBubbleBarBackground.setAlpha((int) (255 * alpha));
+ }
+
+ /**
+ * Sets offset of each bubble view in the y direction from the base position in the bar.
+ */
+ public void setBubbleOffsetY(float offsetY) {
+ mBubbleOffsetY = offsetY;
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).setTranslationY(getBubbleTranslationY());
+ }
+ }
+
+ /**
* Sets new icon sizes and newBubbleBarPadding between icons and bubble bar borders.
*
* @param newIconSize new icon size
@@ -322,7 +364,7 @@
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
- childView.setScaleY(mIconScale);
+ childView.setScaleX(mIconScale);
childView.setScaleY(mIconScale);
FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams();
params.height = (int) mIconSize;
@@ -770,6 +812,9 @@
removeView(removedBubble);
int index = addingOverflow ? getChildCount() : 0;
addView(addedBubble, index, lp);
+ if (onEndRunnable != null) {
+ onEndRunnable.run();
+ }
return;
}
int index = addingOverflow ? getChildCount() : 0;
@@ -965,10 +1010,7 @@
final float expandedWidth = expandedWidth();
final float collapsedWidth = collapsedWidth();
int childCount = getChildCount();
- float viewBottom = mBubbleBarBounds.height() + (isExpanded() ? mPointerSize : 0);
- float bubbleBarAnimatedTop = viewBottom - getBubbleBarHeight();
- // When translating X & Y the scale is ignored, so need to deduct it from the translations
- final float ty = bubbleBarAnimatedTop + mBubbleBarPadding - getScaleIconShift();
+ final float ty = getBubbleTranslationY();
final boolean onLeft = bubbleBarLocation.isOnLeft(isLayoutRtl());
// elevation state is opposite to widthState - when expanded all icons are flat
float elevationState = (1 - widthState);
@@ -1015,7 +1057,7 @@
// where the bubble will end up when the animation ends
final float targetX = expandedX + expandedBarShift;
bv.setTranslationX(widthState * (targetX - collapsedX) + collapsedX);
- bv.setAlpha(1);
+ bv.setVisibility(VISIBLE);
} else {
// If bar is on the right, account for bubble bar expanding and shifting left
final float collapsedBarShift = onLeft ? 0 : currentWidth - collapsedWidth;
@@ -1025,9 +1067,9 @@
// the overflow.
if (widthState == 0) {
if (bv.isOverflow() || i > MAX_VISIBLE_BUBBLES_COLLAPSED - 1) {
- bv.setAlpha(0);
+ bv.setVisibility(INVISIBLE);
} else {
- bv.setAlpha(1);
+ bv.setVisibility(VISIBLE);
}
}
}
@@ -1105,6 +1147,13 @@
return mBubbleBarPadding + translationX - getScaleIconShift();
}
+ private float getBubbleTranslationY() {
+ float viewBottom = mBubbleBarBounds.height() + (isExpanded() ? mPointerSize : 0);
+ float bubbleBarAnimatedTop = viewBottom - getBubbleBarHeight();
+ // When translating X & Y the scale is ignored, so need to deduct it from the translations
+ return mBubbleOffsetY + bubbleBarAnimatedTop + mBubbleBarPadding - getScaleIconShift();
+ }
+
/**
* Reorders the views to match the provided list.
*/
@@ -1338,7 +1387,7 @@
* touch bounds.
*/
public boolean isEventOverAnyItem(MotionEvent ev) {
- if (getVisibility() == View.VISIBLE) {
+ if (getVisibility() == VISIBLE) {
getBoundsOnScreen(mTempRect);
return mTempRect.contains((int) ev.getX(), (int) ev.getY());
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index d9e3406..ed08de5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -18,6 +18,8 @@
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
@@ -34,6 +36,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.launcher3.taskbar.TaskbarInsetsController;
@@ -80,10 +83,19 @@
// These are exposed to {@link BubbleStashController} to animate for stashing/un-stashing
private final MultiValueAlpha mBubbleBarAlpha;
+ private final AnimatedFloat mBubbleBarBubbleAlpha = new AnimatedFloat(this::updateBubbleAlpha);
+ private final AnimatedFloat mBubbleBarBackgroundAlpha = new AnimatedFloat(
+ this::updateBackgroundAlpha);
private final AnimatedFloat mBubbleBarScaleX = new AnimatedFloat(this::updateScaleX);
private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY);
+ private final AnimatedFloat mBubbleBarBackgroundScaleX = new AnimatedFloat(
+ this::updateBackgroundScaleX);
+ private final AnimatedFloat mBubbleBarBackgroundScaleY = new AnimatedFloat(
+ this::updateBackgroundScaleY);
private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat(
this::updateTranslationY);
+ private final AnimatedFloat mBubbleOffsetY = new AnimatedFloat(
+ this::updateBubbleOffsetY);
// Modified when swipe up is happening on the bubble bar or task bar.
private float mBubbleBarSwipeUpTranslationY;
@@ -258,6 +270,14 @@
return mBubbleBarAlpha;
}
+ public AnimatedFloat getBubbleBarBubbleAlpha() {
+ return mBubbleBarBubbleAlpha;
+ }
+
+ public AnimatedFloat getBubbleBarBackgroundAlpha() {
+ return mBubbleBarBackgroundAlpha;
+ }
+
public AnimatedFloat getBubbleBarScaleX() {
return mBubbleBarScaleX;
}
@@ -266,10 +286,22 @@
return mBubbleBarScaleY;
}
+ public AnimatedFloat getBubbleBarBackgroundScaleX() {
+ return mBubbleBarBackgroundScaleX;
+ }
+
+ public AnimatedFloat getBubbleBarBackgroundScaleY() {
+ return mBubbleBarBackgroundScaleY;
+ }
+
public AnimatedFloat getBubbleBarTranslationY() {
return mBubbleBarTranslationY;
}
+ public AnimatedFloat getBubbleOffsetY() {
+ return mBubbleOffsetY;
+ }
+
public float getBubbleBarCollapsedWidth() {
return mBarView.collapsedWidth();
}
@@ -535,6 +567,26 @@
mBarView.setScaleY(scale);
}
+ private void updateBackgroundScaleX(float scale) {
+ mBarView.setBackgroundScaleX(scale);
+ }
+
+ private void updateBackgroundScaleY(float scale) {
+ mBarView.setBackgroundScaleY(scale);
+ }
+
+ private void updateBubbleAlpha(float alpha) {
+ mBarView.setBubbleAlpha(alpha);
+ }
+
+ private void updateBubbleOffsetY(float transY) {
+ mBarView.setBubbleOffsetY(transY);
+ }
+
+ private void updateBackgroundAlpha(float alpha) {
+ mBarView.setBackgroundAlpha(alpha);
+ }
+
//
// Manipulating the specific bubble views in the bar
//
@@ -820,6 +872,48 @@
}
/**
+ * Create an animator for showing or hiding bubbles when stashed state changes
+ *
+ * @param isStashed {@code true} when bubble bar should be stashed to the handle
+ */
+ public Animator createRevealAnimatorForStashChange(boolean isStashed) {
+ Rect stashedHandleBounds = new Rect();
+ mBubbleStashController.getHandleBounds(stashedHandleBounds);
+ int childCount = mBarView.getChildCount();
+ float newChildWidth = (float) stashedHandleBounds.width() / childCount;
+ AnimatorSet animatorSet = new AnimatorSet();
+ for (int i = 0; i < childCount; i++) {
+ BubbleView child = (BubbleView) mBarView.getChildAt(i);
+ animatorSet.play(
+ createRevealAnimForBubble(child, isStashed, stashedHandleBounds,
+ newChildWidth));
+ }
+ return animatorSet;
+ }
+
+ private Animator createRevealAnimForBubble(BubbleView bubbleView, boolean isStashed,
+ Rect stashedHandleBounds, float newWidth) {
+ Rect viewBounds = new Rect(0, 0, bubbleView.getWidth(), bubbleView.getHeight());
+
+ int viewCenterY = viewBounds.centerY();
+ int halfHandleHeight = stashedHandleBounds.height() / 2;
+ int widthDelta = Math.max(0, (int) (viewBounds.width() - newWidth) / 2);
+
+ Rect stashedViewBounds = new Rect(
+ viewBounds.left + widthDelta,
+ viewCenterY - halfHandleHeight,
+ viewBounds.right - widthDelta,
+ viewCenterY + halfHandleHeight
+ );
+
+ float viewRadius = 0f; // Use 0 to not clip the new message dot or the app icon
+ float stashedRadius = stashedViewBounds.height() / 2f;
+
+ return new RoundedRectRevealOutlineProvider(viewRadius, stashedRadius, viewBounds,
+ stashedViewBounds).createRevealAnimator(bubbleView, !isStashed, 0);
+ }
+
+ /**
* Listener to receive updates about bubble bar bounds changing
*/
public interface BubbleBarBoundsChangeListener {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
index fdd385a..3640c3b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -187,6 +187,13 @@
}
/**
+ * Returns bounds of the stashed handle view
+ */
+ public void getBounds(Rect bounds) {
+ bounds.set(mStashedHandleBounds);
+ }
+
+ /**
* Called when system ui state changes. Bubbles don't show when the device is locked.
*/
public void setHiddenForSysui(boolean hidden) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index 591a9da..561df5c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
@@ -110,6 +111,10 @@
setFocusable(true);
setClickable(true);
+
+ // We manage the shadow ourselves when creating the bitmap
+ setOutlineAmbientShadowColor(Color.TRANSPARENT);
+ setOutlineSpotShadowColor(Color.TRANSPARENT);
}
private void updateBubbleSizeAndDotRender() {
@@ -152,16 +157,16 @@
applyDragTranslation();
}
+ private void applyDragTranslation() {
+ setTranslationX(mDragTranslationX + mOffsetX);
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
updateBubbleSizeAndDotRender();
}
- private void applyDragTranslation() {
- setTranslationX(mDragTranslationX + mOffsetX);
- }
-
@Override
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 99c50f2..6a955d9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -169,6 +169,8 @@
bubbleBarView.translationY = 0f
bubbleBarView.scaleX = 1f
bubbleBarView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y
+ bubbleBarView.setBackgroundScaleX(1f)
+ bubbleBarView.setBackgroundScaleY(1f)
bubbleBarView.relativePivotY = 0.5f
// this is the offset between the center of the bubble bar and the center of the stash
@@ -311,6 +313,7 @@
animatingBubble = null
if (!canceled) bubbleStashController.stashBubbleBarImmediate()
bubbleBarView.relativePivotY = 1f
+ bubbleBarView.scaleY = 1f
bubbleStashController.updateTaskbarTouchRegion()
}
animator.start()
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
index 8d63217..9721792 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar.bubbles.stashing
+import android.graphics.Rect
import android.view.InsetsController
import android.view.MotionEvent
import android.view.View
@@ -146,6 +147,9 @@
/** Returns the translation of the handle. */
fun getHandleTranslationY(): Float?
+ /** Returns bounds of the handle */
+ fun getHandleBounds(bounds: Rect)
+
/**
* Returns bubble bar Y position according to [isBubblesShowingOnHome] and
* [isBubblesShowingOnOverview] values. Default implementation only analyse
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
index eaf4bf9..7d6f7ad 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
@@ -19,6 +19,7 @@
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
+import android.graphics.Rect
import android.view.MotionEvent
import android.view.View
import com.android.launcher3.anim.AnimatedFloat
@@ -200,6 +201,10 @@
override fun getHandleTranslationY(): Float? = null
+ override fun getHandleBounds(bounds: Rect) {
+ // no op since does not have a handle view
+ }
+
private fun updateExpandedState(expand: Boolean) {
if (bubbleBarViewController.isHiddenForNoBubbles) {
// If there are no bubbles the bar is invisible, nothing to do here.
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
index 1157305..4f0337d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
@@ -19,6 +19,7 @@
import android.animation.Animator
import android.animation.AnimatorSet
import android.content.Context
+import android.graphics.Rect
import android.view.MotionEvent
import android.view.View
import androidx.annotation.VisibleForTesting
@@ -46,7 +47,7 @@
class TransientBubbleStashController(
private val taskbarHotseatDimensionsProvider: TaskbarHotseatDimensionsProvider,
- private val context: Context
+ private val context: Context,
) : BubbleStashController {
private lateinit var bubbleBarViewController: BubbleBarViewController
@@ -66,9 +67,12 @@
// bubble bar properties
private lateinit var bubbleBarAlpha: MultiPropertyFactory<View>.MultiProperty
+ private lateinit var bubbleBarBubbleAlpha: AnimatedFloat
+ private lateinit var bubbleBarBackgroundAlpha: AnimatedFloat
private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat
- private lateinit var bubbleBarScaleX: AnimatedFloat
- private lateinit var bubbleBarScaleY: AnimatedFloat
+ private lateinit var bubbleBarBubbleTranslationY: AnimatedFloat
+ private lateinit var bubbleBarBackgroundScaleX: AnimatedFloat
+ private lateinit var bubbleBarBackgroundScaleY: AnimatedFloat
private val handleCenterFromScreenBottom =
context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f
@@ -140,17 +144,20 @@
taskbarInsetsController: TaskbarInsetsController,
bubbleBarViewController: BubbleBarViewController,
bubbleStashedHandleViewController: BubbleStashedHandleViewController?,
- controllersAfterInitAction: ControllersAfterInitAction
+ controllersAfterInitAction: ControllersAfterInitAction,
) {
this.taskbarInsetsController = taskbarInsetsController
this.bubbleBarViewController = bubbleBarViewController
this.bubbleStashedHandleViewController = bubbleStashedHandleViewController
this.controllersAfterInitAction = controllersAfterInitAction
bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY
+ bubbleBarBubbleTranslationY = bubbleBarViewController.bubbleOffsetY
// bubble bar has only alpha property, getting it at index 0
bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0)
- bubbleBarScaleX = bubbleBarViewController.bubbleBarScaleX
- bubbleBarScaleY = bubbleBarViewController.bubbleBarScaleY
+ bubbleBarBubbleAlpha = bubbleBarViewController.bubbleBarBubbleAlpha
+ bubbleBarBackgroundAlpha = bubbleBarViewController.bubbleBarBackgroundAlpha
+ bubbleBarBackgroundScaleX = bubbleBarViewController.bubbleBarBackgroundScaleX
+ bubbleBarBackgroundScaleY = bubbleBarViewController.bubbleBarBackgroundScaleY
stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0
stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0)
}
@@ -160,10 +167,12 @@
if (isBubblesShowingOnHome || isBubblesShowingOnOverview) {
isStashed = false
animatorSet.playTogether(
- bubbleBarScaleX.animateToValue(1f),
- bubbleBarScaleY.animateToValue(1f),
+ bubbleBarBackgroundScaleX.animateToValue(1f),
+ bubbleBarBackgroundScaleY.animateToValue(1f),
bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY),
- bubbleBarAlpha.animateToValue(1f)
+ bubbleBarAlpha.animateToValue(1f),
+ bubbleBarBubbleAlpha.animateToValue(1f),
+ bubbleBarBackgroundAlpha.animateToValue(1f),
)
} else {
isStashed = true
@@ -181,8 +190,10 @@
stashHandleViewAlpha?.value = 0f
this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY)
bubbleBarAlpha.setValue(1f)
- bubbleBarScaleX.updateValue(1f)
- bubbleBarScaleY.updateValue(1f)
+ bubbleBarBubbleAlpha.updateValue(1f)
+ bubbleBarBackgroundAlpha.updateValue(1f)
+ bubbleBarBackgroundScaleX.updateValue(1f)
+ bubbleBarBackgroundScaleY.updateValue(1f)
isStashed = false
onIsStashedChanged()
}
@@ -192,8 +203,11 @@
stashHandleViewAlpha?.value = 1f
this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation())
bubbleBarAlpha.setValue(0f)
- bubbleBarScaleX.updateValue(getStashScaleX())
- bubbleBarScaleY.updateValue(getStashScaleY())
+ // Reset bubble and background alpha to 1 and only keep the bubble bar alpha at 0
+ bubbleBarBubbleAlpha.updateValue(1f)
+ bubbleBarBackgroundAlpha.updateValue(1f)
+ bubbleBarBackgroundScaleX.updateValue(getStashScaleX())
+ bubbleBarBackgroundScaleY.updateValue(getStashScaleY())
isStashed = true
onIsStashedChanged()
}
@@ -258,8 +272,12 @@
override fun getHandleTranslationY(): Float? = bubbleStashedHandleViewController?.translationY
+ override fun getHandleBounds(bounds: Rect) {
+ bubbleStashedHandleViewController?.getBounds(bounds)
+ }
+
private fun getStashTranslation(): Float {
- return bubbleBarTranslationY / 2f
+ return (bubbleBarTranslationY - stashedHeight) / 2f
}
@VisibleForTesting
@@ -285,10 +303,10 @@
private fun createStashAnimator(isStashed: Boolean, duration: Long): AnimatorSet {
val animatorSet = AnimatorSet()
- val alphaDuration = if (isStashed) duration else TASKBAR_STASH_ALPHA_DURATION
- val alphaDelay = if (isStashed) TASKBAR_STASH_ALPHA_START_DELAY else 0L
animatorSet.play(
- createStashAlphaAnimator(isStashed).apply {
+ createBackgroundAlphaAnimator(isStashed).apply {
+ val alphaDuration = if (isStashed) duration else TASKBAR_STASH_ALPHA_DURATION
+ val alphaDelay = if (isStashed) TASKBAR_STASH_ALPHA_START_DELAY else 0L
this.duration = max(0L, alphaDuration - alphaDelay)
this.startDelay = alphaDelay
this.interpolator = LINEAR
@@ -296,6 +314,16 @@
)
animatorSet.play(
+ bubbleBarBubbleAlpha
+ .animateToValue(getBarAlphaStart(isStashed), getBarAlphaEnd(isStashed))
+ .apply {
+ this.duration = TASKBAR_STASH_ALPHA_DURATION
+ this.startDelay = TASKBAR_STASH_ALPHA_START_DELAY
+ this.interpolator = LINEAR
+ }
+ )
+
+ animatorSet.play(
createSpringOnStashAnimator(isStashed).apply {
this.duration = duration
this.interpolator = LINEAR
@@ -303,6 +331,23 @@
)
animatorSet.play(
+ bubbleBarViewController.createRevealAnimatorForStashChange(isStashed).apply {
+ this.duration = duration
+ this.interpolator = EMPHASIZED
+ }
+ )
+
+ // Animate bubble translation to keep reveal animation in the bounds of the bar
+ val bubbleTyStart = if (isStashed) 0f else -bubbleBarTranslationY
+ val bubbleTyEnd = if (isStashed) -bubbleBarTranslationY else 0f
+ animatorSet.play(
+ bubbleBarBubbleTranslationY.animateToValue(bubbleTyStart, bubbleTyEnd).apply {
+ this.duration = duration
+ this.interpolator = EMPHASIZED
+ }
+ )
+
+ animatorSet.play(
bubbleStashedHandleViewController?.createRevealAnimToIsStashed(isStashed)?.apply {
this.duration = duration
this.interpolator = EMPHASIZED
@@ -326,10 +371,28 @@
}
)
+ animatorSet.doOnStart {
+ // Update the start value for bubble view and background alpha when the entire animation
+ // begins.
+ // Alpha animation has a delay, and if we set the initial values at the start of the
+ // alpha animation, it will cause flickers.
+ bubbleBarBubbleAlpha.updateValue(getBarAlphaStart(isStashed))
+ bubbleBarBackgroundAlpha.updateValue(getBarAlphaStart(isStashed))
+ // We animate alpha for background and bubble views separately. Make sure the container
+ // is always visible.
+ bubbleBarAlpha.value = 1f
+ }
animatorSet.doOnEnd {
animator = null
controllersAfterInitAction.runAfterInit {
if (isStashed) {
+ bubbleBarAlpha.value = 0f
+ // reset bubble view alpha
+ bubbleBarBubbleAlpha.updateValue(1f)
+ bubbleBarBackgroundAlpha.updateValue(1f)
+ // reset stash translation
+ translationYDuringStash.updateValue(0f)
+ bubbleBarBubbleTranslationY.updateValue(0f)
bubbleBarViewController.isExpanded = false
}
taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
@@ -338,15 +401,30 @@
return animatorSet
}
- private fun createStashAlphaAnimator(isStashed: Boolean): AnimatorSet {
- val stashHandleAlphaTarget = if (isStashed) 1f else 0f
- val barAlphaTarget = if (isStashed) 0f else 1f
+ private fun createBackgroundAlphaAnimator(isStashed: Boolean): AnimatorSet {
return AnimatorSet().apply {
- play(bubbleBarAlpha.animateToValue(barAlphaTarget))
- play(stashHandleViewAlpha?.animateToValue(stashHandleAlphaTarget))
+ play(
+ bubbleBarBackgroundAlpha.animateToValue(
+ getBarAlphaStart(isStashed),
+ getBarAlphaEnd(isStashed),
+ )
+ )
+ play(stashHandleViewAlpha?.animateToValue(getHandleAlphaEnd(isStashed)))
}
}
+ private fun getBarAlphaStart(isStashed: Boolean): Float {
+ return if (isStashed) 1f else 0f
+ }
+
+ private fun getBarAlphaEnd(isStashed: Boolean): Float {
+ return if (isStashed) 0f else 1f
+ }
+
+ private fun getHandleAlphaEnd(isStashed: Boolean): Float {
+ return if (isStashed) 1f else 0f
+ }
+
private fun createSpringOnStashAnimator(isStashed: Boolean): Animator {
if (!isStashed) {
// Animate the stash translation back to 0
@@ -366,8 +444,8 @@
val scaleXTarget = if (isStashed) getStashScaleX() else 1f
val scaleYTarget = if (isStashed) getStashScaleY() else 1f
return AnimatorSet().apply {
- play(bubbleBarScaleX.animateToValue(scaleXTarget))
- play(bubbleBarScaleY.animateToValue(scaleYTarget))
+ play(bubbleBarBackgroundScaleX.animateToValue(scaleXTarget))
+ play(bubbleBarBackgroundScaleY.animateToValue(scaleYTarget))
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
index c83ac50..7739a0e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
@@ -26,23 +26,6 @@
private constructor(
private val taskbarActivityContext: TaskbarActivityContext,
) {
-
- companion object {
- @Volatile private lateinit var taskbarFeatureEvaluator: TaskbarFeatureEvaluator
-
- @JvmStatic
- fun getInstance(
- taskbarActivityContext: TaskbarActivityContext,
- ): TaskbarFeatureEvaluator {
- synchronized(this) {
- if (!::taskbarFeatureEvaluator.isInitialized) {
- taskbarFeatureEvaluator = TaskbarFeatureEvaluator(taskbarActivityContext)
- }
- return taskbarFeatureEvaluator
- }
- }
- }
-
val hasAllApps = true
val hasAppIcons = true
val hasBubbles = false
@@ -59,4 +42,24 @@
val isLandscape: Boolean
get() = taskbarActivityContext.deviceProfile.isLandscape
+
+ fun onDestroy() {
+ taskbarFeatureEvaluator = null
+ }
+
+ companion object {
+ @Volatile private var taskbarFeatureEvaluator: TaskbarFeatureEvaluator? = null
+
+ @JvmStatic
+ fun getInstance(
+ taskbarActivityContext: TaskbarActivityContext,
+ ): TaskbarFeatureEvaluator {
+ synchronized(this) {
+ if (taskbarFeatureEvaluator == null) {
+ taskbarFeatureEvaluator = TaskbarFeatureEvaluator(taskbarActivityContext)
+ }
+ return taskbarFeatureEvaluator!!
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
index 6be0828..e55cb1f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
@@ -37,6 +37,8 @@
val minimumTaskbarIconTouchSize = TaskbarIconSize(48)
+ val transientOrPinnedTaskbarIconPaddingSize = iconSize52dp
+
val transientTaskbarIconSizeByGridSize =
mapOf(
TransientTaskbarIconSizeKey(6, 5, false) to iconSize52dp,
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
index f37b2c1..822ca64 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
@@ -31,7 +31,10 @@
private var taskbarContainer: List<TaskbarContainer> = emptyList()
val taskbarIconPadding: Int =
- if (TaskbarIconSpecs.iconSize52dp.size > taskbarIconSize.size) {
+ if (
+ TaskbarIconSpecs.transientOrPinnedTaskbarIconPaddingSize.size > taskbarIconSize.size &&
+ !taskbarFeatureEvaluator.hasNavButtons
+ ) {
(TaskbarIconSpecs.iconSize52dp.size - taskbarIconSize.size) / 2
} else {
0
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 039c0a0..93cbdc7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -22,7 +22,6 @@
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.Intent;
-import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
@@ -66,13 +65,7 @@
}
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(view);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
- .getActivityLaunchOptions(hostView);
- Object itemInfo = hostView.getTag();
- IBinder launchCookie = null;
- if (itemInfo instanceof ItemInfo) {
- launchCookie = mLauncher.getLaunchCookie((ItemInfo) itemInfo);
- activityOptions.options.setLaunchCookie(launchCookie);
- }
+ .getActivityLaunchOptions(hostView, (ItemInfo) hostView.getTag());
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.
@@ -81,7 +74,7 @@
.registerRemoteAnimationForNextActivityStart(
pendingIntent.getCreatorPackage(),
activityOptions.options.getRemoteAnimationAdapter(),
- launchCookie);
+ activityOptions.options.getLaunchCookie());
} catch (RemoteException e) {
// Do nothing.
}
@@ -92,7 +85,7 @@
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
options = Pair.create(options.first, activityOptions.options);
if (pendingIntent.isActivity()) {
- logAppLaunch(itemInfo);
+ logAppLaunch(hostView.getTag());
}
return RemoteViews.startPendingIntent(hostView, pendingIntent, options);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 0b385d9..1f5cd3a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -41,7 +41,6 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_INTERRUPTED;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.BUBBLE_SHORTCUT;
@@ -64,8 +63,8 @@
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.QUICK_SWITCH_FROM_HOME_FALLBACK;
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
-import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
+import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_50_50;
import android.animation.Animator;
@@ -83,7 +82,6 @@
import android.media.permission.SafeCloseable;
import android.os.Build;
import android.os.Bundle;
-import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.SystemProperties;
import android.os.Trace;
@@ -229,7 +227,6 @@
private FixedContainerItems mAllAppsPredictions;
private HotseatPredictionController mHotseatPredictionController;
private DepthController mDepthController;
- private @Nullable DesktopVisibilityController mDesktopVisibilityController;
private QuickstepTransitionManager mAppTransitionManager;
private OverviewActionsView<?> mActionsView;
@@ -303,8 +300,6 @@
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
mDepthController = new DepthController(this);
if (DesktopModeStatus.canEnterDesktopMode(this)) {
- mDesktopVisibilityController = new DesktopVisibilityController(this);
- mDesktopVisibilityController.registerSystemUiListener();
mSplitSelectStateController.initSplitFromDesktopController(this,
overviewComponentObserver);
}
@@ -556,10 +551,6 @@
mLauncherUnfoldAnimationController.onDestroy();
}
- if (mDesktopVisibilityController != null) {
- mDesktopVisibilityController.unregisterSystemUiListener();
- }
-
if (mSplitSelectStateController != null) {
mSplitSelectStateController.onDestroy();
}
@@ -701,9 +692,7 @@
}
addMultiWindowModeChangedListener(mDepthController);
initUnfoldTransitionProgressProvider();
- if (FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
- mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
- }
+ mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
QuickstepOnboardingPrefs.setup(this);
View.setTraceLayoutSteps(TRACE_LAYOUTS);
@@ -1013,10 +1002,11 @@
@Override
public void setResumed() {
+ DesktopVisibilityController desktopVisibilityController = getDesktopVisibilityController();
if (!WALLPAPER_ACTIVITY.isEnabled(this)
- && mDesktopVisibilityController != null
- && mDesktopVisibilityController.areDesktopTasksVisible()
- && !mDesktopVisibilityController.isRecentsGestureInProgress()) {
+ && desktopVisibilityController != null
+ && desktopVisibilityController.areDesktopTasksVisible()
+ && !desktopVisibilityController.isRecentsGestureInProgress()) {
// Return early to skip setting activity to appear as resumed
// TODO: b/333533253 - Remove after flag rollout
return;
@@ -1156,8 +1146,9 @@
}
@Nullable
+ @Override
public DesktopVisibilityController getDesktopVisibilityController() {
- return mDesktopVisibilityController;
+ return mTISBindHelper.getDesktopVisibilityController();
}
@Nullable
@@ -1192,7 +1183,8 @@
@Override
public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- ActivityOptionsWrapper activityOptions = mAppTransitionManager.getActivityLaunchOptions(v);
+ ActivityOptionsWrapper activityOptions = mAppTransitionManager.getActivityLaunchOptions(
+ v, item != null ? item : (ItemInfo) v.getTag());
if (mLastTouchUpTime > 0) {
activityOptions.options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_LAUNCHER,
mLastTouchUpTime);
@@ -1232,43 +1224,6 @@
mSplitWithKeyboardShortcutController.enterStageSplit(leftOrTop);
}
- /**
- * Return a new launch cookie for the activity launch if supported.
- *
- * @param info the item info for the launch
- */
- public IBinder getLaunchCookie(ItemInfo info) {
- if (info == null) {
- return null;
- }
- switch (info.container) {
- case Favorites.CONTAINER_DESKTOP:
- case Favorites.CONTAINER_HOTSEAT:
- case Favorites.CONTAINER_PRIVATESPACE:
- // Fall through and continue it's on the workspace (we don't support swiping back
- // to other containers like all apps or the hotseat predictions (which can change)
- break;
- default:
- if (info.container >= 0) {
- // Also allow swiping to folders
- break;
- }
- // Reset any existing launch cookies associated with the cookie
- return ObjectWrapper.wrap(NO_MATCHING_ID);
- }
- switch (info.itemType) {
- case Favorites.ITEM_TYPE_APPLICATION:
- case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- case Favorites.ITEM_TYPE_APPWIDGET:
- // Fall through and continue if it's an app, shortcut, or widget
- break;
- default:
- // Reset any existing launch cookies associated with the cookie
- return ObjectWrapper.wrap(NO_MATCHING_ID);
- }
- return ObjectWrapper.wrap(new Integer(info.id));
- }
-
@Override
public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
super.onDisplayInfoChanged(context, info, flags);
@@ -1347,8 +1302,9 @@
@Override
public boolean areDesktopTasksVisible() {
- if (mDesktopVisibilityController != null) {
- return mDesktopVisibilityController.areDesktopTasksVisible();
+ DesktopVisibilityController desktopVisibilityController = getDesktopVisibilityController();
+ if (desktopVisibilityController != null) {
+ return desktopVisibilityController.areDesktopTasksVisible();
}
return false;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index fa80dc2..030a7ac 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -26,7 +26,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.util.BaseDepthController;
@@ -202,17 +201,6 @@
}
@Override
- public float[] getOverviewScaleAndOffset(Launcher launcher) {
- if (!FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) {
- return super.getOverviewScaleAndOffset(launcher);
- }
- // This handles the case of returning to the previous app from Overview -> All Apps gesture.
- // This is the start scale/offset of overview that will be used for that transition.
- // TODO (b/283336332): Translate in Y direction (ideally with overview resistance).
- return new float[] {0.5f /* scale */, NO_OFFSET};
- }
-
- @Override
public int getWorkspaceScrimColor(Launcher launcher) {
return launcher.getDeviceProfile().isTablet
? launcher.getResources().getColor(R.color.widgets_picker_scrim)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 1ba784b..18d717f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -50,9 +50,11 @@
return super.getVerticalProgress(launcher);
}
RecentsView recentsView = launcher.getOverviewPanel();
- int transitionLength = LayoutUtils.getShelfTrackingDistance(launcher,
+ int transitionLength = LayoutUtils.getShelfTrackingDistance(
+ launcher,
launcher.getDeviceProfile(),
- recentsView.getPagedOrientationHandler());
+ recentsView.getPagedOrientationHandler(),
+ recentsView.getSizeStrategy());
AllAppsTransitionController controller = launcher.getAllAppsController();
float scrollRange = Math.max(controller.getShiftRange(), 1);
float progressDelta = (transitionLength / scrollRange);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index d1aa472..ff726e6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -42,7 +42,6 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -221,11 +220,6 @@
mCancelSplitRunnable.accept(animatorSet, duration);
animatorSet.start();
}
- if (FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() &&
- ((mFromState == NORMAL && mToState == ALL_APPS)
- || (mFromState == ALL_APPS && mToState == NORMAL)) && isFling) {
- mVibratorWrapper.vibrateForDragBump();
- }
}
private void onMotionPauseDetected() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 0da7b2d..9164405 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -129,7 +129,10 @@
mRecentsView = mLauncher.getOverviewPanel();
mXRange = mLauncher.getDeviceProfile().widthPx / 2f;
mYRange = LayoutUtils.getShelfTrackingDistance(
- mLauncher, mLauncher.getDeviceProfile(), mRecentsView.getPagedOrientationHandler());
+ mLauncher,
+ mLauncher.getDeviceProfile(),
+ mRecentsView.getPagedOrientationHandler(),
+ mRecentsView.getSizeStrategy());
mMaxYProgress = mLauncher.getDeviceProfile().heightPx / mYRange;
mMotionPauseDetector = new MotionPauseDetector(mLauncher);
mMotionPauseMinDisplacement = mLauncher.getResources().getDimension(
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index b5914a1..b562838 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -29,7 +29,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.AllAppsSwipeController;
@@ -93,9 +92,7 @@
@Override
protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
if (fromState == ALL_APPS && !isDragTowardPositive) {
- return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
- ? mLauncher.getStateManager().getLastState()
- : NORMAL;
+ return NORMAL;
} else if (fromState == NORMAL && shouldOpenAllApps(isDragTowardPositive)) {
return ALL_APPS;
}
@@ -145,8 +142,11 @@
.createPlaybackController();
mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
RecentsView recentsView = mLauncher.getOverviewPanel();
- totalShift = LayoutUtils.getShelfTrackingDistance(mLauncher,
- mLauncher.getDeviceProfile(), recentsView.getPagedOrientationHandler());
+ totalShift = LayoutUtils.getShelfTrackingDistance(
+ mLauncher,
+ mLauncher.getDeviceProfile(),
+ recentsView.getPagedOrientationHandler(),
+ recentsView.getSizeStrategy());
} else {
mCurrentAnimation = mLauncher.getStateManager()
.createAnimationToNewWorkspace(mToState, config);
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 55489bb..240d6ad 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -45,7 +45,6 @@
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
-import static com.android.quickstep.GestureState.GestureEndTarget.ALL_APPS;
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
@@ -193,7 +192,6 @@
// Null if the recents animation hasn't started yet or has been canceled or finished.
protected @Nullable RecentsAnimationController mRecentsAnimationController;
- protected @Nullable RecentsAnimationController mDeferredCleanupRecentsAnimationController;
protected RecentsAnimationTargets mRecentsAnimationTargets;
protected @Nullable RECENTS_CONTAINER mContainer;
protected @Nullable RECENTS_VIEW mRecentsView;
@@ -265,8 +263,6 @@
getNextStateFlag("STATE_CURRENT_TASK_FINISHED");
private static final int STATE_FINISH_WITH_NO_END =
getNextStateFlag("STATE_FINISH_WITH_NO_END");
- private static final int STATE_SETTLED_ON_ALL_APPS =
- getNextStateFlag("STATE_SETTLED_ON_ALL_APPS");
private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED |
@@ -320,7 +316,6 @@
private boolean mGestureStarted;
private boolean mLogDirectionUpOrLeft = true;
private boolean mIsLikelyToStartNewTask;
- private boolean mIsInAllAppsRegion;
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
@@ -457,9 +452,6 @@
this::finishCurrentTransitionToHome);
mStateCallback.runOnceAtState(STATE_SCALED_CONTROLLER_HOME | STATE_CURRENT_TASK_FINISHED,
this::reset);
- mStateCallback.runOnceAtState(STATE_SETTLED_ON_ALL_APPS | STATE_SCREENSHOT_CAPTURED
- | STATE_GESTURE_COMPLETED,
- this::finishCurrentTransitionToAllApps);
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
| STATE_LAUNCHER_DRAWN | STATE_SCALED_CONTROLLER_RECENTS
@@ -540,14 +532,7 @@
HashMap<Integer, ThumbnailData> snapshots =
mGestureState.consumeRecentsAnimationCanceledSnapshot();
if (snapshots != null) {
- mRecentsView.switchToScreenshot(snapshots, () -> {
- if (mRecentsAnimationController != null) {
- mRecentsAnimationController.cleanupScreenshot();
- } else if (mDeferredCleanupRecentsAnimationController != null) {
- mDeferredCleanupRecentsAnimationController.cleanupScreenshot();
- mDeferredCleanupRecentsAnimationController = null;
- }
- });
+ mRecentsView.switchToScreenshot(snapshots, () -> {});
mRecentsView.onRecentsAnimationComplete();
}
});
@@ -724,9 +709,7 @@
maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
Optional.ofNullable(mContainerInterface.getTaskbarController())
.ifPresent(TaskbarUIController::startTranslationSpring);
- if (!mIsInAllAppsRegion) {
- performHapticFeedback();
- }
+ performHapticFeedback();
}
@Override
@@ -774,9 +757,7 @@
.findTask(mGestureState.getTopRunningTaskId())
: null;
final boolean recentsAttachedToAppWindow;
- if (mIsInAllAppsRegion) {
- recentsAttachedToAppWindow = false;
- } else if (mGestureState.getEndTarget() != null) {
+ if (mGestureState.getEndTarget() != null) {
recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
} else if (mContinuingLastGesture
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
@@ -833,31 +814,6 @@
}
}
- /**
- * Update whether user is currently dragging in a region that will trigger all apps.
- */
- private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
- if (mIsInAllAppsRegion == isInAllAppsRegion
- || !mContainerInterface.allowAllAppsFromOverview()) {
- return;
- }
- mIsInAllAppsRegion = isInAllAppsRegion;
-
- // Newly entering or exiting the zone - do haptic and animate recent tasks.
- VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
- maybeUpdateRecentsAttachedState(true);
-
- if (mContainer != null) {
- mContainer.getAppsView().getSearchUiManager()
- .prepareToFocusEditText(mIsInAllAppsRegion);
- }
-
- // Draw active task below Launcher so that All Apps can appear over it.
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(isInAllAppsRegion));
- }
-
-
private void buildAnimationController() {
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
return;
@@ -917,8 +873,6 @@
@UiThread
@Override
public void onCurrentShiftUpdated() {
- float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
- setIsInAllAppsRegion(mCurrentShift.value >= threshold);
updateSysUiFlags(mCurrentShift.value);
applyScrollAndTransform();
@@ -1025,9 +979,6 @@
/* event= */ "cancelRecentsAnimation",
/* gestureEvent= */ CANCEL_RECENTS_ANIMATION);
mActivityInitListener.unregister("AbsSwipeUpHandler.onRecentsAnimationCanceled");
- // Cache the recents animation controller so we can defer its cleanup to after having
- // properly cleaned up the screenshot without accidentally using it.
- mDeferredCleanupRecentsAnimationController = mRecentsAnimationController;
mStateCallback.setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
// Defer clearing the controller and the targets until after we've updated the state
mRecentsAnimationController = null;
@@ -1203,9 +1154,6 @@
}
switch (endTarget) {
- case ALL_APPS:
- mStateCallback.setState(STATE_SETTLED_ON_ALL_APPS | STATE_CAPTURE_SCREENSHOT);
- break;
case HOME:
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
// Notify the SysUI to use fade-in animation when entering PiP
@@ -1324,9 +1272,6 @@
final boolean willGoToNewTask =
isScrollingToNewTask() && Math.abs(velocity.x) > Math.abs(endVelocity);
final boolean isSwipeUp = endVelocity < 0;
- if (mIsInAllAppsRegion) {
- return isSwipeUp ? ALL_APPS : LAST_TASK;
- }
if (!isSwipeUp) {
final boolean isCenteredOnNewTask = mRecentsView != null
&& mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
@@ -1342,9 +1287,7 @@
// Fully gestural mode.
final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
.getDimension(R.dimen.quickstep_fling_threshold_speed);
- if (mIsInAllAppsRegion) {
- return ALL_APPS;
- } else if (isScrollingToNewTask && isFlingX) {
+ if (isScrollingToNewTask && isFlingX) {
// Flinging towards new task takes precedence over mIsMotionPaused (which only
// checks y-velocity).
return NEW_TASK;
@@ -1399,8 +1342,7 @@
.setUserIsNotGoingHome(endTarget != GestureState.GestureEndTarget.HOME);
}
- float endShift = endTarget == ALL_APPS ? mDragLengthFactor
- : endTarget.isLauncher ? 1 : 0;
+ float endShift = endTarget.isLauncher ? 1 : 0;
final float startShift;
if (!isFling) {
long expectedDuration = Math.abs(Math.round((endShift - currentShift)
@@ -2027,12 +1969,6 @@
reset();
}
- @UiThread
- private void finishCurrentTransitionToAllApps() {
- finishCurrentTransitionToHome();
- reset();
- }
-
private void reset() {
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
if (mContainer != null) {
@@ -2174,7 +2110,6 @@
private void updateThumbnail() {
if (mGestureState.getEndTarget() == HOME
|| mGestureState.getEndTarget() == NEW_TASK
- || mGestureState.getEndTarget() == ALL_APPS
|| mRecentsView == null) {
// Capture the screenshot before finishing the transition to home or quickswitching to
// ensure it's taken in the correct orientation, but no need to update the thumbnail.
diff --git a/quickstep/src/com/android/quickstep/BaseContainerInterface.java b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
index 777761b..bf3a662 100644
--- a/quickstep/src/com/android/quickstep/BaseContainerInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
@@ -74,9 +74,6 @@
public abstract boolean deferStartingActivity(RecentsAnimationDeviceState deviceState,
MotionEvent ev);
- /** @return whether to allow going to All Apps from Overview. */
- public abstract boolean allowAllAppsFromOverview();
-
/**
* Returns the color of the scrim behind overview when at rest in this state.
* Return {@link Color#TRANSPARENT} for no scrim.
@@ -131,7 +128,9 @@
@Nullable
public DesktopVisibilityController getDesktopVisibilityController() {
- return null;
+ CONTAINER_TYPE container = getCreatedContainer();
+
+ return container == null ? null : container.getDesktopVisibilityController();
}
/**
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
index e6822ff..f610014 100644
--- a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -142,13 +142,6 @@
"Controls extra dp on the nav bar sides to trigger LPNH. Can be negative for a smaller touch region."
)
- val allAppsOverviewThreshold =
- propReader.get(
- "ALL_APPS_OVERVIEW_THRESHOLD",
- 180,
- "Threshold to open All Apps from Overview"
- )
-
/** Dump config values. */
fun dump(prefix: String, writer: PrintWriter) {
writer.println("$prefix DeviceConfigWrapper:")
@@ -169,7 +162,6 @@
writer.println("$prefix\tenableLpnhDeepPress=$enableLpnhDeepPress")
writer.println("$prefix\tlpnhHapticHintDelay=$lpnhHapticHintDelay")
writer.println("$prefix\tlpnhExtraTouchWidthDp=$lpnhExtraTouchWidthDp")
- writer.println("$prefix\tallAppsOverviewThreshold=$allAppsOverviewThreshold")
}
companion object {
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 94a4527..df83eb2 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -133,11 +133,6 @@
}
@Override
- public boolean allowAllAppsFromOverview() {
- return false;
- }
-
- @Override
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
// In non-gesture mode, user might be clicking on the home button which would directly
// start the home activity instead of going through recents. In that case, defer starting
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 81c9d4a..9cc463a 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -179,7 +179,6 @@
private RemoteAnimationTarget[] mLastAppearedTaskTargets;
private Set<Integer> mPreviouslyAppearedTaskIds = new HashSet<>();
private int[] mLastStartedTaskId = new int[]{INVALID_TASK_ID, INVALID_TASK_ID};
- private RecentsAnimationController mRecentsAnimationController;
private HashMap<Integer, ThumbnailData> mRecentsAnimationCanceledSnapshots;
/** The time when the swipe up gesture is triggered. */
@@ -470,7 +469,6 @@
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
- mRecentsAnimationController = controller;
mStateCallback.setState(STATE_RECENTS_ANIMATION_STARTED);
}
@@ -480,10 +478,6 @@
mStateCallback.setState(STATE_RECENTS_ANIMATION_CANCELED);
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
if (mRecentsAnimationCanceledSnapshots != null) {
- // Clean up the screenshot to finalize the recents animation cancel
- if (mRecentsAnimationController != null) {
- mRecentsAnimationController.cleanupScreenshot();
- }
mRecentsAnimationCanceledSnapshots = null;
}
}
@@ -522,7 +516,7 @@
HashMap<Integer, ThumbnailData> consumeRecentsAnimationCanceledSnapshot() {
if (mRecentsAnimationCanceledSnapshots != null) {
HashMap<Integer, ThumbnailData> data =
- new HashMap<Integer, ThumbnailData>(mRecentsAnimationCanceledSnapshots);
+ new HashMap<>(mRecentsAnimationCanceledSnapshots);
mRecentsAnimationCanceledSnapshots = null;
return data;
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index e9fe2f7..85312e4 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -18,7 +18,6 @@
import static com.android.app.animation.Interpolators.LINEAR;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
-import static com.android.launcher3.LauncherState.FLOATING_SEARCH_BAR;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -40,9 +39,7 @@
import com.android.launcher3.LauncherInitListener;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -79,7 +76,7 @@
&& DisplayController.getNavigationMode(context) != NavigationMode.NO_BUTTON) {
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
- return LayoutUtils.getShelfTrackingDistance(context, dp, orientationHandler);
+ return LayoutUtils.getShelfTrackingDistance(context, dp, orientationHandler, this);
}
}
@@ -169,16 +166,6 @@
@Nullable
@Override
- public DesktopVisibilityController getDesktopVisibilityController() {
- QuickstepLauncher launcher = getCreatedContainer();
- if (launcher == null) {
- return null;
- }
- return launcher.getDesktopVisibilityController();
- }
-
- @Nullable
- @Override
public LauncherTaskbarUIController getTaskbarController() {
QuickstepLauncher launcher = getCreatedContainer();
if (launcher == null) {
@@ -271,13 +258,6 @@
}
@Override
- public boolean allowAllAppsFromOverview() {
- return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
- // If floating search bar would not show in overview, don't allow all apps gesture.
- && OVERVIEW.areElementsVisible(getCreatedContainer(), FLOATING_SEARCH_BAR);
- }
-
- @Override
public boolean isInLiveTileMode() {
QuickstepLauncher launcher = getCreatedContainer();
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index a4ee3dd..1124aac 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -27,7 +27,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.ComponentCallbacks;
import android.content.res.Configuration;
@@ -38,7 +37,6 @@
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
-import android.util.Pair;
import android.view.Choreographer;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
@@ -63,7 +61,7 @@
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
-import com.android.quickstep.util.RectFSpringAnim;
+import com.android.quickstep.util.BackAnimState;
import com.android.systemui.shared.system.QuickStepContract;
import java.lang.ref.WeakReference;
@@ -109,8 +107,6 @@
private RemoteAnimationTarget mLauncherTarget;
private View mLauncherTargetView;
private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
- private boolean mSpringAnimationInProgress = false;
- private boolean mAnimatorSetInProgress = false;
private float mBackProgress = 0;
private boolean mBackInProgress = false;
private OnBackInvokedCallbackStub mBackCallback;
@@ -448,15 +444,15 @@
mQuickstepTransitionManager.transferRectToTargetCoordinate(
mBackTarget, mCurrentRect, true, resolveRectF);
- Pair<RectFSpringAnim, AnimatorSet> pair =
+ BackAnimState backAnim =
mQuickstepTransitionManager.createWallpaperOpenAnimations(
new RemoteAnimationTarget[]{mBackTarget},
new RemoteAnimationTarget[0],
- false /* fromUnlock */,
+ new RemoteAnimationTarget[0],
resolveRectF,
cornerRadius,
mBackInProgress /* fromPredictiveBack */);
- startTransitionAnimations(pair.first, pair.second);
+ startTransitionAnimations(backAnim);
mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
customizeStatusBarAppearance(true);
}
@@ -471,8 +467,6 @@
mCurrentRect.setEmpty();
mStartRect.setEmpty();
mInitialTouchPos.set(0, 0);
- mAnimatorSetInProgress = false;
- mSpringAnimationInProgress = false;
setLauncherTargetViewVisible(true);
mLauncherTargetView = null;
// We don't call customizeStatusBarAppearance here to prevent the status bar update with
@@ -495,27 +489,8 @@
}
}
- private void startTransitionAnimations(RectFSpringAnim springAnim, AnimatorSet anim) {
- mAnimatorSetInProgress = anim != null;
- mSpringAnimationInProgress = springAnim != null;
- if (springAnim != null) {
- springAnim.addAnimatorListener(
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mSpringAnimationInProgress = false;
- tryFinishBackAnimation();
- }
- }
- );
- }
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnimatorSetInProgress = false;
- tryFinishBackAnimation();
- }
- });
+ private void startTransitionAnimations(BackAnimState backAnim) {
+ backAnim.addOnAnimCompleteCallback(this::finishAnimation);
if (mScrimLayer == null) {
// Scrim hasn't been attached yet. Let's attach it.
addScrimLayer();
@@ -535,7 +510,7 @@
}
});
mScrimAlphaAnimator.setDuration(SCRIM_FADE_DURATION).start();
- anim.start();
+ backAnim.start();
}
private void loadResources() {
@@ -568,12 +543,6 @@
mScrimAlpha = 0;
}
- private void tryFinishBackAnimation() {
- if (!mSpringAnimationInProgress && !mAnimatorSetInProgress) {
- finishAnimation();
- }
- }
-
private void customizeStatusBarAppearance(boolean overridingStatusBarFlags) {
if (mOverridingStatusBarFlags == overridingStatusBarFlags) {
return;
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index f653e60..d2dcd7b 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -20,7 +20,6 @@
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.Utilities.mapBoundToRange;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
@@ -42,7 +41,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.ObjectWrapper;
+import com.android.launcher3.util.StableViewInfo;
import com.android.launcher3.views.ClipIconView;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingView;
@@ -301,18 +300,7 @@
return null;
}
- // Find the associated item info for the launch cookie (if available), note that predicted
- // apps actually have an id of -1, so use another default id here
- int launchCookieItemId = NO_MATCHING_ID;
- for (IBinder cookie : launchCookies) {
- Integer itemId = ObjectWrapper.unwrap(cookie);
- if (itemId != null) {
- launchCookieItemId = itemId;
- break;
- }
- }
-
- return mContainer.getFirstMatchForAppClose(launchCookieItemId,
+ return mContainer.getFirstMatchForAppClose(StableViewInfo.fromLaunchCookies(launchCookies),
sourceTaskView.getFirstTask().key.getComponent().getPackageName(),
UserHandle.of(sourceTaskView.getFirstTask().key.userId),
false /* supportsAllAppsState */);
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
index c1f9963..f92c557 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
@@ -29,7 +29,6 @@
import com.android.internal.jank.Cuj
import com.android.launcher3.Flags.enableOverviewCommandHelperTimeout
import com.android.launcher3.PagedView
-import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.logger.LauncherAtom
import com.android.launcher3.logging.StatsLogManager
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON
@@ -248,7 +247,7 @@
recents: RecentsView<*, *>,
taskView: TaskView?,
command: CommandInfo,
- onCallbackResult: () -> Unit
+ onCallbackResult: () -> Unit,
): Boolean {
var callbackList: RunnableList? = null
if (taskView != null) {
@@ -274,15 +273,14 @@
private fun executeWhenRecentsIsNotVisible(
command: CommandInfo,
- onCallbackResult: () -> Unit
+ onCallbackResult: () -> Unit,
): Boolean {
val recentsViewContainer = activityInterface.getCreatedContainer() as? RecentsViewContainer
val recentsView: RecentsView<*, *>? = recentsViewContainer?.getOverviewPanel()
val deviceProfile = recentsViewContainer?.getDeviceProfile()
val uiController = activityInterface.getTaskbarController()
val allowQuickSwitch =
- FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get() &&
- uiController != null &&
+ uiController != null &&
deviceProfile != null &&
(deviceProfile.isTablet || deviceProfile.isTwoPanels)
@@ -349,13 +347,13 @@
val gestureState =
touchInteractionService.createGestureState(
GestureState.DEFAULT_STATE,
- GestureState.TrackpadGestureType.NONE
+ GestureState.TrackpadGestureType.NONE,
)
gestureState.isHandlingAtomicEvent = true
val interactionHandler =
touchInteractionService.swipeUpHandlerFactory.newHandler(
gestureState,
- command.createTime
+ command.createTime,
)
interactionHandler.setGestureEndCallback {
onTransitionComplete(command, interactionHandler, onCallbackResult)
@@ -366,7 +364,7 @@
object : RecentsAnimationCallbacks.RecentsAnimationListener {
override fun onRecentsAnimationStart(
controller: RecentsAnimationController,
- targets: RecentsAnimationTargets
+ targets: RecentsAnimationTargets,
) {
Log.d(TAG, "recents animation started: $command")
updateRecentsViewFocus(command)
@@ -418,7 +416,7 @@
private fun onTransitionComplete(
command: CommandInfo,
handler: AbsSwipeUpHandler<*, *, *>,
- onCommandResult: () -> Unit
+ onCommandResult: () -> Unit,
) {
Log.d(TAG, "switching via recents animation - onTransitionComplete: $command")
command.removeListener(handler)
@@ -434,7 +432,7 @@
Log.d(
TAG,
"next task not scheduled. First pending command type " +
- "is ${commandQueue.firstOrNull()} - command type is: $command"
+ "is ${commandQueue.firstOrNull()} - command type is: $command",
)
return
}
@@ -527,7 +525,7 @@
val type: CommandType,
var status: CommandStatus = CommandStatus.IDLE,
val createTime: Long = SystemClock.elapsedRealtime(),
- private var animationCallbacks: RecentsAnimationCallbacks? = null
+ private var animationCallbacks: RecentsAnimationCallbacks? = null,
) {
fun setAnimationCallbacks(recentsAnimationCallbacks: RecentsAnimationCallbacks) {
this.animationCallbacks = recentsAnimationCallbacks
@@ -545,7 +543,7 @@
IDLE,
PROCESSING,
COMPLETED,
- CANCELED
+ CANCELED,
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 6d5cb4b..9c60693 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -63,6 +63,7 @@
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -525,4 +526,10 @@
public boolean isRecentsViewVisible() {
return getStateManager().getState().isRecentsViewVisible();
}
+
+ @Nullable
+ @Override
+ public DesktopVisibilityController getDesktopVisibilityController() {
+ return mTISBindHelper.getDesktopVisibilityController();
+ }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 7b9b560..0c5806b 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -174,19 +174,7 @@
});
}
- @BinderThread
- @Override
- public boolean onSwitchToScreenshot(Runnable onFinished) {
- Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
- for (RecentsAnimationListener listener : getListeners()) {
- if (listener.onSwitchToScreenshot(onFinished)) return;
- }
- onFinished.run();
- });
- return true;
- }
-
- private final void onAnimationFinished(RecentsAnimationController controller) {
+ private void onAnimationFinished(RecentsAnimationController controller) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
ActiveGestureLog.INSTANCE.addLog(
/* event= */ "RecentsAnimationCallbacks.onAnimationFinished",
@@ -242,12 +230,5 @@
* Callback made when a task started from the recents is ready for an app transition.
*/
default void onTasksAppeared(@NonNull RemoteAnimationTarget[] appearedTaskTarget) {}
-
- /**
- * @return whether this will call onFinished or not (onFinished should only be called once).
- */
- default boolean onSwitchToScreenshot(Runnable onFinished) {
- return false;
- }
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index adcf4ef..190d526 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -19,11 +19,9 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FINISH_RECENTS_ANIMATION;
-import android.content.Context;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
-import android.view.IRecentsAnimationController;
import android.view.SurfaceControl;
import android.view.WindowManagerGlobal;
import android.window.PictureInPictureSurfaceTransaction;
@@ -34,11 +32,11 @@
import com.android.internal.os.IResultReceiver;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
-import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import com.android.wm.shell.recents.IRecentsAnimationController;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -90,15 +88,6 @@
}
}
- /**
- * Remove task remote animation target from
- * {@link RecentsAnimationCallbacks#onTasksAppeared}}.
- */
- @UiThread
- public void removeTaskTarget(int targetTaskId) {
- UI_HELPER_EXECUTOR.execute(() -> mController.removeTask(targetTaskId));
- }
-
@UiThread
public void finishAnimationToHome() {
finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
@@ -173,19 +162,6 @@
}
/**
- * @see IRecentsAnimationController#cleanupScreenshot()
- */
- @UiThread
- public void cleanupScreenshot() {
- UI_HELPER_EXECUTOR.execute(() -> {
- ActiveGestureLog.INSTANCE.addLog(
- "cleanupScreenshot",
- ActiveGestureErrorDetector.GestureEvent.CLEANUP_SCREENSHOT);
- mController.cleanupScreenshot();
- });
- }
-
- /**
* @see RecentsAnimationControllerCompat#detachNavigationBarFromApp
*/
@UiThread
@@ -194,14 +170,6 @@
}
/**
- * @see IRecentsAnimationController#animateNavigationBarToApp(long)
- */
- @UiThread
- public void animateNavigationBarToApp(long duration) {
- UI_HELPER_EXECUTOR.execute(() -> mController.animateNavigationBarToApp(duration));
- }
-
- /**
* @see IRecentsAnimationController#setWillFinishToHome(boolean)
*/
@UiThread
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 1be60de..8adc11a 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -68,7 +68,7 @@
*/
public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy) {
DesktopVisibilityController desktopVisibilityController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+ sizingStrategy.getDesktopVisibilityController();
if (desktopVisibilityController != null) {
int visibleTasksCount = desktopVisibilityController.getVisibleDesktopTasksCount();
if (visibleTasksCount > 0) {
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index dde16c8..b4bd3e3 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -43,8 +43,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
-import android.view.IRecentsAnimationController;
-import android.view.IRecentsAnimationRunner;
import android.view.IRemoteAnimationRunner;
import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
@@ -87,6 +85,8 @@
import com.android.wm.shell.desktopmode.IDesktopTaskListener;
import com.android.wm.shell.draganddrop.IDragAndDrop;
import com.android.wm.shell.onehanded.IOneHanded;
+import com.android.wm.shell.recents.IRecentsAnimationController;
+import com.android.wm.shell.recents.IRecentsAnimationRunner;
import com.android.wm.shell.recents.IRecentTasks;
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.shared.GroupedRecentTaskInfo;
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 49ec597..289a2c1 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -289,38 +289,10 @@
true /*shown*/, null /* animatorHandler */);
}
if (mController != null) {
- if (mLastAppearedTaskTargets != null) {
- for (RemoteAnimationTarget lastTarget : mLastAppearedTaskTargets) {
- for (RemoteAnimationTarget appearedTarget : appearedTaskTargets) {
- if (lastTarget != null &&
- appearedTarget.taskId != lastTarget.taskId) {
- mController.removeTaskTarget(lastTarget.taskId);
- }
- }
- }
- }
mLastAppearedTaskTargets = appearedTaskTargets;
mLastGestureState.updateLastAppearedTaskTargets(mLastAppearedTaskTargets);
}
}
-
- @Override
- public boolean onSwitchToScreenshot(Runnable onFinished) {
- if (!containerInterface.isInLiveTileMode()
- || containerInterface.getCreatedContainer() == null) {
- // No need to switch since tile is already a screenshot.
- onFinished.run();
- } else {
- final RecentsView recentsView =
- containerInterface.getCreatedContainer().getOverviewPanel();
- if (recentsView != null) {
- recentsView.switchToScreenshot(onFinished);
- } else {
- onFinished.run();
- }
- }
- return true;
- }
});
final long eventTime = gestureState.getSwipeUpStartTimeMs();
mCallbacks.addListener(gestureState);
@@ -329,10 +301,7 @@
final ActivityOptions options = ActivityOptions.makeBasic();
options.setPendingIntentBackgroundActivityStartMode(
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);
- // Use regular (non-transient) launch for all apps page to control IME.
- if (!containerInterface.allowAllAppsFromOverview()) {
- options.setTransientLaunch();
- }
+ options.setTransientLaunch();
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
// Notify taskbar that we should skip reacting to launcher visibility change to
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 1a09691..d8063ba 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -304,14 +304,6 @@
}
}
});
- } else {
- // There is no transition animation for app launch from recent in live tile mode so
- // we have to trigger the navigation bar animation from system here.
- final RecentsAnimationController controller =
- recentsView.getRecentsAnimationController();
- if (controller != null) {
- controller.animateNavigationBarToApp(RECENTS_LAUNCH_DURATION);
- }
}
topMostSimulators = remoteTargetHandles;
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4587bdd..44e55c3 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -30,7 +30,6 @@
import static com.android.launcher3.LauncherPrefs.backedUpItem;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
@@ -94,6 +93,7 @@
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.provider.RestoreDbTask;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarManager;
@@ -227,7 +227,6 @@
@BinderThread
@Override
public void onTaskbarToggled() {
- if (!FeatureFlags.ENABLE_KEYBOARD_TASKBAR_TOGGLE.get()) return;
MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
TaskbarActivityContext activityContext =
tis.mTaskbarManager.getCurrentActivityContext();
@@ -379,6 +378,15 @@
));
}
+ @BinderThread
+ @Override
+ public void appTransitionPending(boolean pending) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+ executeForTaskbarManager(
+ taskbarManager -> taskbarManager.appTransitionPending(pending))
+ ));
+ }
+
/**
* Preloads the Overview activity.
* <p>
@@ -453,6 +461,18 @@
return tis.mTaskbarManager;
}
+ /**
+ * Returns the {@link DesktopVisibilityController}
+ * <p>
+ * Returns {@code null} if TouchInteractionService is not connected
+ */
+ @Nullable
+ public DesktopVisibilityController getDesktopVisibilityController() {
+ TouchInteractionService tis = mTis.get();
+ if (tis == null) return null;
+ return tis.mDesktopVisibilityController;
+ }
+
@VisibleForTesting
public void injectFakeTrackpadForTesting() {
TouchInteractionService tis = mTis.get();
@@ -628,6 +648,8 @@
private NavigationMode mGestureStartNavMode = null;
+ private DesktopVisibilityController mDesktopVisibilityController;
+
@Override
public void onCreate() {
super.onCreate();
@@ -640,15 +662,15 @@
mAllAppsActionManager = new AllAppsActionManager(
this, UI_HELPER_EXECUTOR, this::createAllAppsPendingIntent);
mInputManager = getSystemService(InputManager.class);
- if (ENABLE_TRACKPAD_GESTURE.get()) {
- mInputManager.registerInputDeviceListener(mInputDeviceListener,
- UI_HELPER_EXECUTOR.getHandler());
- int [] inputDevices = mInputManager.getInputDeviceIds();
- for (int inputDeviceId : inputDevices) {
- mInputDeviceListener.onInputDeviceAdded(inputDeviceId);
- }
+ mInputManager.registerInputDeviceListener(mInputDeviceListener,
+ UI_HELPER_EXECUTOR.getHandler());
+ int [] inputDevices = mInputManager.getInputDeviceIds();
+ for (int inputDeviceId : inputDevices) {
+ mInputDeviceListener.onInputDeviceAdded(inputDeviceId);
}
- mTaskbarManager = new TaskbarManager(this, mAllAppsActionManager, mNavCallbacks);
+ mDesktopVisibilityController = new DesktopVisibilityController(this);
+ mTaskbarManager = new TaskbarManager(
+ this, mAllAppsActionManager, mNavCallbacks, mDesktopVisibilityController);
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
@@ -677,7 +699,7 @@
if (mDeviceState.isButtonNavMode()
&& !mDeviceState.supportsAssistantGestureInButtonNav()
- && (!ENABLE_TRACKPAD_GESTURE.get() || mTrackpadsConnected.isEmpty())) {
+ && (mTrackpadsConnected.isEmpty())) {
return;
}
@@ -743,8 +765,8 @@
private void onOverviewTargetChange(boolean isHomeAndOverviewSame) {
mAllAppsActionManager.setHomeAndOverviewSame(isHomeAndOverviewSame);
- StatefulActivity newOverviewActivity = mOverviewComponentObserver.getActivityInterface()
- .getCreatedContainer();
+ StatefulActivity<?> newOverviewActivity =
+ mOverviewComponentObserver.getActivityInterface().getCreatedContainer();
if (newOverviewActivity != null) {
mTaskbarManager.setActivity(newOverviewActivity);
}
@@ -808,6 +830,7 @@
mTrackpadsConnected.clear();
mTaskbarManager.destroy();
+ mDesktopVisibilityController.onDestroy();
sConnected = false;
ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
@@ -1244,7 +1267,7 @@
getBaseContext(), mDeviceState, mInputMonitorCompat);
}
- if (ENABLE_TRACKPAD_GESTURE.get() && mGestureState.isTrackpadGesture()
+ if (mGestureState.isTrackpadGesture()
&& canStartSystemGesture && !previousGestureState.isRecentsAnimationRunning()) {
reasonString = newCompoundString(reasonPrefix)
.append(SUBSTRING_PREFIX)
@@ -1654,6 +1677,7 @@
createdOverviewActivity.getDeviceProfile().dump(this, "", pw);
}
mTaskbarManager.dumpLogs("", pw);
+ mDesktopVisibilityController.dumpLogs("", pw);
pw.println("AssistStateManager:");
AssistStateManager.INSTANCE.get(this).dump("\t", pw);
SystemUiProxy.INSTANCE.get(this).dump(pw);
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
new file mode 100644
index 0000000..db29636
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 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.quickstep.dagger;
+
+import com.android.quickstep.logging.LoggingModule;
+
+import dagger.Module;
+
+@Module(includes = {LoggingModule.class})
+public class QuickStepModule {
+}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index f4a2738..e67a9bc 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -253,6 +253,9 @@
}
setFreezeViewVisibility(true);
+ if (mContainer.getDesktopVisibilityController() != null) {
+ mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
index 9284e13..5ad55ae 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
@@ -184,7 +184,7 @@
if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold
&& !mGestureState.isInExtendedSlopRegion()) {
mHasPassedTaskbarNavThreshold = true;
- mTaskbarActivityContext.onSwipeToUnstashTaskbar();
+ mTaskbarActivityContext.onSwipeToUnstashTaskbar(true);
}
if (dY < 0) {
@@ -287,7 +287,7 @@
// start a single unstash timeout if hovering bottom edge under the hinted taskbar.
if (!sUnstashHandler.hasMessagesOrCallbacks()) {
sUnstashHandler.postDelayed(() -> {
- mTaskbarActivityContext.onSwipeToUnstashTaskbar();
+ mTaskbarActivityContext.onSwipeToUnstashTaskbar(false);
mIsStashedTaskbarHovered = false;
}, HOVER_TASKBAR_UNSTASH_TIMEOUT);
}
@@ -315,7 +315,7 @@
startStashedTaskbarHover(/* isHovered = */ true);
} else if (mBottomEdgeBounds.contains(x, y)) {
// If hover screen's bottom edge not below the stashed taskbar, unstash it.
- mTaskbarActivityContext.onSwipeToUnstashTaskbar();
+ mTaskbarActivityContext.onSwipeToUnstashTaskbar(false);
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java b/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java
index 742b0fc..7a86db3 100644
--- a/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java
+++ b/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.interaction;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -175,11 +173,8 @@
void setFakeTaskViewFillColor(@ColorInt int colorResId) {
mFullTaskView.setBackgroundColor(colorResId);
-
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()){
- mTopTaskView.getBackground().setTint(colorResId);
- mBottomTaskView.getBackground().setTint(colorResId);
- }
+ mTopTaskView.getBackground().setTint(colorResId);
+ mBottomTaskView.getBackground().setTint(colorResId);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 6757cd8..be7f8e5 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -15,7 +15,6 @@
*/
package com.android.quickstep.interaction;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION;
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION_COMPLETE;
@@ -40,35 +39,29 @@
BackGestureTutorialController(BackGestureTutorialFragment fragment, TutorialType tutorialType) {
super(fragment, tutorialType);
// Set the Lottie animation colors specifically for the Back gesture
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- LottieAnimationColorUtils.updateToArgbColors(
- mAnimatedGestureDemonstration,
- Map.of(".onSurfaceBack", fragment.mRootView.mColorOnSurfaceBack,
- ".surfaceBack", fragment.mRootView.mColorSurfaceBack,
- ".secondaryBack", fragment.mRootView.mColorSecondaryBack));
+ LottieAnimationColorUtils.updateToArgbColors(
+ mAnimatedGestureDemonstration,
+ Map.of(".onSurfaceBack", fragment.mRootView.mColorOnSurfaceBack,
+ ".surfaceBack", fragment.mRootView.mColorSurfaceBack,
+ ".secondaryBack", fragment.mRootView.mColorSecondaryBack));
- LottieAnimationColorUtils.updateToArgbColors(
- mCheckmarkAnimation,
- Map.of(".checkmark",
- Utilities.isDarkTheme(mContext)
- ? fragment.mRootView.mColorOnSurfaceBack
- : fragment.mRootView.mColorSecondaryBack,
- ".checkmarkBackground", fragment.mRootView.mColorSurfaceBack));
- }
+ LottieAnimationColorUtils.updateToArgbColors(
+ mCheckmarkAnimation,
+ Map.of(".checkmark",
+ Utilities.isDarkTheme(mContext)
+ ? fragment.mRootView.mColorOnSurfaceBack
+ : fragment.mRootView.mColorSecondaryBack,
+ ".checkmarkBackground", fragment.mRootView.mColorSurfaceBack));
}
@Override
public int getIntroductionTitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.back_gesture_tutorial_title
- : R.string.back_gesture_intro_title;
+ return R.string.back_gesture_tutorial_title;
}
@Override
public int getIntroductionSubtitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.back_gesture_tutorial_subtitle
- : R.string.back_gesture_intro_subtitle;
+ return R.string.back_gesture_tutorial_subtitle;
}
@Override
@@ -85,9 +78,7 @@
public int getSuccessFeedbackSubtitle() {
return mTutorialFragment.isAtFinalStep()
? R.string.back_gesture_feedback_complete_without_follow_up
- : ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.back_gesture_feedback_complete_with_follow_up
- : R.string.back_gesture_feedback_complete_with_overview_follow_up;
+ : R.string.back_gesture_feedback_complete_with_follow_up;
}
@Override
@@ -128,20 +119,12 @@
@LayoutRes
int getMockAppTaskCurrentPageLayoutResId() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.layout.back_gesture_tutorial_background
- : mTutorialFragment.isLargeScreen()
- ? R.layout.gesture_tutorial_tablet_mock_conversation
- : R.layout.gesture_tutorial_mock_conversation;
+ return R.layout.back_gesture_tutorial_background;
}
@LayoutRes
int getMockAppTaskPreviousPageLayoutResId() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.layout.back_gesture_tutorial_background
- : mTutorialFragment.isLargeScreen()
- ? R.layout.gesture_tutorial_tablet_mock_conversation_list
- : R.layout.gesture_tutorial_mock_conversation_list;
+ return R.layout.back_gesture_tutorial_background;
}
@Override
@@ -214,17 +197,13 @@
}
private void handleBackAttempt(BackGestureResult result) {
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- resetViewsForBackGesture();
- }
+ resetViewsForBackGesture();
switch (result) {
case BACK_COMPLETED_FROM_LEFT:
case BACK_COMPLETED_FROM_RIGHT:
mTutorialFragment.releaseFeedbackAnimation();
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mExitingAppView.setVisibility(View.GONE);
- }
+ mExitingAppView.setVisibility(View.GONE);
updateFakeAppTaskViewLayout(getMockAppTaskPreviousPageLayoutResId());
showSuccessFeedback();
break;
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index 1b12be8..700fbf8 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.interaction;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
-
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
@@ -211,10 +209,8 @@
}
}
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mGestureCallback.onBackGestureProgress(ev.getX() - mDownPoint.x,
- ev.getY() - mDownPoint.y, mEdgeBackPanel.getIsLeftPanel());
- }
+ mGestureCallback.onBackGestureProgress(ev.getX() - mDownPoint.x,
+ ev.getY() - mDownPoint.y, mEdgeBackPanel.getIsLeftPanel());
// forward touch
mEdgeBackPanel.onMotionEvent(ev);
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index acc9959..bc5cc15 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -37,7 +37,6 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -79,9 +78,7 @@
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
boolean gestureComplete = args != null && args.getBoolean(KEY_GESTURE_COMPLETE, false);
- if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- && args != null
- && args.getBoolean(KEY_USE_TUTORIAL_MENU, false)) {
+ if (args != null && args.getBoolean(KEY_USE_TUTORIAL_MENU, false)) {
mTutorialSteps = null;
TutorialType tutorialTypeOverride = (TutorialType) args.get(KEY_TUTORIAL_TYPE);
mCurrentFragment = tutorialTypeOverride == null
@@ -101,9 +98,7 @@
.add(R.id.gesture_tutorial_fragment_container, mCurrentFragment)
.commit();
- if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- correctUserOrientation();
- }
+ correctUserOrientation();
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
initWindowInsets();
@@ -115,9 +110,7 @@
super.onConfigurationChanged(newConfig);
// Ensure the prompt to rotate the screen is updated
- if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- correctUserOrientation();
- }
+ correctUserOrientation();
}
private void initWindowInsets() {
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 1129e02..bf4eaf2 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.interaction;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
-
import android.graphics.PointF;
import com.android.launcher3.R;
@@ -34,35 +32,29 @@
super(fragment, tutorialType);
// Set the Lottie animation colors specifically for the Home gesture
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- LottieAnimationColorUtils.updateToArgbColors(
- mAnimatedGestureDemonstration,
- Map.of(".onSurfaceHome", fragment.mRootView.mColorOnSurfaceHome,
- ".surfaceHome", fragment.mRootView.mColorSurfaceHome,
- ".secondaryHome", fragment.mRootView.mColorSecondaryHome));
+ LottieAnimationColorUtils.updateToArgbColors(
+ mAnimatedGestureDemonstration,
+ Map.of(".onSurfaceHome", fragment.mRootView.mColorOnSurfaceHome,
+ ".surfaceHome", fragment.mRootView.mColorSurfaceHome,
+ ".secondaryHome", fragment.mRootView.mColorSecondaryHome));
- LottieAnimationColorUtils.updateToArgbColors(
- mCheckmarkAnimation,
- Map.of(".checkmark",
- Utilities.isDarkTheme(mContext)
- ? fragment.mRootView.mColorOnSurfaceHome
- : fragment.mRootView.mColorSecondaryHome,
- ".checkmarkBackground", fragment.mRootView.mColorSurfaceHome));
- }
+ LottieAnimationColorUtils.updateToArgbColors(
+ mCheckmarkAnimation,
+ Map.of(".checkmark",
+ Utilities.isDarkTheme(mContext)
+ ? fragment.mRootView.mColorOnSurfaceHome
+ : fragment.mRootView.mColorSecondaryHome,
+ ".checkmarkBackground", fragment.mRootView.mColorSurfaceHome));
}
@Override
public int getIntroductionTitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.home_gesture_tutorial_title
- : R.string.home_gesture_intro_title;
+ return R.string.home_gesture_tutorial_title;
}
@Override
public int getIntroductionSubtitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.home_gesture_tutorial_subtitle
- : R.string.home_gesture_intro_subtitle;
+ return R.string.home_gesture_tutorial_subtitle;
}
@Override
@@ -72,9 +64,7 @@
@Override
public int getSuccessFeedbackTitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.home_gesture_tutorial_success
- : R.string.gesture_tutorial_nice;
+ return R.string.home_gesture_tutorial_success;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index a04dd44..e45f8d8 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -16,7 +16,6 @@
package com.android.quickstep.interaction;
import static com.android.app.animation.Interpolators.ACCELERATE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -49,34 +48,28 @@
super(fragment, tutorialType);
// Set the Lottie animation colors specifically for the Overview gesture
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- LottieAnimationColorUtils.updateToArgbColors(
- mAnimatedGestureDemonstration,
- Map.of(".onSurfaceOverview", fragment.mRootView.mColorOnSurfaceOverview,
- ".surfaceOverview", fragment.mRootView.mColorSurfaceOverview,
- ".secondaryOverview", fragment.mRootView.mColorSecondaryOverview));
+ LottieAnimationColorUtils.updateToArgbColors(
+ mAnimatedGestureDemonstration,
+ Map.of(".onSurfaceOverview", fragment.mRootView.mColorOnSurfaceOverview,
+ ".surfaceOverview", fragment.mRootView.mColorSurfaceOverview,
+ ".secondaryOverview", fragment.mRootView.mColorSecondaryOverview));
- LottieAnimationColorUtils.updateToArgbColors(
- mCheckmarkAnimation,
- Map.of(".checkmark",
- Utilities.isDarkTheme(mContext)
- ? fragment.mRootView.mColorOnSurfaceOverview
- : fragment.mRootView.mColorSecondaryOverview,
- ".checkmarkBackground", fragment.mRootView.mColorSurfaceOverview));
- }
+ LottieAnimationColorUtils.updateToArgbColors(
+ mCheckmarkAnimation,
+ Map.of(".checkmark",
+ Utilities.isDarkTheme(mContext)
+ ? fragment.mRootView.mColorOnSurfaceOverview
+ : fragment.mRootView.mColorSecondaryOverview,
+ ".checkmarkBackground", fragment.mRootView.mColorSurfaceOverview));
}
@Override
public int getIntroductionTitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.overview_gesture_tutorial_title
- : R.string.overview_gesture_intro_title;
+ return R.string.overview_gesture_tutorial_title;
}
@Override
public int getIntroductionSubtitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.overview_gesture_tutorial_subtitle
- : R.string.overview_gesture_intro_subtitle;
+ return R.string.overview_gesture_tutorial_subtitle;
}
@Override
@@ -86,9 +79,7 @@
@Override
public int getSuccessFeedbackTitle() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.string.overview_gesture_tutorial_success
- : R.string.gesture_tutorial_nice;
+ return R.string.overview_gesture_tutorial_success;
}
@Override
@@ -168,10 +159,7 @@
@Override
protected int getMockPreviousAppTaskThumbnailColor() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? mTutorialFragment.mRootView.mColorSurfaceContainer
- : mContext.getResources().getColor(
- R.color.gesture_tutorial_fake_previous_task_view_color);
+ return mTutorialFragment.mRootView.mColorSurfaceContainer;
}
@Override
@@ -224,11 +212,8 @@
case OVERVIEW_GESTURE_COMPLETED:
setGestureCompleted();
mTutorialFragment.releaseFeedbackAnimation();
- animateTaskViewToOverview(ENABLE_NEW_GESTURE_NAV_TUTORIAL.get());
+ animateTaskViewToOverview(true);
onMotionPaused(true /*arbitrary value*/);
- if (!ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- showSuccessFeedback();
- }
break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED:
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
index affedb9..d733267 100644
--- a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -15,16 +15,12 @@
*/
package com.android.quickstep.interaction;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Insets;
-import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
-import android.view.View;
import android.view.WindowInsets;
import android.widget.RelativeLayout;
@@ -39,10 +35,6 @@
/** Root layout that TutorialFragment uses to intercept motion events. */
public class RootSandboxLayout extends RelativeLayout {
- private final Rect mTempStepIndicatorBounds = new Rect();
- private final Rect mTempInclusionBounds = new Rect();
- private final Rect mTempExclusionBounds = new Rect();
-
@ColorInt final int mColorSurfaceContainer;
@ColorInt final int mColorOnSurfaceHome;
@ColorInt final int mColorSurfaceHome;
@@ -54,11 +46,6 @@
@ColorInt final int mColorSurfaceOverview;
@ColorInt final int mColorSecondaryOverview;
- private View mFeedbackView;
- private View mTutorialStepView;
- private View mSkipButton;
- private View mDoneButton;
-
public RootSandboxLayout(Context context) {
this(context, null);
}
@@ -123,56 +110,4 @@
return getHeight() + insets.top + insets.bottom;
}
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- return;
- }
- mFeedbackView = findViewById(R.id.gesture_tutorial_fragment_feedback_view);
- mTutorialStepView =
- mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
- mSkipButton = mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_close_button);
- mDoneButton = mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_action_button);
-
- mFeedbackView.addOnLayoutChangeListener(
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
- if (mSkipButton.getVisibility() != VISIBLE
- && mDoneButton.getVisibility() != VISIBLE) {
- return;
- }
- // Either the skip or the done button is ever shown at once, never both.
- boolean showingSkipButton = mSkipButton.getVisibility() == VISIBLE;
- boolean isRTL = Utilities.isRtl(getContext().getResources());
- updateTutorialStepViewTranslation(
- showingSkipButton ? mSkipButton : mDoneButton,
- // Translate the step indicator away from whichever button is being
- // shown. The skip button in on the left in LTR or on the right in RTL.
- // The done button is on the right in LTR or left in RTL.
- (showingSkipButton && !isRTL) || (!showingSkipButton && isRTL));
- });
- }
-
- private void updateTutorialStepViewTranslation(
- @NonNull View anchorView, boolean translateToRight) {
- mTempStepIndicatorBounds.set(
- mTutorialStepView.getLeft(),
- mTutorialStepView.getTop(),
- mTutorialStepView.getRight(),
- mTutorialStepView.getBottom());
- mTempInclusionBounds.set(0, 0, mFeedbackView.getWidth(), mFeedbackView.getHeight());
- mTempExclusionBounds.set(
- anchorView.getLeft(),
- anchorView.getTop(),
- anchorView.getRight(),
- anchorView.getBottom());
-
- Utilities.translateOverlappingView(
- mTutorialStepView,
- mTempStepIndicatorBounds,
- mTempInclusionBounds,
- mTempExclusionBounds,
- translateToRight ? Utilities.TRANSLATE_RIGHT : Utilities.TRANSLATE_LEFT);
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index ad13efb..e462706 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -48,7 +48,6 @@
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.GestureState;
import com.android.quickstep.OverviewComponentObserver;
import com.android.quickstep.RecentsAnimationDeviceState;
@@ -127,9 +126,7 @@
void resetTaskViews() {
mFakeHotseatView.setVisibility(View.INVISIBLE);
mFakeIconView.setVisibility(View.INVISIBLE);
- if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mFakeIconView.getBackground().setTint(getFakeTaskViewColor());
- }
+ mFakeIconView.getBackground().setTint(getFakeTaskViewColor());
if (mTutorialFragment.getActivity() != null) {
int height = mTutorialFragment.getRootView().getFullscreenHeight();
int width = mTutorialFragment.getRootView().getWidth();
@@ -138,9 +135,7 @@
mFakeTaskViewRadius = 0;
mFakeTaskView.invalidateOutline();
mFakeTaskView.setVisibility(View.VISIBLE);
- if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mFakeTaskView.setBackgroundColor(getFakeTaskViewColor());
- }
+ mFakeTaskView.setBackgroundColor(getFakeTaskViewColor());
mFakeTaskView.setAlpha(1);
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mFakePreviousTaskView.setAlpha(1);
@@ -390,12 +385,10 @@
false, /* isOpening */
mFakeIconView, mDp);
mFakeIconView.setAlpha(1);
- if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- int iconColor = ColorUtils.blendARGB(
- getFakeTaskViewColor(), getHotseatIconColor(), progress);
- mFakeIconView.getBackground().setTint(iconColor);
- mFakeTaskView.setBackgroundColor(iconColor);
- }
+ int iconColor = ColorUtils.blendARGB(
+ getFakeTaskViewColor(), getHotseatIconColor(), progress);
+ mFakeIconView.getBackground().setTint(iconColor);
+ mFakeTaskView.setBackgroundColor(iconColor);
mFakeTaskView.setAlpha(getWindowAlpha(progress));
mFakePreviousTaskView.setAlpha(getWindowAlpha(progress));
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 54653fa..5028da4 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -19,10 +19,7 @@
import static android.view.View.NO_ID;
import static android.view.View.inflate;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
-
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -33,7 +30,6 @@
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Rect;
-import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.RippleDrawable;
import android.util.Log;
@@ -52,7 +48,6 @@
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
@@ -153,8 +148,7 @@
mFakeHotseatView = rootView.findViewById(R.id.gesture_tutorial_fake_hotseat_view);
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
- mFakeTaskbarView = ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? null : rootView.findViewById(R.id.gesture_tutorial_fake_taskbar_view);
+ mFakeTaskbarView = null;
mFakePreviousTaskView =
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
@@ -165,32 +159,30 @@
mFingerDotView = rootView.findViewById(R.id.gesture_tutorial_finger_dot);
mSkipTutorialDialog = createSkipTutorialDialog();
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mFullGestureDemonstration = rootView.findViewById(R.id.full_gesture_demonstration);
- mCheckmarkAnimation = rootView.findViewById(R.id.checkmark_animation);
- mAnimatedGestureDemonstration = rootView.findViewById(
- R.id.gesture_demonstration_animations);
- mExitingAppView = rootView.findViewById(R.id.exiting_app_back);
- mScreenWidth = mTutorialFragment.getDeviceProfile().widthPx;
- mScreenHeight = mTutorialFragment.getDeviceProfile().heightPx;
- mExitingAppMargin = mContext.getResources().getDimensionPixelSize(
- R.dimen.gesture_tutorial_back_gesture_exiting_app_margin);
- mExitingAppStartingCornerRadius = QuickStepContract.getWindowCornerRadius(mContext);
- mExitingAppEndingCornerRadius = mContext.getResources().getDimensionPixelSize(
- R.dimen.gesture_tutorial_back_gesture_end_corner_radius);
- mAnimatedGestureDemonstration.addLottieOnCompositionLoadedListener(
- this::createScalingMatrix);
+ mFullGestureDemonstration = rootView.findViewById(R.id.full_gesture_demonstration);
+ mCheckmarkAnimation = rootView.findViewById(R.id.checkmark_animation);
+ mAnimatedGestureDemonstration = rootView.findViewById(
+ R.id.gesture_demonstration_animations);
+ mExitingAppView = rootView.findViewById(R.id.exiting_app_back);
+ mScreenWidth = mTutorialFragment.getDeviceProfile().widthPx;
+ mScreenHeight = mTutorialFragment.getDeviceProfile().heightPx;
+ mExitingAppMargin = mContext.getResources().getDimensionPixelSize(
+ R.dimen.gesture_tutorial_back_gesture_exiting_app_margin);
+ mExitingAppStartingCornerRadius = QuickStepContract.getWindowCornerRadius(mContext);
+ mExitingAppEndingCornerRadius = mContext.getResources().getDimensionPixelSize(
+ R.dimen.gesture_tutorial_back_gesture_end_corner_radius);
+ mAnimatedGestureDemonstration.addLottieOnCompositionLoadedListener(
+ this::createScalingMatrix);
- mFeedbackTitleView.setText(getIntroductionTitle());
- mFeedbackSubtitleView.setText(getIntroductionSubtitle());
- mExitingAppView.setClipToOutline(true);
- mExitingAppView.setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRoundRect(mExitingAppRect, mExitingAppRadius);
- }
- });
- }
+ mFeedbackTitleView.setText(getIntroductionTitle());
+ mFeedbackSubtitleView.setText(getIntroductionSubtitle());
+ mExitingAppView.setClipToOutline(true);
+ mExitingAppView.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(mExitingAppRect, mExitingAppRadius);
+ }
+ });
mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
AccessibilityEvent.TYPE_VIEW_FOCUSED);
@@ -261,19 +253,11 @@
@LayoutRes
protected int getMockHotseatResId() {
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- return mTutorialFragment.isLargeScreen()
- ? mTutorialFragment.isFoldable()
- ? R.layout.redesigned_gesture_tutorial_foldable_mock_hotseat
- : R.layout.redesigned_gesture_tutorial_tablet_mock_hotseat
- : R.layout.redesigned_gesture_tutorial_mock_hotseat;
- } else {
- return mTutorialFragment.isLargeScreen()
- ? mTutorialFragment.isFoldable()
- ? R.layout.gesture_tutorial_foldable_mock_hotseat
- : R.layout.gesture_tutorial_tablet_mock_hotseat
- : R.layout.gesture_tutorial_mock_hotseat;
- }
+ return mTutorialFragment.isLargeScreen()
+ ? mTutorialFragment.isFoldable()
+ ? R.layout.redesigned_gesture_tutorial_foldable_mock_hotseat
+ : R.layout.redesigned_gesture_tutorial_tablet_mock_hotseat
+ : R.layout.redesigned_gesture_tutorial_mock_hotseat;
}
@LayoutRes
@@ -312,9 +296,7 @@
@DrawableRes
public int getMockAppIconResId() {
- return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.drawable.redesigned_hotseat_icon
- : R.drawable.default_sandbox_app_icon;
+ return R.drawable.redesigned_hotseat_icon;
}
@DrawableRes
@@ -374,11 +356,7 @@
mFeedbackView.setTranslationY(0);
return;
}
- Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
- AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
- if (gestureAnimation != null && edgeAnimation != null) {
- playFeedbackAnimation(gestureAnimation, edgeAnimation, mShowFeedbackRunnable, true);
- }
+ playFeedbackAnimation();
}
/**
@@ -442,12 +420,7 @@
}
mFeedbackTitleView.setText(titleResId);
- mFeedbackSubtitleView.setText(
- ENABLE_NEW_GESTURE_NAV_TUTORIAL.get() || spokenSubtitleResId == NO_ID
- ? mContext.getText(subtitleResId)
- : Utilities.wrapForTts(
- mContext.getText(subtitleResId),
- mContext.getString(spokenSubtitleResId)));
+ mFeedbackSubtitleView.setText(subtitleResId);
if (isGestureSuccessful) {
if (mTutorialFragment.isAtFinalStep()) {
showActionButton();
@@ -458,27 +431,16 @@
mFakeTaskViewCallback = null;
}
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- showSuccessPage();
- }
+ showSuccessPage();
}
mGestureCompleted = isGestureSuccessful;
-
- Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
- AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
- if (!isGestureSuccessful && gestureAnimation != null && edgeAnimation != null) {
- playFeedbackAnimation(
- gestureAnimation,
- edgeAnimation,
- mShowFeedbackRunnable,
- useGestureAnimationDelay);
- return;
+ if (!isGestureSuccessful) {
+ playFeedbackAnimation();
} else {
mTutorialFragment.releaseFeedbackAnimation();
+ mFeedbackViewCallback = mShowFeedbackRunnable;
+ mFeedbackView.post(mFeedbackViewCallback);
}
- mFeedbackViewCallback = mShowFeedbackRunnable;
-
- mFeedbackView.post(mFeedbackViewCallback);
}
private void showSuccessPage() {
@@ -517,79 +479,17 @@
mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
}
- private void playFeedbackAnimation(
- @NonNull Animator gestureAnimation,
- @NonNull AnimatedVectorDrawable edgeAnimation,
- @NonNull Runnable onStartRunnable,
- boolean useGestureAnimationDelay) {
-
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mFeedbackView.setVisibility(View.VISIBLE);
- mAnimatedGestureDemonstration.setVisibility(View.VISIBLE);
- mFullGestureDemonstration.setVisibility(View.VISIBLE);
- mAnimatedGestureDemonstration.playAnimation();
- return;
- }
-
- if (gestureAnimation.isRunning()) {
- gestureAnimation.cancel();
- }
- if (edgeAnimation.isRunning()) {
- edgeAnimation.reset();
- }
- gestureAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
-
- mEdgeGestureVideoView.setVisibility(GONE);
- if (edgeAnimation.isRunning()) {
- edgeAnimation.stop();
- }
-
- if (!useGestureAnimationDelay) {
- onStartRunnable.run();
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
-
- mEdgeGestureVideoView.setVisibility(View.VISIBLE);
- edgeAnimation.start();
-
- gestureAnimation.removeListener(this);
- }
- });
-
- cancelQueuedGestureAnimation();
- if (useGestureAnimationDelay) {
- mFeedbackViewCallback = onStartRunnable;
- mFakeTaskViewCallback = gestureAnimation::start;
-
- mFeedbackView.post(mFeedbackViewCallback);
- mFakeTaskView.postDelayed(mFakeTaskViewCallback, GESTURE_ANIMATION_DELAY_MS);
- } else {
- gestureAnimation.start();
- }
+ private void playFeedbackAnimation() {
+ mFeedbackView.setVisibility(View.VISIBLE);
+ mAnimatedGestureDemonstration.setVisibility(View.VISIBLE);
+ mFullGestureDemonstration.setVisibility(View.VISIBLE);
+ mAnimatedGestureDemonstration.playAnimation();
}
void setRippleHotspot(float x, float y) {
mRippleDrawable.setHotspot(x, y);
}
- void showRippleEffect(@Nullable Runnable onCompleteRunnable) {
- mRippleDrawable.setState(
- new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled});
- mRippleView.postDelayed(() -> {
- mRippleDrawable.setState(new int[] {});
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
- }
- }, RIPPLE_VISIBLE_MS);
- }
-
void onActionButtonClicked(View button) {
mTutorialFragment.continueTutorial();
}
@@ -601,24 +501,19 @@
updateDrawables();
updateLayout();
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mFeedbackTitleView.setTextAppearance(mContext, getTitleTextAppearance());
- mDoneButton.setTextAppearance(mContext, getDoneButtonTextAppearance());
- mDoneButton.getBackground().setTint(getDoneButtonColor());
- mCheckmarkAnimation.setAnimation(mTutorialFragment.isAtFinalStep()
- ? R.raw.checkmark_animation_end
- : R.raw.checkmark_animation_in_progress);
- if (!isGestureCompleted()) {
- mCheckmarkAnimation.setVisibility(GONE);
- startGestureAnimation();
- if (mTutorialType == TutorialType.BACK_NAVIGATION) {
- resetViewsForBackGesture();
- }
-
+ mFeedbackTitleView.setTextAppearance(mContext, getTitleTextAppearance());
+ mDoneButton.setTextAppearance(mContext, getDoneButtonTextAppearance());
+ mDoneButton.getBackground().setTint(getDoneButtonColor());
+ mCheckmarkAnimation.setAnimation(mTutorialFragment.isAtFinalStep()
+ ? R.raw.checkmark_animation_end
+ : R.raw.checkmark_animation_in_progress);
+ if (!isGestureCompleted()) {
+ mCheckmarkAnimation.setVisibility(GONE);
+ startGestureAnimation();
+ if (mTutorialType == TutorialType.BACK_NAVIGATION) {
+ resetViewsForBackGesture();
}
- } else {
- hideFeedback();
- hideActionButton();
+
}
mGestureCompleted = false;
@@ -654,13 +549,6 @@
: R.style.TextAppearance_GestureTutorial_Feedback_Subtext_Dark);
}
- void hideActionButton() {
- mSkipButton.setVisibility(View.VISIBLE);
- // Invisible to maintain the layout.
- mDoneButton.setVisibility(View.INVISIBLE);
- mDoneButton.setOnClickListener(null);
- }
-
void showActionButton() {
mSkipButton.setVisibility(GONE);
mDoneButton.setVisibility(View.VISIBLE);
@@ -711,10 +599,8 @@
}
private void updateSubtext() {
- if (!ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mTutorialStepView.setTutorialProgress(
- mTutorialFragment.getCurrentStep(), mTutorialFragment.getNumSteps());
- }
+ mTutorialStepView.setTutorialProgress(
+ mTutorialFragment.getCurrentStep(), mTutorialFragment.getNumSteps());
}
private void updateHotseatChildViewColor(@Nullable View child) {
@@ -727,9 +613,7 @@
mTutorialFragment.getRootView().setBackground(AppCompatResources.getDrawable(
mContext, getMockWallpaperResId()));
mTutorialFragment.updateFeedbackAnimation();
- mFakeLauncherView.setBackgroundColor(ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? getFakeLauncherColor()
- : mContext.getColor(R.color.gesture_tutorial_fake_wallpaper_color));
+ mFakeLauncherView.setBackgroundColor(getFakeLauncherColor());
updateFakeViewLayout(mFakeHotseatView, getMockHotseatResId());
mHotseatIconView = mFakeHotseatView.findViewById(R.id.hotseat_icon_1);
mFakeTaskView.animate().alpha(1).setListener(
@@ -738,19 +622,15 @@
mFakeIconView.setBackground(AppCompatResources.getDrawable(
mContext, getMockAppIconResId()));
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mExitingAppView.setBackgroundColor(getExitingAppColor());
- mFakeTaskView.setBackgroundColor(getFakeTaskViewColor());
- updateHotseatChildViewColor(mHotseatIconView);
- updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_2));
- updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_3));
- updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_4));
- updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_5));
- updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_6));
- updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_search_bar));
- } else {
- updateFakeViewLayout(mFakeTaskView, getMockAppTaskLayoutResId());
- }
+ mExitingAppView.setBackgroundColor(getExitingAppColor());
+ mFakeTaskView.setBackgroundColor(getFakeTaskViewColor());
+ updateHotseatChildViewColor(mHotseatIconView);
+ updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_2));
+ updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_3));
+ updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_4));
+ updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_5));
+ updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_6));
+ updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_search_bar));
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 0fafb94..2ff2c83 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -17,7 +17,6 @@
import static android.view.View.NO_ID;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_GESTURE_COMPLETE;
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_TUTORIAL_TYPE;
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_USE_TUTORIAL_MENU;
@@ -215,9 +214,7 @@
super.onCreateView(inflater, container, savedInstanceState);
mRootView = (RootSandboxLayout) inflater.inflate(
- ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
- ? R.layout.redesigned_gesture_tutorial_fragment
- : R.layout.gesture_tutorial_fragment,
+ R.layout.redesigned_gesture_tutorial_fragment,
container,
false);
@@ -383,10 +380,7 @@
if (mTutorialController != null && !isGestureComplete()) {
mTutorialController.hideFeedback();
}
-
- if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
- mTutorialController.pauseAndHideLottieAnimation();
- }
+ mTutorialController.pauseAndHideLottieAnimation();
// Note: Using logical-or to ensure both functions get called.
return mEdgeBackGestureHandler.onTouch(view, motionEvent)
diff --git a/quickstep/src/com/android/quickstep/logging/LoggingModule.java b/quickstep/src/com/android/quickstep/logging/LoggingModule.java
new file mode 100644
index 0000000..8fdf3c7
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/logging/LoggingModule.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.quickstep.logging;
+
+import android.content.Context;
+
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class LoggingModule {
+ @Provides
+ @LauncherAppSingleton
+ SettingsChangeLogger provideSettingsChangeLogger(@ApplicationContext Context context) {
+ return SettingsChangeLogger.INSTANCE.get(context);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt
index 1716f2e..5cf6823 100644
--- a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt
+++ b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt
@@ -24,7 +24,7 @@
class RecentsViewModel(
private val recentsTasksRepository: RecentTasksRepository,
- private val recentsViewData: RecentsViewData
+ private val recentsViewData: RecentsViewData,
) {
fun refreshAllTaskData() {
recentsTasksRepository.getAllTaskData(true)
@@ -58,7 +58,8 @@
recentsViewData.thumbnailSplashProgress.value = taskThumbnailSplashAlpha
}
- suspend fun waitForThumbnailsToUpdate(updatedThumbnails: Map<Int, ThumbnailData>) {
+ suspend fun waitForThumbnailsToUpdate(updatedThumbnails: Map<Int, ThumbnailData>?) {
+ if (updatedThumbnails.isNullOrEmpty()) return
combine(
updatedThumbnails.map {
recentsTasksRepository.getThumbnailById(it.key).filter { thumbnailData ->
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index c7c04ed..b583a4b 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -21,7 +21,6 @@
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
-import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Matrix;
@@ -34,18 +33,11 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.touch.AllAppsSwipeController;
-import com.android.quickstep.DeviceConfigWrapper;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.views.RecentsView;
-import com.android.quickstep.views.RecentsViewContainer;
/**
* Controls an animation that can go beyond progress = 1, at which point resistance should be
@@ -57,10 +49,8 @@
private enum RecentsResistanceParams {
FROM_APP(0.75f, 0.5f, 1f, false),
- FROM_APP_TO_ALL_APPS(1f, 0.6f, 0.8f, false),
FROM_APP_TABLET(1f, 0.7f, 1f, true),
FROM_APP_TABLET_GRID_ONLY(1f, 1f, 1f, true),
- FROM_APP_TO_ALL_APPS_TABLET(1f, 0.5f, 0.5f, false),
FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
@@ -157,46 +147,10 @@
RecentsParams params = new RecentsParams(context, recentsOrientedState, dp, scaleTarget,
scaleProperty, translationTarget, translationProperty);
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
-
- // Apply All Apps animation during the resistance animation.
- if (recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()) {
- RecentsViewContainer container =
- recentsOrientedState.getContainerInterface().getCreatedContainer();
- if (container != null) {
- RecentsView recentsView = container.getOverviewPanel();
- StateManager<LauncherState, StatefulActivity<LauncherState>> stateManager =
- recentsView.getStateManager();
- if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
- && stateManager.isInTransition()) {
-
- // Calculate the resistance progress threshold where All Apps will trigger.
- float threshold = getAllAppsThreshold(context, recentsOrientedState, dp);
-
- StateAnimationConfig config = new StateAnimationConfig();
- AllAppsSwipeController.applyOverviewToAllAppsAnimConfig(dp, config, threshold);
- AnimatorSet allAppsAnimator = stateManager.createAnimationToNewWorkspace(
- LauncherState.ALL_APPS, config).getTarget();
- resistAnim.add(allAppsAnimator);
- }
- }
- }
-
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
return new AnimatorControllerWithResistance(normalController, resistanceController);
}
- private static float getAllAppsThreshold(Context context,
- RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
- int transitionDragLength =
- recentsOrientedState.getContainerInterface().getSwipeUpDestinationAndLength(
- dp, context, TEMP_RECT,
- recentsOrientedState.getOrientationHandler());
- float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
- // -1s are because 0-1 is reserved for the normal transition.
- float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
- return (threshold - 1) / (dragLengthFactor - 1);
- }
-
/**
* Creates the resistance animation for {@link #createForRecents}, or can be used separately
* when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
@@ -305,17 +259,11 @@
this.translationTarget = translationTarget;
this.translationProperty = translationProperty;
if (dp.isTablet) {
- resistanceParams =
- recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
- ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
- : enableGridOnlyOverview()
- ? RecentsResistanceParams.FROM_APP_TABLET_GRID_ONLY
- : RecentsResistanceParams.FROM_APP_TABLET;
+ resistanceParams = enableGridOnlyOverview()
+ ? RecentsResistanceParams.FROM_APP_TABLET_GRID_ONLY
+ : RecentsResistanceParams.FROM_APP_TABLET;
} else {
- resistanceParams =
- recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
- ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
- : RecentsResistanceParams.FROM_APP;
+ resistanceParams = RecentsResistanceParams.FROM_APP;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/BackAnimState.kt b/quickstep/src/com/android/quickstep/util/BackAnimState.kt
new file mode 100644
index 0000000..9009eaa
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/BackAnimState.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 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.quickstep.util
+
+import android.animation.AnimatorSet
+import android.content.Context
+import com.android.launcher3.LauncherAnimationRunner.AnimationResult
+import com.android.launcher3.anim.AnimatorListeners.forEndCallback
+import com.android.launcher3.util.RunnableList
+
+/** Interface to represent animation for back to Launcher transition */
+interface BackAnimState {
+
+ fun addOnAnimCompleteCallback(r: Runnable)
+
+ fun applyToAnimationResult(result: AnimationResult, c: Context)
+
+ fun start()
+}
+
+class AnimatorBackState(private val springAnim: RectFSpringAnim?, private val anim: AnimatorSet?) :
+ BackAnimState {
+
+ override fun addOnAnimCompleteCallback(r: Runnable) {
+ val springAnimWait = RunnableList()
+ springAnim?.addAnimatorListener(forEndCallback(springAnimWait::executeAllAndDestroy))
+ ?: springAnimWait.executeAllAndDestroy()
+
+ val animWait = RunnableList()
+ anim?.addListener(
+ forEndCallback(Runnable { springAnimWait.add(animWait::executeAllAndDestroy) })
+ ) ?: springAnimWait.add(animWait::executeAllAndDestroy)
+ animWait.add(r)
+ }
+
+ override fun applyToAnimationResult(result: AnimationResult, c: Context) {
+ result.setAnimation(anim, c)
+ }
+
+ override fun start() {
+ anim?.start()
+ }
+}
+
+class AlreadyStartedBackAnimState(private val onEndCallback: RunnableList) : BackAnimState {
+
+ override fun addOnAnimCompleteCallback(r: Runnable) {
+ onEndCallback.add(r)
+ }
+
+ override fun applyToAnimationResult(result: AnimationResult, c: Context) {
+ addOnAnimCompleteCallback(result::onAnimationFinished)
+ }
+
+ override fun start() {}
+}
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index 26668c8..4c26761 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -31,7 +31,6 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Hotseat;
import com.android.launcher3.Workspace;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.HorizontalInsettableView;
import com.android.quickstep.SystemUiProxy;
@@ -80,17 +79,12 @@
@UnfoldMain RotationChangeProvider rotationChangeProvider) {
mLauncher = launcher;
- if (FeatureFlags.PREEMPTIVE_UNFOLD_ANIMATION_START.get()) {
- mPreemptiveProgressProvider = new PreemptiveUnfoldTransitionProgressProvider(
- unfoldTransitionProgressProvider, launcher.getMainThreadHandler());
- mPreemptiveProgressProvider.init();
+ mPreemptiveProgressProvider = new PreemptiveUnfoldTransitionProgressProvider(
+ unfoldTransitionProgressProvider, launcher.getMainThreadHandler());
+ mPreemptiveProgressProvider.init();
- mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
- mPreemptiveProgressProvider);
- } else {
- mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
- unfoldTransitionProgressProvider);
- }
+ mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
+ mPreemptiveProgressProvider);
unfoldTransitionProgressProvider.addCallback(mExternalTransitionStatusProvider);
unfoldTransitionProgressProvider.addCallback(
@@ -169,10 +163,6 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
- if (!FeatureFlags.PREEMPTIVE_UNFOLD_ANIMATION_START.get()) {
- return;
- }
-
if (mIsTablet != null && dp.isTablet != mIsTablet) {
// We should preemptively start the animation only if:
// - We changed to the unfolded screen
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index b9338a3..a8460c9 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -23,7 +23,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.NavigationMode;
-import com.android.quickstep.LauncherActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
public class LayoutUtils {
@@ -41,11 +41,14 @@
return swipeHeight;
}
- public static int getShelfTrackingDistance(Context context, DeviceProfile dp,
- RecentsPagedOrientationHandler orientationHandler) {
+ public static int getShelfTrackingDistance(
+ Context context,
+ DeviceProfile dp,
+ RecentsPagedOrientationHandler orientationHandler,
+ BaseContainerInterface<?, ?> baseContainerInterface) {
// Track the bottom of the window.
Rect taskSize = new Rect();
- LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, taskSize,
+ baseContainerInterface.calculateTaskSize(context, dp, taskSize,
orientationHandler);
return orientationHandler.getDistanceToBottomOfRect(dp, taskSize);
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt
index cf08391..595aa00 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt
+++ b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt
@@ -50,32 +50,34 @@
}
/**
- * Counts [numChildren] that are [DesktopTaskView] instances.
+ * Counts [TaskView]s that are [DesktopTaskView] instances.
*
- * @param numChildren Quantity of children to transverse
- * @param getTaskViewAt Function that provides a TaskView given an index
+ * @param taskViews List of [TaskView]s
*/
- fun getDesktopTaskViewCount(numChildren: Int, getTaskViewAt: (Int) -> TaskView?): Int =
- (0 until numChildren).count { getTaskViewAt(it) is DesktopTaskView }
+ fun getDesktopTaskViewCount(taskViews: List<TaskView>): Int =
+ taskViews.count { it is DesktopTaskView }
+
+ /** Returns a list of all large TaskView Ids from [TaskView]s */
+ fun getLargeTaskViewIds(taskViews: Iterable<TaskView>): List<Int> =
+ taskViews.filter { it.isLargeTile }.map { it.taskViewId }
/**
* Returns the first TaskView that should be displayed as a large tile.
*
- * @param numChildren Quantity of children to transverse
- * @param getTaskViewAt Function that provides a TaskView given an index
+ * @param taskViews List of [TaskView]s
*/
- fun getFirstLargeTaskView(numChildren: Int, getTaskViewAt: (Int) -> TaskView?): TaskView? {
- return (0 until numChildren).firstNotNullOfOrNull { index ->
- val taskView = getTaskViewAt(index)
- if (taskView?.isLargeTile == true) taskView else null
- }
- }
+ fun getFirstLargeTaskView(taskViews: List<TaskView>): TaskView? =
+ taskViews.firstOrNull { it.isLargeTile }
fun screenshotTasks(
taskView: TaskView,
- recentsAnimationController: RecentsAnimationController
+ recentsAnimationController: RecentsAnimationController,
): Map<Int, ThumbnailData> =
taskView.taskContainers.associate {
it.task.key.id to recentsAnimationController.screenshotTask(it.task.key.id)
}
+
+ /** Returns the current list of [TaskView] children. */
+ fun getTaskViews(taskViewCount: Int, requireTaskViewAt: (Int) -> TaskView): List<TaskView> =
+ (0 until taskViewCount).map(requireTaskViewAt)
}
diff --git a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
index 304b8f4..c3270dc 100644
--- a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
+++ b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
@@ -30,7 +30,6 @@
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.util.window.CachedDisplayInfo;
import com.android.launcher3.util.window.WindowManagerProxy;
-import com.android.quickstep.LauncherActivityInterface;
import java.util.List;
import java.util.Set;
@@ -40,8 +39,17 @@
*/
public class SystemWindowManagerProxy extends WindowManagerProxy {
+ private final TISBindHelper mTISBindHelper;
+
public SystemWindowManagerProxy(Context context) {
super(true);
+ mTISBindHelper = new TISBindHelper(context, binder -> {});
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ mTISBindHelper.onDestroy();
}
@Override
@@ -53,7 +61,7 @@
@Override
public boolean isInDesktopMode() {
DesktopVisibilityController desktopController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+ mTISBindHelper.getDesktopVisibilityController();
return desktopController != null && desktopController.areDesktopTasksVisible();
}
diff --git a/quickstep/src/com/android/quickstep/util/TISBindHelper.java b/quickstep/src/com/android/quickstep/util/TISBindHelper.java
index 9a01042..b573604 100644
--- a/quickstep/src/com/android/quickstep/util/TISBindHelper.java
+++ b/quickstep/src/com/android/quickstep/util/TISBindHelper.java
@@ -25,6 +25,7 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.taskbar.TaskbarManager;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.TouchInteractionService;
@@ -108,6 +109,11 @@
return mBinder == null ? null : mBinder.getTaskbarManager();
}
+ @Nullable
+ public DesktopVisibilityController getDesktopVisibilityController() {
+ return mBinder == null ? null : mBinder.getDesktopVisibilityController();
+ }
+
/**
* Sets flag whether a predictive back-to-home animation is in progress
*/
diff --git a/quickstep/src/com/android/quickstep/util/TaskGridNavHelper.java b/quickstep/src/com/android/quickstep/util/TaskGridNavHelper.java
index 98d363e..498078b 100644
--- a/quickstep/src/com/android/quickstep/util/TaskGridNavHelper.java
+++ b/quickstep/src/com/android/quickstep/util/TaskGridNavHelper.java
@@ -22,13 +22,13 @@
import com.android.launcher3.util.IntArray;
import java.lang.annotation.Retention;
+import java.util.List;
/**
* Helper class for navigating RecentsView grid tasks via arrow keys and tab.
*/
public class TaskGridNavHelper {
public static final int CLEAR_ALL_PLACEHOLDER_ID = -1;
- public static final int INVALID_FOCUSED_TASK_ID = -1;
public static final int DIRECTION_UP = 0;
public static final int DIRECTION_DOWN = 1;
@@ -43,25 +43,25 @@
private final IntArray mOriginalTopRowIds;
private IntArray mTopRowIds;
private IntArray mBottomRowIds;
- private final int mFocusedTaskId;
- public TaskGridNavHelper(IntArray topIds, IntArray bottomIds, int focusedTaskId) {
- mFocusedTaskId = focusedTaskId;
+ public TaskGridNavHelper(IntArray topIds, IntArray bottomIds,
+ List<Integer> largeTileIds) {
mOriginalTopRowIds = topIds.clone();
- generateTaskViewIdGrid(topIds, bottomIds);
+ generateTaskViewIdGrid(topIds, bottomIds, largeTileIds);
}
- private void generateTaskViewIdGrid(IntArray topRowIdArray, IntArray bottomRowIdArray) {
- boolean hasFocusedTask = mFocusedTaskId != INVALID_FOCUSED_TASK_ID;
- int maxSize =
- Math.max(topRowIdArray.size(), bottomRowIdArray.size()) + (hasFocusedTask ? 1 : 0);
- int minSize =
- Math.min(topRowIdArray.size(), bottomRowIdArray.size()) + (hasFocusedTask ? 1 : 0);
+ private void generateTaskViewIdGrid(IntArray topRowIdArray, IntArray bottomRowIdArray,
+ List<Integer> largeTileIds) {
- // Add the focused task to the beginning of both arrays if it exists.
- if (hasFocusedTask) {
- topRowIdArray.add(0, mFocusedTaskId);
- bottomRowIdArray.add(0, mFocusedTaskId);
+ int maxSize = Math.max(topRowIdArray.size(), bottomRowIdArray.size())
+ + largeTileIds.size();
+ int minSize = Math.min(topRowIdArray.size(), bottomRowIdArray.size())
+ + largeTileIds.size();
+
+ // Add Large tile task views first at the beginning
+ for (int i = 0; i < largeTileIds.size(); i++) {
+ topRowIdArray.add(i, largeTileIds.get(i));
+ bottomRowIdArray.add(i, largeTileIds.get(i));
}
// Fill in the shorter array with the ids from the longer one.
diff --git a/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt b/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt
index 09563f5..915c9e5 100644
--- a/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt
+++ b/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt
@@ -22,7 +22,6 @@
import com.android.launcher3.DeviceProfile
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener
import com.android.launcher3.anim.PendingAnimation
-import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.uioverrides.QuickstepLauncher
import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
@@ -30,7 +29,7 @@
/** Controls animations that are happening during unfolding foldable devices */
class LauncherUnfoldTransitionController(
private val launcher: QuickstepLauncher,
- private val progressProvider: ProxyUnfoldTransitionProvider
+ private val progressProvider: ProxyUnfoldTransitionProvider,
) : OnDeviceProfileChangeListener, ActivityLifecycleCallbacksAdapter, TransitionProgressListener {
private var isTablet: Boolean? = null
@@ -57,10 +56,6 @@
}
override fun onDeviceProfileChanged(dp: DeviceProfile) {
- if (!FeatureFlags.PREEMPTIVE_UNFOLD_ANIMATION_START.get()) {
- return
- }
-
if (isTablet != null && dp.isTablet != isTablet) {
// We should preemptively start the animation only if:
// - We changed to the unfolded screen
@@ -93,7 +88,7 @@
provider = this,
factory = this::onPrepareUnfoldAnimation,
duration =
- 1000L // The expected duration for the animation. Then only comes to play if we have
+ 1000L, // The expected duration for the animation. Then only comes to play if we have
// to run the animation ourselves in case sysui misses the end signal
)
timeoutAlarm.cancelAlarm()
@@ -119,7 +114,7 @@
launcher,
isVertical,
dp.displayInfo.currentSize,
- anim
+ anim,
)
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 709e0aa..e37e036 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -841,8 +841,7 @@
private final RecentsViewModel mRecentsViewModel;
private final RecentsViewModelHelper mHelper;
-
- private final RecentsViewUtils mRecentsViewUtils = new RecentsViewUtils();
+ private final RecentsViewUtils mUtils = new RecentsViewUtils();
public RecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
BaseContainerInterface sizeStrategy) {
@@ -1103,14 +1102,13 @@
@Override
public void onTaskIconChanged(@NonNull String pkg, @NonNull UserHandle user) {
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView tv = requireTaskViewAt(i);
- Task task = tv.getFirstTask();
+ for (TaskView taskView : getTaskViews()) {
+ Task task = taskView.getFirstTask();
if (pkg.equals(task.key.getPackageName()) && task.key.userId == user.getIdentifier()) {
task.icon = null;
- if (tv.getTaskContainers().stream().anyMatch(
+ if (taskView.getTaskContainers().stream().anyMatch(
container -> container.getIconView().getDrawable() != null)) {
- tv.onTaskListVisibilityChanged(true /* visible */);
+ taskView.onTaskListVisibilityChanged(true /* visible */);
}
}
}
@@ -1499,8 +1497,7 @@
return null;
}
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (taskView.containsTaskId(taskId)) {
return taskView;
}
@@ -1521,8 +1518,7 @@
int[] taskIdsCopy = Arrays.copyOf(taskIds, taskIds.length);
Arrays.sort(taskIdsCopy);
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
int[] taskViewIdsCopy = taskView.getTaskIds();
Arrays.sort(taskViewIdsCopy);
if (Arrays.equals(taskIdsCopy, taskViewIdsCopy)) {
@@ -1558,9 +1554,7 @@
*/
public void setTaskBorderEnabled(boolean enabled) {
mBorderEnabled = enabled;
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
taskView.setBorderEnabled(enabled);
}
mClearAllButton.setBorderEnabled(enabled);
@@ -1627,9 +1621,7 @@
super.onTouchEvent(ev);
if (showAsGrid()) {
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (isTaskViewVisible(taskView) && taskView.offerTouchToChildren(ev)) {
// Keep consuming events to pass to delegate
return true;
@@ -1883,7 +1875,7 @@
// Move Desktop Tasks to the end of the list
if (enableLargeDesktopWindowingTile()) {
- taskGroups = mRecentsViewUtils.sortDesktopTasksToFront(taskGroups);
+ taskGroups = mUtils.sortDesktopTasksToFront(taskGroups);
}
// Add views as children based on whether it's grouped or single task. Looping through
@@ -1939,7 +1931,7 @@
// Keep same previous focused task
TaskView newFocusedTaskView = getTaskViewByTaskIds(focusedTaskIds);
// If the list changed, maybe the focused task doesn't exist anymore
- int newFocusedTaskViewIndex = mRecentsViewUtils.getFocusedTaskIndex(taskGroups);
+ int newFocusedTaskViewIndex = mUtils.getFocusedTaskIndex(taskGroups);
if (newFocusedTaskView == null && getTaskViewCount() > newFocusedTaskViewIndex) {
newFocusedTaskView = getTaskViewAt(newFocusedTaskViewIndex);
}
@@ -2030,15 +2022,13 @@
}
private void removeTasksViewsAndClearAllButton() {
- // This handles an edge case where applyLoadPlan happens during a gesture when the
- // only Task is one with excludeFromRecents, in which case we should not remove it.
- final int stubRunningTaskIndex = isGestureActive() ? getRunningTaskIndex() : -1;
-
- for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- if (i == stubRunningTaskIndex) {
+ for (TaskView taskView : getTaskViews()) {
+ if (isGestureActive() && taskView.isRunningTask()) {
+ // This handles an edge case where applyLoadPlan happens during a gesture when the
+ // only Task is one with excludeFromRecents, in which case we should not remove it.
continue;
}
- removeView(requireTaskViewAt(i));
+ removeView(taskView);
}
if (getTaskViewCount() == 0 && indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
@@ -2059,7 +2049,7 @@
* @return Number of children that are instances of DesktopTaskView
*/
private int getDesktopTaskViewCount() {
- return mRecentsViewUtils.getDesktopTaskViewCount(getChildCount(), this::getTaskViewAt);
+ return mUtils.getDesktopTaskViewCount(getTaskViews());
}
/**
@@ -2082,8 +2072,7 @@
}
public void resetTaskVisuals() {
- for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (Arrays.stream(taskView.getTaskIds()).noneMatch(
taskId -> taskId == mIgnoreResetTaskId)) {
taskView.resetViewTransforms();
@@ -2126,9 +2115,8 @@
if (enableRefactorTaskThumbnail()) {
mRecentsViewModel.updateFullscreenProgress(mFullscreenProgress);
}
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setFullscreenProgress(mFullscreenProgress);
}
mClearAllButton.setFullscreenProgress(fullscreenProgress);
@@ -2274,8 +2262,7 @@
? mLastComputedCarouselTaskSize.right - mLastComputedTaskSize.right
: mLastComputedCarouselTaskSize.left - mLastComputedTaskSize.left;
}
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
taskView.updateTaskSize(mLastComputedTaskSize, mLastComputedGridTaskSize,
mLastComputedCarouselTaskSize);
taskView.setNonGridTranslationX(accumulatedTranslationX);
@@ -2664,7 +2651,7 @@
}
private @Nullable TaskView getFirstLargeTaskView() {
- return mRecentsViewUtils.getFirstLargeTaskView(getChildCount(), this::getTaskViewAt);
+ return mUtils.getFirstLargeTaskView(getTaskViews());
}
@Nullable
@@ -2673,8 +2660,7 @@
return null;
}
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (taskView.getTaskViewId() == taskViewId) {
return taskView;
}
@@ -2823,8 +2809,8 @@
}
private void updateChildTaskOrientations() {
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setOrientationState(mOrientationState);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setOrientationState(mOrientationState);
}
boolean shouldRotateMenuForFakeRotation =
!mOrientationState.isRecentsActivityRotationAllowed();
@@ -3083,9 +3069,8 @@
public void setTaskIconScaledDown(boolean isScaledDown) {
if (mTaskIconScaledDown != isScaledDown) {
mTaskIconScaledDown = isScaledDown;
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
}
}
}
@@ -3098,9 +3083,7 @@
public void animateUpTaskIconScale() {
mTaskIconScaledDown = false;
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
taskView.animateIconScaleAndDimIntoView();
}
}
@@ -3395,9 +3378,8 @@
private void setGridProgress(float gridProgress) {
mGridProgress = gridProgress;
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setGridProgress(gridProgress);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setGridProgress(gridProgress);
}
mClearAllButton.setGridProgress(gridProgress);
}
@@ -3407,14 +3389,10 @@
mRecentsViewModel.updateThumbnailSplashProgress(taskThumbnailSplashAlpha);
return;
}
- int taskCount = getTaskViewCount();
- if (taskCount == 0) {
- return;
- }
mTaskThumbnailSplashAlpha = taskThumbnailSplashAlpha;
- for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setTaskThumbnailSplashAlpha(taskThumbnailSplashAlpha);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setTaskThumbnailSplashAlpha(taskThumbnailSplashAlpha);
}
}
@@ -3637,8 +3615,7 @@
nextFocusedTaskFromTop =
!mTopRowIdSet.isEmpty() && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
// Pick the next focused task from the preferred row.
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (taskView == dismissedTaskView || taskView.isLargeTile()) {
continue;
}
@@ -3766,8 +3743,7 @@
END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+ (taskCount - 1) * halfAdditionalDismissTranslationOffset,
END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET, 1);
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
anim.setFloat(taskView, TaskView.GRID_END_TRANSLATION_X, longGridRowWidthDiff,
clampToProgress(LINEAR, dismissTranslationInterpolationEnd, 1));
dismissTranslationInterpolationEnd = Utilities.boundToRange(
@@ -4227,9 +4203,8 @@
return new IntArray(0);
}
IntArray topArray = new IntArray(mTopRowIdSet.size());
- int taskViewCount = getTaskViewCount();
- for (int i = 0; i < taskViewCount; i++) {
- int taskViewId = requireTaskViewAt(i).getTaskViewId();
+ for (TaskView taskView : getTaskViews()) {
+ int taskViewId = taskView.getTaskViewId();
if (mTopRowIdSet.contains(taskViewId)) {
topArray.add(taskViewId);
}
@@ -4246,9 +4221,7 @@
return new IntArray(0);
}
IntArray bottomArray = new IntArray(bottomRowIdArraySize);
- int taskViewCount = getTaskViewCount();
- for (int i = 0; i < taskViewCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
int taskViewId = taskView.getTaskViewId();
if (!mTopRowIdSet.contains(taskViewId) && !taskView.isLargeTile()) {
bottomArray.add(taskViewId);
@@ -4308,9 +4281,8 @@
}
PendingAnimation anim = new PendingAnimation(duration);
- int count = getTaskViewCount();
- for (int i = 0; i < count; i++) {
- addDismissedTaskAnimations(requireTaskViewAt(i), duration, anim);
+ for (TaskView taskView : getTaskViews()) {
+ addDismissedTaskAnimations(taskView, duration, anim);
}
mPendingAnimation = anim;
@@ -4356,9 +4328,8 @@
}
// Init task grid nav helper with top/bottom id arrays.
- // TODO(b/361070854): Add keyboard navigation for all large tiles.
TaskGridNavHelper taskGridNavHelper = new TaskGridNavHelper(getTopRowIdArray(),
- getBottomRowIdArray(), mFocusedTaskViewId);
+ getBottomRowIdArray(), mUtils.getLargeTaskViewIds(getTaskViews()));
// Get current page's task view ID.
TaskView currentPageTaskView = getCurrentPageTaskView();
@@ -4477,12 +4448,11 @@
mContentAlpha = alpha;
TaskView runningTaskView = getRunningTaskView();
- for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- TaskView child = requireTaskViewAt(i);
- if (runningTaskView != null && mRunningTaskTileHidden && child == runningTaskView) {
+ for (TaskView taskView : getTaskViews()) {
+ if (runningTaskView != null && mRunningTaskTileHidden && taskView == runningTaskView) {
continue;
}
- child.setStableAlpha(alpha);
+ taskView.setStableAlpha(alpha);
}
mClearAllButton.setContentAlpha(mContentAlpha);
int alphaInt = Math.round(alpha * 255);
@@ -4591,6 +4561,13 @@
return Objects.requireNonNull(getTaskViewAt(index));
}
+ /**
+ * Returns the current list of [TaskView] children.
+ */
+ private List<TaskView> getTaskViews() {
+ return mUtils.getTaskViews(getTaskViewCount(), this::requireTaskViewAt);
+ }
+
public void setOnEmptyMessageUpdatedListener(OnEmptyMessageUpdatedListener listener) {
mOnEmptyMessageUpdatedListener = listener;
}
@@ -4895,9 +4872,9 @@
protected void setTaskViewsResistanceTranslation(float translation) {
mTaskViewsSecondaryTranslation = translation;
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView task = requireTaskViewAt(i);
- task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
+ for (TaskView taskView : getTaskViews()) {
+ taskView.getTaskResistanceTranslationProperty().set(taskView,
+ translation / getScaleY());
}
runActionOnRemoteHandles(
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
@@ -4905,23 +4882,21 @@
}
private void updateTaskViewsSnapshotRadius() {
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).updateSnapshotRadius();
+ for (TaskView taskView : getTaskViews()) {
+ taskView.updateSnapshotRadius();
}
}
protected void setTaskViewsPrimarySplitTranslation(float translation) {
mTaskViewsPrimarySplitTranslation = translation;
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView task = requireTaskViewAt(i);
- task.getPrimarySplitTranslationProperty().set(task, translation);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.getPrimarySplitTranslationProperty().set(taskView, translation);
}
}
protected void setTaskViewsSecondarySplitTranslation(float translation) {
mTaskViewsSecondarySplitTranslation = translation;
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (taskView == mSplitHiddenTaskView && !taskView.containsMultipleTasks()) {
continue;
}
@@ -6088,9 +6063,7 @@
private void updateEnabledOverlays() {
TaskView focusedTaskView = getFocusedTaskView();
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ for (TaskView taskView : getTaskViews()) {
if (taskView == focusedTaskView) {
continue;
}
@@ -6164,7 +6137,7 @@
return;
}
- Map<Integer, ThumbnailData> updatedThumbnails = mRecentsViewUtils.screenshotTasks(taskView,
+ Map<Integer, ThumbnailData> updatedThumbnails = mUtils.screenshotTasks(taskView,
mRecentsAnimationController);
if (enableRefactorTaskThumbnail()) {
mHelper.switchToScreenshot(taskView, updatedThumbnails, onFinishRunnable);
@@ -6262,8 +6235,8 @@
mRecentsViewModel.setTintAmount(tintAmount);
}
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setColorTint(mColorTint, mTintingColor);
}
Drawable scrimBg = mContainer.getScrimView().getBackground();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index 060c71e..8f19444 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -26,8 +26,11 @@
import android.view.View;
import android.view.Window;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.BaseActivity;
import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimView;
@@ -198,4 +201,7 @@
.setOrientationHandler(orientationForLogging))
.build());
}
+
+ @Nullable
+ DesktopVisibilityController getDesktopVisibilityController();
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
index 4604b70..f22c672 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
@@ -49,9 +49,7 @@
recentsViewModel.setRunningTaskShowScreenshot(true)
viewAttachedScope.launch {
recentsViewModel.waitForRunningTaskShowScreenshotToUpdate()
- if (updatedThumbnails != null) {
- recentsViewModel.waitForThumbnailsToUpdate(updatedThumbnails)
- }
+ recentsViewModel.waitForThumbnailsToUpdate(updatedThumbnails)
ViewUtils.postFrameDrawn(taskView, onFinishRunnable)
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 601dae8..291ccef 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -46,7 +46,6 @@
import androidx.core.view.updateLayoutParams
import com.android.app.animation.Interpolators
import com.android.launcher3.Flags.enableCursorHoverStates
-import com.android.launcher3.Flags.enableFocusOutline
import com.android.launcher3.Flags.enableGridOnlyOverview
import com.android.launcher3.Flags.enableHoverOfChildElementsInTaskview
import com.android.launcher3.Flags.enableLargeDesktopWindowingTile
@@ -55,7 +54,6 @@
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.anim.AnimatedFloat
-import com.android.launcher3.config.FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.testing.TestLogging
@@ -201,14 +199,14 @@
get() =
pagedOrientationHandler.getPrimaryValue(
SPLIT_SELECT_TRANSLATION_X,
- SPLIT_SELECT_TRANSLATION_Y
+ SPLIT_SELECT_TRANSLATION_Y,
)
protected val secondarySplitTranslationProperty: FloatProperty<TaskView>
get() =
pagedOrientationHandler.getSecondaryValue(
SPLIT_SELECT_TRANSLATION_X,
- SPLIT_SELECT_TRANSLATION_Y
+ SPLIT_SELECT_TRANSLATION_Y,
)
protected val primaryDismissTranslationProperty: FloatProperty<TaskView>
@@ -223,21 +221,21 @@
get() =
pagedOrientationHandler.getPrimaryValue(
TASK_OFFSET_TRANSLATION_X,
- TASK_OFFSET_TRANSLATION_Y
+ TASK_OFFSET_TRANSLATION_Y,
)
protected val secondaryTaskOffsetTranslationProperty: FloatProperty<TaskView>
get() =
pagedOrientationHandler.getSecondaryValue(
TASK_OFFSET_TRANSLATION_X,
- TASK_OFFSET_TRANSLATION_Y
+ TASK_OFFSET_TRANSLATION_Y,
)
protected val taskResistanceTranslationProperty: FloatProperty<TaskView>
get() =
pagedOrientationHandler.getSecondaryValue(
TASK_RESISTANCE_TRANSLATION_X,
- TASK_RESISTANCE_TRANSLATION_Y
+ TASK_RESISTANCE_TRANSLATION_Y,
)
private val tempCoordinates = FloatArray(2)
@@ -435,7 +433,7 @@
field = value
Log.d(
TAG,
- "${taskIds.contentToString()} - setting border animator visibility to: $field"
+ "${taskIds.contentToString()} - setting border animator visibility to: $field",
)
hoverBorderAnimator?.setBorderVisibility(visible = field, animated = true)
}
@@ -455,7 +453,7 @@
FOCUS_TRANSITION,
FOCUS_TRANSITION_INDEX_COUNT,
{ x: Float, y: Float -> x * y },
- 1f
+ 1f,
)
private val focusTransitionFullscreen =
focusTransitionPropertyFactory.get(FOCUS_TRANSITION_INDEX_FULLSCREEN)
@@ -486,27 +484,23 @@
taskViewModel = RecentsDependencies.get(this, "TaskViewType" to type)
}
- val keyboardFocusHighlightEnabled =
- (ENABLE_KEYBOARD_QUICK_SWITCH.get() || enableFocusOutline())
val cursorHoverStatesEnabled = enableCursorHoverStates()
- setWillNotDraw(!keyboardFocusHighlightEnabled && !cursorHoverStatesEnabled)
+ setWillNotDraw(!cursorHoverStatesEnabled)
context.obtainStyledAttributes(attrs, R.styleable.TaskView, defStyleAttr, defStyleRes).use {
this.focusBorderAnimator =
focusBorderAnimator
- ?: if (keyboardFocusHighlightEnabled)
- createSimpleBorderAnimator(
- currentFullscreenParams.cornerRadius.toInt(),
- context.resources.getDimensionPixelSize(
- R.dimen.keyboard_quick_switch_border_width
- ),
- { bounds: Rect -> getThumbnailBounds(bounds) },
- this,
- it.getColor(
- R.styleable.TaskView_focusBorderColor,
- BorderAnimator.DEFAULT_BORDER_COLOR
- )
- )
- else null
+ ?: createSimpleBorderAnimator(
+ currentFullscreenParams.cornerRadius.toInt(),
+ context.resources.getDimensionPixelSize(
+ R.dimen.keyboard_quick_switch_border_width
+ ),
+ { bounds: Rect -> getThumbnailBounds(bounds) },
+ this,
+ it.getColor(
+ R.styleable.TaskView_focusBorderColor,
+ BorderAnimator.DEFAULT_BORDER_COLOR,
+ ),
+ )
this.hoverBorderAnimator =
hoverBorderAnimator
?: if (cursorHoverStatesEnabled)
@@ -519,8 +513,8 @@
this,
it.getColor(
R.styleable.TaskView_hoverBorderColor,
- BorderAnimator.DEFAULT_BORDER_COLOR
- )
+ BorderAnimator.DEFAULT_BORDER_COLOR,
+ ),
)
else null
}
@@ -634,7 +628,7 @@
addAction(
AccessibilityAction(
R.id.action_close,
- context.getText(R.string.accessibility_close)
+ context.getText(R.string.accessibility_close),
)
)
@@ -658,7 +652,7 @@
1,
it.taskViewCount - it.indexOfChild(this@TaskView) - 1,
1,
- false
+ false,
)
}
}
@@ -704,7 +698,7 @@
R.id.show_windows,
R.id.digital_wellbeing_toast,
STAGE_POSITION_UNDEFINED,
- taskOverlayFactory
+ taskOverlayFactory,
)
)
taskContainers.forEach { it.bind() }
@@ -742,7 +736,7 @@
stagePosition,
digitalWellBeingToast,
findViewById(showWindowViewId)!!,
- taskOverlayFactory
+ taskOverlayFactory,
)
}
@@ -860,7 +854,7 @@
if (relativeToDragLayer) {
container.dragLayer.getDescendantRectRelativeToSelf(
it.snapshotView,
- thumbnailBounds
+ thumbnailBounds,
)
} else {
thumbnailBounds.set(it.snapshotView)
@@ -979,7 +973,7 @@
@JvmOverloads
open fun setShouldShowScreenshot(
shouldShowScreenshot: Boolean,
- thumbnailDatas: Map<Int, ThumbnailData?>? = null
+ thumbnailDatas: Map<Int, ThumbnailData?>? = null,
) {
if (this.shouldShowScreenshot == shouldShowScreenshot) return
this.shouldShowScreenshot = shouldShowScreenshot
@@ -1030,7 +1024,7 @@
if (!isClickableAsLiveTile) {
Log.e(
TAG,
- "launchAsLiveTile - TaskView is not clickable as a live tile; returning to home: ${taskIds.contentToString()}"
+ "launchAsLiveTile - TaskView is not clickable as a live tile; returning to home: ${taskIds.contentToString()}",
)
return null
}
@@ -1049,7 +1043,7 @@
apps.toTypedArray(),
wallpapers.toTypedArray(),
remoteTargetHandles[0].transformParams.targetSet.nonApps,
- remoteTargetHandles[0].transformParams.targetSet.targetMode
+ remoteTargetHandles[0].transformParams.targetSet.targetMode,
)
}
if (targets == null) {
@@ -1059,7 +1053,7 @@
if (runnableList == null) {
Log.e(
TAG,
- "launchAsLiveTile - Recents animation cancelled and cannot launch task as non-live tile; returning to home: ${taskIds.contentToString()}"
+ "launchAsLiveTile - Recents animation cancelled and cannot launch task as non-live tile; returning to home: ${taskIds.contentToString()}",
)
}
isClickableAsLiveTile = true
@@ -1068,7 +1062,7 @@
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN,
"composeRecentsLaunchAnimator",
- taskIds.contentToString()
+ taskIds.contentToString(),
)
val runnableList = RunnableList()
with(AnimatorSet()) {
@@ -1081,7 +1075,7 @@
true /* launcherClosing */,
recentsView.stateManager,
recentsView,
- recentsView.depthController
+ recentsView.depthController,
)
addListener(
object : AnimatorListenerAdapter() {
@@ -1118,7 +1112,7 @@
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN,
"startActivityFromRecentsAsync",
- taskIds.contentToString()
+ taskIds.contentToString(),
)
val opts =
container.getActivityLaunchOptions(this, null).apply {
@@ -1130,7 +1124,7 @@
) {
Log.d(
TAG,
- "launchAsStaticTile - startActivityFromRecents: ${taskIds.contentToString()}"
+ "launchAsStaticTile - startActivityFromRecents: ${taskIds.contentToString()}",
)
ActiveGestureLog.INSTANCE.trackEvent(
ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED
@@ -1163,12 +1157,12 @@
@JvmOverloads
open fun launchWithoutAnimation(
isQuickSwitch: Boolean = false,
- callback: (launched: Boolean) -> Unit
+ callback: (launched: Boolean) -> Unit,
) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN,
"startActivityFromRecentsAsync",
- taskIds.contentToString()
+ taskIds.contentToString(),
)
val firstContainer = taskContainers[0]
val failureListener = TaskRemovedDuringLaunchListener(context.applicationContext)
@@ -1199,7 +1193,7 @@
0,
0,
Executors.MAIN_EXECUTOR.handler,
- { callback(true) }
+ { callback(true) },
) {
failureListener.onTransitionFinished()
}
@@ -1227,7 +1221,7 @@
}
Log.d(
TAG,
- "launchWithoutAnimation - startActivityFromRecents: ${taskIds.contentToString()}"
+ "launchWithoutAnimation - startActivityFromRecents: ${taskIds.contentToString()}",
)
}
}
@@ -1246,7 +1240,7 @@
recentsView?.initiateSplitSelect(
this,
splitPositionOption.stagePosition,
- SplitConfigurationOptions.getLogEventForPosition(splitPositionOption.stagePosition)
+ SplitConfigurationOptions.getLogEventForPosition(splitPositionOption.stagePosition),
)
}
@@ -1269,7 +1263,7 @@
container.splitAnimationThumbnail,
/* intent */ null,
/* user */ null,
- container.itemInfo
+ container.itemInfo,
)
}
@@ -1374,13 +1368,13 @@
this[0] = viewHalfWidth
this[1] = viewHalfHeight
},
- false
+ false,
)
transformingTouchDelegate.setBounds(
(tempCenterCoordinates[0] - viewHalfWidth).toInt(),
(tempCenterCoordinates[1] - viewHalfHeight).toInt(),
(tempCenterCoordinates[0] + viewHalfWidth).toInt(),
- (tempCenterCoordinates[1] + viewHalfHeight).toInt()
+ (tempCenterCoordinates[1] + viewHalfHeight).toInt(),
)
}
@@ -1390,7 +1384,7 @@
it.showWindowsView?.let { showWindowsView ->
updateFilterCallback(
showWindowsView,
- getFilterUpdateCallback(it.task.key.packageName)
+ getFilterUpdateCallback(it.task.key.packageName),
)
}
}
@@ -1710,7 +1704,7 @@
Interpolators.clampToProgress(
Interpolators.FAST_OUT_SLOW_IN,
1f - FOCUS_TRANSITION_THRESHOLD,
- 1f
+ 1f,
)!!
private val SYSTEM_GESTURE_EXCLUSION_RECT = listOf(Rect())
diff --git a/quickstep/testing/com/android/launcher3/taskbar/bubbles/testing/FakeBubbleViewFactory.kt b/quickstep/testing/com/android/launcher3/taskbar/bubbles/testing/FakeBubbleViewFactory.kt
new file mode 100644
index 0000000..37a07c3
--- /dev/null
+++ b/quickstep/testing/com/android/launcher3/taskbar/bubbles/testing/FakeBubbleViewFactory.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 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.taskbar.bubbles.testing
+
+import android.app.Notification
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.util.PathParser
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.android.launcher3.R
+import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
+import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.wm.shell.shared.bubbles.BubbleInfo
+
+object FakeBubbleViewFactory {
+
+ /** Inflates a [BubbleView] and adds it to the [parent] view if it is present. */
+ fun createBubble(
+ context: Context,
+ key: String,
+ parent: ViewGroup?,
+ iconSize: Int = 50,
+ iconColor: Int,
+ badgeColor: Int = Color.RED,
+ dotColor: Int = Color.BLUE,
+ suppressNotification: Boolean = false,
+ ): BubbleView {
+ val inflater = LayoutInflater.from(context)
+ // BubbleView uses launcher's badge to icon ratio and expects the badge image to already
+ // have the right size
+ val badgeToIconRatio = 0.444f
+ val badgeRadius = iconSize * badgeToIconRatio / 2
+ val icon = createCircleBitmap(radius = iconSize / 2, color = iconColor)
+ val badge = createCircleBitmap(radius = badgeRadius.toInt(), color = badgeColor)
+
+ val flags =
+ if (suppressNotification) Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION else 0
+ val bubbleInfo =
+ BubbleInfo(key, flags, null, null, 0, context.packageName, null, null, false, true)
+ val bubbleView = inflater.inflate(R.layout.bubblebar_item_view, parent, false) as BubbleView
+ val dotPath =
+ PathParser.createPathFromPathData(
+ context.resources.getString(com.android.internal.R.string.config_icon_mask)
+ )
+ val bubble =
+ BubbleBarBubble(bubbleInfo, bubbleView, badge, icon, dotColor, dotPath, "test app")
+ bubbleView.setBubble(bubble)
+ return bubbleView
+ }
+
+ private fun createCircleBitmap(radius: Int, color: Int): Bitmap {
+ val bitmap = Bitmap.createBitmap(radius * 2, radius * 2, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(bitmap)
+ canvas.drawARGB(0, 0, 0, 0)
+ val paint = Paint()
+ paint.color = color
+ canvas.drawCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), paint)
+ return bitmap
+ }
+}
diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt
new file mode 100644
index 0000000..e4b8069
--- /dev/null
+++ b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2024 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.taskbar.bubbles
+
+import android.content.Context
+import android.graphics.Color
+import android.platform.test.rule.ScreenRecordRule
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.FrameLayout.LayoutParams.MATCH_PARENT
+import android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
+import androidx.activity.ComponentActivity
+import androidx.test.core.app.ApplicationProvider
+import com.android.launcher3.R
+import com.android.launcher3.taskbar.bubbles.testing.FakeBubbleViewFactory
+import com.google.android.apps.nexuslauncher.imagecomparison.goldenpathmanager.ViewScreenshotGoldenPathManager
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.Displays
+import platform.test.screenshot.ViewScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
+
+/** Screenshot tests for [BubbleBarView]. */
+@RunWith(ParameterizedAndroidJunit4::class)
+@ScreenRecordRule.ScreenRecord
+class BubbleBarViewScreenshotTest(emulationSpec: DeviceEmulationSpec) {
+
+ private val context = ApplicationProvider.getApplicationContext<Context>()
+ private lateinit var bubbleBarView: BubbleBarView
+
+ companion object {
+ @Parameters(name = "{0}")
+ @JvmStatic
+ fun getTestSpecs() =
+ DeviceEmulationSpec.forDisplays(
+ Displays.Phone,
+ isDarkTheme = false,
+ isLandscape = false,
+ )
+ }
+
+ @get:Rule
+ val screenshotRule =
+ ViewScreenshotTestRule(
+ emulationSpec,
+ ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec)),
+ )
+
+ @Test
+ fun bubbleBarView_collapsed_oneBubble() {
+ screenshotRule.screenshotTest("bubbleBarView_collapsed_oneBubble") { activity ->
+ activity.actionBar?.hide()
+ setupBubbleBarView()
+ bubbleBarView.addBubble(createBubble("key1", Color.GREEN))
+ val container = FrameLayout(context)
+ val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
+ container.layoutParams = lp
+ container.addView(bubbleBarView)
+ container
+ }
+ }
+
+ @Test
+ fun bubbleBarView_collapsed_twoBubbles() {
+ screenshotRule.screenshotTest("bubbleBarView_collapsed_twoBubbles") { activity ->
+ activity.actionBar?.hide()
+ setupBubbleBarView()
+ bubbleBarView.addBubble(createBubble("key1", Color.GREEN))
+ bubbleBarView.addBubble(createBubble("key2", Color.CYAN))
+ val container = FrameLayout(context)
+ val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
+ container.layoutParams = lp
+ container.addView(bubbleBarView)
+ container
+ }
+ }
+
+ @Test
+ fun bubbleBarView_expanded_threeBubbles() {
+ // if we're still expanding, wait with taking a screenshot
+ val shouldWait: (ComponentActivity, View) -> Boolean = { _, _ -> bubbleBarView.isExpanding }
+ screenshotRule.screenshotTest(
+ "bubbleBarView_expanded_threeBubbles",
+ checkView = shouldWait,
+ ) { activity ->
+ activity.actionBar?.hide()
+ setupBubbleBarView()
+ bubbleBarView.addBubble(createBubble("key1", Color.GREEN))
+ bubbleBarView.addBubble(createBubble("key2", Color.CYAN))
+ bubbleBarView.addBubble(createBubble("key3", Color.MAGENTA))
+ val container = FrameLayout(context)
+ val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
+ container.layoutParams = lp
+ container.addView(bubbleBarView)
+ bubbleBarView.isExpanded = true
+ container
+ }
+ }
+
+ private fun setupBubbleBarView() {
+ bubbleBarView = BubbleBarView(context)
+ val lp = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
+ bubbleBarView.layoutParams = lp
+ val paddingTop =
+ context.resources.getDimensionPixelSize(R.dimen.bubblebar_pointer_visible_size)
+ bubbleBarView.setPadding(0, paddingTop, 0, 0)
+ bubbleBarView.visibility = View.VISIBLE
+ bubbleBarView.alpha = 1f
+ }
+
+ private fun createBubble(key: String, color: Int): BubbleView {
+ val bubbleView =
+ FakeBubbleViewFactory.createBubble(
+ context,
+ key,
+ parent = bubbleBarView,
+ iconColor = color,
+ )
+ bubbleView.showDotIfNeeded(1f)
+ bubbleBarView.setSelectedBubble(bubbleView)
+ return bubbleView
+ }
+}
diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt
index eb459ff..47f393f 100644
--- a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt
+++ b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt
@@ -15,17 +15,10 @@
*/
package com.android.launcher3.taskbar.bubbles
-import android.app.Notification
import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Canvas
import android.graphics.Color
-import android.graphics.Paint
-import android.util.PathParser
-import android.view.LayoutInflater
import androidx.test.core.app.ApplicationProvider
-import com.android.launcher3.R
-import com.android.wm.shell.shared.bubbles.BubbleInfo
+import com.android.launcher3.taskbar.bubbles.testing.FakeBubbleViewFactory
import com.google.android.apps.nexuslauncher.imagecomparison.goldenpathmanager.ViewScreenshotGoldenPathManager
import org.junit.Rule
import org.junit.Test
@@ -50,7 +43,7 @@
DeviceEmulationSpec.forDisplays(
Displays.Phone,
isDarkTheme = false,
- isLandscape = false
+ isLandscape = false,
)
}
@@ -58,7 +51,7 @@
val screenshotRule =
ViewScreenshotTestRule(
emulationSpec,
- ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec))
+ ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec)),
)
@Test
@@ -86,39 +79,16 @@
}
private fun setupBubbleView(suppressNotification: Boolean = false): BubbleView {
- val inflater = LayoutInflater.from(context)
-
- val iconSize = 100
- // BubbleView uses launcher's badge to icon ratio and expects the badge image to already
- // have the right size
- val badgeToIconRatio = 0.444f
- val badgeRadius = iconSize * badgeToIconRatio / 2
- val icon = createCircleBitmap(radius = iconSize / 2, color = Color.LTGRAY)
- val badge = createCircleBitmap(radius = badgeRadius.toInt(), color = Color.RED)
-
- val flags =
- if (suppressNotification) Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION else 0
- val bubbleInfo =
- BubbleInfo("key", flags, null, null, 0, context.packageName, null, null, false, true)
- val bubbleView = inflater.inflate(R.layout.bubblebar_item_view, null) as BubbleView
- val dotPath =
- PathParser.createPathFromPathData(
- context.resources.getString(com.android.internal.R.string.config_icon_mask)
+ val bubbleView =
+ FakeBubbleViewFactory.createBubble(
+ context,
+ key = "key",
+ parent = null,
+ iconSize = 100,
+ iconColor = Color.LTGRAY,
+ suppressNotification = suppressNotification,
)
- val bubble =
- BubbleBarBubble(bubbleInfo, bubbleView, badge, icon, Color.BLUE, dotPath, "test app")
- bubbleView.setBubble(bubble)
bubbleView.showDotIfNeeded(1f)
return bubbleView
}
-
- private fun createCircleBitmap(radius: Int, color: Int): Bitmap {
- val bitmap = Bitmap.createBitmap(radius * 2, radius * 2, Bitmap.Config.ARGB_8888)
- val canvas = Canvas(bitmap)
- canvas.drawARGB(0, 0, 0, 0)
- val paint = Paint()
- paint.color = color
- canvas.drawCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), paint)
- return bitmap
- }
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
index 262d8da..d4a3b3a 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar.bubbles.stashing
+import android.animation.AnimatorSet
import android.animation.AnimatorTestRule
import android.content.Context
import android.view.View
@@ -31,6 +32,7 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController
import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController
+import com.android.launcher3.taskbar.bubbles.BubbleView
import com.android.launcher3.util.MultiValueAlpha
import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
@@ -54,13 +56,13 @@
companion object {
const val TASKBAR_BOTTOM_SPACE = 5
- const val BUBBLE_BAR_WIDTH = 200f
- const val BUBBLE_BAR_HEIGHT = 100f
+ const val BUBBLE_BAR_WIDTH = 200
+ const val BUBBLE_BAR_HEIGHT = 100
const val HOTSEAT_TRANSLATION_Y = -45f
const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE
const val HANDLE_VIEW_WIDTH = 150
const val HANDLE_VIEW_HEIGHT = 4
- const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -2.5f
+ const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -4.5f
}
@get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
@@ -76,10 +78,14 @@
private val context = ApplicationProvider.getApplicationContext<Context>()
private lateinit var bubbleBarView: BubbleBarView
private lateinit var stashedHandleView: StashedHandleView
+ private lateinit var bubbleView: BubbleView
private lateinit var barTranslationY: AnimatedFloat
private lateinit var barScaleX: AnimatedFloat
private lateinit var barScaleY: AnimatedFloat
private lateinit var barAlpha: MultiValueAlpha
+ private lateinit var bubbleOffsetY: AnimatedFloat
+ private lateinit var bubbleAlpha: AnimatedFloat
+ private lateinit var backgroundAlpha: AnimatedFloat
private lateinit var stashedHandleAlpha: MultiValueAlpha
private lateinit var stashedHandleScale: AnimatedFloat
private lateinit var stashedHandleTranslationY: AnimatedFloat
@@ -102,7 +108,7 @@
taskbarInsetsController,
bubbleBarViewController,
bubbleStashedHandleViewController,
- ImmediateAction()
+ ImmediateAction(),
)
}
@@ -158,11 +164,13 @@
mTransientBubbleStashController.isStashed = false
whenever(bubbleBarViewController.isHiddenForNoBubbles).thenReturn(false)
+ val bubbleInitialTranslation = bubbleView.translationY
+
// When stash
getInstrumentation().runOnMainSync {
mTransientBubbleStashController.updateStashedAndExpandedState(
stash = true,
- expand = false
+ expand = false,
)
}
@@ -178,9 +186,13 @@
assertThat(bubbleBarView.alpha).isEqualTo(0f)
assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScaleX())
assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScaleY())
+ assertThat(bubbleBarView.background.alpha).isEqualTo(255)
// Handle view is visible
assertThat(stashedHandleView.translationY).isEqualTo(0)
assertThat(stashedHandleView.alpha).isEqualTo(1)
+ // Bubble view is reset
+ assertThat(bubbleView.translationY).isEqualTo(bubbleInitialTranslation)
+ assertThat(bubbleView.alpha).isEqualTo(1f)
}
@Test
@@ -271,7 +283,7 @@
val height = mTransientBubbleStashController.getTouchableHeight()
// Then bubble bar height is returned
- assertThat(height).isEqualTo(BUBBLE_BAR_HEIGHT.toInt())
+ assertThat(height).isEqualTo(BUBBLE_BAR_HEIGHT)
}
private fun advanceTimeBy(advanceMs: Long) {
@@ -282,31 +294,46 @@
private fun setUpBubbleBarView() {
getInstrumentation().runOnMainSync {
bubbleBarView = BubbleBarView(context)
- bubbleBarView.layoutParams = FrameLayout.LayoutParams(0, 0)
+ bubbleBarView.layoutParams =
+ FrameLayout.LayoutParams(BUBBLE_BAR_WIDTH, BUBBLE_BAR_HEIGHT)
+ bubbleView = BubbleView(context)
+ bubbleBarView.addBubble(bubbleView)
+ bubbleBarView.layout(0, 0, BUBBLE_BAR_WIDTH, BUBBLE_BAR_HEIGHT)
}
}
private fun setUpStashedHandleView() {
getInstrumentation().runOnMainSync {
stashedHandleView = StashedHandleView(context)
- stashedHandleView.layoutParams = FrameLayout.LayoutParams(0, 0)
+ stashedHandleView.layoutParams =
+ FrameLayout.LayoutParams(HANDLE_VIEW_WIDTH, HANDLE_VIEW_HEIGHT)
}
}
private fun setUpBubbleBarController() {
barTranslationY =
AnimatedFloat(Runnable { bubbleBarView.translationY = barTranslationY.value })
+ bubbleOffsetY = AnimatedFloat { value -> bubbleBarView.setBubbleOffsetY(value) }
barScaleX = AnimatedFloat { value -> bubbleBarView.scaleX = value }
barScaleY = AnimatedFloat { value -> bubbleBarView.scaleY = value }
barAlpha = MultiValueAlpha(bubbleBarView, 1 /* num alpha channels */)
+ bubbleAlpha = AnimatedFloat { value -> bubbleBarView.setBubbleAlpha(value) }
+ backgroundAlpha = AnimatedFloat { value -> bubbleBarView.setBackgroundAlpha(value) }
whenever(bubbleBarViewController.hasBubbles()).thenReturn(true)
whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY)
- whenever(bubbleBarViewController.bubbleBarScaleX).thenReturn(barScaleX)
- whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScaleY)
+ whenever(bubbleBarViewController.bubbleOffsetY).thenReturn(bubbleOffsetY)
+ whenever(bubbleBarViewController.bubbleBarBackgroundScaleX).thenReturn(barScaleX)
+ whenever(bubbleBarViewController.bubbleBarBackgroundScaleY).thenReturn(barScaleY)
whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha)
- whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH)
- whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)
+ whenever(bubbleBarViewController.bubbleBarBubbleAlpha).thenReturn(bubbleAlpha)
+ whenever(bubbleBarViewController.bubbleBarBackgroundAlpha).thenReturn(backgroundAlpha)
+ whenever(bubbleBarViewController.bubbleBarCollapsedWidth)
+ .thenReturn(BUBBLE_BAR_WIDTH.toFloat())
+ whenever(bubbleBarViewController.bubbleBarCollapsedHeight)
+ .thenReturn(BUBBLE_BAR_HEIGHT.toFloat())
+ whenever(bubbleBarViewController.createRevealAnimatorForStashChange(any()))
+ .thenReturn(AnimatorSet())
}
private fun setUpBubbleStashedHandleViewController() {
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt
index bbcf566..cb5e464 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt
@@ -26,6 +26,7 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ServiceTestRule
import com.android.launcher3.LauncherAppState
+import com.android.launcher3.statehandlers.DesktopVisibilityController
import com.android.launcher3.taskbar.TaskbarActivityContext
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks
@@ -143,6 +144,7 @@
PendingIntent(IIntentSender.Default())
},
object : TaskbarNavButtonCallbacks {},
+ DesktopVisibilityController(context),
) {
override fun recreateTaskbar() {
super.recreateTaskbar()
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt
index fe67313..33d96a8 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt
@@ -70,6 +70,55 @@
assertThat(thumbnailDataFlow2.first()).isNull()
}
+ @Test
+ fun updatesRunningTaskShowScreenshot() = runTest {
+ systemUnderTest.setRunningTaskShowScreenshot(true)
+ systemUnderTest.waitForRunningTaskShowScreenshotToUpdate()
+ }
+
+ @Test
+ fun waitForThumbnailsToUpdate() = runTest {
+ // Given taskRepository with visible 2 tasks containing thumbnailData
+ val thumbnailData1 = createThumbnailData().apply { snapshotId = 1 }
+ val thumbnailData2 = createThumbnailData().apply { snapshotId = 2 }
+ tasksRepository.seedTasks(tasks)
+ tasksRepository.seedThumbnailData(mapOf(1 to thumbnailData1, 2 to thumbnailData2))
+ systemUnderTest.updateVisibleTasks(listOf(1, 2))
+
+ val thumbnailDataFlow1 = tasksRepository.getThumbnailById(1)
+ val thumbnailDataFlow2 = tasksRepository.getThumbnailById(2)
+
+ // Then getThumbnailById should initially contains correct thumbnailData
+ assertThat(thumbnailDataFlow1.first()).isEqualTo(thumbnailData1)
+ assertThat(thumbnailDataFlow2.first()).isEqualTo(thumbnailData2)
+
+ // When thumbnailData is updated in taskRepository
+ tasksRepository.seedThumbnailData(
+ mapOf(1 to thumbnailData1, 2 to createThumbnailData().apply { snapshotId = 3 })
+ )
+ // setVisibleTasks forces FakeTasksRepository to update the flows returned by
+ // getThumbnailById
+ tasksRepository.setVisibleTasks(listOf(1, 2))
+
+ // Then wait for thumbnailData should complete, and the previous getThumbnailById flow
+ // should return updated values
+ systemUnderTest.waitForThumbnailsToUpdate(
+ mapOf(2 to createThumbnailData().apply { snapshotId = 3 })
+ )
+ assertThat(thumbnailDataFlow1.first()).isEqualTo(thumbnailData1)
+ assertThat(thumbnailDataFlow2.first()?.snapshotId).isEqualTo(3)
+ }
+
+ @Test
+ fun waitForThumbnailsToUpdate_emptyMap() = runTest {
+ systemUnderTest.waitForThumbnailsToUpdate(emptyMap())
+ }
+
+ @Test
+ fun waitForThumbnailsToUpdate_null() = runTest {
+ systemUnderTest.waitForThumbnailsToUpdate(null)
+ }
+
private fun createTaskWithId(taskId: Int) =
Task(Task.TaskKey(taskId, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
colorBackground = Color.argb(taskId, taskId, taskId, taskId)
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskGridNavHelperTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskGridNavHelperTest.java
deleted file mode 100644
index 7ef4910..0000000
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskGridNavHelperTest.java
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (C) 2023 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.quickstep.util;
-
-import static com.android.quickstep.util.TaskGridNavHelper.CLEAR_ALL_PLACEHOLDER_ID;
-import static com.android.quickstep.util.TaskGridNavHelper.INVALID_FOCUSED_TASK_ID;
-
-import static org.junit.Assert.assertEquals;
-
-import com.android.launcher3.util.IntArray;
-
-import org.junit.Test;
-
-public class TaskGridNavHelperTest {
-
- @Test
- public void equalLengthRows_noFocused_onTop_pressDown_goesToBottom() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 1;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_DOWN;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 2, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_pressUp_goesToBottom() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 1;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_UP;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 2, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_pressDown_goesToTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 2;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_DOWN;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 1, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_pressUp_goesToTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 2;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_UP;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 1, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_pressLeft_goesLeft() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 1;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 3, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_pressLeft_goesLeft() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 2;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 4, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_secondItem_pressRight_goesRight() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 3;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 1, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_secondItem_pressRight_goesRight() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 4;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 2, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_pressRight_cycleToClearAll() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 1;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", CLEAR_ALL_PLACEHOLDER_ID, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_pressRight_cycleToClearAll() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 2;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", CLEAR_ALL_PLACEHOLDER_ID, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_lastItem_pressLeft_toClearAll() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 5;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", CLEAR_ALL_PLACEHOLDER_ID, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_lastItem_pressLeft_toClearAll() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 6;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", CLEAR_ALL_PLACEHOLDER_ID, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onClearAll_pressLeft_cycleToFirst() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 1, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onClearAll_pressRight_toLastInBottom() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 6, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_withFocused_onFocused_pressLeft_toTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int focusedTaskId = 99;
- int currentPageTaskViewId = focusedTaskId;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, focusedTaskId);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 1, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_withFocused_onFocused_pressUp_stayOnFocused() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int focusedTaskId = 99;
- int currentPageTaskViewId = focusedTaskId;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_UP;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, focusedTaskId);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", focusedTaskId, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_withFocused_onFocused_pressDown_stayOnFocused() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int focusedTaskId = 99;
- int currentPageTaskViewId = focusedTaskId;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_DOWN;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, focusedTaskId);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", focusedTaskId, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_withFocused_onFocused_pressRight_cycleToClearAll() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int focusedTaskId = 99;
- int currentPageTaskViewId = focusedTaskId;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, focusedTaskId);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", CLEAR_ALL_PLACEHOLDER_ID, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_withFocused_onClearAll_pressLeft_cycleToFocusedTask() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int focusedTaskId = 99;
- int currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, focusedTaskId);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", focusedTaskId, nextGridPage);
- }
-
- @Test
- public void longerTopRow_noFocused_atEndTopBeyondBottom_pressDown_stayTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5, 7);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 7;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_DOWN;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 7, nextGridPage);
- }
-
- @Test
- public void longerTopRow_noFocused_atEndTopBeyondBottom_pressUp_stayTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5, 7);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 7;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_UP;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 7, nextGridPage);
- }
-
- @Test
- public void longerTopRow_noFocused_atEndBottom_pressLeft_goToTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5, 7);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 6;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_LEFT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 7, nextGridPage);
- }
-
- @Test
- public void longerTopRow_noFocused_atClearAll_pressRight_goToLonger() {
- IntArray topIds = IntArray.wrap(1, 3, 5, 7);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 7, nextGridPage);
- }
-
- @Test
- public void longerBottomRow_noFocused_atClearAll_pressRight_goToLonger() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6, 7);
- int currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_RIGHT;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 7, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_pressTab_goesToBottom() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 1;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_TAB;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 2, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_pressTab_goesToNextTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 2;
- int delta = 1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_TAB;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 3, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onTop_pressTabWithShift_goesToPreviousBottom() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 3;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_TAB;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 2, nextGridPage);
- }
-
- @Test
- public void equalLengthRows_noFocused_onBottom_pressTabWithShift_goesToTop() {
- IntArray topIds = IntArray.wrap(1, 3, 5);
- IntArray bottomIds = IntArray.wrap(2, 4, 6);
- int currentPageTaskViewId = 2;
- int delta = -1;
- @TaskGridNavHelper.TASK_NAV_DIRECTION int direction = TaskGridNavHelper.DIRECTION_TAB;
- boolean cycle = true;
- TaskGridNavHelper taskGridNavHelper =
- new TaskGridNavHelper(topIds, bottomIds, INVALID_FOCUSED_TASK_ID);
-
- int nextGridPage =
- taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, cycle);
-
- assertEquals("Wrong next page returned.", 1, nextGridPage);
- }
-}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskGridNavHelperTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskGridNavHelperTest.kt
new file mode 100644
index 0000000..7aab75f
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskGridNavHelperTest.kt
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 2023 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.quickstep.util
+
+import com.android.launcher3.util.IntArray
+import com.android.quickstep.util.TaskGridNavHelper.CLEAR_ALL_PLACEHOLDER_ID
+import com.android.quickstep.util.TaskGridNavHelper.DIRECTION_DOWN
+import com.android.quickstep.util.TaskGridNavHelper.DIRECTION_LEFT
+import com.android.quickstep.util.TaskGridNavHelper.DIRECTION_RIGHT
+import com.android.quickstep.util.TaskGridNavHelper.DIRECTION_TAB
+import com.android.quickstep.util.TaskGridNavHelper.DIRECTION_UP
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class TaskGridNavHelperTest {
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↓
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_pressDown_goesToBottom() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 1, DIRECTION_DOWN, delta = 1))
+ .isEqualTo(2)
+ }
+
+ /* ↑----→
+ 5 3 1 |
+ CLEAR_ALL |
+ 6 4 2←---|
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_pressUp_goesToBottom() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 1, DIRECTION_UP, delta = 1)).isEqualTo(2)
+ }
+
+ /* ↓----↑
+ 5 3 1 |
+ CLEAR_ALL |
+ 6 4 2 |
+ ↓----→
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_pressDown_goesToTop() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 2, DIRECTION_DOWN, delta = 1))
+ .isEqualTo(1)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↑
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_pressUp_goesToTop() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 2, DIRECTION_UP, delta = 1)).isEqualTo(1)
+ }
+
+ /*
+ 5 3<--1
+ CLEAR_ALL
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_pressLeft_goesLeft() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 1, DIRECTION_LEFT, delta = 1))
+ .isEqualTo(3)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL
+ 6 4<--2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_pressLeft_goesLeft() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 2, DIRECTION_LEFT, delta = 1))
+ .isEqualTo(4)
+ }
+
+ /*
+ 5 3-->1
+ CLEAR_ALL
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_secondItem_pressRight_goesRight() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 3, DIRECTION_RIGHT, delta = -1))
+ .isEqualTo(1)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL
+ 6 4-->2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_secondItem_pressRight_goesRight() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 4, DIRECTION_RIGHT, delta = -1))
+ .isEqualTo(2)
+ }
+
+ /*
+ ↓------------------←
+ | |
+ ↓ 5 3 1---→
+ CLEAR_ALL
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_pressRight_cycleToClearAll() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 1, DIRECTION_RIGHT, delta = -1))
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ /*
+ ↓------------------←
+ | ↑
+ ↓ 5 3 1 |
+ CLEAR_ALL ↑
+ 6 4 2---→
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_pressRight_cycleToClearAll() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 2, DIRECTION_RIGHT, delta = -1))
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ /*
+ ←----5 3 1
+ ↓
+ CLEAR_ALL
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_lastItem_pressLeft_toClearAll() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 5, DIRECTION_LEFT, delta = 1))
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL
+ ↑
+ ←---6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_lastItem_pressLeft_toClearAll() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 6, DIRECTION_LEFT, delta = 1))
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ /*
+ |→-----------------------|
+ | ↓
+ ↑ 5 3 1
+ ←------CLEAR_ALL
+
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onClearAll_pressLeft_cycleToFirst() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID,
+ DIRECTION_LEFT,
+ delta = 1,
+ )
+ )
+ .isEqualTo(1)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL--↓
+ |
+ |--→6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onClearAll_pressRight_toLastInBottom() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID,
+ DIRECTION_RIGHT,
+ delta = -1,
+ )
+ )
+ .isEqualTo(6)
+ }
+
+ /*
+ 5 3 1←---
+ ↑
+ CLEAR_ALL ←--FOCUSED_TASK
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_withFocused_onFocused_pressLeft_toTop() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = FOCUSED_TASK_ID,
+ DIRECTION_LEFT,
+ delta = 1,
+ largeTileIds = listOf(FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(1)
+ }
+
+ /*
+ 5 3 1
+ ←--↑
+ CLEAR_ALL ↓-→FOCUSED_TASK
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_withFocused_onFocused_pressUp_stayOnFocused() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = FOCUSED_TASK_ID,
+ DIRECTION_UP,
+ delta = 1,
+ largeTileIds = listOf(FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↑--→FOCUSED_TASK
+ ↑←--↓
+ 6 4 2
+ */
+
+ @Test
+ fun equalLengthRows_withFocused_onFocused_pressDown_stayOnFocused() {
+
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = FOCUSED_TASK_ID,
+ DIRECTION_DOWN,
+ delta = 1,
+ largeTileIds = listOf(FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ ↓-------------------------------←|
+ | ↑
+ ↓ 5 3 1 |
+ CLEAR_ALL FOCUSED_TASK--→
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_withFocused_onFocused_pressRight_cycleToClearAll() {
+
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = FOCUSED_TASK_ID,
+ DIRECTION_RIGHT,
+ delta = -1,
+ largeTileIds = listOf(FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ /*
+ |→---------------------------|
+ | |
+ ↑ 5 3 1 ↓
+ ←------CLEAR_ALL FOCUSED_TASK
+
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_withFocused_onClearAll_pressLeft_cycleToFocusedTask() {
+
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID,
+ DIRECTION_LEFT,
+ delta = 1,
+ largeTileIds = listOf(FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ 7←-↑ 5 3 1
+ ↓--→
+ CLEAR_ALL
+ 6 4 2
+ */
+ @Test
+ fun longerTopRow_noFocused_atEndTopBeyondBottom_pressDown_stayTop() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = 7,
+ DIRECTION_DOWN,
+ delta = 1,
+ topIds = IntArray.wrap(1, 3, 5, 7),
+ )
+ )
+ .isEqualTo(7)
+ }
+
+ /*
+ ←--↑
+ ↓-→7 5 3 1
+ CLEAR_ALL
+ 6 4 2
+ */
+ @Test
+ fun longerTopRow_noFocused_atEndTopBeyondBottom_pressUp_stayTop() {
+ assertThat(
+ getNextGridPage(
+ /* topIds = */ currentPageTaskViewId = 7,
+ DIRECTION_UP,
+ delta = 1,
+ topIds = IntArray.wrap(1, 3, 5, 7),
+ )
+ )
+ .isEqualTo(7)
+ }
+
+ /*
+ 7 5 3 1
+ CLEAR_ALL ↑
+ ←----6 4 2
+ */
+ @Test
+ fun longerTopRow_noFocused_atEndBottom_pressLeft_goToTop() {
+ assertThat(
+ getNextGridPage(
+ /* topIds = */ currentPageTaskViewId = 6,
+ DIRECTION_LEFT,
+ delta = 1,
+ topIds = IntArray.wrap(1, 3, 5, 7),
+ )
+ )
+ .isEqualTo(7)
+ }
+
+ /*
+ 7 5 3 1
+ ↑
+ CLEAR_ALL-----→
+ 6 4 2
+ */
+ @Test
+ fun longerTopRow_noFocused_atClearAll_pressRight_goToLonger() {
+ assertThat(
+ getNextGridPage(
+ /* topIds = */ currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID,
+ DIRECTION_RIGHT,
+ delta = -1,
+ topIds = IntArray.wrap(1, 3, 5, 7),
+ )
+ )
+ .isEqualTo(7)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL-----→
+ ↓
+ 7 6 4 2
+ */
+ @Test
+ fun longerBottomRow_noFocused_atClearAll_pressRight_goToLonger() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID,
+ DIRECTION_RIGHT,
+ delta = -1,
+ bottomIds = IntArray.wrap(2, 4, 6, 7),
+ )
+ )
+ .isEqualTo(7)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↓
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_pressTab_goesToBottom() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 1, DIRECTION_TAB, delta = 1))
+ .isEqualTo(2)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↑
+ ←---↑
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_pressTab_goesToNextTop() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 2, DIRECTION_TAB, delta = 1))
+ .isEqualTo(3)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↓
+ ----→
+ ↓
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onTop_pressTabWithShift_goesToPreviousBottom() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 3, DIRECTION_TAB, delta = -1))
+ .isEqualTo(2)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL ↑
+ 6 4 2
+ */
+ @Test
+ fun equalLengthRows_noFocused_onBottom_pressTabWithShift_goesToTop() {
+ assertThat(getNextGridPage(currentPageTaskViewId = 2, DIRECTION_TAB, delta = -1))
+ .isEqualTo(1)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL FOCUSED_TASK←--DESKTOP
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressLeftFromDesktopTask_goesToFocusedTask() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = DESKTOP_TASK_ID,
+ DIRECTION_LEFT,
+ delta = 1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL FOCUSED_TASK--→DESKTOP
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressRightFromFocusedTask_goesToDesktopTask() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = FOCUSED_TASK_ID,
+ DIRECTION_RIGHT,
+ delta = -1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(DESKTOP_TASK_ID)
+ }
+
+ /*
+ ↓-----------------------------------------←|
+ | |
+ ↓ 5 3 1 ↑
+ CLEAR_ALL FOCUSED_TASK DESKTOP--→
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressRightFromDesktopTask_goesToClearAll() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = DESKTOP_TASK_ID,
+ DIRECTION_RIGHT,
+ delta = -1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ /*
+ |→-------------------------------------------|
+ | |
+ ↑ 5 3 1 ↓
+ ←------CLEAR_ALL FOCUSED_TASK DESKTOP
+
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressLeftFromClearAll_goesToDesktopTask() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = CLEAR_ALL_PLACEHOLDER_ID,
+ DIRECTION_LEFT,
+ delta = 1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(DESKTOP_TASK_ID)
+ }
+
+ /*
+ 5 3 1
+ CLEAR_ALL FOCUSED_TASK DESKTOP
+ ↑
+ 6 4 2→----↑
+ */
+ @Test
+ fun withLargeTile_pressRightFromBottom_goesToLargeTile() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = 2,
+ DIRECTION_RIGHT,
+ delta = -1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ 5 3 1→----|
+ ↓
+ CLEAR_ALL FOCUSED_TASK DESKTOP
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressRightFromTop_goesToLargeTile() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = 1,
+ DIRECTION_RIGHT,
+ delta = -1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ 5 3 1
+
+ CLEAR_ALL FOCUSED_TASK←---DESKTOP
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressTabFromDeskTop_goesToFocusedTask() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = DESKTOP_TASK_ID,
+ DIRECTION_TAB,
+ delta = 1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(FOCUSED_TASK_ID)
+ }
+
+ /*
+ CLEAR_ALL FOCUSED_TASK DESKTOP
+ ↓
+ 2←----↓
+ */
+ @Test
+ fun withLargeTile_pressLeftFromLargeTile_goesToBottom() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = FOCUSED_TASK_ID,
+ DIRECTION_LEFT,
+ delta = 1,
+ topIds = IntArray(),
+ bottomIds = IntArray.wrap(2),
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(2)
+ }
+
+ /*
+ ↓-----------------------------------------←|
+ | |
+ ↓ 5 3 1 ↑
+ CLEAR_ALL FOCUSED_TASK DESKTOP--→
+ 6 4 2
+ */
+ @Test
+ fun withLargeTile_pressShiftTabFromDeskTop_goesToClearAll() {
+ assertThat(
+ getNextGridPage(
+ currentPageTaskViewId = DESKTOP_TASK_ID,
+ DIRECTION_TAB,
+ delta = -1,
+ largeTileIds = listOf(DESKTOP_TASK_ID, FOCUSED_TASK_ID),
+ )
+ )
+ .isEqualTo(CLEAR_ALL_PLACEHOLDER_ID)
+ }
+
+ private fun getNextGridPage(
+ currentPageTaskViewId: Int,
+ direction: Int,
+ delta: Int,
+ topIds: IntArray = IntArray.wrap(1, 3, 5),
+ bottomIds: IntArray = IntArray.wrap(2, 4, 6),
+ largeTileIds: List<Int> = emptyList(),
+ ): Int {
+ val taskGridNavHelper = TaskGridNavHelper(topIds, bottomIds, largeTileIds)
+ return taskGridNavHelper.getNextGridPage(currentPageTaskViewId, delta, direction, true)
+ }
+
+ private companion object {
+ const val FOCUSED_TASK_ID = 99
+ const val DESKTOP_TASK_ID = 100
+ }
+}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
index 88ffeea..b67bc5a 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
@@ -31,7 +31,6 @@
import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.TaskItemInfo
-import com.android.launcher3.statehandlers.DesktopVisibilityController
import com.android.quickstep.RecentsModel
import com.android.quickstep.RecentsModel.RecentTasksChangedListener
import com.android.quickstep.TaskIconCache
@@ -66,9 +65,7 @@
// Update canShowRunningAndRecentAppsAtInit before setUp() is called for each test.
canShowRunningAndRecentAppsAtInit =
description.methodName !in
- listOf(
- "canShowRunningAndRecentAppsAtInitIsFalse_getTasksNeverCalled",
- )
+ listOf("canShowRunningAndRecentAppsAtInitIsFalse_getTasksNeverCalled")
}
}
@@ -76,7 +73,6 @@
@Mock private lateinit var mockRecentsModel: RecentsModel
@Mock private lateinit var mockContext: Context
@Mock private lateinit var mockResources: Resources
- @Mock private lateinit var mockDesktopVisibilityController: DesktopVisibilityController
private var taskListChangeId: Int = 1
@@ -100,13 +96,11 @@
recentTasksChangedListener = null
it
}
- recentAppsController =
- TaskbarRecentAppsController(mockContext, mockRecentsModel) {
- mockDesktopVisibilityController
- }
+ recentAppsController = TaskbarRecentAppsController(mockContext, mockRecentsModel)
recentAppsController.canShowRunningApps = canShowRunningAndRecentAppsAtInit
recentAppsController.canShowRecentApps = canShowRunningAndRecentAppsAtInit
recentAppsController.init(taskbarControllers)
+ taskbarControllers.onPostInit()
recentTasksChangedListener =
if (canShowRunningAndRecentAppsAtInit) {
@@ -133,7 +127,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2),
runningTasks = listOf(createTask(1, RUNNING_APP_PACKAGE_1)),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
verify(mockRecentsModel, never()).getTasks(any<Consumer<List<GroupTask>>>())
}
@@ -147,7 +141,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2),
runningTasks = listOf(createTask(1, RUNNING_APP_PACKAGE_1)),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
// Verify that getTasks() was not called again after the init().
verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>())
@@ -162,7 +156,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = hotseatPackages,
runningTasks = emptyList(),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(newHotseatItems.map { it?.targetPackage })
.containsExactlyElementsIn(hotseatPackages)
@@ -177,7 +171,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = hotseatPackages,
runningTasks = emptyList(),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(newHotseatItems.map { it?.targetPackage })
.containsExactlyElementsIn(hotseatPackages)
@@ -191,7 +185,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2, PREDICTED_PACKAGE_1),
runningTasks = emptyList(),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val expectedPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2)
assertThat(newHotseatItems.map { it?.targetPackage })
@@ -206,7 +200,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2),
runningTasks = listOf(createTask(id = 1, HOTSEAT_PACKAGE_1)),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(newHotseatItems).hasLength(2)
@@ -226,9 +220,9 @@
runningTasks =
listOf(
createTask(id = 1, HOTSEAT_PACKAGE_1),
- createTask(id = 2, HOTSEAT_PACKAGE_1)
+ createTask(id = 2, HOTSEAT_PACKAGE_1),
),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
// First task is in Hotseat Items
@@ -251,7 +245,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2, PREDICTED_PACKAGE_1),
runningTasks = emptyList(),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val expectedPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2)
assertThat(newHotseatItems.map { it?.targetPackage })
@@ -267,9 +261,9 @@
runningTasks =
listOf(
createTask(id = 1, RUNNING_APP_PACKAGE_1),
- createTask(id = 2, RUNNING_APP_PACKAGE_2)
+ createTask(id = 2, RUNNING_APP_PACKAGE_2),
),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(recentAppsController.shownTasks).isEmpty()
}
@@ -281,7 +275,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2, PREDICTED_PACKAGE_1),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
assertThat(recentAppsController.shownTasks).isEmpty()
}
@@ -294,9 +288,9 @@
runningTasks =
listOf(
createTask(id = 1, RUNNING_APP_PACKAGE_1),
- createTask(id = 2, RUNNING_APP_PACKAGE_2)
+ createTask(id = 2, RUNNING_APP_PACKAGE_2),
),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(recentAppsController.shownTasks).isEmpty()
assertThat(recentAppsController.minimizedTaskIds).isEmpty()
@@ -308,7 +302,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
assertThat(recentAppsController.shownTasks).isEmpty()
}
@@ -321,7 +315,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val shownTasks = recentAppsController.shownTasks.map { it.task1 }
assertThat(shownTasks).containsExactlyElementsIn(listOf(task1, task2))
@@ -335,7 +329,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(recentAppsController.runningTaskIds).isEmpty()
assertThat(recentAppsController.minimizedTaskIds).isEmpty()
@@ -349,7 +343,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(recentAppsController.runningTaskIds).containsExactlyElementsIn(listOf(1, 2))
assertThat(recentAppsController.minimizedTaskIds).isEmpty()
@@ -362,12 +356,12 @@
listOf(
createTask(id = 1, HOTSEAT_PACKAGE_1),
createTask(id = 2, RUNNING_APP_PACKAGE_1),
- createTask(id = 3, RUNNING_APP_PACKAGE_2)
+ createTask(id = 3, RUNNING_APP_PACKAGE_2),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2),
runningTasks = runningTasks,
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
assertThat(recentAppsController.runningTaskIds).containsExactlyElementsIn(listOf(1, 2, 3))
assertThat(recentAppsController.minimizedTaskIds).isEmpty()
@@ -383,7 +377,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = runningTasks,
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(recentAppsController.runningTaskIds).containsExactly(1, 2, 3)
assertThat(recentAppsController.minimizedTaskIds).containsExactly(3)
@@ -397,7 +391,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
assertThat(recentAppsController.runningTaskIds).containsExactlyElementsIn(listOf(1, 2))
}
@@ -410,13 +404,13 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val shownTasks = recentAppsController.shownTasks.map { it.task1 }
@@ -431,13 +425,13 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val shownTasks = recentAppsController.shownTasks.map { it.task1 }
@@ -452,17 +446,17 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(RUNNING_APP_PACKAGE_1),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
updateRecentTasks( // Trigger a recent-tasks change before calling updateHotseatItems()
runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = listOf(RUNNING_APP_PACKAGE_1),
runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val newHotseatItems = recentAppsController.shownHotseatItems
@@ -479,12 +473,12 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2, RECENT_PACKAGE_3)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2, RECENT_PACKAGE_3),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_2, RECENT_PACKAGE_3, RECENT_PACKAGE_1)
+ recentTaskPackages = listOf(RECENT_PACKAGE_2, RECENT_PACKAGE_3, RECENT_PACKAGE_1),
)
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
// Most recent packages, minus the currently running one (RECENT_PACKAGE_1).
@@ -500,12 +494,12 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task2, task1, task3),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
val expectedOrder =
@@ -519,12 +513,12 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_3, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_3, RECENT_PACKAGE_2),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_2, RECENT_PACKAGE_3, RECENT_PACKAGE_1)
+ recentTaskPackages = listOf(RECENT_PACKAGE_2, RECENT_PACKAGE_3, RECENT_PACKAGE_1),
)
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
// Most recent packages, minus the currently running one (RECENT_PACKAGE_1).
@@ -540,12 +534,12 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1, task2, task3),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
assertThat(shownPackages).isEqualTo(listOf(RUNNING_APP_PACKAGE_1, RUNNING_APP_PACKAGE_2))
@@ -557,12 +551,12 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2, RECENT_PACKAGE_3)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2, RECENT_PACKAGE_3),
)
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_2, RECENT_PACKAGE_3)
+ recentTaskPackages = listOf(RECENT_PACKAGE_2, RECENT_PACKAGE_3),
)
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
// Most recent packages, minus the currently running one (RECENT_PACKAGE_3).
@@ -579,7 +573,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(runningTask1, runningTask2),
- recentTaskPackages = recentTaskPackages
+ recentTaskPackages = recentTaskPackages,
)
setInDesktopMode(true)
@@ -597,7 +591,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(runningTask1, runningTask2),
- recentTaskPackages = recentTaskPackages
+ recentTaskPackages = recentTaskPackages,
)
setInDesktopMode(false)
recentTasksChangedListener!!.onRecentTasksChanged()
@@ -613,7 +607,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2, RECENT_PACKAGE_3)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2, RECENT_PACKAGE_3),
)
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
// RECENT_PACKAGE_3 is the top task (visible to user) so should be excluded.
@@ -629,7 +623,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(runningTask1, runningTask2),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
val shownPackages = recentAppsController.shownTasks.map { it.packageNames }
// Only 2 recent tasks shown: Desktop Tile + 1 Recent Task
@@ -645,7 +639,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_SPLIT_PACKAGES_1, RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_SPLIT_PACKAGES_1, RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
val shownPackages = recentAppsController.shownTasks.map { it.packageNames }
// Only 2 recent tasks shown: Pair + 1 Recent Task
@@ -661,14 +655,14 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
verify(taskbarViewController, times(1)).commitRunningAppsToUI()
// Call onRecentTasksChanged() again with the same tasks, verify it's a no-op.
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = emptyList(),
- recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2),
)
verify(taskbarViewController, times(1)).commitRunningAppsToUI()
}
@@ -681,14 +675,14 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(runningTask1, runningTask2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
verify(taskbarViewController, times(1)).commitRunningAppsToUI()
// Call onRecentTasksChanged() again with the same tasks, verify it's a no-op.
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(runningTask1, runningTask2),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
verify(taskbarViewController, times(1)).commitRunningAppsToUI()
}
@@ -702,7 +696,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1Minimized, task2Visible),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
verify(taskbarViewController, times(1)).commitRunningAppsToUI()
@@ -710,7 +704,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = emptyList(),
runningTasks = listOf(task1Minimized, task2Minimized),
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
verify(taskbarViewController, times(2)).commitRunningAppsToUI()
@@ -726,7 +720,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = hotseatPackages,
runningTasks = originalTasks,
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
verify(taskbarViewController, times(1)).commitRunningAppsToUI()
@@ -734,7 +728,7 @@
prepareHotseatAndRunningAndRecentApps(
hotseatPackages = hotseatPackages,
runningTasks = newTasks,
- recentTaskPackages = emptyList()
+ recentTaskPackages = emptyList(),
)
verify(taskbarViewController, times(2)).commitRunningAppsToUI()
@@ -751,10 +745,7 @@
return recentAppsController.shownHotseatItems.toTypedArray()
}
- private fun updateRecentTasks(
- runningTasks: List<Task>,
- recentTaskPackages: List<String>,
- ) {
+ private fun updateRecentTasks(runningTasks: List<Task>, recentTaskPackages: List<String>) {
val recentTasks = createRecentTasksFromPackageNames(recentTaskPackages)
val allTasks =
ArrayList<GroupTask>().apply {
@@ -790,7 +781,7 @@
private fun createTestAppInfo(
packageName: String = "testPackageName",
- className: String = "testClassName"
+ className: String = "testClassName",
) = AppInfo(ComponentName(packageName, className), className /* title */, userHandle, Intent())
private fun createRecentTasksFromPackageNames(packageNames: List<String>): List<GroupTask> {
@@ -800,7 +791,7 @@
GroupTask(
createTask(100, splitPackages[0]),
createTask(101, splitPackages[1]),
- /* splitBounds = */ null
+ /* splitBounds = */ null,
)
} else {
// Use the number at the end of the test packageName as the id.
@@ -818,14 +809,15 @@
Intent().apply { `package` = packageName },
ComponentName(packageName, "TestActivity"),
userHandle.identifier,
- 0
+ 0,
)
)
.apply { this.isVisible = isVisible }
}
private fun setInDesktopMode(inDesktopMode: Boolean) {
- whenever(mockDesktopVisibilityController.areDesktopTasksVisible()).thenReturn(inDesktopMode)
+ whenever(taskbarControllers.taskbarDesktopModeController.areDesktopTasksVisible)
+ .thenReturn(inDesktopMode)
}
private val GroupTask.packageNames: List<String>
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 2e456a7..2858929 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -248,7 +248,6 @@
}
@Test
- @ScreenRecordRule.ScreenRecord // b/355042336
public void testOverview() throws IOException {
startAppFast(getAppPackageName());
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
index c419cd2..a16811e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
@@ -23,7 +23,6 @@
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,8 +30,6 @@
@RunWith(AndroidJUnit4.class)
public class TaplTestsPersistentTaskbar extends AbstractTaplTestsTaskbar {
- //TODO(b/359277238): fix falling tests
- @Ignore
@Test
@NavigationModeSwitch
public void testTaskbarFillsWidth() {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 943c1bd..de2c506 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -350,7 +350,6 @@
@Test
@TaskbarModeSwitch
- @ScreenRecord // b/358607191
public void testQuickSwitchToPreviousAppForTablet() throws Exception {
assumeTrue(mLauncher.isTablet());
startTestActivity(2);
@@ -516,8 +515,6 @@
isInState(() -> LauncherState.NORMAL));
}
- //TODO(b/359277238): fix falling tests
- @Ignore
@Test
@PortraitLandscape
@TaskbarModeSwitch
diff --git a/quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt b/quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
index 4d10f0f..cb59f7d 100644
--- a/quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
@@ -55,7 +55,6 @@
private val taskbarDragLayer = mock<TaskbarDragLayer>()
private val taskbarSharedState = mock<TaskbarSharedState>()
private var isInDesktopMode = false
- private val isInDesktopModeProvider = { isInDesktopMode }
private val launcherPrefs =
mock<LauncherPrefs> {
on { get(TASKBAR_PINNING) } doReturn false
@@ -71,8 +70,9 @@
whenever(taskbarActivityContext.launcherPrefs).thenReturn(launcherPrefs)
whenever(taskbarActivityContext.dragLayer).thenReturn(taskbarDragLayer)
whenever(taskbarActivityContext.statsLogManager).thenReturn(statsLogManager)
- pinningController =
- spy(TaskbarPinningController(taskbarActivityContext, isInDesktopModeProvider))
+ whenever(taskbarControllers.taskbarDesktopModeController.areDesktopTasksVisible)
+ .thenAnswer { _ -> isInDesktopMode }
+ pinningController = spy(TaskbarPinningController(taskbarActivityContext))
pinningController.init(taskbarControllers, taskbarSharedState)
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 8ae6d73..cc5baea 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -25,7 +25,6 @@
import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_PORTRAIT;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
@@ -503,7 +502,7 @@
bottomSheetCloseDuration = res.getInteger(R.integer.config_bottomSheetCloseDuration);
if (isTablet) {
bottomSheetWorkspaceScale = workspaceContentScale;
- if (isMultiDisplay && !ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH.get()) {
+ if (isMultiDisplay) {
// TODO(b/259893832): Revert to use maxWallpaperScale to calculate bottomSheetDepth
// when screen recorder bug is fixed.
if (enableScalingRevealHomeAnimation()) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bafb528..365e3d4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -241,6 +241,7 @@
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.StableViewInfo;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
@@ -2424,17 +2425,16 @@
* Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close
* animation.
*
- * @param preferredItemId The id of the preferred item to match to if it exists,
- * or ItemInfo#NO_MATCHING_ID if you want to not match by item id
+ * @param svi The StableViewInfo of the preferred item to match to if it exists or null
* @param packageName The package name of the app to match.
* @param user The user of the app to match.
* @param supportsAllAppsState If true and we are in All Apps state, looks for view in All Apps.
* Else we only looks on the workspace.
*/
- public @Nullable View getFirstMatchForAppClose(int preferredItemId, String packageName,
+ public @Nullable View getFirstMatchForAppClose(
+ @Nullable StableViewInfo svi, String packageName,
UserHandle user, boolean supportsAllAppsState) {
- final Predicate<ItemInfo> preferredItem = info ->
- info != null && info.id == preferredItemId;
+ final Predicate<ItemInfo> preferredItem = svi == null ? i -> false : svi::matches;
final Predicate<ItemInfo> packageAndUserAndApp = info ->
info != null
&& info.itemType == ITEM_TYPE_APPLICATION
@@ -2525,6 +2525,9 @@
final int itemCount = container.getChildCount();
for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
View item = container.getChildAt(itemIdx);
+ if (item.getVisibility() != View.VISIBLE) {
+ continue;
+ }
if (item instanceof ViewGroup viewGroup) {
View view = mapOverViewGroup(viewGroup, op);
if (view != null) {
@@ -3036,6 +3039,7 @@
return mPopupDataProvider.getDotInfoForItem(info);
}
+ @NonNull
public LauncherOverlayManager getOverlayManager() {
return mOverlayManager;
}
diff --git a/src/com/android/launcher3/LauncherApplication.java b/src/com/android/launcher3/LauncherApplication.java
index 8969b60..490186a 100644
--- a/src/com/android/launcher3/LauncherApplication.java
+++ b/src/com/android/launcher3/LauncherApplication.java
@@ -30,7 +30,7 @@
public void onCreate() {
super.onCreate();
MainProcessInitializer.initialize(this);
- mAppComponent = DaggerLauncherAppComponent.builder().build();
+ mAppComponent = DaggerLauncherAppComponent.builder().appContext(this).build();
}
public LauncherBaseAppComponent getAppComponent() {
diff --git a/src/com/android/launcher3/MotionEventsUtils.java b/src/com/android/launcher3/MotionEventsUtils.java
index 3228ec6..fb244b0 100644
--- a/src/com/android/launcher3/MotionEventsUtils.java
+++ b/src/com/android/launcher3/MotionEventsUtils.java
@@ -18,8 +18,6 @@
import static android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
-
import android.annotation.TargetApi;
import android.os.Build;
import android.view.MotionEvent;
@@ -35,14 +33,12 @@
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static boolean isTrackpadScroll(MotionEvent event) {
- return ENABLE_TRACKPAD_GESTURE.get()
- && event.getClassification() == CLASSIFICATION_TWO_FINGER_SWIPE;
+ return event.getClassification() == CLASSIFICATION_TWO_FINGER_SWIPE;
}
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static boolean isTrackpadMultiFingerSwipe(MotionEvent event) {
- return ENABLE_TRACKPAD_GESTURE.get()
- && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE;
+ return event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE;
}
public static boolean isTrackpadThreeFingerSwipe(MotionEvent event) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 365fbd3..0ec3b79 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1463,6 +1463,15 @@
mEdgeGlowLeft.onFlingVelocity(velocity);
mEdgeGlowRight.onFlingVelocity(velocity);
}
+
+ // Detect if user tries to swipe to -1 page but gets disallowed by checking if there was
+ // left-over values in mEdgeGlowLeft (or mEdgeGlowRight in RLT).
+ final int layoutDir = getLayoutDirection();
+ if ((mEdgeGlowLeft.getDistance() > 0 && layoutDir == LAYOUT_DIRECTION_LTR)
+ || (mEdgeGlowRight.getDistance() > 0 && layoutDir == LAYOUT_DIRECTION_RTL)) {
+ onDisallowSwipeToMinusOnePage();
+ }
+
mEdgeGlowLeft.onRelease(ev);
mEdgeGlowRight.onRelease(ev);
// End any intermediate reordering states
@@ -1487,6 +1496,8 @@
return true;
}
+ protected void onDisallowSwipeToMinusOnePage() {}
+
protected void onNotSnappingToPageInFreeScroll() { }
/**
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 255260e..0e9c861 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1123,6 +1123,11 @@
return super.onTouchEvent(ev);
}
+ @Override
+ protected void onDisallowSwipeToMinusOnePage() {
+ mLauncher.getOverlayManager().onDisallowSwipeToMinusOnePage();
+ }
+
/**
* Called directly from a CellLayout (not by the framework), after we've been added as a
* listener via setOnInterceptTouchEventListener(). This allows us to tell the CellLayout
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index cc4724c..6b5e3be 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -22,8 +22,6 @@
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
-import static com.android.launcher3.config.FeatureFlags.ALL_APPS_GONE_VISIBILITY;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_RV_PREINFLATION;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_COUNT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
@@ -679,18 +677,13 @@
@NonNull AllAppsRecyclerView mainRecyclerView,
@Nullable AllAppsRecyclerView workRecyclerView,
@NonNull AllAppsRecyclerViewPool recycledViewPool) {
- if (!ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
- return;
- }
final boolean hasWorkProfile = workRecyclerView != null;
recycledViewPool.setHasWorkProfile(hasWorkProfile);
mainRecyclerView.setRecycledViewPool(recycledViewPool);
if (workRecyclerView != null) {
workRecyclerView.setRecycledViewPool(recycledViewPool);
}
- if (ALL_APPS_GONE_VISIBILITY.get()) {
- mainRecyclerView.updatePoolSize(hasWorkProfile);
- }
+ mainRecyclerView.updatePoolSize(hasWorkProfile);
}
private void replaceAppsRVContainer(boolean showTabs) {
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index ae45a35..4e1e950 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -18,8 +18,6 @@
import static androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT;
import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
-import static com.android.launcher3.config.FeatureFlags.ALL_APPS_GONE_VISIBILITY;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_RV_PREINFLATION;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import static com.android.launcher3.logger.LauncherAtom.SearchResultContainer;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_PERSONAL_SCROLLED_DOWN;
@@ -124,13 +122,11 @@
// all apps.
int maxPoolSizeForAppIcons = grid.getMaxAllAppsRowCount()
* grid.numShownAllAppsColumns;
- if (ALL_APPS_GONE_VISIBILITY.get() && ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
- // If we set all apps' hidden visibility to GONE and enable pre-inflation, we want to
- // preinflate one page of all apps icons plus [PREINFLATE_ICONS_ROW_COUNT] rows +
- // [EXTRA_ICONS_COUNT]. Thus we need to bump the max pool size of app icons accordingly.
- maxPoolSizeForAppIcons +=
- PREINFLATE_ICONS_ROW_COUNT * grid.numShownAllAppsColumns + EXTRA_ICONS_COUNT;
- }
+ // If we set all apps' hidden visibility to GONE and enable pre-inflation, we want to
+ // preinflate one page of all apps icons plus [PREINFLATE_ICONS_ROW_COUNT] rows +
+ // [EXTRA_ICONS_COUNT]. Thus we need to bump the max pool size of app icons accordingly.
+ maxPoolSizeForAppIcons +=
+ PREINFLATE_ICONS_ROW_COUNT * grid.numShownAllAppsColumns + EXTRA_ICONS_COUNT;
if (hasWorkProfile) {
maxPoolSizeForAppIcons *= 2;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index a4f130a..29b9e77 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_RV_PREINFLATION;
import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK;
@@ -109,7 +108,7 @@
mPackageUserKeytoUidMap = map;
// Preinflate all apps RV when apps has changed, which can happen after unlocking screen,
// rotating screen, or downloading/upgrading apps.
- if (shouldPreinflate && ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
+ if (shouldPreinflate) {
mAllAppsRecyclerViewPool.preInflateAllAppsViewHolders(mContext);
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 1b0ad04..c6852e0 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -37,7 +37,6 @@
import android.animation.Animator;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.util.FloatProperty;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -52,11 +51,9 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AllAppsSwipeController;
@@ -359,22 +356,6 @@
});
}
- if (FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() && config.isUserControlled()
- && Utilities.ATLEAST_S) {
- if (toState == ALL_APPS) {
- builder.addOnFrameListener(
- new VibrationAnimatorUpdateListener(this, mVibratorWrapper,
- SWIPE_DRAG_COMMIT_THRESHOLD, 1));
- } else {
- builder.addOnFrameListener(
- new VibrationAnimatorUpdateListener(this, mVibratorWrapper,
- 0, SWIPE_DRAG_COMMIT_THRESHOLD));
- }
- builder.addEndListener((unused) -> {
- mVibratorWrapper.cancelVibrate();
- });
- }
-
float targetProgress = toState.getVerticalProgress(mLauncher);
if (Float.compare(mProgress, targetProgress) == 0) {
setAlphas(toState, config, builder);
@@ -391,8 +372,7 @@
setAlphas(toState, config, builder);
// This controls both haptics for tapping on QSB and going to all apps.
- if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL) &&
- !FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get()) {
+ if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL)) {
mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
@@ -432,8 +412,7 @@
mAppsView = appsView;
mAppsView.setScrimView(scrimView);
- mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT,
- FeatureFlags.ALL_APPS_GONE_VISIBILITY.get() ? View.GONE : View.INVISIBLE);
+ mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT, View.GONE);
mAppsViewAlpha.setUpdateVisibility(true);
mAppsViewTranslationY = new MultiPropertyFactory<>(
mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum);
@@ -445,45 +424,4 @@
public void setShiftRange(float shiftRange) {
mShiftRange = shiftRange;
}
-
- /**
- * This VibrationAnimatorUpdateListener class takes in four parameters, a controller, start
- * threshold, end threshold, and a Vibrator wrapper. We use the progress given by the controller
- * as it gives an accurate progress that dictates where the vibrator should vibrate.
- * Note: once the user begins a gesture and does the commit haptic, there should not be anymore
- * haptics played for that gesture.
- */
- private static class VibrationAnimatorUpdateListener implements
- ValueAnimator.AnimatorUpdateListener {
- private final VibratorWrapper mVibratorWrapper;
- private final AllAppsTransitionController mController;
- private final float mStartThreshold;
- private final float mEndThreshold;
- private boolean mHasCommitted;
-
- VibrationAnimatorUpdateListener(AllAppsTransitionController controller,
- VibratorWrapper vibratorWrapper, float startThreshold,
- float endThreshold) {
- mController = controller;
- mVibratorWrapper = vibratorWrapper;
- mStartThreshold = startThreshold;
- mEndThreshold = endThreshold;
- }
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- if (mHasCommitted) {
- return;
- }
- float currentProgress =
- AllAppsTransitionController.ALL_APPS_PROGRESS.get(mController);
- if (currentProgress > mStartThreshold && currentProgress < mEndThreshold) {
- mVibratorWrapper.vibrateForDragTexture();
- } else if (!(currentProgress == 0 || currentProgress == 1)) {
- // This check guards against committing at the location of the start of the gesture
- mVibratorWrapper.vibrateForDragCommit();
- mHasCommitted = true;
- }
- }
- }
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index d0596fa..eb65320 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -62,17 +62,10 @@
* and set a default value for the flag. This will be the default value on Debug builds.
* <p>
*/
- // TODO(Block 2): Clean up flags
- public static final BooleanFlag ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH = getDebugFlag(270395073,
- "ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH", DISABLED,
- "Allow bottom sheet depth to be smaller than 1 for multi-display devices.");
-
// TODO(Block 3): Clean up flags
public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(270394476,
"ENABLE_DISMISS_PREDICTION_UNDO", DISABLED,
"Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
- public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(270395171,
- "CONTINUOUS_VIEW_TREE_CAPTURE", ENABLED, "Capture View tree every frame");
public static final BooleanFlag ENABLE_WORKSPACE_LOADING_OPTIMIZATION = getDebugFlag(251502424,
"ENABLE_WORKSPACE_LOADING_OPTIMIZATION", DISABLED,
@@ -85,26 +78,10 @@
+ "data preparation for loading the home screen");
// TODO(Block 4): Cleanup flags
- public static final BooleanFlag ENABLE_ALL_APPS_FROM_OVERVIEW =
- getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
- "Allow entering All Apps from Overview (e.g. long swipe up from app)");
-
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
"Enable option to show keyboard when going to all-apps");
- // TODO(Block 5): Clean up flags
- public static final BooleanFlag ENABLE_TWOLINE_DEVICESEARCH = getDebugFlag(201388851,
- "ENABLE_TWOLINE_DEVICESEARCH", DISABLED,
- "Enable two line label for icons with labels on device search.");
-
- public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag(270395143,
- "ENABLE_ICON_IN_TEXT_HEADER", DISABLED, "Show icon in textheader");
-
- public static final BooleanFlag ENABLE_PREMIUM_HAPTICS_ALL_APPS = getDebugFlag(270396358,
- "ENABLE_PREMIUM_HAPTICS_ALL_APPS", DISABLED,
- "Enables haptics opening/closing All apps");
-
// TODO(Block 6): Clean up flags
public static final BooleanFlag ENABLE_ALL_APPS_SEARCH_IN_TASKBAR = getDebugFlag(270393900,
"ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", ENABLED,
@@ -125,10 +102,6 @@
public static final BooleanFlag FOLDABLE_SINGLE_PAGE = getDebugFlag(270395274,
"FOLDABLE_SINGLE_PAGE", DISABLED, "Use a single page for the workspace");
- public static final BooleanFlag ENABLE_PARAMETRIZE_REORDER = getDebugFlag(289420844,
- "ENABLE_PARAMETRIZE_REORDER", DISABLED,
- "Enables generating the reorder using a set of parameters");
-
// TODO(Block 12): Clean up flags
public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag(270396680,
"ENABLE_MULTI_INSTANCE", DISABLED,
@@ -175,10 +148,6 @@
public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag(270390012,
"PROMISE_APPS_IN_ALL_APPS", DISABLED, "Add promise icon in all-apps");
- public static final BooleanFlag KEYGUARD_ANIMATION = getDebugFlag(270390904,
- "KEYGUARD_ANIMATION", DISABLED,
- "Enable animation for keyguard going away on wallpaper");
-
public static final BooleanFlag ENABLE_DEVICE_SEARCH = getReleaseFlag(270390907,
"ENABLE_DEVICE_SEARCH", ENABLED, "Allows on device search in all apps");
@@ -235,17 +204,6 @@
"ENABLE_SEARCH_UNINSTALLED_APPS", ENABLED, "Search uninstalled app results.");
// TODO(Block 20): Clean up flags
- public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(270393276,
- "ENABLE_SCRIM_FOR_APP_LAUNCH", DISABLED, "Enables scrim during app launch animation.");
-
- public static final BooleanFlag ENABLE_BACK_SWIPE_HOME_ANIMATION = getDebugFlag(270393426,
- "ENABLE_BACK_SWIPE_HOME_ANIMATION", ENABLED,
- "Enables home animation to icon when user swipes back.");
-
- public static final BooleanFlag ENABLE_DYNAMIC_TASKBAR_THRESHOLDS = getDebugFlag(294252473,
- "ENABLE_DYNAMIC_TASKBAR_THRESHOLDS", ENABLED,
- "Enables taskbar thresholds that scale based on screen size.");
-
// Aconfig migration complete for ENABLE_HOME_TRANSITION_LISTENER.
public static final BooleanFlag ENABLE_HOME_TRANSITION_LISTENER = getDebugFlag(306053414,
"ENABLE_HOME_TRANSITION_LISTENER", DISABLED,
@@ -264,18 +222,7 @@
"ENABLE_WIDGET_TRANSITION_FOR_RESIZING", DISABLED,
"Enable widget transition animation when resizing the widgets");
- public static final BooleanFlag PREEMPTIVE_UNFOLD_ANIMATION_START = getDebugFlag(270397209,
- "PREEMPTIVE_UNFOLD_ANIMATION_START", ENABLED,
- "Enables starting the unfold animation preemptively when unfolding, without"
- + "waiting for SystemUI and then merging the SystemUI progress whenever we "
- + "start receiving the events");
-
// TODO(Block 25): Clean up flags
- public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag(270396257,
- "ENABLE_NEW_GESTURE_NAV_TUTORIAL", ENABLED,
- "Enable the redesigned gesture navigation tutorial");
-
- // TODO(Block 26): Clean up flags
public static final BooleanFlag ENABLE_WIDGET_HOST_IN_BACKGROUND = getDebugFlag(270394384,
"ENABLE_WIDGET_HOST_IN_BACKGROUND", ENABLED,
"Enable background widget updates listening for widget holder");
@@ -300,10 +247,6 @@
"SEPARATE_RECENTS_ACTIVITY", DISABLED,
"Uses a separate recents activity instead of using the integrated recents+Launcher UI");
- public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = getReleaseFlag(270393258,
- "ENABLE_ENFORCED_ROUNDED_CORNERS", ENABLED,
- "Enforce rounded corners on all App Widgets");
-
public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag(270394973,
"USE_LOCAL_ICON_OVERRIDES", ENABLED,
"Use inbuilt monochrome icons if app doesn't provide one");
@@ -317,21 +260,11 @@
com.android.wm.shell.Flags.enableSplitContextual();
}
- public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag(271010401,
- "ENABLE_TRACKPAD_GESTURE", ENABLED, "Enables trackpad gesture.");
-
// TODO(Block 29): Clean up flags
public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(270393897,
"ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", DISABLED,
"Enables displaying the all apps button in the hotseat.");
- public static final BooleanFlag ENABLE_KEYBOARD_QUICK_SWITCH = getDebugFlag(270396844,
- "ENABLE_KEYBOARD_QUICK_SWITCH", ENABLED, "Enables keyboard quick switching");
-
- public static final BooleanFlag ENABLE_KEYBOARD_TASKBAR_TOGGLE = getDebugFlag(281726846,
- "ENABLE_KEYBOARD_TASKBAR_TOGGLE", ENABLED,
- "Enables keyboard taskbar stash toggling");
-
// TODO(Block 30): Clean up flags
public static final BooleanFlag USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES = getDebugFlag(270395010,
"USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", DISABLED,
@@ -349,14 +282,6 @@
return ENABLE_RESPONSIVE_WORKSPACE.get() || Flags.enableResponsiveWorkspace();
}
- // TODO(Block 33): Clean up flags
- public static final BooleanFlag ENABLE_ALL_APPS_RV_PREINFLATION = getDebugFlag(288161355,
- "ENABLE_ALL_APPS_RV_PREINFLATION", ENABLED,
- "Enables preinflating all apps icons to avoid scrolling jank.");
- public static final BooleanFlag ALL_APPS_GONE_VISIBILITY = getDebugFlag(291651514,
- "ALL_APPS_GONE_VISIBILITY", ENABLED,
- "Set all apps container view's hidden visibility to GONE instead of INVISIBLE.");
-
public static BooleanFlag getDebugFlag(
int bugId, String key, BooleanFlag flagState, String description) {
return flagState;
diff --git a/src/com/android/launcher3/dagger/ActivityContextScope.java b/src/com/android/launcher3/dagger/ActivityContextScope.java
new file mode 100644
index 0000000..887f15c
--- /dev/null
+++ b/src/com/android/launcher3/dagger/ActivityContextScope.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.dagger;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singletons associated with Launcher activity context.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Scope
+public @interface ActivityContextScope {
+}
diff --git a/src/com/android/launcher3/dagger/ApplicationContext.java b/src/com/android/launcher3/dagger/ApplicationContext.java
new file mode 100644
index 0000000..9a5b08b
--- /dev/null
+++ b/src/com/android/launcher3/dagger/ApplicationContext.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.dagger;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/**
+ * Qualifier for Launcher application context.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Qualifier
+public @interface ApplicationContext {
+}
diff --git a/src/com/android/launcher3/dagger/LauncherAppSingleton.java b/src/com/android/launcher3/dagger/LauncherAppSingleton.java
new file mode 100644
index 0000000..92c00b6
--- /dev/null
+++ b/src/com/android/launcher3/dagger/LauncherAppSingleton.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.dagger;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the LauncherAppComponent.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Scope
+public @interface LauncherAppSingleton {
+}
diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
index 3488c95..1a59d82 100644
--- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
+++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
@@ -16,6 +16,10 @@
package com.android.launcher3.dagger;
+import android.content.Context;
+
+import dagger.BindsInstance;
+
/**
* Launcher base component for Dagger injection.
*
@@ -27,6 +31,7 @@
public interface LauncherBaseAppComponent {
/** Builder for LauncherBaseAppComponent. */
interface Builder {
+ @BindsInstance Builder appContext(@ApplicationContext Context context);
LauncherBaseAppComponent build();
}
}
diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java
index 260d490..077ddfc 100644
--- a/src/com/android/launcher3/graphics/SysUiScrim.java
+++ b/src/com/android/launcher3/graphics/SysUiScrim.java
@@ -18,8 +18,6 @@
import static android.graphics.Paint.DITHER_FLAG;
import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
-
import android.animation.ObjectAnimator;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -111,7 +109,7 @@
new int[]{0x00FFFFFF, 0x2FFFFFFF},
new float[]{0f, 1f});
- if (!KEYGUARD_ANIMATION.get() && !mHideSysUiScrim) {
+ if (!mHideSysUiScrim) {
view.addOnAttachStateChangeListener(this);
}
}
diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
index f54fc57..8d2a7f9 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
@@ -121,13 +121,21 @@
@NonNull DeviceGridState destDeviceState,
@NonNull DatabaseHelper target,
@NonNull SQLiteDatabase source) {
+
+ Log.i("b/360462379", "Going from " + srcDeviceState.getColumns() + "x"
+ + srcDeviceState.getRows());
+ Log.i("b/360462379", "Going to " + destDeviceState.getColumns() + "x"
+ + destDeviceState.getRows());
+
if (!needsToMigrate(srcDeviceState, destDeviceState)) {
+ Log.i("b/360462379", "Does not need to migrate.");
return true;
}
if (Flags.enableGridMigrationFix()
&& srcDeviceState.getColumns().equals(destDeviceState.getColumns())
&& srcDeviceState.getRows() < destDeviceState.getRows()) {
+ Log.i("b/360462379", "Grid migration fix entry point.");
// Only use this strategy when comparing the previous grid to the new grid and the
// columns are the same and the destination has more rows
copyTable(source, TABLE_NAME, target.getWritableDatabase(), TABLE_NAME, context);
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 62198cb..b706d24 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -81,8 +81,6 @@
public static final boolean DEBUG = false;
public static final int NO_ID = -1;
- // An id that doesn't match any item, including predicted apps with have an id=NO_ID
- public static final int NO_MATCHING_ID = Integer.MIN_VALUE;
/** Hidden field Settings.Secure.NAV_BAR_KIDS_MODE */
private static final Uri NAV_BAR_KIDS_MODE = Settings.Secure.getUriFor("nav_bar_kids_mode");
@@ -545,6 +543,14 @@
this.title = title;
}
+ /**
+ * Returns a string ID that is stable for a user session, but may not be persisted
+ */
+ @Nullable
+ public Object getStableId() {
+ return getComponentKey();
+ }
+
private int getUserType(UserIconInfo info) {
if (info == null) {
return SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_UNKNOWN;
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 0c90eb9..1b245ab 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -7,7 +7,6 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP;
import static com.android.launcher3.widget.picker.model.data.WidgetPickerDataUtils.findAllWidgetsForPackageUser;
-import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +34,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
@@ -184,10 +184,12 @@
@Override
public void onClick(View view) {
- dismissTaskMenuView();
Rect sourceBounds = Utilities.getViewBounds(view);
+ ActivityOptionsWrapper options = mTarget.getActivityLaunchOptions(view, mItemInfo);
+ // Dismiss the taskMenu when the app launch animation is complete
+ options.onEndCallback.add(this::dismissTaskMenuView);
PackageManagerHelper.startDetailsActivityForInfo(view.getContext(), mItemInfo,
- sourceBounds, ActivityOptions.makeBasic().toBundle());
+ sourceBounds, options.toBundle());
mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP);
}
diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
index 6ff51ca..82229f8 100644
--- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
+++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
@@ -24,7 +24,6 @@
import com.android.launcher3.BubbleTextView
import com.android.launcher3.BuildConfig
import com.android.launcher3.allapps.BaseAllAppsAdapter
-import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.util.CancellableTask
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.launcher3.util.Executors.VIEW_PREINFLATION_EXECUTOR
@@ -78,7 +77,7 @@
ActivityContextDelegate(
context.createConfigurationContext(context.resources.configuration),
Themes.getActivityThemeRes(context),
- context
+ context,
)
// Because we perform onCreateViewHolder() on worker thread, we need a separate
@@ -91,7 +90,7 @@
context,
context.appsView.layoutInflater.cloneInContext(allAppsPreInflationContext),
null,
- null
+ null,
) {
override fun setAppsPerRow(appsPerRow: Int) = Unit
@@ -124,7 +123,7 @@
for (i in 0 until minOf(viewHolders.size, getPreinflateCount(context))) {
putRecycledView(viewHolders[i])
}
- }
+ },
)
mCancellableTask = task
VIEW_PREINFLATION_EXECUTOR.submit(mCancellableTask)
@@ -144,18 +143,15 @@
* app icons plus [EXTRA_ICONS_COUNT] is the magic minimal count of app icons to preinflate to
* suffice fast scrolling.
*
- * Note that if [FeatureFlags.ALL_APPS_GONE_VISIBILITY] is enabled, we need to preinfate extra
- * app icons in size of one all apps pages, so that opening all apps don't need to inflate app
- * icons.
+ * Note that we need to preinfate extra app icons in size of one all apps pages, so that opening
+ * all apps don't need to inflate app icons.
*/
fun <T> getPreinflateCount(context: T): Int where T : Context, T : ActivityContext {
var targetPreinflateCount =
PREINFLATE_ICONS_ROW_COUNT * context.deviceProfile.numShownAllAppsColumns +
EXTRA_ICONS_COUNT
- if (FeatureFlags.ALL_APPS_GONE_VISIBILITY.get()) {
- val grid = ActivityContext.lookupContext<T>(context).deviceProfile
- targetPreinflateCount += grid.maxAllAppsRowCount * grid.numShownAllAppsColumns
- }
+ val grid = ActivityContext.lookupContext<T>(context).deviceProfile
+ targetPreinflateCount += grid.maxAllAppsRowCount * grid.numShownAllAppsColumns
if (hasWorkProfile) {
targetPreinflateCount *= 2
}
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index fe4a83b..9dcdf22 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -22,13 +22,9 @@
import static com.android.app.animation.Interpolators.FINAL_FRAME;
import static com.android.app.animation.Interpolators.INSTANT;
import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.app.animation.Interpolators.clampToProgress;
-import static com.android.app.animation.Interpolators.mapToProgress;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_KEYBOARD_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
@@ -37,15 +33,12 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import com.android.app.animation.Interpolators;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.states.StateAnimationConfig;
@@ -281,36 +274,6 @@
}
}
- /**
- * Applies Animation config values for transition from overview to all apps.
- *
- * @param threshold progress at which all apps will open upon release
- */
- public static void applyOverviewToAllAppsAnimConfig(
- DeviceProfile deviceProfile, StateAnimationConfig config, float threshold) {
- config.animProps |= StateAnimationConfig.USER_CONTROLLED;
- config.animFlags = SKIP_OVERVIEW;
- if (deviceProfile.isTablet) {
- config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
- config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
- // The fact that we end on Workspace is not very ideal, but since we do, fade it in at
- // the end of the transition. Don't scale/translate it.
- config.setInterpolator(ANIM_WORKSPACE_FADE, clampToProgress(LINEAR, 0.8f, 1));
- config.setInterpolator(ANIM_WORKSPACE_SCALE, INSTANT);
- config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, INSTANT);
- } else {
- // Pop the background panel, keyboard, and content in at full opacity at the threshold.
- config.setInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE,
- thresholdInterpolator(threshold, INSTANT));
- config.setInterpolator(ANIM_ALL_APPS_KEYBOARD_FADE,
- thresholdInterpolator(threshold, INSTANT));
- config.setInterpolator(ANIM_ALL_APPS_FADE, thresholdInterpolator(threshold, INSTANT));
-
- config.setInterpolator(ANIM_VERTICAL_PROGRESS,
- thresholdInterpolator(threshold, mapToProgress(LINEAR, threshold, 1f)));
- }
- }
-
/** Creates an interpolator that is 0 until the threshold, then follows given interpolator. */
private static Interpolator thresholdInterpolator(float threshold, Interpolator interpolator) {
return progress -> progress <= threshold ? 0 : interpolator.getInterpolation(progress);
diff --git a/src/com/android/launcher3/util/ActivityOptionsWrapper.java b/src/com/android/launcher3/util/ActivityOptionsWrapper.java
index 99cc1f7..17ff2a9 100644
--- a/src/com/android/launcher3/util/ActivityOptionsWrapper.java
+++ b/src/com/android/launcher3/util/ActivityOptionsWrapper.java
@@ -25,6 +25,7 @@
public class ActivityOptionsWrapper {
public final ActivityOptions options;
+ // Called when the app launch animation is complete
public final RunnableList onEndCallback;
public ActivityOptionsWrapper(ActivityOptions options, RunnableList onEndCallback) {
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index b1e82bb..072bcdf 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -187,11 +187,6 @@
return INSTANCE.get(context).getInfo().isTransientTaskbar();
}
- /** Returns whether we are currently in Desktop mode. */
- public static boolean isInDesktopMode(Context context) {
- return INSTANCE.get(context).getInfo().isInDesktopMode();
- }
-
/**
* Handles info change for desktop mode.
*/
@@ -496,10 +491,6 @@
return navigationMode == NavigationMode.NO_BUTTON && !isTransientTaskbar();
}
- public boolean isInDesktopMode() {
- return mIsInDesktopMode;
- }
-
/**
* Returns {@code true} if the bounds represent a tablet.
*/
diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java
index 1a0f9a0..63f14bd 100644
--- a/src/com/android/launcher3/util/MainThreadInitializedObject.java
+++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java
@@ -35,6 +35,9 @@
/**
* Utility class for defining singletons which are initiated on main thread.
+ *
+ * TODO(b/361850561): Do not delete MainThreadInitializedObject until we find a way to
+ * unregister and understand how singleton objects are destroyed in dagger graph.
*/
public class MainThreadInitializedObject<T extends SafeCloseable> {
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 8c5a76e..469e363 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -212,7 +212,7 @@
if (info instanceof ItemInfoWithIcon appInfo
&& (appInfo.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
context.startActivity(ApiWrapper.INSTANCE.get(context).getAppMarketActivityIntent(
- appInfo.getTargetComponent().getPackageName(), Process.myUserHandle()));
+ appInfo.getTargetComponent().getPackageName(), Process.myUserHandle()), opts);
return;
}
ComponentName componentName = null;
diff --git a/src/com/android/launcher3/util/StableViewInfo.kt b/src/com/android/launcher3/util/StableViewInfo.kt
new file mode 100644
index 0000000..29dcd59
--- /dev/null
+++ b/src/com/android/launcher3/util/StableViewInfo.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 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.util
+
+import android.os.IBinder
+import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.ItemInfo.NO_ID
+
+/** Info parameters that can be used to identify a Launcher object */
+data class StableViewInfo(val itemId: Int, val containerId: Int, val stableId: Any) {
+
+ fun matches(info: ItemInfo?) =
+ info != null &&
+ itemId == info.id &&
+ containerId == info.container &&
+ stableId == info.stableId
+
+ companion object {
+
+ private fun ItemInfo.toStableViewInfo() =
+ stableId?.let { sId ->
+ if (id != NO_ID || container != NO_ID) StableViewInfo(id, container, sId) else null
+ }
+
+ /**
+ * Return a new launch cookie for the activity launch if supported.
+ *
+ * @param info the item info for the launch
+ */
+ @JvmStatic
+ fun toLaunchCookie(info: ItemInfo?) =
+ info?.toStableViewInfo()?.let { ObjectWrapper.wrap(it) }
+
+ /**
+ * Unwraps the binder and returns the first non-null StableViewInfo in the list or null if
+ * none can be found
+ */
+ @JvmStatic
+ fun fromLaunchCookies(launchCookies: List<IBinder>) =
+ launchCookies.firstNotNullOfOrNull { ObjectWrapper.unwrap<StableViewInfo>(it) }
+ }
+}
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index 6bae1ba..a4b8eb0 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -25,12 +25,10 @@
import android.content.Context;
import android.media.AudioAttributes;
import android.net.Uri;
-import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
-import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Utilities;
@@ -54,20 +52,6 @@
static final Uri HAPTIC_FEEDBACK_URI = Settings.System.getUriFor(HAPTIC_FEEDBACK_ENABLED);
@VisibleForTesting static final float LOW_TICK_SCALE = 0.9f;
- @VisibleForTesting static final float DRAG_TEXTURE_SCALE = 0.03f;
- @VisibleForTesting static final float DRAG_COMMIT_SCALE = 0.5f;
- @VisibleForTesting static final float DRAG_BUMP_SCALE = 0.4f;
- @VisibleForTesting static final int DRAG_TEXTURE_EFFECT_SIZE = 200;
-
- @Nullable
- private final VibrationEffect mDragEffect;
- @Nullable
- private final VibrationEffect mCommitEffect;
- @Nullable
- private final VibrationEffect mBumpEffect;
-
- private long mLastDragTime;
- private final int mThresholdUntilNextDragCallMillis;
/**
* Haptic when entering overview.
@@ -100,28 +84,6 @@
} else {
mIsHapticFeedbackEnabled = false;
}
-
- if (Utilities.ATLEAST_S && mVibrator.areAllPrimitivesSupported(
- PRIMITIVE_LOW_TICK)) {
-
- // Drag texture, Commit, and Bump should only be used for premium phones.
- // Before using these haptics make sure check if the device can use it
- mDragEffect = getDragEffect();
- mCommitEffect = VibrationEffect.startComposition().addPrimitive(
- VibrationEffect.Composition.PRIMITIVE_TICK, DRAG_COMMIT_SCALE).compose();
- mBumpEffect = VibrationEffect.startComposition().addPrimitive(
- PRIMITIVE_LOW_TICK, DRAG_BUMP_SCALE).compose();
- int primitiveDuration = mVibrator.getPrimitiveDurations(
- PRIMITIVE_LOW_TICK)[0];
-
- mThresholdUntilNextDragCallMillis =
- DRAG_TEXTURE_EFFECT_SIZE * primitiveDuration + 100;
- } else {
- mDragEffect = null;
- mCommitEffect = null;
- mBumpEffect = null;
- mThresholdUntilNextDragCallMillis = 0;
- }
}
@Override
@@ -132,52 +94,11 @@
}
/**
- * This is called when the user swipes to/from all apps. This is meant to be used in between
- * long animation progresses so that it gives a dragging texture effect. For a better
- * experience, this should be used in combination with vibrateForDragCommit().
- */
- public void vibrateForDragTexture() {
- if (mDragEffect == null) {
- return;
- }
- long currentTime = SystemClock.elapsedRealtime();
- long elapsedTimeSinceDrag = currentTime - mLastDragTime;
- if (elapsedTimeSinceDrag >= mThresholdUntilNextDragCallMillis) {
- vibrate(mDragEffect);
- mLastDragTime = currentTime;
- }
- }
-
- /**
- * This is used when user reaches the commit threshold when swiping to/from from all apps.
- */
- public void vibrateForDragCommit() {
- if (mCommitEffect != null) {
- vibrate(mCommitEffect);
- }
- // resetting dragTexture timestamp to be able to play dragTexture again
- mLastDragTime = 0;
- }
-
- /**
- * The bump haptic is used to be called at the end of a swipe and only if it the gesture is a
- * FLING going to/from all apps. Client can just call this method elsewhere just for the
- * effect.
- */
- public void vibrateForDragBump() {
- if (mBumpEffect != null) {
- vibrate(mBumpEffect);
- }
- }
-
- /**
* This should be used to cancel a haptic in case where the haptic shouldn't be vibrating. For
* example, when no animation is happening but a vibrator happens to be vibrating still.
*/
public void cancelVibrate() {
UI_HELPER_EXECUTOR.execute(mVibrator::cancel);
- // reset dragTexture timestamp to be able to play dragTexture again whenever cancelled
- mLastDragTime = 0;
}
/** Vibrates with the given effect if haptic feedback is available and enabled. */
@@ -217,13 +138,4 @@
vibrate(primitiveLowTickEffect);
}
}
-
- static VibrationEffect getDragEffect() {
- VibrationEffect.Composition dragEffect = VibrationEffect.startComposition();
- for (int i = 0; i < DRAG_TEXTURE_EFFECT_SIZE; i++) {
- dragEffect.addPrimitive(
- PRIMITIVE_LOW_TICK, DRAG_TEXTURE_SCALE);
- }
- return dragEffect.compose();
- }
}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 4ee6aff..6739387 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -253,11 +253,14 @@
public static void getLocationBoundsForView(Launcher launcher, View v, boolean isOpening,
RectF outRect, Rect outViewBounds) {
boolean ignoreTransform = !isOpening;
- if (v instanceof BubbleTextHolder) {
- v = ((BubbleTextHolder) v).getBubbleText();
+ if (v instanceof DeepShortcutView dsv) {
+ v = dsv.getIconView();
ignoreTransform = false;
- } else if (v.getParent() instanceof DeepShortcutView) {
- v = ((DeepShortcutView) v.getParent()).getIconView();
+ } else if (v.getParent() instanceof DeepShortcutView dsv) {
+ v = dsv.getIconView();
+ ignoreTransform = false;
+ } else if (v instanceof BubbleTextHolder bth) {
+ v = bth.getBubbleText();
ignoreTransform = false;
}
if (v == null) {
@@ -298,10 +301,10 @@
Drawable badge = null;
if (info instanceof SystemShortcut) {
- if (originalView instanceof ImageView) {
- drawable = ((ImageView) originalView).getDrawable();
- } else if (originalView instanceof DeepShortcutView) {
- drawable = ((DeepShortcutView) originalView).getIconView().getBackground();
+ if (originalView instanceof ImageView iv) {
+ drawable = iv.getDrawable();
+ } else if (originalView instanceof DeepShortcutView dsv) {
+ drawable = dsv.getIconView().getBackground();
} else {
drawable = originalView.getBackground();
}
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index 7fa7517..5f8e2c0 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.views;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.views.FloatingIconView.getLocationBoundsForView;
import static com.android.launcher3.views.FloatingIconViewCompanion.setPropertiesVisible;
@@ -160,7 +159,7 @@
if (mContract == null) {
return;
}
- View icon = mLauncher.getFirstMatchForAppClose(NO_MATCHING_ID,
+ View icon = mLauncher.getFirstMatchForAppClose(null /* StableViewInfo */,
mContract.componentName.getPackageName(), mContract.user,
false /* supportsAllAppsState */);
diff --git a/src/com/android/launcher3/widget/RoundedCornerEnforcement.java b/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
index 2e5e251..a2fac46 100644
--- a/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
+++ b/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
@@ -29,7 +29,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
import java.util.List;
@@ -73,7 +72,7 @@
/** Check if the app widget is in the deny list. */
public static boolean isRoundedCornerEnabled() {
- return Utilities.ATLEAST_S && FeatureFlags.ENABLE_ENFORCED_ROUNDED_CORNERS.get();
+ return Utilities.ATLEAST_S;
}
/**
diff --git a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
index 4d7f937..63d87e8 100644
--- a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
+++ b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
@@ -18,12 +18,10 @@
import dagger.Component;
-import javax.inject.Singleton;
-
/**
* Root component for Dagger injection for Launcher AOSP.
*/
-@Singleton
+@LauncherAppSingleton
@Component
public interface LauncherAppComponent extends LauncherBaseAppComponent {
/** Builder for aosp LauncherAppComponent. */
diff --git a/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java b/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java
index a940774..eaa9ef0 100644
--- a/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java
+++ b/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java
@@ -49,6 +49,8 @@
default void onActivityDestroyed() { }
+ default void onDisallowSwipeToMinusOnePage() {}
+
/**
* @deprecated use LauncherOverlayTouchProxy directly
*/
diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index ea58136..d7dd40b 100644
--- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -170,7 +170,7 @@
public static final String UIOBJECT_STALE_ELEMENT = "b/319501259";
public static final String TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE = "b/326908466";
public static final String WIDGET_CONFIG_NULL_EXTRA_INTENT = "b/324419890";
- public static final String OVERVIEW_SELECT_TOOLTIP_MISALIGNED = "b/332485341";
+
public static final String REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW = "enable-grid-only-overview";
public static final String REQUEST_FLAG_ENABLE_APP_PAIRS = "enable-app-pairs";
diff --git a/tests/multivalentTests/src/com/android/launcher3/allapps/FloatingHeaderViewTests.kt b/tests/multivalentTests/src/com/android/launcher3/allapps/FloatingHeaderViewTest.kt
similarity index 98%
rename from tests/multivalentTests/src/com/android/launcher3/allapps/FloatingHeaderViewTests.kt
rename to tests/multivalentTests/src/com/android/launcher3/allapps/FloatingHeaderViewTest.kt
index ac2c553..d2103ae 100644
--- a/tests/multivalentTests/src/com/android/launcher3/allapps/FloatingHeaderViewTests.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/allapps/FloatingHeaderViewTest.kt
@@ -31,7 +31,7 @@
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
-class FloatingHeaderViewTests {
+class FloatingHeaderViewTest {
@get:Rule val mSetFlagsRule = SetFlagsRule()
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt
index 330c394..d321e41 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt
@@ -17,7 +17,6 @@
package com.android.launcher3.util
import android.media.AudioAttributes
-import android.os.SystemClock
import android.os.VibrationEffect
import android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK
import android.os.VibrationEffect.Composition.PRIMITIVE_TICK
@@ -35,13 +34,11 @@
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.any
-import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.never
import org.mockito.kotlin.same
-import org.mockito.kotlin.verifyNoMoreInteractions
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -118,55 +115,6 @@
}
@Test
- fun vibrate_for_drag_bump() {
- underTest.vibrateForDragBump()
-
- awaitTasksCompleted()
- verify(vibrator).vibrate(vibrationEffectCaptor.capture(), same(VIBRATION_ATTRS))
- val expectedEffect =
- VibrationEffect.startComposition()
- .addPrimitive(PRIMITIVE_LOW_TICK, VibratorWrapper.DRAG_BUMP_SCALE)
- .compose()
- assertThat(vibrationEffectCaptor.value).isEqualTo(expectedEffect)
- }
-
- @Test
- fun vibrate_for_drag_commit() {
- underTest.vibrateForDragCommit()
-
- awaitTasksCompleted()
- verify(vibrator).vibrate(vibrationEffectCaptor.capture(), same(VIBRATION_ATTRS))
- val expectedEffect =
- VibrationEffect.startComposition()
- .addPrimitive(PRIMITIVE_TICK, VibratorWrapper.DRAG_COMMIT_SCALE)
- .compose()
- assertThat(vibrationEffectCaptor.value).isEqualTo(expectedEffect)
- }
-
- @Test
- fun vibrate_for_drag_texture() {
- SystemClock.setCurrentTimeMillis(40000)
-
- underTest.vibrateForDragTexture()
-
- awaitTasksCompleted()
- verify(vibrator).vibrate(vibrationEffectCaptor.capture(), same(VIBRATION_ATTRS))
- assertThat(vibrationEffectCaptor.value).isEqualTo(VibratorWrapper.getDragEffect())
- }
-
- @Test
- fun vibrate_for_drag_texture_within_time_window_noOp() {
- SystemClock.setCurrentTimeMillis(40000)
- underTest.vibrateForDragTexture()
- awaitTasksCompleted()
- reset(vibrator)
-
- underTest.vibrateForDragTexture()
-
- verifyNoMoreInteractions(vibrator)
- }
-
- @Test
fun haptic_feedback_disabled_no_vibrate() {
`when`(vibrator.hasVibrator()).thenReturn(false)
underTest = VibratorWrapper(vibrator, settingsCache)
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestStabilityRule.java b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestStabilityRule.java
index ad2d8c2..6313cf0 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestStabilityRule.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestStabilityRule.java
@@ -47,7 +47,7 @@
+ ")$");
private static final Pattern PLATFORM_BUILD =
Pattern.compile("^("
- + "(?<commandLine>eng\\.[a-z]+\\.[0-9]+\\.[0-9]+)|"
+ + "(?<commandLine>eng\\..+)|"
+ "(?<presubmit>P[0-9]+)|"
+ "(?<postsubmit>[0-9]+)"
+ ")$");
diff --git a/tests/src/com/android/launcher3/dragging/TaplDragTest.java b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
index 76c1948..8fe77ac 100644
--- a/tests/src/com/android/launcher3/dragging/TaplDragTest.java
+++ b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
@@ -197,7 +197,6 @@
@PlatinumTest(focusArea = "launcher")
@Test
@PortraitLandscape
- @ScreenRecordRule.ScreenRecord // b/343953783
public void testDragAppIcon() {
final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
diff --git a/tests/src/com/android/launcher3/tablet/TaplIsTabletTest.kt b/tests/src/com/android/launcher3/tablet/TaplIsTabletTest.kt
new file mode 100644
index 0000000..a6de607
--- /dev/null
+++ b/tests/src/com/android/launcher3/tablet/TaplIsTabletTest.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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.tablet
+
+import android.platform.test.rule.AllowedDevices
+import android.platform.test.rule.DeviceProduct
+import com.android.launcher3.Launcher
+import com.android.launcher3.ui.AbstractLauncherUiTest
+import junit.framework.TestCase.assertFalse
+import junit.framework.TestCase.assertTrue
+import org.junit.Test
+
+class TaplIsTabletTest : AbstractLauncherUiTest<Launcher>() {
+
+ /** Investigating b/366237798 by isolating and seeing flake rate of mLauncher.isTablet */
+ @Test
+ @AllowedDevices(
+ DeviceProduct.CF_FOLDABLE,
+ DeviceProduct.CF_TABLET,
+ DeviceProduct.TANGORPRO,
+ DeviceProduct.FELIX,
+ DeviceProduct.COMET,
+ )
+ fun isTabletShouldBeTrue() {
+ assertTrue(mLauncher.isTablet)
+ }
+
+ /** Investigating b/366237798 by isolating and seeing flake rate of mLauncher.isTablet */
+ @Test
+ @AllowedDevices(DeviceProduct.CF_PHONE, DeviceProduct.CHEETAH)
+ fun isTabletShouldBeFalse() {
+ assertFalse(mLauncher.isTablet)
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
index 20c5a25..638ae7c 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
@@ -242,7 +242,6 @@
});
}
- @ScreenRecordRule.ScreenRecord // b/329935119
@Test
@PortraitLandscape
public void testEmptyPageDoesNotGetRemovedIfPagePairIsNotEmpty() {
diff --git a/tests/tapl/com/android/launcher3/tapl/Taskbar.java b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
index e6315f3..b4aaab7 100644
--- a/tests/tapl/com/android/launcher3/tapl/Taskbar.java
+++ b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
@@ -52,7 +52,7 @@
if (!mLauncher.isTransientTaskbar()) {
Assert.assertEquals("Persistent taskbar should fill screen width",
- getVisibleBounds().width(), mLauncher.getRealDisplaySize().x);
+ mLauncher.getRealDisplaySize().x, getVisibleBounds().width());
}
}