Merge "Fix overview and quickswitch gesture logging" into tm-dev
diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
index 5c66944..9f3be69 100644
--- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java
+++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
@@ -62,6 +62,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
+import com.android.launcher3.Utilities;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.FolderContainer;
@@ -116,7 +117,8 @@
@AnyThread
private void sendEvent(AppTarget target, LauncherAtom.ItemInfo locationInfo, int eventId,
int targetPredictor) {
- if (target != null) {
+ // TODO: remove the running test check when b/231648228 is fixed.
+ if (target != null && !Utilities.IS_RUNNING_IN_TEST_HARNESS) {
AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
.setLaunchLocation(getContainer(locationInfo))
.build();
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 2d7ce32..c4837a0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -62,7 +62,7 @@
PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
mOpenCloseAnimator.setDuration(
- ALL_APPS.getTransitionDuration(mContext, true /* isToState */)).start();
+ ALL_APPS.getTransitionDuration(mActivityContext, true /* isToState */)).start();
} else {
mTranslationShift = TRANSLATION_SHIFT_OPENED;
}
@@ -81,7 +81,8 @@
@Override
protected void handleClose(boolean animate) {
Optional.ofNullable(mOnCloseBeginListener).ifPresent(OnCloseListener::onSlideInViewClosed);
- handleClose(animate, ALL_APPS.getTransitionDuration(mContext, false /* isToState */));
+ handleClose(animate,
+ ALL_APPS.getTransitionDuration(mActivityContext, false /* isToState */));
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 621dfb8..7b01670 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,6 +20,7 @@
import android.content.Context;
+import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
@@ -38,8 +39,11 @@
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
- return isToState ? 500 : 300;
+ public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
+ int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
+ return !context.getDeviceProfile().isTablet && isToState
+ ? 600
+ : isToState ? 500 : 300;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 5acce89..13389c0 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
+import static com.android.launcher3.PagedView.INVALID_PAGE;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
@@ -66,6 +67,7 @@
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
@@ -926,7 +928,13 @@
mLogDirectionUpOrLeft = velocity.x < 0;
}
mDownPos = downPos;
- handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */);
+ Runnable handleNormalGestureEndCallback = () ->
+ handleNormalGestureEnd(endVelocity, isFling, velocity, /* isCancel= */ false);
+ if (mRecentsView != null) {
+ mRecentsView.runOnPageScrollsInitialized(handleNormalGestureEndCallback);
+ } else {
+ handleNormalGestureEndCallback.run();
+ }
}
private void endRunningWindowAnim(boolean cancel) {
@@ -1130,6 +1138,13 @@
} else if (endTarget == RECENTS) {
if (mRecentsView != null) {
int nearestPage = mRecentsView.getDestinationPage();
+ if (nearestPage == INVALID_PAGE) {
+ // Allow the snap to invalid page to catch future error cases.
+ Log.e(TAG,
+ "RecentsView destination page is invalid",
+ new IllegalStateException());
+ }
+
boolean isScrolling = false;
if (mRecentsView.getNextPage() != nearestPage) {
// We shouldn't really scroll to the next page when swiping up to recents.
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 48127c0..6745246 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -84,6 +84,8 @@
private STATE_TYPE mTargetState;
+ @Nullable private Runnable mOnInitBackgroundStateUICallback = null;
+
protected BaseActivityInterface(boolean rotationSupportedByActivity,
STATE_TYPE overviewState, STATE_TYPE backgroundState) {
this.rotationSupportedByActivity = rotationSupportedByActivity;
@@ -408,6 +410,21 @@
return null;
}
+ protected void runOnInitBackgroundStateUI(Runnable callback) {
+ mOnInitBackgroundStateUICallback = callback;
+ ACTIVITY_TYPE activity = getCreatedActivity();
+ if (activity != null && activity.getStateManager().getState() == mBackgroundState) {
+ onInitBackgroundStateUI();
+ }
+ }
+
+ private void onInitBackgroundStateUI() {
+ if (mOnInitBackgroundStateUICallback != null) {
+ mOnInitBackgroundStateUICallback.run();
+ mOnInitBackgroundStateUICallback = null;
+ }
+ }
+
public interface AnimationFactory {
void createActivityInterface(long transitionLength);
@@ -447,13 +464,14 @@
mStartState = mActivity.getStateManager().getState();
}
- protected ACTIVITY_TYPE initUI() {
+ protected ACTIVITY_TYPE initBackgroundStateUI() {
STATE_TYPE resetState = mStartState;
if (mStartState.shouldDisableRestore()) {
resetState = mActivity.getStateManager().getRestState();
}
mActivity.getStateManager().setRestState(resetState);
mActivity.getStateManager().goToState(mBackgroundState, false);
+ onInitBackgroundStateUI();
return mActivity;
}
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 7feec2c..ba61574 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -89,7 +89,7 @@
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
- factory.initUI();
+ factory.initBackgroundStateUI();
return factory;
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 10a3a2e..c13b95f 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -135,7 +135,7 @@
}
};
- BaseQuickstepLauncher launcher = factory.initUI();
+ BaseQuickstepLauncher launcher = factory.initBackgroundStateUI();
// Since all apps is not visible, we can safely reset the scroll position.
// This ensures then the next swipe up to all-apps starts from scroll 0.
launcher.getAppsView().reset(false /* animate */);
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 42f9eb6..dffdc5a 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -217,7 +217,8 @@
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
- interactionHandler.onGestureEnded(0, new PointF(), new PointF());
+ activityInterface.runOnInitBackgroundStateUI(() ->
+ interactionHandler.onGestureEnded(0, new PointF(), new PointF()));
cmd.removeListener(this);
}
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 10c56c9..85ef6cb 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -130,7 +130,7 @@
if (IS_VERBOSE) {
Log.d(TAG, String.format("\nwriteSnapshot(%d):\n%s", instanceId.getId(), info));
}
- if (!Utilities.ATLEAST_R) {
+ if (!Utilities.ATLEAST_R || Utilities.IS_RUNNING_IN_TEST_HARNESS) {
return;
}
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
@@ -415,6 +415,10 @@
consumer.consume(event, atomInfo);
}
+ // TODO: remove this when b/231648228 is fixed.
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ return;
+ }
SysUiStatsLog.write(
SysUiStatsLog.LAUNCHER_EVENT,
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
@@ -510,6 +514,9 @@
}
private static int getCardinality(LauncherAtom.ItemInfo info) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ return 0;
+ }
switch (info.getContainerInfo().getContainerCase()) {
case PREDICTED_HOTSEAT_CONTAINER:
return info.getContainerInfo().getPredictedHotseatContainer().getCardinality();
@@ -625,6 +632,9 @@
}
private static int getHierarchy(LauncherAtom.ItemInfo info) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ return 0;
+ }
if (info.getContainerInfo().getContainerCase() == FOLDER) {
return info.getContainerInfo().getFolder().getParentContainerCase().getNumber()
+ FOLDER_HIERARCHY_OFFSET;
@@ -665,6 +675,9 @@
}
private static int getSearchAttributes(LauncherAtom.ItemInfo info) {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ return 0;
+ }
ContainerInfo containerInfo = info.getContainerInfo();
if (containerInfo.getContainerCase() == EXTENDED_CONTAINERS
&& containerInfo.getExtendedContainers().getContainerCase()
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 72f4221..b634518 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -946,7 +946,7 @@
mHasVisibleTaskData.delete(i);
}
if (child instanceof GroupedTaskView) {
- mGroupedTaskViewPool.recycle((GroupedTaskView)taskView);
+ mGroupedTaskViewPool.recycle((GroupedTaskView) taskView);
} else {
mTaskViewPool.recycle(taskView);
}
@@ -1855,17 +1855,18 @@
if (!mActivity.getDeviceProfile().isTablet) {
return super.getDestinationPage(scaledScroll);
}
-
- final int childCount = getChildCount();
- if (mPageScrolls == null || childCount != mPageScrolls.length) {
- return -1;
+ if (!pageScrollsInitialized()) {
+ Log.e(TAG,
+ "Cannot get destination page: RecentsView not properly initialized",
+ new IllegalStateException());
+ return INVALID_PAGE;
}
// When in tablet with variable task width, return the page which scroll is closest to
// screenStart instead of page nearest to center of screen.
int minDistanceFromScreenStart = Integer.MAX_VALUE;
- int minDistanceFromScreenStartIndex = -1;
- for (int i = 0; i < childCount; ++i) {
+ int minDistanceFromScreenStartIndex = INVALID_PAGE;
+ for (int i = 0; i < getChildCount(); ++i) {
int distanceFromScreenStart = Math.abs(mPageScrolls[i] - scaledScroll);
if (distanceFromScreenStart < minDistanceFromScreenStart) {
minDistanceFromScreenStart = distanceFromScreenStart;
@@ -4051,7 +4052,7 @@
// TODO(194414938) starting bounds seem slightly off, investigate
Rect firstTaskStartingBounds = new Rect();
Rect firstTaskEndingBounds = mTempRect;
- int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext(),
+ int duration = mActivity.getStateManager().getState().getTransitionDuration(mActivity,
false /* isToState */);
PendingAnimation pendingAnimation = new PendingAnimation(duration);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 4d38822..4bf247c 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -52,6 +52,8 @@
public class TaplTestsQuickstep extends AbstractQuickStepTest {
private static final String APP_NAME = "LauncherTestApp";
+ private static final String CALCULATOR_APP_PACKAGE =
+ resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
@Before
public void setUp() throws Exception {
@@ -73,7 +75,7 @@
public static void startTestApps() throws Exception {
startAppFast(getAppPackageName());
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ startAppFast(CALCULATOR_APP_PACKAGE);
startTestActivity(2);
}
@@ -207,7 +209,7 @@
@NavigationModeSwitch
@PortraitLandscape
public void testBackground() throws Exception {
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ startAppFast(CALCULATOR_APP_PACKAGE);
final LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
assertNotNull("Background.switchToOverview() returned null",
@@ -302,7 +304,7 @@
mLauncher.getWorkspace();
waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ startAppFast(CALCULATOR_APP_PACKAGE);
mLauncher.pressBack();
mLauncher.getWorkspace();
waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2ad1d47..ad87451 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1279,13 +1279,16 @@
* @param info The data structure describing the shortcut.
*/
View createShortcut(WorkspaceItemInfo info) {
- return createShortcut((ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);
+ // This can be called before PagedView#pageScrollsInitialized returns true, so use the
+ // first page, which we always assume to be present.
+ return createShortcut((ViewGroup) mWorkspace.getChildAt(0), info);
}
/**
* Creates a view representing a shortcut inflated from the specified resource.
*
- * @param parent The group the shortcut belongs to.
+ * @param parent The group the shortcut belongs to. This is not necessarily the group where
+ * the shortcut should be added.
* @param info The data structure describing the shortcut.
* @return A View inflated from layoutResId.
*/
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 0a1d25c..95a8a2a 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -129,7 +129,10 @@
private boolean mAllowEasyFling;
protected PagedOrientationHandler mOrientationHandler = PagedOrientationHandler.PORTRAIT;
- protected int[] mPageScrolls;
+ private final ArrayList<Runnable> mOnPageScrollsInitializedCallbacks = new ArrayList<>();
+
+ // We should always check pageScrollsInitialized() is true when using mPageScrolls.
+ @Nullable protected int[] mPageScrolls = null;
private boolean mIsBeingDragged;
// The amount of movement to begin scrolling
@@ -684,14 +687,37 @@
setMeasuredDimension(widthSize, heightSize);
}
+ /** Returns true iff this PagedView's scroll amounts are initialized to each page index. */
+ protected boolean pageScrollsInitialized() {
+ return mPageScrolls != null && mPageScrolls.length == getChildCount();
+ }
+
+ /**
+ * Queues the given callback to be run once {@code mPageScrolls} has been initialized.
+ */
+ public void runOnPageScrollsInitialized(Runnable callback) {
+ mOnPageScrollsInitializedCallbacks.add(callback);
+ if (pageScrollsInitialized()) {
+ onPageScrollsInitialized();
+ }
+ }
+
+ private void onPageScrollsInitialized() {
+ for (Runnable callback : mOnPageScrollsInitializedCallbacks) {
+ callback.run();
+ }
+ mOnPageScrollsInitializedCallbacks.clear();
+ }
+
@SuppressLint("DrawAllocation")
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
mIsLayoutValid = true;
final int childCount = getChildCount();
+ int[] pageScrolls = mPageScrolls;
boolean pageScrollChanged = false;
- if (mPageScrolls == null || childCount != mPageScrolls.length) {
- mPageScrolls = new int[childCount];
+ if (!pageScrollsInitialized()) {
+ pageScrolls = new int[childCount];
pageScrollChanged = true;
}
@@ -701,10 +727,8 @@
if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
- boolean isScrollChanged = getPageScrolls(mPageScrolls, true, SIMPLE_SCROLL_LOGIC);
- if (isScrollChanged) {
- pageScrollChanged = true;
- }
+ pageScrollChanged |= getPageScrolls(pageScrolls, true, SIMPLE_SCROLL_LOGIC);
+ mPageScrolls = pageScrolls;
final LayoutTransition transition = getLayoutTransition();
// If the transition is running defer updating max scroll, as some empty pages could
@@ -738,6 +762,7 @@
if (mScroller.isFinished() && pageScrollChanged) {
setCurrentPage(getNextPage());
}
+ onPageScrollsInitialized();
}
/**
@@ -849,8 +874,10 @@
@Override
public void onViewRemoved(View child) {
super.onViewRemoved(child);
- mCurrentPage = validateNewPage(mCurrentPage);
- mCurrentScrollOverPage = mCurrentPage;
+ runOnPageScrollsInitialized(() -> {
+ mCurrentPage = validateNewPage(mCurrentPage);
+ mCurrentScrollOverPage = mCurrentPage;
+ });
dispatchPageCountChanged();
}
@@ -1153,7 +1180,7 @@
}
public int getScrollForPage(int index) {
- if (mPageScrolls == null || index >= mPageScrolls.length || index < 0) {
+ if (!pageScrollsInitialized() || index >= mPageScrolls.length || index < 0) {
return 0;
} else {
return mPageScrolls[index];
@@ -1163,7 +1190,7 @@
// While layout transitions are occurring, a child's position may stray from its baseline
// position. This method returns the magnitude of this stray at any given time.
public int getLayoutTransitionOffsetForPage(int index) {
- if (mPageScrolls == null || index >= mPageScrolls.length || index < 0) {
+ if (!pageScrollsInitialized() || index >= mPageScrolls.length || index < 0) {
return 0;
} else {
View child = getChildAt(index);
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 4ff5d5e..f8a2c79 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -156,14 +156,18 @@
String.format("upperBound (%f) must be greater than lowerBound (%f)",
upperBound, lowerBound));
}
- return t -> clampToProgress(t, lowerBound, upperBound);
+ return t -> clampToProgress(interpolator, t, lowerBound, upperBound);
}
/**
* Returns the progress value's progress between the lower and upper bounds. That is, the
* progress will be 0f from 0f to lowerBound, and reach 1f by upperBound.
+ *
+ * Between lowerBound and upperBound, the progress value will be interpolated using the provided
+ * interpolator.
*/
- public static float clampToProgress(float progress, float lowerBound, float upperBound) {
+ public static float clampToProgress(
+ Interpolator interpolator, float progress, float lowerBound, float upperBound) {
if (upperBound < lowerBound) {
throw new IllegalArgumentException(
String.format("upperBound (%f) must be greater than lowerBound (%f)",
@@ -179,7 +183,15 @@
if (progress > upperBound) {
return 1;
}
- return (progress - lowerBound) / (upperBound - lowerBound);
+ return interpolator.getInterpolation((progress - lowerBound) / (upperBound - lowerBound));
+ }
+
+ /**
+ * Returns the progress value's progress between the lower and upper bounds. That is, the
+ * progress will be 0f from 0f to lowerBound, and reach 1f by upperBound.
+ */
+ public static float clampToProgress(float progress, float lowerBound, float upperBound) {
+ return clampToProgress(Interpolators.LINEAR, progress, lowerBound, upperBound);
}
/**
diff --git a/src/com/android/launcher3/statemanager/BaseState.java b/src/com/android/launcher3/statemanager/BaseState.java
index 4a68dda..f9a36ad 100644
--- a/src/com/android/launcher3/statemanager/BaseState.java
+++ b/src/com/android/launcher3/statemanager/BaseState.java
@@ -18,6 +18,7 @@
import android.content.Context;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
/**
* Interface representing a state of a StatefulActivity
@@ -36,7 +37,8 @@
/**
* @return How long the animation to this state should take (or from this state to NORMAL).
*/
- int getTransitionDuration(Context context, boolean isToState);
+ <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
+ int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState);
/**
* Returns the state to go back to from this state
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index 2f8e680..52a6759 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,6 +20,7 @@
import android.content.Context;
+import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
@@ -39,8 +40,11 @@
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
- return isToState ? 500 : 300;
+ public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
+ int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
+ return !context.getDeviceProfile().isTablet && isToState
+ ? 600
+ : isToState ? 500 : 300;
}
@Override
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
new file mode 100644
index 0000000..5f92199
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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.tapl;
+
+/**
+ * Operations on home screen qsb.
+ */
+public class HomeQsb {
+
+ private final LauncherInstrumentation mLauncher;
+
+ HomeQsb(LauncherInstrumentation launcher) {
+ mLauncher = launcher;
+ mLauncher.waitForLauncherObject("search_container_hotseat");
+ }
+
+ /**
+ * Show search result page from tapping qsb.
+ */
+ public SearchResultFromQsb showSearchResult() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to open search result page");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.clickLauncherObject(
+ mLauncher.waitForLauncherObject("search_container_hotseat"));
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "clicked qsb to open search result page")) {
+ return new SearchResultFromQsb(mLauncher);
+ }
+ }
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 45a0196..39cd4ff 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -33,7 +33,7 @@
/**
* Ancestor for AppIcon and AppMenuItem.
*/
-abstract class Launchable {
+public abstract class Launchable {
protected static final int DEFAULT_DRAG_STEPS = 10;
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
new file mode 100644
index 0000000..82652c7
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 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.tapl;
+
+import android.widget.TextView;
+
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiObject2;
+
+/**
+ * Operations on search result page opened from home screen qsb.
+ */
+public class SearchResultFromQsb {
+ // The input resource id in the search box.
+ private static final String INPUT_RES = "input";
+ private final LauncherInstrumentation mLauncher;
+
+ SearchResultFromQsb(LauncherInstrumentation launcher) {
+ mLauncher = launcher;
+ mLauncher.waitForLauncherObject("search_container_all_apps");
+ }
+
+ /** Set the input to the search input edit text and update search results. */
+ public void searchForInput(String input) {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to search for result with an input");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.waitForLauncherObject(INPUT_RES).setText(input);
+ }
+ }
+
+ /** Find the app from search results with app name. */
+ public Launchable findAppIcon(String appName) {
+ UiObject2 icon = mLauncher.waitForLauncherObject(By.clazz(TextView.class).text(appName));
+ return new AllAppsAppIcon(mLauncher, icon);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index b0b42ba..954af3d 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -112,6 +112,18 @@
}
/**
+ * Returns the home qsb.
+ *
+ * The qsb must already be visible when calling this method.
+ */
+ public HomeQsb getQsb() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to get the home qsb")) {
+ return new HomeQsb(mLauncher);
+ }
+ }
+
+ /**
* Returns an icon for the app, if currently visible.
*
* @param appName name of the app