diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index 72218bf26e..8c92c7db49 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -135,8 +135,7 @@ public class QuickstepAtomicAnimationFactory extends config.duration = Math.max(config.duration, scrollDuration); // Sync scroll so that it ends before or at the same time as the taskbar animation. - if (DisplayController.isTransientTaskbar(mActivity) - && mActivity.getDeviceProfile().isTaskbarPresent) { + if (mActivity.getDeviceProfile().isTaskbarPresent) { config.duration = Math.min(config.duration, TASKBAR_TO_HOME_DURATION); } overview.snapToPage(DEFAULT_PAGE, Math.toIntExact(config.duration)); diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index 36bdad4da4..62ce341e41 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -328,11 +328,15 @@ public interface TaskShortcutFactory { // No "save app pair" menu item if: // - app pairs feature is not enabled + // - we are in 3p launcher // - the task in question is a single task // - at least one app in app pair is unpinnable // - the Overview Actions Button should be visible - if (!FeatureFlags.enableAppPairs() || !taskView.containsMultipleTasks() - || hasUnpinnableApp || shouldShowActionsButtonInstead) { + if (!FeatureFlags.enableAppPairs() + || !recentsView.supportsAppPairs() + || !taskView.containsMultipleTasks() + || hasUnpinnableApp + || shouldShowActionsButtonInstead) { return null; } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 415f73f1aa..788012445b 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -40,7 +40,6 @@ import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_MOVE; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_UP; -import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.RECENTS_ANIMATION_START_PENDING; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER; @@ -734,15 +733,17 @@ public class TouchInteractionService extends Service { // an ACTION_HOVER_ENTER will fire as well. boolean isHoverActionWithoutConsumer = enableCursorHoverStates() && isHoverActionWithoutConsumer(event); - if (mTaskAnimationManager.isRecentsAnimationStartPending() - && (action == ACTION_DOWN || isHoverActionWithoutConsumer)) { - ActiveGestureLog.INSTANCE.addLog( - new CompoundString("TIS.onInputEvent: ") - .append("Cannot process input event: a recents animation has been ") - .append("requested, but hasn't started."), - RECENTS_ANIMATION_START_PENDING); - return; - } + + // TODO(b/285636175): Uncomment this once WM can properly guarantee all animation callbacks +// if (mTaskAnimationManager.isRecentsAnimationStartPending() +// && (action == ACTION_DOWN || isHoverActionWithoutConsumer)) { +// ActiveGestureLog.INSTANCE.addLog( +// new CompoundString("TIS.onInputEvent: ") +// .append("Cannot process input event: a recents animation has been ") +// .append("requested, but hasn't started."), +// RECENTS_ANIMATION_START_PENDING); +// return; +// } SafeCloseable traceToken = TraceHelper.INSTANCE.allowIpcs("TIS.onInputEvent"); diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java index 8a87f63aaf..69de3b0f98 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java @@ -45,8 +45,7 @@ public class FallbackNavBarTouchController implements TouchController, NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode, DisplayController.INSTANCE.get(mActivity).getInfo()); mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity, - true /* disableHorizontalSwipe */, navBarPosition, - null /* onInterceptTouch */, this); + true /* disableHorizontalSwipe */, navBarPosition, this); } else { mTriggerSwipeUpTracker = null; } @@ -78,7 +77,4 @@ public class FallbackNavBarTouchController implements TouchController, public void onSwipeUp(boolean wasFling, PointF finalVelocity) { mActivity.getOverviewPanel().startHome(); } - - @Override - public void onSwipeUpCancelled() {} } diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index 0ee50a46b2..32d8be988c 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -302,4 +302,10 @@ public class FallbackRecentsView extends RecentsView= mSquaredTouchSlop; } - if (mOnSwipeUp != null) { - if (isSwipeUp) { - mOnSwipeUp.onSwipeUp(wasFling, new PointF(velocityX, velocityY)); - } else { - mOnSwipeUp.onSwipeUpCancelled(); - } + if (isSwipeUp) { + mOnSwipeUp.onSwipeUp(wasFling, new PointF(velocityX, velocityY)); + } else { + mOnSwipeUp.onSwipeUpCancelled(); } } @@ -172,6 +169,9 @@ public class TriggerSwipeUpTouchTracker { void onSwipeUp(boolean wasFling, PointF finalVelocity); /** Called on touch up if a swipe up was not detected. */ - void onSwipeUpCancelled(); + default void onSwipeUpCancelled() { } + + /** Called when the touch for swipe up is intercepted. */ + default void onSwipeUpTouchIntercepted() { } } } diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index 7a1c49a213..e0091a5ae2 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -106,6 +106,7 @@ public class OverviewActionsView extends FrameLayo public @interface AppPairButtonHiddenFlags { } public static final int FLAG_SINGLE_TASK_HIDE_APP_PAIR = 1 << 0; public static final int FLAG_SMALL_SCREEN_HIDE_APP_PAIR = 1 << 1; + public static final int FLAG_3P_LAUNCHER_HIDE_APP_PAIR = 1 << 2; private MultiValueAlpha mMultiValueAlpha; @@ -254,6 +255,13 @@ public class OverviewActionsView extends FrameLayo updateAppPairButtonHiddenFlags(FLAG_SMALL_SCREEN_HIDE_APP_PAIR, isSmallScreen); } + /** + * Updates flags to hide and show actions buttons for 1p/3p launchers. + */ + public void updateFor3pLauncher(boolean is3pLauncher) { + updateAppPairButtonHiddenFlags(FLAG_3P_LAUNCHER_HIDE_APP_PAIR, is3pLauncher); + } + /** * Updates the proper flags to indicate whether the "Screenshot" button should be hidden. * diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 2cbeb31fbd..133749d601 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4022,6 +4022,8 @@ public abstract class RecentsView callback, boolean isQuickswitch) { if (mTask != null) { + testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS, "TaskView.launchTaskAnimated"); TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask); diff --git a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java index 37dde10d0e..8702f70dfe 100644 --- a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java +++ b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.model; +import static android.content.pm.ApplicationInfo.CATEGORY_PRODUCTIVITY; +import static android.content.pm.ApplicationInfo.FLAG_INSTALLED; import static android.os.Process.myUserHandle; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION; @@ -37,6 +39,8 @@ import android.app.prediction.AppTargetId; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; +import android.content.pm.ApplicationInfo; +import android.content.pm.LauncherApps; import android.os.UserHandle; import android.platform.test.flag.junit.SetFlagsRule; import android.text.TextUtils; @@ -81,6 +85,8 @@ public final class WidgetsPredicationUpdateTaskTest { private FakeBgDataModelCallback mCallback = new FakeBgDataModelCallback(); private LauncherModelHelper mModelHelper; private UserHandle mUserHandle; + private LauncherApps mLauncherApps; + @Before public void setup() throws Exception { @@ -103,12 +109,18 @@ public final class WidgetsPredicationUpdateTaskTest { allWidgets = Arrays.asList(mApp1Provider1, mApp1Provider2, mApp2Provider1, mApp4Provider1, mApp4Provider2, mApp5Provider1); + mLauncherApps = mModelHelper.sandboxContext.spyService(LauncherApps.class); doAnswer(i -> { String pkg = i.getArgument(0); - return ApplicationInfoBuilder.newBuilder().setPackageName(pkg).setName( - "App " + pkg).build(); - }).when(mModelHelper.sandboxContext.getPackageManager()) - .getApplicationInfo(anyString(), anyInt()); + ApplicationInfo applicationInfo = ApplicationInfoBuilder.newBuilder() + .setPackageName(pkg) + .setName("App " + pkg) + .build(); + applicationInfo.category = CATEGORY_PRODUCTIVITY; + applicationInfo.flags = FLAG_INSTALLED; + return applicationInfo; + }).when(mLauncherApps).getApplicationInfo(anyString(), anyInt(), any()); + AppWidgetManager manager = mModelHelper.sandboxContext.spyService(AppWidgetManager.class); doReturn(allWidgets).when(manager).getInstalledProviders(); doReturn(allWidgets).when(manager).getInstalledProvidersForProfile(eq(myUserHandle())); diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index 213f58fa8b..077ca60aae 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -76,17 +76,21 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.junit.runners.model.Statement; +import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @LargeTest @RunWith(AndroidJUnit4.class) public class FallbackRecentsTest { private static final String FALLBACK_LAUNCHER_TITLE = "Test launcher"; + private static final Pattern COMPONENT_INFO_REGEX = Pattern.compile("ComponentInfo\\{(.*)\\}"); private final UiDevice mDevice; private final LauncherInstrumentation mLauncher; @@ -253,7 +257,7 @@ public class FallbackRecentsTest { //@NavigationModeSwitch @Test @ScreenRecordRule.ScreenRecord // b/321775748 - public void testOverview() { + public void testOverview() throws IOException { startAppFast(getAppPackageName()); startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); startTestActivity(2); @@ -261,7 +265,10 @@ public class FallbackRecentsTest { Wait.atMost("Expected three apps in the task list", () -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher); + checkTestLauncher(); BaseOverview overview = mLauncher.getLaunchedAppState().switchToOverview(); + checkTestLauncher(); + executeOnRecents(recents -> { assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3); }); @@ -303,6 +310,17 @@ public class FallbackRecentsTest { mOtherLauncherActivity.packageName).text(FALLBACK_LAUNCHER_TITLE)), WAIT_TIME_MS)); } + private void checkTestLauncher() throws IOException { + final Matcher matcher = COMPONENT_INFO_REGEX.matcher( + mDevice.executeShellCommand("cmd shortcut get-default-launcher")); + assertTrue("Incorrect output from get-default-launcher", matcher.find()); + assertEquals("Current Launcher activity is incorrect", + "com.google.android.apps.nexuslauncher.tests/com.android" + + ".launcher3.testcomponent.TestLauncherActivity", + matcher.group(1) + ); + } + private int getCurrentOverviewPage(RecentsActivity recents) { return recents.getOverviewPanel().getCurrentPage(); } diff --git a/res/values/strings.xml b/res/values/strings.xml index aaef15b2af..7bf1c87830 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -75,12 +75,14 @@ Suggestions - Your Daily Essentials - News For You + Essentials + News & magazines Your Chill Zone - Reach Your Fitness Goals - Stay Ahead of the Weather - You Might Also Like + Entertainment + Social + Health & fitness + Weather + Suggested for you %1$s widgets on right, search and options on left