Simplifying some test utility methods
Bug: 283821111
Test: Presubmit
Flag: N/A
Change-Id: I7b9690bc0cc53d097d26cd4f0ab2dd36ba88e1cb
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index eb4c136..85d10b4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -819,8 +819,11 @@
.setDuration(isStashed ? duration / 2 : duration));
}
- private static void play(AnimatorSet as, Animator a, long startDelay, long duration,
+ private static void play(AnimatorSet as, @Nullable Animator a, long startDelay, long duration,
Interpolator interpolator) {
+ if (a == null) {
+ return;
+ }
a.setDuration(duration);
a.setStartDelay(startDelay);
a.setInterpolator(interpolator);
diff --git a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
index 7e408a8..acb2db5 100644
--- a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
+++ b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
@@ -187,7 +187,7 @@
LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
LauncherSettings.Settings.call(mResolver,
LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(false);
// Make sure the widget is big enough to show a list of items
info.minSpanX = 2;
info.minSpanY = 2;
diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java
index edc8c1b..f24d1d2 100644
--- a/src/com/android/launcher3/model/DeviceGridState.java
+++ b/src/com/android/launcher3/model/DeviceGridState.java
@@ -33,6 +33,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
+import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
import java.util.Locale;
import java.util.Objects;
@@ -92,6 +93,9 @@
* Stores the device state to shared preferences
*/
public void writeToPrefs(Context context) {
+ if (context instanceof SandboxContext) {
+ return;
+ }
LauncherPrefs.get(context).put(
WORKSPACE_SIZE.to(mGridSizeString),
HOTSEAT_COUNT.to(mNumHotseat),
diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
index 9d16610..c233872 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
@@ -45,7 +45,6 @@
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetManagerHelper;
@@ -133,10 +132,8 @@
Log.v(TAG, "Workspace migration completed in "
+ (System.currentTimeMillis() - migrationStartTime));
- if (!(context instanceof SandboxContext)) {
- // Save current configuration, so that the migration does not run again.
- destDeviceState.writeToPrefs(context);
- }
+ // Save current configuration, so that the migration does not run again.
+ destDeviceState.writeToPrefs(context);
}
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 91fd65d..0767426 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -367,18 +367,9 @@
final boolean isSdCardReady = Utilities.isBootCompleted();
final WidgetManagerHelper widgetHelper = new WidgetManagerHelper(context);
- boolean clearDb = false;
- if (!mApp.getModel().getModelDbController().migrateGridIfNeeded()) {
- // Migration failed. Clear workspace.
- clearDb = true;
- }
-
- if (clearDb) {
- Log.d(TAG, "loadWorkspace: resetting launcher database");
- Settings.call(contentResolver, Settings.METHOD_CREATE_EMPTY_DB);
- }
-
+ mApp.getModel().getModelDbController().tryMigrateDB();
Log.d(TAG, "loadWorkspace: loading default favorites");
+ mApp.getModel().getModelDbController().loadDefaultFavoritesIfNecessary();
Settings.call(contentResolver, Settings.METHOD_LOAD_DEFAULT_FAVORITES);
synchronized (mBgDataModel) {
diff --git a/src/com/android/launcher3/model/ModelDbController.java b/src/com/android/launcher3/model/ModelDbController.java
index f0e5ef6..d5cc82b 100644
--- a/src/com/android/launcher3/model/ModelDbController.java
+++ b/src/com/android/launcher3/model/ModelDbController.java
@@ -280,13 +280,29 @@
mOpenHelper.getReadableDatabase(), Favorites.HYBRID_HOTSEAT_BACKUP_TABLE);
}
+
+ /**
+ * Migrates the DB if needed. If the migration failed, it clears the DB.
+ */
+ public void tryMigrateDB() {
+ if (!migrateGridIfNeeded()) {
+ Log.d(TAG, "Migration failed: resetting launcher database");
+ createEmptyDB();
+ LauncherPrefs.get(mContext).putSync(
+ getEmptyDbCreatedKey(mOpenHelper.getDatabaseName()).to(true));
+
+ // Write the grid state to avoid another migration
+ new DeviceGridState(LauncherAppState.getIDP(mContext)).writeToPrefs(mContext);
+ }
+ }
+
/**
* Migrates the DB if needed, and returns false if the migration failed
* and DB needs to be cleared.
* @return true if migration was success or ignored, false if migration failed
* and the DB should be reset.
*/
- public boolean migrateGridIfNeeded() {
+ private boolean migrateGridIfNeeded() {
createDbIfNotExists();
InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
if (!GridSizeMigrationUtil.needsToMigrate(mContext, idp)) {
diff --git a/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java b/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
index 8ce932d..80cc5aa 100644
--- a/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
+++ b/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
@@ -15,62 +15,80 @@
*/
package com.android.launcher3.celllayout;
+import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.util.TestUtil.runOnExecutorSync;
-import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.model.BgDataModel.Callbacks;
+import com.android.launcher3.model.ModelDbController;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.util.ContentWriter;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ExecutionException;
+import java.util.function.Supplier;
public class FavoriteItemsTransaction {
- private ArrayList<ItemInfo> mItemsToSubmit;
+ private ArrayList<Supplier<ItemInfo>> mItemsToSubmit;
private Context mContext;
- private ContentResolver mResolver;
- public AbstractLauncherUiTest mTest;
- public FavoriteItemsTransaction(Context context, AbstractLauncherUiTest test) {
+ public FavoriteItemsTransaction(Context context) {
mItemsToSubmit = new ArrayList<>();
mContext = context;
- mResolver = mContext.getContentResolver();
- mTest = test;
}
- public FavoriteItemsTransaction addItem(ItemInfo itemInfo) {
+ public FavoriteItemsTransaction addItem(Supplier<ItemInfo> itemInfo) {
this.mItemsToSubmit.add(itemInfo);
return this;
}
- public FavoriteItemsTransaction removeLast() {
- this.mItemsToSubmit.remove(this.mItemsToSubmit.size() - 1);
- return this;
- }
-
/**
* Commits all the ItemInfo into the database of Favorites
**/
- public void commit() throws ExecutionException, InterruptedException {
- List<ContentValues> values = new ArrayList<>();
- for (ItemInfo item : this.mItemsToSubmit) {
- ContentWriter writer = new ContentWriter(mContext);
- item.onAddToDatabase(writer);
- writer.put(LauncherSettings.Favorites._ID, item.id);
- values.add(writer.getValues(mContext));
- }
- // Submit the icons to the database in the model thread to prevent race conditions
- MODEL_EXECUTOR.submit(() -> mResolver.bulkInsert(LauncherSettings.Favorites.CONTENT_URI,
- values.toArray(new ContentValues[0]))).get();
- // Reload the state of the Launcher
- MAIN_EXECUTOR.submit(() -> LauncherAppState.getInstance(
- mContext).getModel().forceReload()).get();
+ public void commit() {
+ LauncherModel model = LauncherAppState.getInstance(mContext).getModel();
+ // Load the model once so that there is no pending migration:
+ loadModelSync(model);
+
+ runOnExecutorSync(MODEL_EXECUTOR, () -> {
+ ModelDbController controller = model.getModelDbController();
+ // Migrate any previous data so that the DB state is correct
+ controller.tryMigrateDB();
+
+ // Create DB again to load fresh data
+ controller.createEmptyDB();
+ controller.clearEmptyDbFlag();
+
+ // Add new data
+ List<ContentValues> values = new ArrayList<>();
+ int count = mItemsToSubmit.size();
+ for (int i = 0; i < count; i++) {
+ ContentWriter writer = new ContentWriter(mContext);
+ mItemsToSubmit.get(i).get().onAddToDatabase(writer);
+ writer.put(LauncherSettings.Favorites._ID, i);
+ values.add(writer.getValues(mContext));
+ }
+ controller.bulkInsert(TABLE_NAME, values.toArray(new ContentValues[0]));
+ });
+
+ // Reload model
+ runOnExecutorSync(MAIN_EXECUTOR, model::forceReload);
+ loadModelSync(model);
+ }
+
+ private void loadModelSync(LauncherModel model) {
+ Callbacks mockCb = new Callbacks() { };
+ runOnExecutorSync(MAIN_EXECUTOR, () -> model.addCallbacksAndLoad(mockCb));
+ runOnExecutorSync(MODEL_EXECUTOR, () -> { });
+
+ runOnExecutorSync(MAIN_EXECUTOR, () -> { });
+ runOnExecutorSync(MAIN_EXECUTOR, () -> model.removeCallbacks(mockCb));
}
}
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index c4aa42b..c426480 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -60,7 +60,7 @@
@Before
public void setup() throws Throwable {
- mWorkspaceBuilder = new TestWorkspaceBuilder(this, mTargetContext);
+ mWorkspaceBuilder = new TestWorkspaceBuilder(mTargetContext);
TaplTestsLauncher3.initialize(this);
clearHomescreen();
}
@@ -109,7 +109,7 @@
testCase.mStart);
FavoriteItemsTransaction transaction =
- new FavoriteItemsTransaction(mTargetContext, this);
+ new FavoriteItemsTransaction(mTargetContext);
transaction = buildWorkspaceFromBoards(testCase.mStart, transaction);
transaction.commit();
// resetLoaderState triggers the launcher to start loading the workspace which allows
diff --git a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
index 5945605..cde733e 100644
--- a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
+++ b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.celllayout;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.ui.TestViewHelpers.findWidgetProvider;
import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
import android.content.ComponentName;
@@ -25,33 +28,29 @@
import android.os.UserHandle;
import android.util.Log;
-import androidx.test.core.app.ApplicationProvider;
-
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.ui.TestViewHelpers;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import java.util.function.Supplier;
+import java.util.stream.IntStream;
+
public class TestWorkspaceBuilder {
private static final String TAG = "CellLayoutBoardBuilder";
private static final ComponentName APP_COMPONENT_NAME = new ComponentName(
"com.google.android.calculator", "com.android.calculator2.Calculator");
- public AbstractLauncherUiTest mTest;
-
private UserHandle mMyUser;
private Context mContext;
private ContentResolver mResolver;
- public TestWorkspaceBuilder(AbstractLauncherUiTest test, Context context) {
- mTest = test;
+ public TestWorkspaceBuilder(Context context) {
mMyUser = Process.myUserHandle();
mContext = context;
mResolver = mContext.getContentResolver();
@@ -68,10 +67,9 @@
for (int y = initY; y < initY + widgetRect.getSpanY(); y++) {
try {
// this widgets are filling, we don't care if we can't place them
- ItemInfo item = createWidgetInCell(
+ transaction.addItem(createWidgetInCell(
new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE,
- new Rect(x, y, x, y)), screenId);
- transaction.addItem(item);
+ new Rect(x, y, x, y)), screenId));
} catch (Exception e) {
Log.d(TAG, "Unable to place filling widget at " + x + "," + y);
}
@@ -108,7 +106,7 @@
board.getWidgets().forEach(
(widgetRect) -> addCorrespondingWidgetRect(widgetRect, transaction, screenId));
board.getIcons().forEach((iconPoint) ->
- transaction.addItem(createIconInCell(iconPoint, screenId))
+ transaction.addItem(() -> createIconInCell(iconPoint, screenId))
);
return transaction;
}
@@ -118,24 +116,25 @@
* be clean otherwise this doesn't overrides the existing icons.
*/
public FavoriteItemsTransaction fillHotseatIcons(FavoriteItemsTransaction transaction) {
- int hotseatCount = InvariantDeviceProfile.INSTANCE.get(mContext).numDatabaseHotseatIcons;
- for (int i = 0; i < hotseatCount; i++) {
- transaction.addItem(getHotseatValues(i));
- }
+ IntStream.range(0, InvariantDeviceProfile.INSTANCE.get(mContext).numDatabaseHotseatIcons)
+ .forEach(i -> transaction.addItem(() -> getHotseatValues(i)));
return transaction;
}
- private ItemInfo createWidgetInCell(CellLayoutBoard.WidgetRect widgetRect, int screenId) {
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false);
- LauncherAppWidgetInfo item = createWidgetInfo(info,
- ApplicationProvider.getApplicationContext(), true);
- item.id = getID();
- item.cellX = widgetRect.getCellX();
- item.cellY = widgetRect.getCellY();
- item.spanX = widgetRect.getSpanX();
- item.spanY = widgetRect.getSpanY();
- item.screenId = screenId;
- return item;
+ private Supplier<ItemInfo> createWidgetInCell(
+ CellLayoutBoard.WidgetRect widgetRect, int screenId) {
+ // Create the widget lazily since the appWidgetId can get lost during setup
+ return () -> {
+ LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
+ LauncherAppWidgetInfo item = createWidgetInfo(info, getApplicationContext(), true);
+ item.id = getID();
+ item.cellX = widgetRect.getCellX();
+ item.cellY = widgetRect.getCellY();
+ item.spanX = widgetRect.getSpanX();
+ item.spanY = widgetRect.getSpanY();
+ item.screenId = screenId;
+ return item;
+ };
}
private ItemInfo createIconInCell(CellLayoutBoard.IconPoint iconPoint, int screenId) {
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 09c4b1f..4506fa3 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.TestUtil.getOnUiThread;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -39,7 +40,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
-import android.system.OsConstants;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -64,6 +64,7 @@
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.SimpleBroadcastReceiver;
+import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.util.rule.FailureWatcher;
@@ -82,10 +83,8 @@
import org.junit.rules.TestRule;
import java.io.IOException;
-import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -98,7 +97,7 @@
public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 5;
- public static final long DEFAULT_UI_TIMEOUT = 10000;
+ public static final long DEFAULT_UI_TIMEOUT = TestUtil.DEFAULT_UI_TIMEOUT;
private static final String TAG = "AbstractLauncherUiTest";
private static boolean sDumpWasGenerated = false;
@@ -332,22 +331,6 @@
mLauncher.waitForLauncherInitialized();
}
- /**
- * Runs the callback on the UI thread and returns the result.
- */
- protected <T> T getOnUiThread(final Callable<T> callback) {
- try {
- return mMainThreadExecutor.submit(callback).get(DEFAULT_UI_TIMEOUT,
- TimeUnit.MILLISECONDS);
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout in getOnUiThread, sending SIGABRT", e);
- Process.sendSignal(Process.myPid(), OsConstants.SIGABRT);
- throw new RuntimeException(e);
- } catch (Throwable e) {
- throw new RuntimeException(e);
- }
- }
-
protected <T> T getFromLauncher(Function<Launcher, T> f) {
if (!TestHelpers.isInLauncherProcess()) return null;
return getOnUiThread(() -> f.apply(mActivityMonitor.getActivity()));
diff --git a/tests/src/com/android/launcher3/ui/TestViewHelpers.java b/tests/src/com/android/launcher3/ui/TestViewHelpers.java
index 083f580..4b2bade 100644
--- a/tests/src/com/android/launcher3/ui/TestViewHelpers.java
+++ b/tests/src/com/android/launcher3/ui/TestViewHelpers.java
@@ -15,11 +15,14 @@
*/
package com.android.launcher3.ui;
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import static androidx.test.InstrumentationRegistry.getTargetContext;
+import static android.os.Process.myUserHandle;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.launcher3.util.TestUtil.getOnUiThread;
+
+import android.app.Instrumentation;
import android.content.ComponentName;
-import android.os.Process;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -29,7 +32,6 @@
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetManagerHelper;
-import java.util.concurrent.Callable;
import java.util.function.Function;
public class TestViewHelpers {
@@ -38,23 +40,16 @@
/**
* Finds a widget provider which can fit on the home screen.
*
- * @param test test suite.
* @param hasConfigureScreen if true, a provider with a config screen is returned.
*/
- public static LauncherAppWidgetProviderInfo findWidgetProvider(AbstractLauncherUiTest test,
- final boolean hasConfigureScreen) {
- LauncherAppWidgetProviderInfo info =
- test.getOnUiThread(new Callable<LauncherAppWidgetProviderInfo>() {
- @Override
- public LauncherAppWidgetProviderInfo call() throws Exception {
- ComponentName cn = new ComponentName(getInstrumentation().getContext(),
- hasConfigureScreen ? AppWidgetWithConfig.class
- : AppWidgetNoConfig.class);
- Log.d(TAG, "findWidgetProvider componentName=" + cn.flattenToString());
- return new WidgetManagerHelper(getTargetContext())
- .findProvider(cn, Process.myUserHandle());
- }
- });
+ public static LauncherAppWidgetProviderInfo findWidgetProvider(boolean hasConfigureScreen) {
+ LauncherAppWidgetProviderInfo info = getOnUiThread(() -> {
+ Instrumentation i = getInstrumentation();
+ ComponentName cn = new ComponentName(i.getContext(),
+ hasConfigureScreen ? AppWidgetWithConfig.class : AppWidgetNoConfig.class);
+ Log.d(TAG, "findWidgetProvider componentName=" + cn.flattenToString());
+ return new WidgetManagerHelper(i.getTargetContext()).findProvider(cn, myUserHandle());
+ });
if (info == null) {
throw new IllegalArgumentException("No valid widget provider");
}
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 3806648..fddbc37 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
@@ -64,7 +64,7 @@
@Before
public void setUp() throws Exception {
super.setUp();
- mWidgetInfo = TestViewHelpers.findWidgetProvider(this, true /* hasConfigureScreen */);
+ mWidgetInfo = TestViewHelpers.findWidgetProvider(true /* hasConfigureScreen */);
mAppWidgetManager = AppWidgetManager.getInstance(mTargetContext);
}
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 028b9b6..5cdc886 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -61,7 +61,7 @@
waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
final LauncherAppWidgetProviderInfo widgetInfo =
- TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */);
+ TestViewHelpers.findWidgetProvider(false /* hasConfigureScreen */);
WidgetResizeFrame resizeFrame = mLauncher
.getWorkspace()
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index 0f861eb..99d2201 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -17,6 +17,7 @@
import static androidx.test.InstrumentationRegistry.getTargetContext;
+import static com.android.launcher3.util.TestUtil.getOnUiThread;
import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
import static org.junit.Assert.assertEquals;
@@ -103,7 +104,7 @@
@Test
public void testBindNormalWidget_withConfig() {
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, true);
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(true);
LauncherAppWidgetInfo item = createWidgetInfo(info, getTargetContext(), true);
addItemToScreen(item);
@@ -112,7 +113,7 @@
@Test
public void testBindNormalWidget_withoutConfig() {
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(false);
LauncherAppWidgetInfo item = createWidgetInfo(info, getTargetContext(), true);
addItemToScreen(item);
@@ -121,7 +122,7 @@
@Test
public void testUnboundWidget_removed() {
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(false);
LauncherAppWidgetInfo item = createWidgetInfo(info, getTargetContext(), false);
item.appWidgetId = -33;
@@ -140,7 +141,7 @@
@Test
public void testPendingWidget_autoRestored() {
// A non-restored widget with no config screen gets restored automatically.
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(false);
// Do not bind the widget
LauncherAppWidgetInfo item = createWidgetInfo(info, getTargetContext(), false);
@@ -153,7 +154,7 @@
@Test
public void testPendingWidget_withConfigScreen() {
// A non-restored widget with config screen get bound and shows a 'Click to setup' UI.
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, true);
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(true);
// Do not bind the widget
LauncherAppWidgetInfo item = createWidgetInfo(info, getTargetContext(), false);
diff --git a/tests/src/com/android/launcher3/util/TestUtil.java b/tests/src/com/android/launcher3/util/TestUtil.java
index 14bc8b9..7332b83 100644
--- a/tests/src/com/android/launcher3/util/TestUtil.java
+++ b/tests/src/com/android/launcher3/util/TestUtil.java
@@ -18,14 +18,13 @@
import static android.util.Base64.NO_PADDING;
import static android.util.Base64.NO_WRAP;
-import static androidx.test.InstrumentationRegistry.getContext;
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import static androidx.test.InstrumentationRegistry.getTargetContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_KEY;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_LABEL;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_TAG;
+import android.app.Instrumentation;
import android.app.blob.BlobHandle;
import android.app.blob.BlobStoreManager;
import android.content.Context;
@@ -35,9 +34,12 @@
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
+import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
+import android.system.OsConstants;
import android.util.Base64;
+import android.util.Log;
import androidx.test.uiautomator.UiDevice;
@@ -52,27 +54,35 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
+import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
public class TestUtil {
+ private static final String TAG = "TestUtil";
+
public static final String DUMMY_PACKAGE = "com.example.android.aardwolf";
public static final int DEFAULT_USER_ID = 0;
+ public static final long DEFAULT_UI_TIMEOUT = 10000;
public static void installDummyApp() throws IOException {
installDummyAppForUser(DEFAULT_USER_ID);
}
public static void installDummyAppForUser(int userId) throws IOException {
+ Instrumentation instrumentation = getInstrumentation();
// Copy apk from resources to a local file and install from there.
- final Resources resources = getContext().getResources();
+ final Resources resources = instrumentation.getContext().getResources();
final InputStream in = resources.openRawResource(
resources.getIdentifier("aardwolf_dummy_app",
- "raw", getContext().getPackageName()));
- final String apkFilename = getInstrumentation().getTargetContext().
- getFilesDir().getPath() + "/dummy_app.apk";
+ "raw", instrumentation.getContext().getPackageName()));
+ final String apkFilename = instrumentation.getTargetContext()
+ .getFilesDir().getPath() + "/dummy_app.apk";
try (PackageInstallCheck pic = new PackageInstallCheck()) {
final FileOutputStream out = new FileOutputStream(apkFilename);
@@ -85,7 +95,7 @@
in.close();
out.close();
- final String result = UiDevice.getInstance(getInstrumentation())
+ final String result = UiDevice.getInstance(instrumentation)
.executeShellCommand("pm install --user " + userId + " " + apkFilename);
Assert.assertTrue(
"Failed to install wellbeing test apk; make sure the device is rooted",
@@ -177,13 +187,33 @@
}
}
+ /**
+ * Runs the callback on the UI thread and returns the result.
+ */
+ public static <T> T getOnUiThread(final Callable<T> callback) {
+ try {
+ FutureTask<T> task = new FutureTask<>(callback);
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ task.run();
+ } else {
+ new Handler(Looper.getMainLooper()).post(task);
+ }
+ return task.get(DEFAULT_UI_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException e) {
+ Log.e(TAG, "Timeout in getOnUiThread, sending SIGABRT", e);
+ Process.sendSignal(Process.myPid(), OsConstants.SIGABRT);
+ throw new RuntimeException(e);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/** Interface to indicate a runnable which can throw any exception. */
public interface UncheckedRunnable {
/** Method to run the task */
void run() throws Exception;
}
-
private static class PackageInstallCheck extends LauncherApps.Callback
implements AutoCloseable {
@@ -191,7 +221,8 @@
final LauncherApps mLauncherApps;
PackageInstallCheck() {
- mLauncherApps = getTargetContext().getSystemService(LauncherApps.class);
+ mLauncherApps = getInstrumentation().getTargetContext()
+ .getSystemService(LauncherApps.class);
mLauncherApps.registerCallback(this, new Handler(Looper.getMainLooper()));
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 1111d32..2286d7e 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -138,17 +138,6 @@
OUTSIDE_WITH_KEYCODE,
}
- /**
- * Represents a point in the code at which a callback can run.
- */
- public enum CALLBACK_RUN_POINT {
- CALLBACK_HOLD_BEFORE_DROP,
- CALLBACK_HOVER_ENTER,
- CALLBACK_HOVER_EXIT,
- }
-
- private Consumer<CALLBACK_RUN_POINT> mCallbackAtRunPoint = null;
-
// Base class for launcher containers.
abstract static class VisibleContainer {
protected final LauncherInstrumentation mLauncher;
@@ -2064,22 +2053,6 @@
}
/**
- * Sets the consumer to run callbacks at all run-points.
- */
- public void setRunPointCallback(Consumer<CALLBACK_RUN_POINT> callback) {
- mCallbackAtRunPoint = callback;
- }
-
- /**
- * Runs the callback at the specified point if it exists.
- */
- void runCallbackIfActive(CALLBACK_RUN_POINT runPoint) {
- if (mCallbackAtRunPoint != null) {
- mCallbackAtRunPoint.accept(runPoint);
- }
- }
-
- /**
* Waits until a particular condition is true. Based on WaitMixin.
*/
boolean waitAndGet(BooleanSupplier condition, long timeout, long interval) {
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java
index b2cc92d..e3035bf 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java
@@ -15,13 +15,7 @@
*/
package com.android.launcher3.tapl;
-import static com.android.launcher3.tapl.LauncherInstrumentation.CALLBACK_RUN_POINT.CALLBACK_HOVER_ENTER;
-import static com.android.launcher3.tapl.LauncherInstrumentation.CALLBACK_RUN_POINT.CALLBACK_HOVER_EXIT;
-
-import android.graphics.Point;
import android.graphics.Rect;
-import android.os.SystemClock;
-import android.view.MotionEvent;
import androidx.test.uiautomator.UiObject2;
@@ -42,28 +36,4 @@
public Rect getVisibleBounds() {
return mMenuItem.getVisibleBounds();
}
-
- /**
- * Emulate the cursor entering and exiting a hover over this menu item.
- */
- public void hoverCursor() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "cursor hover entering menu item")) {
- long downTime = SystemClock.uptimeMillis();
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_ENTER,
- new Point(mMenuItem.getVisibleCenter().x, mMenuItem.getVisibleCenter().y),
- null);
- mLauncher.runCallbackIfActive(CALLBACK_HOVER_ENTER);
-
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "cursor hover exiting menu item")) {
- downTime = SystemClock.uptimeMillis();
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_EXIT,
- new Point(mMenuItem.getVisibleCenter().x, mMenuItem.getVisibleCenter().y),
- null);
- mLauncher.runCallbackIfActive(CALLBACK_HOVER_EXIT);
- }
- }
- }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 7bb02cb..8604988 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -18,7 +18,6 @@
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_SCROLLED;
-import static com.android.launcher3.tapl.LauncherInstrumentation.CALLBACK_RUN_POINT.CALLBACK_HOLD_BEFORE_DROP;
import static com.android.launcher3.testing.shared.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
@@ -553,7 +552,6 @@
launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
downTime, SystemClock.uptimeMillis(), false,
LauncherInstrumentation.GestureScope.INSIDE);
- launcher.runCallbackIfActive(CALLBACK_HOLD_BEFORE_DROP);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}
}
@@ -587,7 +585,6 @@
launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
downTime, SystemClock.uptimeMillis(), false,
LauncherInstrumentation.GestureScope.INSIDE);
- launcher.runCallbackIfActive(CALLBACK_HOLD_BEFORE_DROP);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}
}