Merge "Fix two panel tapl test dragging issue"
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 59ade49..099915a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -221,13 +221,9 @@
* @return true if the event is over the hotseat
*/
static boolean isTouchOverHotseat(Launcher launcher, MotionEvent ev) {
- return (ev.getY() >= getHotseatTop(launcher));
- }
-
- public static int getHotseatTop(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
- return launcher.getDragLayer().getHeight() - hotseatHeight;
+ return (ev.getY() >= (launcher.getDragLayer().getHeight() - hotseatHeight));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 4c570f1..ef81449 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -7,11 +7,9 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.LauncherState;
import com.android.launcher3.testing.TestInformationHandler;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
import com.android.quickstep.util.LayoutUtils;
public class QuickstepTestInformationHandler extends TestInformationHandler {
@@ -26,15 +24,6 @@
public Bundle call(String method, String arg, @Nullable Bundle extras) {
final Bundle response = new Bundle();
switch (method) {
- case TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT: {
- return getLauncherUIProperty(Bundle::putInt, l -> {
- final float progress = LauncherState.OVERVIEW.getVerticalProgress(l)
- - LauncherState.ALL_APPS.getVerticalProgress(l);
- final float distance = l.getAllAppsController().getShiftRange() * progress;
- return (int) distance;
- });
- }
-
case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: {
final float swipeHeight =
LayoutUtils.getDefaultSwipeHeight(mContext, mDeviceProfile);
@@ -50,11 +39,6 @@
return response;
}
- case TestProtocol.REQUEST_HOTSEAT_TOP: {
- return getLauncherUIProperty(
- Bundle::putInt, PortraitStatesTouchController::getHotseatTop);
- }
-
case TestProtocol.REQUEST_GET_FOCUSED_TASK_HEIGHT_FOR_TABLET: {
if (!mDeviceProfile.isTablet) {
return null;
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 49e4bd3..307c51f 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -192,13 +192,12 @@
}
public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds,
- View viewToCover, boolean fadeWithThumbnail) {
+ boolean fadeWithThumbnail) {
final BaseDragLayer dragLayer = mActivity.getDragLayer();
int[] dragLayerBounds = new int[2];
dragLayer.getLocationOnScreen(dragLayerBounds);
SplitOverlayProperties prop = new SplitOverlayProperties(endBounds,
- startingBounds, viewToCover, dragLayerBounds[0],
- dragLayerBounds[1]);
+ startingBounds, dragLayerBounds[0], dragLayerBounds[1]);
ValueAnimator transitionAnimator = ValueAnimator.ofFloat(0, 1);
animation.add(transitionAnimator);
@@ -221,10 +220,10 @@
initialWindowRadius, 0, animDuration, LINEAR);
final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, LINEAR);
final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, LINEAR);
- final FloatProp mTaskViewScaleX = new FloatProp(prop.initialTaskViewScaleX,
- prop.finalTaskViewScaleX, 0, animDuration, LINEAR);
- final FloatProp mTaskViewScaleY = new FloatProp(prop.initialTaskViewScaleY,
- prop.finalTaskViewScaleY, 0, animDuration, LINEAR);
+ final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0,
+ animDuration, LINEAR);
+ final FloatProp mTaskViewScaleY = new FloatProp(1f, prop.finalTaskViewScaleY, 0,
+ animDuration, LINEAR);
@Override
public void onUpdate(float percent, boolean initOnly) {
// Calculate the icon position.
@@ -241,24 +240,20 @@
private static class SplitOverlayProperties {
- private final float initialTaskViewScaleX;
- private final float initialTaskViewScaleY;
private final float finalTaskViewScaleX;
private final float finalTaskViewScaleY;
private final float dX;
private final float dY;
- SplitOverlayProperties(Rect endBounds, RectF startTaskViewBounds, View view,
+ SplitOverlayProperties(Rect endBounds, RectF startTaskViewBounds,
int dragLayerLeft, int dragLayerTop) {
float maxScaleX = endBounds.width() / startTaskViewBounds.width();
float maxScaleY = endBounds.height() / startTaskViewBounds.height();
- initialTaskViewScaleX = view.getScaleX();
- initialTaskViewScaleY = view.getScaleY();
finalTaskViewScaleX = maxScaleX;
finalTaskViewScaleY = maxScaleY;
- // Animate the app icon to the center of the window bounds in screen coordinates.
+ // Animate to the center of the window bounds in screen coordinates.
float centerX = endBounds.centerX() - dragLayerLeft;
float centerY = endBounds.centerY() - dragLayerTop;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b9ca6ca..a042bff 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2736,7 +2736,7 @@
));
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
- mTempRect, mSplitHiddenTaskView, true /*fadeWithThumbnail*/);
+ mTempRect, true /*fadeWithThumbnail*/);
} else {
mSplitSelectSource.view.setVisibility(INVISIBLE);
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
@@ -2744,7 +2744,7 @@
mSplitSelectSource.drawable, startingTaskRect, null /*additionalOffsetter*/);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
- mTempRect, mSplitSelectSource.view, true /*fadeWithThumbnail*/);
+ mTempRect, true /*fadeWithThumbnail*/);
}
anim.addEndListener(success -> {
if (success) {
@@ -4028,7 +4028,7 @@
mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
mFirstFloatingTaskView.addAnimation(pendingAnimation,
- new RectF(firstTaskStartingBounds), firstTaskEndingBounds, mFirstFloatingTaskView,
+ new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
false /*fadeWithThumbnail*/);
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
@@ -4040,8 +4040,7 @@
));
mSecondFloatingTaskView.setAlpha(1);
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
- secondTaskEndingBounds, taskView.getThumbnail(),
- true /*fadeWithThumbnail*/);
+ secondTaskEndingBounds, true /*fadeWithThumbnail*/);
pendingAnimation.addEndListener(aBoolean ->
mSplitSelectStateController.setSecondTaskId(taskView.getTask().key.id,
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index cdb8082..488789b 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -464,11 +464,15 @@
return getItemInfo(mTask);
}
- protected WorkspaceItemInfo getItemInfo(Task task) {
- ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
+ protected WorkspaceItemInfo getItemInfo(@Nullable Task task) {
WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
+ if (task == null) {
+ return stubInfo;
+ }
+
+ ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
stubInfo.user = componentKey.user;
stubInfo.intent = new Intent().setComponent(componentKey.componentName);
stubInfo.title = task.title;
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index cba4833..4529217 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -165,7 +165,7 @@
assertTrue("Fallback Launcher not visible", mDevice.wait(Until.hasObject(By.pkg(
mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
- mLauncher.getBackground().switchToOverview();
+ mLauncher.getLaunchedAppState().switchToOverview();
}
// b/143488140
@@ -174,7 +174,7 @@
public void goToOverviewFromApp() {
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.getBackground().switchToOverview();
+ mLauncher.getLaunchedAppState().switchToOverview();
}
protected void executeOnRecents(Consumer<RecentsActivity> f) {
@@ -200,7 +200,7 @@
private BaseOverview pressHomeAndGoToOverview() {
mDevice.pressHome();
- return mLauncher.getBackground().switchToOverview();
+ return mLauncher.getLaunchedAppState().switchToOverview();
}
// b/143488140
@@ -213,7 +213,7 @@
Wait.atMost("Expected three apps in the task list",
() -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
- BaseOverview overview = mLauncher.getBackground().switchToOverview();
+ BaseOverview overview = mLauncher.getLaunchedAppState().switchToOverview();
executeOnRecents(recents -> {
assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3);
});
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 75d057e..5351963 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -78,7 +78,7 @@
closeLauncherActivity();
// The test action.
- mLauncher.getBackground().switchToOverview();
+ mLauncher.getLaunchedAppState().switchToOverview();
}
closeLauncherActivity();
mLauncher.pressHome();
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index e3198a8..396cb1b 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -32,8 +32,8 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.tapl.AllApps;
-import com.android.launcher3.tapl.Background;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.LaunchedAppState;
import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.OverviewActions;
@@ -84,7 +84,7 @@
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInBackground(launcher)));
+ isInLaunchedApp(launcher)));
}
@Test
@@ -136,7 +136,7 @@
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInBackground(launcher)));
+ isInLaunchedApp(launcher)));
// Test dismissing a task.
overview = mLauncher.pressHome().switchToOverview();
@@ -210,21 +210,22 @@
@PortraitLandscape
public void testBackground() throws Exception {
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- final Background background = getAndAssertBackground();
+ final LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
- assertNotNull("Background.switchToOverview() returned null", background.switchToOverview());
+ assertNotNull("Background.switchToOverview() returned null",
+ launchedAppState.switchToOverview());
assertTrue("Launcher internal state didn't switch to Overview",
isInState(() -> LauncherState.OVERVIEW));
}
- private Background getAndAssertBackground() {
- final Background background = mLauncher.getBackground();
- assertNotNull("Launcher.getBackground() returned null", background);
+ private LaunchedAppState getAndAssertLaunchedApp() {
+ final LaunchedAppState launchedAppState = mLauncher.getLaunchedAppState();
+ assertNotNull("Launcher.getLaunchedApp() returned null", launchedAppState);
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInBackground(launcher)));
- return background;
+ isInLaunchedApp(launcher)));
+ return launchedAppState;
}
@Test
@@ -253,13 +254,13 @@
startTestActivity(3);
startTestActivity(4);
- Background background = getAndAssertBackground();
- background.quickSwitchToPreviousApp();
+ LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
+ launchedAppState.quickSwitchToPreviousApp();
assertTrue("The first app we should have quick switched to is not running",
isTestActivityRunning(3));
- background = getAndAssertBackground();
- background.quickSwitchToPreviousApp();
+ launchedAppState = getAndAssertLaunchedApp();
+ launchedAppState.quickSwitchToPreviousApp();
if (mLauncher.getNavigationModel() == NavigationModel.THREE_BUTTON) {
// 3-button mode toggles between 2 apps, rather than going back further.
assertTrue("Second quick switch should have returned to the first app.",
@@ -268,13 +269,13 @@
assertTrue("The second app we should have quick switched to is not running",
isTestActivityRunning(2));
}
- background = getAndAssertBackground();
- background.quickSwitchToPreviousAppSwipeLeft();
+ launchedAppState = getAndAssertLaunchedApp();
+ launchedAppState.quickSwitchToPreviousAppSwipeLeft();
assertTrue("The 2nd app we should have quick switched to is not running",
isTestActivityRunning(3));
- background = getAndAssertBackground();
- background.switchToOverview();
+ launchedAppState = getAndAssertLaunchedApp();
+ launchedAppState.switchToOverview();
}
private boolean isTestActivityRunning(int activityNumber) {
@@ -291,7 +292,7 @@
mLauncher.pressHome().quickSwitchToPreviousApp();
assertTrue("The most recent task is not running after quick switching from home",
isTestActivityRunning(2));
- getAndAssertBackground();
+ getAndAssertLaunchedApp();
}
// TODO(b/204830798): test with all navigation modes(add @NavigationModeSwitch annotation)
@@ -306,7 +307,7 @@
mLauncher.getWorkspace();
waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
diff --git a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
index 0f5a1c8..661beda 100644
--- a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
+++ b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
@@ -51,7 +51,7 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.tapl.Background;
+import com.android.launcher3.tapl.LaunchedAppState;
import com.android.launcher3.testcomponent.ListViewService;
import com.android.launcher3.testcomponent.ListViewService.SimpleViewsFactory;
import com.android.launcher3.testcomponent.TestCommandReceiver;
@@ -119,13 +119,13 @@
try {
// Go to overview once so that all views are initialized and cached
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.getBackground().switchToOverview().dismissAllTasks();
+ mLauncher.getLaunchedAppState().switchToOverview().dismissAllTasks();
// Track view creations
mInitTracker.startTracking();
startTestActivity(2);
- mLauncher.getBackground().switchToOverview();
+ mLauncher.getLaunchedAppState().switchToOverview();
assertEquals("Views inflated during swipe up", 0, mInitTracker.viewInitCount);
} finally {
@@ -205,18 +205,18 @@
// Go to overview once so that all views are initialized and cached
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.getBackground().switchToOverview().dismissAllTasks();
+ mLauncher.getLaunchedAppState().switchToOverview().dismissAllTasks();
// Track view creations
mInitTracker.startTracking();
startTestActivity(2);
- Background background = mLauncher.getBackground();
+ LaunchedAppState launchedAppState = mLauncher.getLaunchedAppState();
// Update widget
updateBeforeSwipeUp.accept(widgetId);
- background.switchToOverview();
+ launchedAppState.switchToOverview();
assertEquals("Views inflated during swipe up", 0, mInitTracker.viewInitCount);
// Widget is updated when going home
diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml
index 0d2fce0..e42d0a3 100644
--- a/res/values-v31/styles.xml
+++ b/res/values-v31/styles.xml
@@ -87,6 +87,7 @@
<style name="HomeSettings.CollapsedToolbarTitle"
parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
<item name="android:fontFamily">google-sans</item>
+ <item name="android:textSize">20sp</item>
</style>
<style name="HomeSettings.ExpandedToolbarTitle" parent="HomeSettings.CollapsedToolbarTitle">
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index cbc21eb..9bc3d15 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -671,14 +671,15 @@
/**
* Returns the full drawable for info without any flattening or pre-processing.
*
- * @param outObj this is set to the internal data associated with {@param info},
+ * @param shouldThemeIcon If true, will theme icons when applicable
+ * @param outObj this is set to the internal data associated with {@code info},
* eg {@link LauncherActivityInfo} or {@link ShortcutInfo}.
*/
@TargetApi(Build.VERSION_CODES.TIRAMISU)
public static Drawable getFullDrawable(Context context, ItemInfo info, int width, int height,
- Object[] outObj) {
+ boolean shouldThemeIcon, Object[] outObj) {
Drawable icon = loadFullDrawableWithoutTheme(context, info, width, height, outObj);
- if (ATLEAST_T && icon instanceof AdaptiveIconDrawable) {
+ if (ATLEAST_T && icon instanceof AdaptiveIconDrawable && shouldThemeIcon) {
AdaptiveIconDrawable aid = (AdaptiveIconDrawable) icon.mutate();
Drawable mono = aid.getMonochrome();
if (mono != null && Themes.isThemedIconEnabled(context)) {
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 4588a04..8bfd774 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -216,7 +216,8 @@
Object[] outObj = new Object[1];
int w = mWidth;
int h = mHeight;
- Drawable dr = Utilities.getFullDrawable(mActivity, info, w, h, outObj);
+ Drawable dr = Utilities.getFullDrawable(mActivity, info, w, h,
+ true /* shouldThemeIcon */, outObj);
if (dr instanceof AdaptiveIconDrawable) {
int blurMargin = (int) mActivity.getResources()
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index f512ced..3129e2a 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -350,41 +350,101 @@
iconRequest.itemInfo.getTargetComponent()));
Trace.beginSection("loadIconSubsectionInBulk");
- try (Cursor c = createBulkQueryCursor(
- filteredList,
- /* user = */ sectionKey.first,
- /* useLowResIcons = */ sectionKey.second)) {
- int componentNameColumnIndex = c.getColumnIndexOrThrow(IconDB.COLUMN_COMPONENT);
- while (c.moveToNext()) {
- ComponentName cn = ComponentName.unflattenFromString(
- c.getString(componentNameColumnIndex));
- List<IconRequestInfo<T>> duplicateIconRequests =
- duplicateIconRequestsMap.get(cn);
-
- if (cn != null) {
- CacheEntry entry = cacheLocked(
- cn,
- /* user = */ sectionKey.first,
- () -> duplicateIconRequests.get(0).launcherActivityInfo,
- mLauncherActivityInfoCachingLogic,
- c,
- /* usePackageIcon= */ false,
- /* useLowResIcons = */ sectionKey.second);
-
- for (IconRequestInfo<T> iconRequest : duplicateIconRequests) {
- applyCacheEntry(entry, iconRequest.itemInfo);
- }
- }
- }
- } catch (SQLiteException e) {
- Log.d(TAG, "Error reading icon cache", e);
- } finally {
- Trace.endSection();
- }
+ loadIconSubsection(sectionKey, filteredList, duplicateIconRequestsMap);
+ Trace.endSection();
});
Trace.endSection();
}
+ private <T extends ItemInfoWithIcon> void loadIconSubsection(
+ Pair<UserHandle, Boolean> sectionKey,
+ List<IconRequestInfo<T>> filteredList,
+ Map<ComponentName, List<IconRequestInfo<T>>> duplicateIconRequestsMap) {
+ Trace.beginSection("loadIconSubsectionWithDatabase");
+ try (Cursor c = createBulkQueryCursor(
+ filteredList,
+ /* user = */ sectionKey.first,
+ /* useLowResIcons = */ sectionKey.second)) {
+ // Database title and icon loading
+ int componentNameColumnIndex = c.getColumnIndexOrThrow(IconDB.COLUMN_COMPONENT);
+ while (c.moveToNext()) {
+ ComponentName cn = ComponentName.unflattenFromString(
+ c.getString(componentNameColumnIndex));
+ List<IconRequestInfo<T>> duplicateIconRequests =
+ duplicateIconRequestsMap.get(cn);
+
+ if (cn != null) {
+ CacheEntry entry = cacheLocked(
+ cn,
+ /* user = */ sectionKey.first,
+ () -> duplicateIconRequests.get(0).launcherActivityInfo,
+ mLauncherActivityInfoCachingLogic,
+ c,
+ /* usePackageIcon= */ false,
+ /* useLowResIcons = */ sectionKey.second);
+
+ for (IconRequestInfo<T> iconRequest : duplicateIconRequests) {
+ applyCacheEntry(entry, iconRequest.itemInfo);
+ }
+ }
+ }
+ } catch (SQLiteException e) {
+ Log.d(TAG, "Error reading icon cache", e);
+ } finally {
+ Trace.endSection();
+ }
+
+ Trace.beginSection("loadIconSubsectionWithFallback");
+ // Fallback title and icon loading
+ for (ComponentName cn : duplicateIconRequestsMap.keySet()) {
+ IconRequestInfo<T> iconRequestInfo = duplicateIconRequestsMap.get(cn).get(0);
+ ItemInfoWithIcon itemInfo = iconRequestInfo.itemInfo;
+ BitmapInfo icon = itemInfo.bitmap;
+ boolean loadFallbackTitle = TextUtils.isEmpty(itemInfo.title);
+ boolean loadFallbackIcon = icon == null
+ || isDefaultIcon(icon, itemInfo.user)
+ || icon == BitmapInfo.LOW_RES_INFO;
+
+ if (loadFallbackTitle || loadFallbackIcon) {
+ Log.i(TAG,
+ "Database bulk icon loading failed, using fallback bulk icon loading "
+ + "for: " + cn);
+ CacheEntry entry = new CacheEntry();
+ LauncherActivityInfo lai = iconRequestInfo.launcherActivityInfo;
+
+ // Fill fields that are not updated below so they are not subsequently
+ // deleted.
+ entry.title = itemInfo.title;
+ if (icon != null) {
+ entry.bitmap = icon;
+ }
+ entry.contentDescription = itemInfo.contentDescription;
+
+ if (loadFallbackIcon) {
+ loadFallbackIcon(
+ lai,
+ entry,
+ mLauncherActivityInfoCachingLogic,
+ /* usePackageIcon= */ false,
+ /* usePackageTitle= */ loadFallbackTitle,
+ cn,
+ sectionKey.first);
+ }
+ if (loadFallbackTitle && TextUtils.isEmpty(entry.title)) {
+ loadFallbackTitle(
+ lai,
+ entry,
+ mLauncherActivityInfoCachingLogic,
+ sectionKey.first);
+ }
+
+ for (IconRequestInfo<T> iconRequest : duplicateIconRequestsMap.get(cn)) {
+ applyCacheEntry(entry, iconRequest.itemInfo);
+ }
+ }
+ }
+ Trace.endSection();
+ }
/**
* Fill in {@param infoInOut} with the corresponding icon and label.
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 4f40567..2bf3b14 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -75,13 +75,10 @@
"home-to-overview-swipe-height";
public static final String REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT =
"background-to-overview-swipe-height";
- public static final String REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT =
- "all-apps-to-overview-swipe-height";
public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT =
"home-to-all-apps-swipe-height";
public static final String REQUEST_ICON_HEIGHT =
"icon-height";
- public static final String REQUEST_HOTSEAT_TOP = "hotseat-top";
public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized";
public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list";
public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list";
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 106bb92..0f69530 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -247,11 +247,13 @@
* @param originalView The View that the FloatingIconView will replace.
* @param info ItemInfo of the originalView
* @param pos The position of the view.
+ * @param btvIcon The drawable of the BubbleTextView. May be null if original view is not a BTV
+ * @param outIconLoadResult We store the icon results into this object.
*/
@WorkerThread
@SuppressWarnings("WrongThread")
private static void getIconResult(Launcher l, View originalView, ItemInfo info, RectF pos,
- Drawable btvIcon, IconLoadResult iconLoadResult) {
+ @Nullable Drawable btvIcon, IconLoadResult outIconLoadResult) {
Drawable drawable;
boolean supportsAdaptiveIcons = !info.isDisabled(); // Use original icon for disabled icons.
@@ -271,7 +273,9 @@
int width = (int) pos.width();
int height = (int) pos.height();
if (supportsAdaptiveIcons) {
- drawable = getFullDrawable(l, info, width, height, sTmpObjArray);
+ boolean shouldThemeIcon = btvIcon instanceof FastBitmapDrawable
+ && ((FastBitmapDrawable) btvIcon).isThemed();
+ drawable = getFullDrawable(l, info, width, height, shouldThemeIcon, sTmpObjArray);
if (drawable instanceof AdaptiveIconDrawable) {
badge = getBadge(l, info, sTmpObjArray[0]);
} else {
@@ -284,24 +288,25 @@
// Similar to DragView, we simply use the BubbleTextView icon here.
drawable = btvIcon;
} else {
- drawable = getFullDrawable(l, info, width, height, sTmpObjArray);
+ drawable = getFullDrawable(l, info, width, height, true /* shouldThemeIcon */,
+ sTmpObjArray);
}
}
}
drawable = drawable == null ? null : drawable.getConstantState().newDrawable();
int iconOffset = getOffsetForIconBounds(l, drawable, pos);
- synchronized (iconLoadResult) {
- iconLoadResult.btvDrawable = btvIcon == null || drawable == btvIcon
+ synchronized (outIconLoadResult) {
+ outIconLoadResult.btvDrawable = btvIcon == null || drawable == btvIcon
? null : btvIcon.getConstantState().newDrawable();
- iconLoadResult.drawable = drawable;
- iconLoadResult.badge = badge;
- iconLoadResult.iconOffset = iconOffset;
- if (iconLoadResult.onIconLoaded != null) {
- l.getMainExecutor().execute(iconLoadResult.onIconLoaded);
- iconLoadResult.onIconLoaded = null;
+ outIconLoadResult.drawable = drawable;
+ outIconLoadResult.badge = badge;
+ outIconLoadResult.iconOffset = iconOffset;
+ if (outIconLoadResult.onIconLoaded != null) {
+ l.getMainExecutor().execute(outIconLoadResult.onIconLoaded);
+ outIconLoadResult.onIconLoaded = null;
}
- iconLoadResult.isIconLoaded = true;
+ outIconLoadResult.isIconLoaded = true;
}
}
@@ -528,8 +533,7 @@
btvIcon = null;
}
- IconLoadResult result = new IconLoadResult(info,
- btvIcon == null ? false : btvIcon.isThemed());
+ IconLoadResult result = new IconLoadResult(info, btvIcon != null && btvIcon.isThemed());
result.btvDrawable = btvIcon;
final long fetchIconId = sFetchIconId++;
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 5afbee2..79a4673 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -509,7 +509,7 @@
"Launcher still active", launcher -> launcher == null, DEFAULT_UI_TIMEOUT);
}
- protected boolean isInBackground(Launcher launcher) {
+ protected boolean isInLaunchedApp(Launcher launcher) {
return launcher == null || !launcher.hasBeenResumed();
}
@@ -549,7 +549,7 @@
ordinal == TestProtocol.NORMAL_STATE_ORDINAL);
break;
}
- case ALL_APPS: {
+ case HOME_ALL_APPS: {
assertTrue(
"Launcher is not resumed in state: " + expectedContainerType,
isResumed);
@@ -564,7 +564,7 @@
ordinal == TestProtocol.OVERVIEW_STATE_ORDINAL);
break;
}
- case BACKGROUND: {
+ case LAUNCHED_APP: {
assertTrue("Launcher is resumed in state: " + expectedContainerType,
!isResumed);
assertTrue(TestProtocol.stateOrdinalToString(ordinal),
@@ -577,10 +577,10 @@
}
} else {
assertTrue(
- "Container type is not BACKGROUND or FALLBACK_OVERVIEW: "
+ "Container type is not LAUNCHED_APP or FALLBACK_OVERVIEW: "
+ expectedContainerType,
- expectedContainerType == ContainerType.BACKGROUND ||
- expectedContainerType == ContainerType.FALLBACK_OVERVIEW);
+ expectedContainerType == ContainerType.LAUNCHED_APP
+ || expectedContainerType == ContainerType.FALLBACK_OVERVIEW);
}
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 2035da1..da8bf6e 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -38,6 +38,10 @@
import com.android.launcher3.tapl.AppIconMenuItem;
import com.android.launcher3.tapl.Folder;
import com.android.launcher3.tapl.FolderIcon;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.HomeAppIcon;
+import com.android.launcher3.tapl.HomeAppIconMenu;
+import com.android.launcher3.tapl.HomeAppIconMenuItem;
import com.android.launcher3.tapl.Widgets;
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.util.TestUtil;
@@ -215,7 +219,7 @@
assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
// Test starting a workspace app.
- final AppIcon app = workspace.getWorkspaceAppIcon("Chrome");
+ final HomeAppIcon app = workspace.getWorkspaceAppIcon("Chrome");
assertNotNull("No Chrome app in workspace", app);
}
@@ -228,7 +232,7 @@
"Launcher activity is the top activity; expecting another activity to be the "
+ "top "
+ "one",
- test.isInBackground(launcher)));
+ test.isInLaunchedApp(launcher)));
} finally {
allApps.unfreeze();
}
@@ -237,7 +241,7 @@
@Test
@PortraitLandscape
public void testAppIconLaunchFromAllAppsFromHome() throws Exception {
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
assertTrue("Launcher internal state is not All Apps",
isInState(() -> LauncherState.ALL_APPS));
@@ -286,9 +290,7 @@
@Test
@PortraitLandscape
public void testLaunchMenuItem() throws Exception {
- final AllApps allApps = mLauncher.
- getWorkspace().
- switchToAllApps();
+ final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
final AppIconMenu menu = allApps.
@@ -313,8 +315,7 @@
// 1. Open all apps and wait for load complete.
// 2. Drag icon to homescreen.
// 3. Verify that the icon works on homescreen.
- final AllApps allApps = mLauncher.getWorkspace().
- switchToAllApps();
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
@@ -325,7 +326,7 @@
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInBackground(launcher)));
+ isInLaunchedApp(launcher)));
}
@Test
@@ -334,18 +335,18 @@
// 1. Open all apps and wait for load complete.
// 2. Find the app and long press it to show shortcuts.
// 3. Press icon center until shortcuts appear
- final AllApps allApps = mLauncher
+ final HomeAllApps allApps = mLauncher
.getWorkspace()
.switchToAllApps();
allApps.freeze();
try {
- final AppIconMenu menu = allApps
+ final HomeAppIconMenu menu = allApps
.getAppIcon(APP_NAME)
.openDeepShortcutMenu();
- final AppIconMenuItem menuItem0 = menu.getMenuItem(0);
- final AppIconMenuItem menuItem2 = menu.getMenuItem(2);
+ final HomeAppIconMenuItem menuItem0 = menu.getMenuItem(0);
+ final HomeAppIconMenuItem menuItem2 = menu.getMenuItem(2);
- final AppIconMenuItem menuItem;
+ final HomeAppIconMenuItem menuItem;
final String expectedShortcutName = "Shortcut 3";
if (menuItem0.getText().equals(expectedShortcutName)) {
@@ -364,27 +365,27 @@
}
}
- private AppIcon createShortcutIfNotExist(String name) {
- AppIcon appIcon = mLauncher.getWorkspace().tryGetWorkspaceAppIcon(name);
- if (appIcon == null) {
- AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ private HomeAppIcon createShortcutIfNotExist(String name) {
+ HomeAppIcon homeAppIcon = mLauncher.getWorkspace().tryGetWorkspaceAppIcon(name);
+ if (homeAppIcon == null) {
+ HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon(name).dragToWorkspace(false, false);
} finally {
allApps.unfreeze();
}
- appIcon = mLauncher.getWorkspace().getWorkspaceAppIcon(name);
+ homeAppIcon = mLauncher.getWorkspace().getWorkspaceAppIcon(name);
}
- return appIcon;
+ return homeAppIcon;
}
@Ignore("b/205014516")
@Test
@PortraitLandscape
public void testDragToFolder() throws Exception {
- final AppIcon playStoreIcon = createShortcutIfNotExist("Play Store");
- final AppIcon gmailIcon = createShortcutIfNotExist("Gmail");
+ final HomeAppIcon playStoreIcon = createShortcutIfNotExist("Play Store");
+ final HomeAppIcon gmailIcon = createShortcutIfNotExist("Gmail");
FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
@@ -398,7 +399,7 @@
assertNull("Play Store should be moved to a folder.",
workspace.tryGetWorkspaceAppIcon("Play Store"));
- final AppIcon youTubeIcon = createShortcutIfNotExist("YouTube");
+ final HomeAppIcon youTubeIcon = createShortcutIfNotExist("YouTube");
folderIcon = youTubeIcon.dragToIcon(folderIcon);
folder = folderIcon.open();
@@ -415,7 +416,7 @@
mLauncher.getWorkspace();
waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
@@ -432,16 +433,16 @@
@PortraitLandscape
public void testDeleteFromWorkspace() throws Exception {
// test delete both built-in apps and user-installed app from workspace
- for (String appName : new String[]{"Gmail", "Play Store", APP_NAME}) {
- final AppIcon appIcon = createShortcutIfNotExist(appName);
- Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(appIcon);
+ for (String appName : new String[] {"Gmail", "Play Store", APP_NAME}) {
+ final HomeAppIcon homeAppIcon = createShortcutIfNotExist(appName);
+ Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(homeAppIcon);
assertNull(appName + " app was found after being deleted from workspace",
workspace.tryGetWorkspaceAppIcon(appName));
}
}
private void verifyAppUninstalledFromAllApps(Workspace workspace, String appName) {
- final AllApps allApps = workspace.switchToAllApps();
+ final HomeAllApps allApps = workspace.switchToAllApps();
allApps.freeze();
try {
assertNull(appName + " app was found on all apps after being uninstalled",
@@ -469,7 +470,7 @@
TestUtil.installDummyApp();
try {
Workspace workspace = mLauncher.getWorkspace();
- final AllApps allApps = workspace.switchToAllApps();
+ final HomeAllApps allApps = workspace.switchToAllApps();
allApps.freeze();
try {
workspace = allApps.getAppIcon(DUMMY_APP_NAME).uninstall();
@@ -496,7 +497,7 @@
};
for (Point target : targets) {
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon(APP_NAME).dragToWorkspace(target.x, target.y);
@@ -508,7 +509,7 @@
}
// test to move a shortcut to other cell.
- final AppIcon launcherTestAppIcon = createShortcutIfNotExist(APP_NAME);
+ final HomeAppIcon launcherTestAppIcon = createShortcutIfNotExist(APP_NAME);
for (Point target : targets) {
launcherTestAppIcon.dragToWorkspace(target.x, target.y);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 800322b..3658f41 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -36,7 +36,7 @@
/**
* Operations on AllApps opened from Home. Also a parent for All Apps opened from Overview.
*/
-public class AllApps extends LauncherInstrumentation.VisibleContainer {
+public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
private static final int MAX_SCROLL_ATTEMPTS = 40;
private final int mHeight;
@@ -55,11 +55,6 @@
.getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- @Override
- protected LauncherInstrumentation.ContainerType getContainerType() {
- return LauncherInstrumentation.ContainerType.ALL_APPS;
- }
-
private boolean hasClickableIcon(UiObject2 allAppsContainer, UiObject2 appListRecycler,
BySelector appIconSelector, int displayBottom) {
final UiObject2 icon;
@@ -157,7 +152,7 @@
final UiObject2 appIcon = mLauncher.waitForObjectInContainer(appListRecycler,
appIconSelector);
- return new AllAppsAppIcon(mLauncher, appIcon);
+ return createAppIcon(appIcon);
} else {
return null;
}
@@ -178,6 +173,8 @@
return appIcon;
}
+ protected abstract AppIcon createAppIcon(UiObject2 icon);
+
private void scrollBackToBeginning() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to scroll back in all apps")) {
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java b/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java
index 03d387e..8adce29 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java
@@ -23,7 +23,7 @@
/**
* App icon in all apps.
*/
-final class AllAppsAppIcon extends AppIcon {
+final class AllAppsAppIcon extends HomeAppIcon {
private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onAllAppsItemLongClick");
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
deleted file mode 100644
index 835790d..0000000
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
-
-import android.graphics.Point;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.UiObject2;
-
-import com.android.launcher3.testing.TestProtocol;
-
-/**
- * Operations on AllApps opened from Overview.
- */
-public final class AllAppsFromOverview extends AllApps {
-
- AllAppsFromOverview(LauncherInstrumentation launcher) {
- super(launcher);
- verifyActiveContainer();
- }
-
- /**
- * Swipes down to switch back to Overview whence we came from.
- *
- * @return the overview panel.
- */
- @NonNull
- public Overview switchBackToOverview() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to switch back from all apps to overview")) {
- final UiObject2 allAppsContainer = verifyActiveContainer();
- // Swipe from the search box to the bottom.
- final UiObject2 qsb = mLauncher.waitForObjectInContainer(
- allAppsContainer, "search_container_all_apps");
- final Point start = qsb.getVisibleCenter();
- final int swipeHeight = mLauncher.getTestInfo(
- TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT).
- getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
-
- final int endY = start.y + swipeHeight;
- LauncherInstrumentation.log("AllAppsFromOverview.switchBackToOverview before swipe");
- mLauncher.swipeToState(start.x, start.y, start.x, endY, 60, OVERVIEW_STATE_ORDINAL,
- LauncherInstrumentation.GestureScope.INSIDE);
-
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("swiped down")) {
- return new Overview(mLauncher);
- }
- }
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index 50611d7..bef242c 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -16,36 +16,33 @@
package com.android.launcher3.tapl;
-import android.graphics.Point;
-import android.graphics.Rect;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
import com.android.launcher3.testing.TestProtocol;
-import java.util.function.Supplier;
import java.util.regex.Pattern;
/**
- * App icon, whether in all apps or in workspace/
+ * App icon, whether in all apps, workspace or the taskbar.
*/
-public abstract class AppIcon extends Launchable implements FolderDragTarget {
-
- private final String mAppName;
+public abstract class AppIcon extends Launchable {
AppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
super(launcher, icon);
- mAppName = icon.getText();
}
static BySelector getAppIconSelector(String appName, LauncherInstrumentation launcher) {
return By.clazz(TextView.class).text(appName).pkg(launcher.getLauncherPackageName());
}
+ static BySelector getAnyAppIconSelector() {
+ return By.clazz(TextView.class);
+ }
+
protected abstract Pattern getLongClickEvent();
/**
@@ -53,7 +50,7 @@
*/
public AppIconMenu openMenu() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- return new AppIconMenu(mLauncher, mLauncher.clickAndGet(
+ return createMenu(mLauncher.clickAndGet(
mObject, "popup_container", getLongClickEvent()));
}
}
@@ -63,33 +60,12 @@
*/
public AppIconMenu openDeepShortcutMenu() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- return new AppIconMenu(mLauncher, mLauncher.clickAndGet(
+ return createMenu(mLauncher.clickAndGet(
mObject, "deep_shortcuts_container", getLongClickEvent()));
}
}
- /**
- * Drag the AppIcon to the given position of other icon. The drag must result in a folder.
- *
- * @param target the destination icon.
- */
- @NonNull
- public FolderIcon dragToIcon(FolderDragTarget target) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to drag icon")) {
- final Rect dropBounds = target.getDropLocationBounds();
- Workspace.dragIconToWorkspace(
- mLauncher, this,
- () -> {
- final Rect bounds = target.getDropLocationBounds();
- return new Point(bounds.centerX(), bounds.centerY());
- },
- getLongPressIndicator());
- FolderIcon result = target.getTargetFolder(dropBounds);
- mLauncher.assertTrue("Can't find the target folder.", result != null);
- return result;
- }
- }
+ protected abstract AppIconMenu createMenu(UiObject2 menu);
@Override
protected void addExpectedEventsForLongClick() {
@@ -110,63 +86,4 @@
protected String launchableType() {
return "app icon";
}
-
- @Override
- public Rect getDropLocationBounds() {
- return mLauncher.getVisibleBounds(mObject);
- }
-
- @Override
- public FolderIcon getTargetFolder(Rect bounds) {
- for (FolderIcon folderIcon : mLauncher.getWorkspace().getFolderIcons()) {
- final Rect folderIconBounds = folderIcon.getDropLocationBounds();
- if (bounds.contains(folderIconBounds.centerX(), folderIconBounds.centerY())) {
- return folderIcon;
- }
- }
- return null;
- }
-
- /**
- * Uninstall the appIcon by dragging it to the 'uninstall' drop point of the drop_target_bar.
- *
- * @return validated workspace after the existing appIcon being uninstalled.
- */
- public Workspace uninstall() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "uninstalling app icon")) {
- return Workspace.uninstallAppIcon(
- mLauncher, this,
- this::addExpectedEventsForLongClick
- );
- }
- }
-
- /**
- * Drag an object to the given cell in workspace. The target cell must be empty.
- *
- * @param cellX zero based column number, starting from the left of the screen.
- * @param cellY zero based row number, starting from the top of the screen.
- */
- public AppIcon dragToWorkspace(int cellX, int cellY) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))
- ) {
- final Supplier<Point> dest = () -> Workspace.getCellCenter(mLauncher, cellX, cellY);
- Workspace.dragIconToWorkspace(mLauncher, this, dest, true, getLongPressIndicator(),
- () -> addExpectedEventsForLongClick(), null);
- try (LauncherInstrumentation.Closable ignore = mLauncher.addContextLayer("dragged")) {
- WorkspaceAppIcon appIcon =
- (WorkspaceAppIcon) mLauncher.getWorkspace().getWorkspaceAppIcon(mAppName);
- mLauncher.assertTrue(
- String.format(
- "The %s icon should be in the cell (%d, %d).", mAppName, cellX,
- cellY),
- appIcon.isInCell(cellX, cellY));
- return appIcon;
- }
- }
- }
-}
\ No newline at end of file
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 7f28151..82d9630 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -25,9 +25,9 @@
/**
* Context menu of an app icon.
*/
-public class AppIconMenu {
- private final LauncherInstrumentation mLauncher;
- private final UiObject2 mDeepShortcutsContainer;
+public abstract class AppIconMenu {
+ protected final LauncherInstrumentation mLauncher;
+ protected final UiObject2 mDeepShortcutsContainer;
AppIconMenu(LauncherInstrumentation launcher,
UiObject2 deepShortcutsContainer) {
@@ -42,6 +42,17 @@
final List<UiObject2> menuItems = mLauncher.getObjectsInContainer(mDeepShortcutsContainer,
"bubble_text");
assertTrue(menuItems.size() > itemNumber);
- return new AppIconMenuItem(mLauncher, menuItems.get(itemNumber));
+ return createMenuItem(menuItems.get(itemNumber));
}
+
+ /**
+ * Returns a menu item with the given text. Fails if it doesn't exist.
+ */
+ public AppIconMenuItem getMenuItem(String shortcutText) {
+ final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
+ AppIcon.getAppIconSelector(shortcutText, mLauncher));
+ return createMenuItem(menuItem);
+ }
+
+ protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
index ac0db08..a6a1531 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
@@ -23,7 +23,7 @@
/**
* Menu item in an app icon menu.
*/
-public class AppIconMenuItem extends Launchable {
+public abstract class AppIconMenuItem extends Launchable {
AppIconMenuItem(LauncherInstrumentation launcher, UiObject2 shortcut) {
super(launcher, shortcut);
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 4333b27..589e13c 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -37,7 +37,7 @@
* Indicates the base state with a UI other than Overview running as foreground. It can also
* indicate Launcher as long as Launcher is not in Overview state.
*/
-public class Background extends LauncherInstrumentation.VisibleContainer {
+public abstract class Background extends LauncherInstrumentation.VisibleContainer {
private static final int ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION = 500;
private static final Pattern SQUARE_BUTTON_EVENT = Pattern.compile("onOverviewToggle");
@@ -45,11 +45,6 @@
super(launcher);
}
- @Override
- protected LauncherInstrumentation.ContainerType getContainerType() {
- return LauncherInstrumentation.ContainerType.BACKGROUND;
- }
-
/**
* Swipes up or presses the square button to switch to Overview.
* Returns the base overview, which can be either in Launcher or the fallback recents.
@@ -212,17 +207,17 @@
}
@NonNull
- public Background quickSwitchToPreviousApp() {
+ public LaunchedAppState quickSwitchToPreviousApp() {
boolean toRight = true;
quickSwitch(toRight);
- return new Background(mLauncher);
+ return new LaunchedAppState(mLauncher);
}
@NonNull
- public Background quickSwitchToPreviousAppSwipeLeft() {
+ public LaunchedAppState quickSwitchToPreviousAppSwipeLeft() {
boolean toRight = false;
quickSwitch(toRight);
- return new Background(mLauncher);
+ return new LaunchedAppState(mLauncher);
}
@NonNull
diff --git a/tests/tapl/com/android/launcher3/tapl/Folder.java b/tests/tapl/com/android/launcher3/tapl/Folder.java
index f046b6e..26f0a8b 100644
--- a/tests/tapl/com/android/launcher3/tapl/Folder.java
+++ b/tests/tapl/com/android/launcher3/tapl/Folder.java
@@ -40,7 +40,7 @@
* Find an app icon with given name or raise assertion error.
*/
@NonNull
- public AppIcon getAppIcon(String appName) {
+ public HomeAppIcon getAppIcon(String appName) {
try (LauncherInstrumentation.Closable ignored = mLauncher.addContextLayer(
"Want to get app icon in folder")) {
return new WorkspaceAppIcon(mLauncher,
diff --git a/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java b/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java
index d797418..2c60668 100644
--- a/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java
+++ b/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java
@@ -19,7 +19,10 @@
import android.graphics.Rect;
public interface FolderDragTarget {
+
+ /** This method requires public access, however should not be called in tests. */
Rect getDropLocationBounds();
+ /** This method requires public access, however should not be called in tests. */
FolderIcon getTargetFolder(Rect bounds);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/FolderIcon.java b/tests/tapl/com/android/launcher3/tapl/FolderIcon.java
index 2e79d70..9b4717f 100644
--- a/tests/tapl/com/android/launcher3/tapl/FolderIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/FolderIcon.java
@@ -52,11 +52,13 @@
return new Folder(mLauncher);
}
+ /** This method requires public access, however should not be called in tests. */
@Override
public Rect getDropLocationBounds() {
return mLauncher.getVisibleBounds(mObject.getParent());
}
+ /** This method requires public access, however should not be called in tests. */
@Override
public FolderIcon getTargetFolder(Rect bounds) {
return this;
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
new file mode 100644
index 0000000..2e00d59
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
@@ -0,0 +1,42 @@
+/*
+ * 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 androidx.annotation.NonNull;
+import androidx.test.uiautomator.UiObject2;
+
+public class HomeAllApps extends AllApps {
+
+ HomeAllApps(LauncherInstrumentation launcher) {
+ super(launcher);
+ }
+
+ @Override
+ protected LauncherInstrumentation.ContainerType getContainerType() {
+ return LauncherInstrumentation.ContainerType.HOME_ALL_APPS;
+ }
+
+ @NonNull
+ @Override
+ public HomeAppIcon getAppIcon(String appName) {
+ return (AllAppsAppIcon) super.getAppIcon(appName);
+ }
+
+ @Override
+ protected HomeAppIcon createAppIcon(UiObject2 icon) {
+ return new AllAppsAppIcon(mLauncher, icon);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
new file mode 100644
index 0000000..4b36dc0
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
@@ -0,0 +1,139 @@
+/*
+ * 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.graphics.Point;
+import android.graphics.Rect;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.UiObject2;
+
+import java.util.function.Supplier;
+
+/**
+ * App icon on the workspace or all apps.
+ */
+public abstract class HomeAppIcon extends AppIcon implements FolderDragTarget, WorkspaceDragSource {
+
+ private final String mAppName;
+
+ HomeAppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
+ super(launcher, icon);
+ mAppName = icon.getText();
+ }
+
+ /**
+ * Drag the AppIcon to the given position of other icon. The drag must result in a folder.
+ *
+ * @param target the destination icon.
+ */
+ @NonNull
+ public FolderIcon dragToIcon(FolderDragTarget target) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to drag icon")) {
+ final Rect dropBounds = target.getDropLocationBounds();
+ Workspace.dragIconToWorkspace(
+ mLauncher, this,
+ () -> {
+ final Rect bounds = target.getDropLocationBounds();
+ return new Point(bounds.centerX(), bounds.centerY());
+ },
+ getLongPressIndicator());
+ FolderIcon result = target.getTargetFolder(dropBounds);
+ mLauncher.assertTrue("Can't find the target folder.", result != null);
+ return result;
+ }
+ }
+
+ /** This method requires public access, however should not be called in tests. */
+ @Override
+ public Rect getDropLocationBounds() {
+ return mLauncher.getVisibleBounds(mObject);
+ }
+
+ /** This method requires public access, however should not be called in tests. */
+ @Override
+ public FolderIcon getTargetFolder(Rect bounds) {
+ for (FolderIcon folderIcon : mLauncher.getWorkspace().getFolderIcons()) {
+ final Rect folderIconBounds = folderIcon.getDropLocationBounds();
+ if (bounds.contains(folderIconBounds.centerX(), folderIconBounds.centerY())) {
+ return folderIcon;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public HomeAppIconMenu openDeepShortcutMenu() {
+ return (HomeAppIconMenu) super.openDeepShortcutMenu();
+ }
+
+ @Override
+ protected HomeAppIconMenu createMenu(UiObject2 menu) {
+ return new HomeAppIconMenu(mLauncher, menu);
+ }
+
+ /**
+ * Uninstall the appIcon by dragging it to the 'uninstall' drop point of the drop_target_bar.
+ *
+ * @return validated workspace after the existing appIcon being uninstalled.
+ */
+ public Workspace uninstall() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "uninstalling app icon")) {
+ return Workspace.uninstallAppIcon(
+ mLauncher, this,
+ this::addExpectedEventsForLongClick
+ );
+ }
+ }
+
+ /**
+ * Drag an object to the given cell in workspace. The target cell must be empty.
+ *
+ * @param cellX zero based column number, starting from the left of the screen.
+ * @param cellY zero based row number, starting from the top of the screen.
+ */
+ public HomeAppIcon dragToWorkspace(int cellX, int cellY) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))
+ ) {
+ final Supplier<Point> dest = () -> Workspace.getCellCenter(mLauncher, cellX, cellY);
+ Workspace.dragIconToWorkspace(mLauncher, this, dest, true, getLongPressIndicator(),
+ () -> addExpectedEventsForLongClick(), null);
+ try (LauncherInstrumentation.Closable ignore = mLauncher.addContextLayer("dragged")) {
+ WorkspaceAppIcon appIcon =
+ (WorkspaceAppIcon) mLauncher.getWorkspace().getWorkspaceAppIcon(mAppName);
+ mLauncher.assertTrue(
+ String.format(
+ "The %s icon should be in the cell (%d, %d).", mAppName, cellX,
+ cellY),
+ appIcon.isInCell(cellX, cellY));
+ return appIcon;
+ }
+ }
+ }
+
+
+ /** This method requires public access, however should not be called in tests. */
+ @Override
+ public Launchable getLaunchable() {
+ return this;
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java
new file mode 100644
index 0000000..71fb6c0
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java
@@ -0,0 +1,39 @@
+/*
+ * 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 androidx.test.uiautomator.UiObject2;
+
+/**
+ * Context menu of a home screen app icon.
+ */
+public final class HomeAppIconMenu extends AppIconMenu {
+
+ HomeAppIconMenu(LauncherInstrumentation launcher,
+ UiObject2 deepShortcutsContainer) {
+ super(launcher, deepShortcutsContainer);
+ }
+
+ @Override
+ public HomeAppIconMenuItem getMenuItem(int itemNumber) {
+ return (HomeAppIconMenuItem) super.getMenuItem(itemNumber);
+ }
+
+ @Override
+ protected HomeAppIconMenuItem createMenuItem(UiObject2 menuItem) {
+ return new HomeAppIconMenuItem(mLauncher, menuItem);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java
new file mode 100644
index 0000000..1ff0c10
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java
@@ -0,0 +1,35 @@
+/*
+ * 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 androidx.test.uiautomator.UiObject2;
+
+/**
+ * Menu item in a home screen app icon menu.
+ */
+public final class HomeAppIconMenuItem extends AppIconMenuItem implements WorkspaceDragSource {
+
+ HomeAppIconMenuItem(LauncherInstrumentation launcher,
+ UiObject2 shortcut) {
+ super(launcher, shortcut);
+ }
+
+ /** This method requires public access, however should not be called in tests. */
+ @Override
+ public Launchable getLaunchable() {
+ return this;
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 7ec5208..02a6b91 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -18,17 +18,25 @@
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
+
import android.graphics.Point;
+import android.view.MotionEvent;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
+import com.android.launcher3.testing.TestProtocol;
+
/**
* Ancestor for AppIcon and AppMenuItem.
*/
abstract class Launchable {
+
+ protected static final int DEFAULT_DRAG_STEPS = 10;
+
protected final LauncherInstrumentation mLauncher;
protected final UiObject2 mObject;
@@ -45,7 +53,7 @@
/**
* Clicks the object to launch its app.
*/
- public Background launch(String expectedPackageName) {
+ public LaunchedAppState launch(String expectedPackageName) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
return launch(By.pkg(expectedPackageName));
}
@@ -55,56 +63,88 @@
protected abstract String launchableType();
- private Background launch(BySelector selector) {
+ private LaunchedAppState launch(BySelector selector) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to launch an app from " + launchableType())) {
LauncherInstrumentation.log("Launchable.launch before click "
+ mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
final String label = mObject.getText();
- mLauncher.executeAndWaitForEvent(
- () -> {
- mLauncher.clickLauncherObject(mObject);
- expectActivityStartEvents();
- },
- event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
- () -> "Launching an app didn't open a new window: " + label,
- "clicking " + launchableType());
+ executeAndWaitForWindowChange(() -> {
+ mLauncher.clickLauncherObject(mObject);
+ expectActivityStartEvents();
+ }, label, "clicking " + launchableType());
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("clicked")) {
- mLauncher.assertTrue(
- "App didn't start: " + label + " (" + selector + ")",
- TestHelpers.wait(Until.hasObject(selector),
- LauncherInstrumentation.WAIT_TIME_MS));
- return new Background(mLauncher);
+ return assertAppLaunched(label, selector);
}
}
}
- /**
- * Drags an object to the center of homescreen.
- *
- * @param startsActivity whether it's expected to start an activity.
- * @param isWidgetShortcut whether we drag a widget shortcut
- */
- public void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- final Point launchableCenter = getObject().getVisibleCenter();
- final Point displaySize = mLauncher.getRealDisplaySize();
- final int width = displaySize.x / 2;
- Workspace.dragIconToWorkspace(
- mLauncher,
- this,
- new Point(
- launchableCenter.x >= width
- ? launchableCenter.x - width / 2
- : launchableCenter.x + width / 2,
- displaySize.y / 2),
- getLongPressIndicator(),
- startsActivity,
- isWidgetShortcut,
- () -> addExpectedEventsForLongClick());
+ protected void executeAndWaitForWindowChange(Runnable command, String label, String action) {
+ mLauncher.executeAndWaitForEvent(
+ command,
+ event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ () -> "Launching an app didn't open a new window: " + label,
+ action);
+ }
+
+ protected LaunchedAppState assertAppLaunched(String label, BySelector selector) {
+ mLauncher.assertTrue(
+ "App didn't start: " + label + " (" + selector + ")",
+ TestHelpers.wait(Until.hasObject(selector),
+ LauncherInstrumentation.WAIT_TIME_MS));
+ return new LaunchedAppState(mLauncher);
+ }
+
+ Point startDrag(long downTime, String longPressIndicator,
+ Runnable expectLongClickEvents, boolean runToSpringLoadedState) {
+ final Point iconCenter = getObject().getVisibleCenter();
+ final Point dragStartCenter = new Point(iconCenter.x,
+ iconCenter.y - getStartDragThreshold());
+
+ if (runToSpringLoadedState) {
+ mLauncher.runToState(() -> movePointerForStartDrag(
+ downTime,
+ iconCenter,
+ dragStartCenter,
+ longPressIndicator,
+ expectLongClickEvents),
+ SPRING_LOADED_STATE_ORDINAL, "long-pressing and triggering drag start");
+ } else {
+ movePointerForStartDrag(
+ downTime,
+ iconCenter,
+ dragStartCenter,
+ longPressIndicator,
+ expectLongClickEvents);
}
+
+
+ return dragStartCenter;
+ }
+
+ /**
+ * Drags this Launchable a short distance before starting a full drag.
+ *
+ * This is necessary for shortcuts, which require being dragged beyond a threshold to close
+ * their container and start drag callbacks.
+ */
+ private void movePointerForStartDrag(long downTime, Point iconCenter, Point dragStartCenter,
+ String longPressIndicator, Runnable expectLongClickEvents) {
+ mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
+ iconCenter, LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.log("movePointerForStartDrag: sent down");
+ expectLongClickEvents.run();
+ mLauncher.waitForLauncherObject(longPressIndicator);
+ LauncherInstrumentation.log("movePointerForStartDrag: indicator");
+ mLauncher.movePointer(iconCenter, dragStartCenter, DEFAULT_DRAG_STEPS, false,
+ downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
+ }
+
+ private int getStartDragThreshold() {
+ return mLauncher.getTestInfo(TestProtocol.REQUEST_START_DRAG_THRESHOLD).getInt(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
protected abstract void addExpectedEventsForLongClick();
diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
new file mode 100644
index 0000000..3f1be80
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * Background state operations specific to when an app has been launched.
+ */
+public final class LaunchedAppState extends Background {
+
+ LaunchedAppState(LauncherInstrumentation launcher) {
+ super(launcher);
+ }
+
+ @Override
+ protected LauncherInstrumentation.ContainerType getContainerType() {
+ return LauncherInstrumentation.ContainerType.LAUNCHED_APP;
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 7c377d5..f063191 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -91,6 +91,7 @@
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* The main tapl object. The only object that can be explicitly constructed by the using code. It
@@ -122,7 +123,7 @@
// Types for launcher containers that the user is interacting with. "Background" is a
// pseudo-container corresponding to inactive launcher covered by another app.
public enum ContainerType {
- WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW
+ WORKSPACE, HOME_ALL_APPS, OVERVIEW, WIDGETS, FALLBACK_OVERVIEW, LAUNCHED_APP
}
public enum NavigationModel {ZERO_BUTTON, THREE_BUTTON}
@@ -135,7 +136,7 @@
}
// Base class for launcher containers.
- static abstract class VisibleContainer {
+ abstract static class VisibleContainer {
protected final LauncherInstrumentation mLauncher;
protected VisibleContainer(LauncherInstrumentation launcher) {
@@ -500,17 +501,20 @@
}
private String getVisiblePackages() {
- final String apps = mDevice.findObjects(getAnyObjectSelector())
- .stream()
- .map(LauncherInstrumentation::getApplicationPackageSafe)
- .distinct()
- .filter(pkg -> pkg != null && !SYSTEMUI_PACKAGE.equals(pkg))
- .collect(Collectors.joining(", "));
+ final String apps = getVisiblePackagesStream().collect(Collectors.joining(", "));
return !apps.isEmpty()
? "active app: " + apps
: "the test doesn't see views from any app, including Launcher";
}
+ private Stream<String> getVisiblePackagesStream() {
+ return mDevice.findObjects(getAnyObjectSelector())
+ .stream()
+ .map(LauncherInstrumentation::getApplicationPackageSafe)
+ .distinct()
+ .filter(pkg -> pkg != null && !SYSTEMUI_PACKAGE.equals(pkg));
+ }
+
private static String getApplicationPackageSafe(UiObject2 object) {
try {
return object.getApplicationPackage();
@@ -526,7 +530,7 @@
if (hasLauncherObject(OVERVIEW_RES_ID)) return "Overview";
if (hasLauncherObject(WORKSPACE_RES_ID)) return "Workspace";
if (hasLauncherObject(APPS_RES_ID)) return "AllApps";
- return "Background (" + getVisiblePackages() + ")";
+ return "LaunchedApp (" + getVisiblePackages() + ")";
}
public void setSystemHealthSupplier(Function<Long, String> supplier) {
@@ -726,7 +730,7 @@
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
return waitForLauncherObject(WIDGETS_RES_ID);
}
- case ALL_APPS: {
+ case HOME_ALL_APPS: {
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
@@ -736,13 +740,12 @@
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
-
return waitForLauncherObject(OVERVIEW_RES_ID);
}
case FALLBACK_OVERVIEW: {
return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
}
- case BACKGROUND: {
+ case LAUNCHED_APP: {
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
@@ -823,6 +826,8 @@
}
GestureScope gestureScope = gestureStartFromLauncher
+ // Without the navigation bar layer, the gesture scope on tablets remains inside the
+ // launcher process.
? (isTablet() ? GestureScope.INSIDE : GestureScope.INSIDE_TO_OUTSIDE)
: GestureScope.OUTSIDE_WITH_PILFER;
linearGesture(
@@ -960,14 +965,14 @@
}
/**
- * Gets the Workspace object if the current state is "background home", i.e. some other app is
- * active. Fails if the launcher is not in that state.
+ * Gets the LaunchedApp object if another app is active. Fails if the launcher is not in that
+ * state.
*
- * @return Background object.
+ * @return LaunchedApp object.
*/
@NonNull
- public Background getBackground() {
- return new Background(this);
+ public LaunchedAppState getLaunchedAppState() {
+ return new LaunchedAppState(this);
}
/**
@@ -1004,32 +1009,17 @@
}
/**
- * Gets the All Apps object if the current state is showing the all apps panel opened by swiping
- * from workspace. Fails if the launcher is not in that state. Please don't call this method if
- * App Apps was opened by swiping up from Overview, as it won't fail and will return an
- * incorrect object.
+ * Gets the homescreen All Apps object if the current state is showing the all apps panel opened
+ * by swiping from workspace. Fails if the launcher is not in that state. Please don't call this
+ * method if App Apps was opened by swiping up from Overview, as it won't fail and will return
+ * an incorrect object.
*
- * @return All Aps object.
+ * @return Home All Apps object.
*/
@NonNull
- public AllApps getAllApps() {
+ public HomeAllApps getAllApps() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get all apps object")) {
- return new AllApps(this);
- }
- }
-
- /**
- * Gets the All Apps object if the current state is showing the all apps panel opened by swiping
- * from overview. Fails if the launcher is not in that state. Please don't call this method if
- * App Apps was opened by swiping up from home, as it won't fail and will return an
- * incorrect object.
- *
- * @return All Aps object.
- */
- @NonNull
- public AllAppsFromOverview getAllAppsFromOverview() {
- try (LauncherInstrumentation.Closable c = addContextLayer("want to get all apps object")) {
- return new AllAppsFromOverview(this);
+ return new HomeAllApps(this);
}
}
@@ -1117,15 +1107,21 @@
}
}
- @NonNull
- UiObject2 waitForObjectInContainer(UiObject2 container, BySelector selector) {
+ @NonNull UiObject2 waitForObjectInContainer(UiObject2 container, BySelector selector) {
+ return waitForObjectsInContainer(container, selector).get(0);
+ }
+
+ @NonNull List<UiObject2> waitForObjectsInContainer(
+ UiObject2 container, BySelector selector) {
try {
- final UiObject2 object = container.wait(
- Until.findObject(selector),
+ final List<UiObject2> objects = container.wait(
+ Until.findObjects(selector),
WAIT_TIME_MS);
- assertNotNull("Can't find a view in Launcher, id: " + selector + " in container: "
- + container.getResourceName(), object);
- return object;
+ assertNotNull("Can't find views in Launcher, id: " + selector + " in container: "
+ + container.getResourceName(), objects);
+ assertTrue("Can't find views in Launcher, id: " + selector + " in container: "
+ + container.getResourceName(), objects.size() > 0);
+ return objects;
} catch (StaleObjectException e) {
fail("The container disappeared from screen");
return null;
diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java
index 0d06be3..66a51a5 100644
--- a/tests/tapl/com/android/launcher3/tapl/Overview.java
+++ b/tests/tapl/com/android/launcher3/tapl/Overview.java
@@ -16,12 +16,7 @@
package com.android.launcher3.tapl;
-import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
-
-import androidx.annotation.NonNull;
-
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
-import com.android.launcher3.testing.TestProtocol;
/**
* Overview pane.
@@ -37,38 +32,6 @@
return LauncherInstrumentation.ContainerType.OVERVIEW;
}
- /**
- * Swipes up to All Apps.
- *
- * @return the App Apps object.
- */
- @NonNull
- public AllAppsFromOverview switchToAllApps() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to switch from overview to all apps")) {
- verifyActiveContainer();
-
- // Swipe from an app icon to the top.
- LauncherInstrumentation.log("Overview.switchToAllApps before swipe");
- mLauncher.swipeToState(
- mLauncher.getDevice().getDisplayWidth() / 2,
- mLauncher.getTestInfo(
- TestProtocol.REQUEST_HOTSEAT_TOP).
- getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD),
- mLauncher.getDevice().getDisplayWidth() / 2,
- 0,
- 12,
- ALL_APPS_STATE_ORDINAL,
- LauncherInstrumentation.GestureScope.INSIDE);
-
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "swiped all way up from overview")) {
- return new AllAppsFromOverview(mLauncher);
- }
- }
- }
-
@Override
public void dismissAllTasks() {
super.dismissAllTasks();
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index a860e7d..c8caa42 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -127,7 +127,7 @@
/**
* Clicks at the task.
*/
- public Background open() {
+ public LaunchedAppState open() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
verifyActiveContainer();
mLauncher.executeAndWaitForEvent(
@@ -137,7 +137,7 @@
+ mTask.getParent().getContentDescription(),
"clicking an overview task");
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
- return new Background(mLauncher);
+ return new LaunchedAppState(mLauncher);
}
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java
index f569ef4..73e9830 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widget.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widget.java
@@ -30,7 +30,7 @@
/**
* Widget in workspace or a widget list.
*/
-public final class Widget extends Launchable {
+public final class Widget extends Launchable implements WorkspaceDragSource {
private static final Pattern LONG_CLICK_EVENT = Pattern.compile("Widgets.onLongClick");
@@ -57,6 +57,12 @@
return "widget";
}
+ /** This method requires public access, however should not be called in tests. */
+ @Override
+ public Launchable getLaunchable() {
+ return this;
+ }
+
/**
* Drags a non-configurable widget from the widgets container to the workspace and returns the
* resize frame that is shown after the widget is added.
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 20d860d..4f4ce30 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -20,7 +20,6 @@
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
-import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
@@ -79,7 +78,7 @@
* @return the All Apps object.
*/
@NonNull
- public AllApps switchToAllApps() {
+ public HomeAllApps switchToAllApps() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to switch from workspace to all apps")) {
@@ -106,7 +105,7 @@
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"swiped to all apps")) {
- return new AllApps(mLauncher);
+ return new HomeAllApps(mLauncher);
}
}
}
@@ -118,7 +117,7 @@
* @return app icon, if found, null otherwise.
*/
@Nullable
- public AppIcon tryGetWorkspaceAppIcon(String appName) {
+ public HomeAppIcon tryGetWorkspaceAppIcon(String appName) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get a workspace icon")) {
final UiObject2 workspace = verifyActiveContainer();
@@ -136,7 +135,7 @@
* @return app icon.
*/
@NonNull
- public AppIcon getWorkspaceAppIcon(String appName) {
+ public HomeAppIcon getWorkspaceAppIcon(String appName) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get a workspace icon")) {
return new WorkspaceAppIcon(mLauncher,
@@ -179,12 +178,12 @@
* pageDelta: 3, the latest page that can be created is 2) the icon will be dragged onto the
* page that can be created and is closest to the target page.
*
- * @param appIcon - icon to drag.
+ * @param homeAppIcon - icon to drag.
* @param pageDelta - how many pages should the icon be dragged from the current page.
* It can be a negative value. currentPage + pageDelta should be greater
* than or equal to 0.
*/
- public void dragIcon(AppIcon appIcon, int pageDelta) {
+ public void dragIcon(HomeAppIcon homeAppIcon, int pageDelta) {
if (mHotseat.getVisibleBounds().height() > mHotseat.getVisibleBounds().width()) {
throw new UnsupportedOperationException(
"dragIcon does NOT support dragging when the hotseat is on the side.");
@@ -193,18 +192,18 @@
final UiObject2 workspace = verifyActiveContainer();
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"dragging icon to page with delta: " + pageDelta)) {
- dragIcon(workspace, appIcon, pageDelta);
+ dragIcon(workspace, homeAppIcon, pageDelta);
verifyActiveContainer();
}
}
}
- private void dragIcon(UiObject2 workspace, AppIcon appIcon, int pageDelta) {
+ private void dragIcon(UiObject2 workspace, HomeAppIcon homeAppIcon, int pageDelta) {
int pageWidth = mLauncher.getDevice().getDisplayWidth() / pagesPerScreen();
int targetX = (pageWidth / 2) + pageWidth * pageDelta;
dragIconToWorkspace(
mLauncher,
- appIcon,
+ homeAppIcon,
new Point(targetX, mLauncher.getVisibleBounds(workspace).centerY()),
"popup_container",
false,
@@ -219,16 +218,11 @@
}
@NonNull
- public AppIcon getHotseatAppIcon(String appName) {
+ public HomeAppIcon getHotseatAppIcon(String appName) {
return new WorkspaceAppIcon(mLauncher, mLauncher.waitForObjectInContainer(
mHotseat, AppIcon.getAppIconSelector(appName, mLauncher)));
}
- private static int getStartDragThreshold(LauncherInstrumentation launcher) {
- return launcher.getTestInfo(TestProtocol.REQUEST_START_DRAG_THRESHOLD).getInt(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
/*
* Get the center point of the delete/uninstall icon in the drop target bar.
*/
@@ -242,18 +236,18 @@
/**
* Delete the appIcon from the workspace.
*
- * @param appIcon to be deleted.
+ * @param homeAppIcon to be deleted.
* @return validated workspace after the existing appIcon being deleted.
*/
- public Workspace deleteAppIcon(AppIcon appIcon) {
+ public Workspace deleteAppIcon(HomeAppIcon homeAppIcon) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"removing app icon from workspace")) {
dragIconToWorkspace(
- mLauncher, appIcon,
+ mLauncher, homeAppIcon,
() -> getDropPointFromDropTargetBar(mLauncher, DELETE_TARGET_TEXT_ID),
true, /* decelerating */
- appIcon.getLongPressIndicator(),
+ homeAppIcon.getLongPressIndicator(),
() -> mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT),
null);
@@ -267,21 +261,23 @@
/**
* Uninstall the appIcon by dragging it to the 'uninstall' drop point of the drop_target_bar.
*
+ * @param launcher the root TAPL instrumentation object of {@link LauncherInstrumentation} type.
+ * @param homeAppIcon to be uninstalled.
* @param launcher the root TAPL instrumentation object of {@link
* LauncherInstrumentation} type.
- * @param appIcon to be uninstalled.
+ * @param homeAppIcon to be uninstalled.
* @param expectLongClickEvents the runnable to be executed to verify expected longclick event.
* @return validated workspace after the existing appIcon being uninstalled.
*/
- static Workspace uninstallAppIcon(LauncherInstrumentation launcher, AppIcon appIcon,
+ static Workspace uninstallAppIcon(LauncherInstrumentation launcher, HomeAppIcon homeAppIcon,
Runnable expectLongClickEvents) {
try (LauncherInstrumentation.Closable c = launcher.addContextLayer(
"uninstalling app icon")) {
dragIconToWorkspace(
- launcher, appIcon,
+ launcher, homeAppIcon,
() -> getDropPointFromDropTargetBar(launcher, UNINSTALL_TARGET_TEXT_ID),
true, /* decelerating */
- appIcon.getLongPressIndicator(),
+ homeAppIcon.getLongPressIndicator(),
expectLongClickEvents,
null);
@@ -334,31 +330,6 @@
o -> new FolderIcon(mLauncher, o)).collect(Collectors.toList());
}
- /**
- * Drag an icon up with a short distance that makes workspace go to spring loaded state.
- *
- * @return the position after dragging.
- */
- private static Point dragIconToSpringLoaded(LauncherInstrumentation launcher, long downTime,
- UiObject2 icon,
- String longPressIndicator, Runnable expectLongClickEvents) {
- final Point iconCenter = icon.getVisibleCenter();
- final Point dragStartCenter = new Point(iconCenter.x,
- iconCenter.y - getStartDragThreshold(launcher));
-
- launcher.runToState(() -> {
- launcher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
- iconCenter, LauncherInstrumentation.GestureScope.INSIDE);
- LauncherInstrumentation.log("dragIconToSpringLoaded: sent down");
- expectLongClickEvents.run();
- launcher.waitForLauncherObject(longPressIndicator);
- LauncherInstrumentation.log("dragIconToSpringLoaded: indicator");
- launcher.movePointer(iconCenter, dragStartCenter, DEFAULT_DRAG_STEPS, false,
- downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
- }, SPRING_LOADED_STATE_ORDINAL, "long-pressing and triggering drag start");
- return dragStartCenter;
- }
-
private static void dropDraggedIcon(LauncherInstrumentation launcher, Point dest, long downTime,
@Nullable Runnable expectedEvents) {
launcher.runToState(
@@ -403,8 +374,11 @@
try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
"want to drag icon to workspace")) {
final long downTime = SystemClock.uptimeMillis();
- Point dragStart = dragIconToSpringLoaded(launcher, downTime,
- launchable.getObject(), longPressIndicator, expectLongClickEvents);
+ Point dragStart = launchable.startDrag(
+ downTime,
+ longPressIndicator,
+ expectLongClickEvents,
+ /* runToSpringLoadedState= */ true);
Point targetDest = dest.get();
int displayX = launcher.getRealDisplaySize().x;
diff --git a/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java b/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java
index 0523a63..114e6a5 100644
--- a/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java
@@ -25,7 +25,7 @@
/**
* App icon in workspace.
*/
-final class WorkspaceAppIcon extends AppIcon {
+final class WorkspaceAppIcon extends HomeAppIcon {
WorkspaceAppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
super(launcher, icon);
diff --git a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
new file mode 100644
index 0000000..93c2213
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
@@ -0,0 +1,53 @@
+/*
+ * 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.graphics.Point;
+
+/** Launchable that can serve as a source for dragging and dropping to the workspace. */
+interface WorkspaceDragSource {
+
+ /**
+ * Drags an object to the center of homescreen.
+ *
+ * @param startsActivity whether it's expected to start an activity.
+ * @param isWidgetShortcut whether we drag a widget shortcut
+ */
+ default void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
+ Launchable launchable = getLaunchable();
+ LauncherInstrumentation launcher = launchable.mLauncher;
+ try (LauncherInstrumentation.Closable e = launcher.eventsCheck()) {
+ final Point launchableCenter = launchable.getObject().getVisibleCenter();
+ final Point displaySize = launcher.getRealDisplaySize();
+ final int width = displaySize.x / 2;
+ Workspace.dragIconToWorkspace(
+ launcher,
+ launchable,
+ new Point(
+ launchableCenter.x >= width
+ ? launchableCenter.x - width / 2
+ : launchableCenter.x + width / 2,
+ displaySize.y / 2),
+ launchable.getLongPressIndicator(),
+ startsActivity,
+ isWidgetShortcut,
+ launchable::addExpectedEventsForLongClick);
+ }
+ }
+
+ /** This method requires public access, however should not be called in tests. */
+ Launchable getLaunchable();
+}