Merge "TAPL: Optimization: avoid getting actual events twice" into ub-launcher3-master
diff --git a/SharedLibWrapper/build.gradle b/SharedLibWrapper/build.gradle
new file mode 100644
index 0000000..674e38a
--- /dev/null
+++ b/SharedLibWrapper/build.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'java'
+
+final String ANDROID_TOP = "${rootDir}/../../.."
+final String FRAMEWORK_PREBUILTS_DIR = "${ANDROID_TOP}/prebuilts/framework_intermediates/"
+
+sourceSets {
+ main {
+ java.srcDirs = ["${ANDROID_TOP}/frameworks/lib/systemui/SharedLibWrapper/src"]
+ }
+}
+
+sourceCompatibility = 1.8
+
+dependencies {
+ implementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/quickstep/libs", include: 'sysui_shared.jar')
+ compileOnly fileTree(dir: "$ANDROID_TOP/prebuilts/fullsdk-${org.gradle.internal.os.OperatingSystem.current().isMacOsX() ? "darwin" : "linux"}/platforms/${COMPILE_SDK}", include: 'android.jar')
+}
diff --git a/build.gradle b/build.gradle
index e296455..534ca65 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@
repositories {
mavenCentral()
google()
+ jcenter()
}
dependencies {
classpath GRADLE_CLASS_PATH
@@ -62,12 +63,6 @@
minSdkVersion 28
}
- withQuickstepIconRecents {
- dimension "recents"
-
- minSdkVersion 28
- }
-
withoutQuickstep {
dimension "recents"
}
@@ -78,11 +73,6 @@
if (variant.buildType.name.endsWith('release')) {
variant.setIgnore(true)
}
-
- // Icon recents is Go only
- if (name.contains("WithQuickstepIconRecents") && !name.contains("l3go")) {
- variant.setIgnore(true)
- }
}
sourceSets {
@@ -96,10 +86,6 @@
}
}
- debug {
- manifest.srcFile "AndroidManifest.xml"
- }
-
androidTest {
res.srcDirs = ['tests/res']
java.srcDirs = ['tests/src', 'tests/tapl']
@@ -112,15 +98,30 @@
aosp {
java.srcDirs = ['src_flags', 'src_shortcuts_overrides']
+ }
+
+ aospWithoutQuickstep {
manifest.srcFile "AndroidManifest.xml"
}
+ aospWithQuickstep {
+ manifest.srcFile "quickstep/AndroidManifest-launcher.xml"
+ }
+
l3go {
res.srcDirs = ['go/res']
java.srcDirs = ['go/src']
manifest.srcFile "go/AndroidManifest.xml"
}
+ l3goWithoutQuickstepDebug {
+ manifest.srcFile "AndroidManifest.xml"
+ }
+
+ l3goWithQuickstepDebug {
+ manifest.srcFile "quickstep/AndroidManifest-launcher.xml"
+ }
+
withoutQuickstep {
java.srcDirs = ['src_ui_overrides']
}
@@ -130,20 +131,17 @@
java.srcDirs = ['quickstep/src', 'quickstep/recents_ui_overrides/src']
manifest.srcFile "quickstep/AndroidManifest.xml"
}
-
- withQuickstepIconRecents {
- res.srcDirs = ['quickstep/res', 'go/quickstep/res']
- java.srcDirs = ['quickstep/src', 'go/quickstep/src']
- manifest.srcFile "quickstep/AndroidManifest.xml"
- }
}
}
-repositories {
- maven { url "../../../prebuilts/fullsdk-darwin/extras/android/m2repository" }
- maven { url "../../../prebuilts/fullsdk-linux/extras/android/m2repository" }
- mavenCentral()
- google()
+allprojects {
+ repositories {
+ maven { url "../../../prebuilts/sdk/current/androidx/m2repository" }
+ maven { url "../../../prebuilts/fullsdk-darwin/extras/android/m2repository" }
+ maven { url "../../../prebuilts/fullsdk-linux/extras/android/m2repository" }
+ mavenCentral()
+ google()
+ }
}
dependencies {
@@ -151,14 +149,12 @@
implementation "androidx.recyclerview:recyclerview:${ANDROID_X_VERSION}"
implementation "androidx.preference:preference:${ANDROID_X_VERSION}"
implementation project(':IconLoader')
+ withQuickstepImplementation project(':SharedLibWrapper')
implementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/libs", include: 'launcher_protos.jar')
// Recents lib dependency
withQuickstepImplementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/quickstep/libs", include: 'sysui_shared.jar')
- // Recents lib dependency for Go
- withQuickstepIconRecentsImplementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/quickstep/libs", include: 'sysui_shared.jar')
-
// Required for AOSP to compile. This is already included in the sysui_shared.jar
withoutQuickstepImplementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/libs", include: 'plugin_core.jar')
@@ -175,7 +171,7 @@
protobuf {
// Configure the protoc executable
protoc {
- artifact = 'com.google.protobuf:protoc:3.0.0-alpha-3'
+ artifact = 'com.google.protobuf:protoc:3.0.0'
generateProtoTasks {
all().each { task ->
diff --git a/gradle.properties b/gradle.properties
index a77f52a..7a51375 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,11 +2,11 @@
android.useAndroidX = true
android.enableJetifier = true
-ANDROID_X_VERSION=1.0.0-beta01
+ANDROID_X_VERSION=1+
-GRADLE_CLASS_PATH=com.android.tools.build:gradle:3.3.0
+GRADLE_CLASS_PATH=com.android.tools.build:gradle:3.5.1
-PROTOBUF_CLASS_PATH=com.google.protobuf:protobuf-gradle-plugin:0.8.6
+PROTOBUF_CLASS_PATH=com.google.protobuf:protobuf-gradle-plugin:0.8.8
PROTOBUF_DEPENDENCY=com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7
BUILD_TOOLS_VERSION=28.0.3
diff --git a/iconloaderlib/build.gradle b/iconloaderlib/build.gradle
index 8a4d2b7..d7a62e1 100644
--- a/iconloaderlib/build.gradle
+++ b/iconloaderlib/build.gradle
@@ -3,7 +3,6 @@
android {
compileSdkVersion COMPILE_SDK
buildToolsVersion BUILD_TOOLS_VERSION
- publishNonDefault true
defaultConfig {
minSdkVersion 25
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index d4db05a..1e01709 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -69,9 +69,9 @@
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.views.FloatingIconView;
+import com.android.quickstep.RemoteAnimationTargets;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.RemoteAnimationTargets;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.QuickStepContract;
@@ -83,6 +83,8 @@
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import java.lang.ref.WeakReference;
+
/**
* {@link LauncherAppTransitionManager} with Quickstep-specific app transitions for launching from
* home and/or all-apps.
@@ -149,6 +151,7 @@
private DeviceProfile mDeviceProfile;
private RemoteAnimationProvider mRemoteAnimationProvider;
+ private WrappedAnimationRunnerImpl mWallpaperOpenRunner;
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override
@@ -176,7 +179,6 @@
mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y);
mLauncher.addOnDeviceProfileChangeListener(this);
- registerRemoteAnimations();
}
@Override
@@ -598,18 +600,36 @@
/**
* Registers remote animations used when closing apps to home screen.
*/
- private void registerRemoteAnimations() {
- // Unregister this
+ @Override
+ public void registerRemoteAnimations() {
if (hasControlRemoteAppTransitionPermission()) {
+ mWallpaperOpenRunner = createWallpaperOpenRunner(false /* fromUnlock */);
+
RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
WindowManagerWrapper.ACTIVITY_TYPE_STANDARD,
- new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(false /* fromUnlock */),
+ new RemoteAnimationAdapterCompat(
+ new WrappedLauncherAnimationRunner<>(mWallpaperOpenRunner,
+ false /* startAtFrontOfQueue */),
CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
}
}
+ /**
+ * Unregisters all remote animations.
+ */
+ @Override
+ public void unregisterRemoteAnimations() {
+ if (hasControlRemoteAppTransitionPermission()) {
+ new ActivityCompat(mLauncher).unregisterRemoteAnimations();
+
+ // Also clear strong references to the runners registered with the remote animation
+ // definition so we don't have to wait for the system gc
+ mWallpaperOpenRunner = null;
+ }
+ }
+
private boolean launcherIsATargetWithMode(RemoteAnimationTargetCompat[] targets, int mode) {
return taskIsATargetWithMode(targets, mLauncher.getTaskId(), mode);
}
@@ -618,9 +638,8 @@
* @return Runner that plays when user goes to Launcher
* ie. pressing home, swiping up from nav bar.
*/
- RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) {
- return new WallpaperOpenLauncherAnimationRunner(mHandler, false /* startAtFrontOfQueue */,
- fromUnlock);
+ WrappedAnimationRunnerImpl createWallpaperOpenRunner(boolean fromUnlock) {
+ return new WallpaperOpenLauncherAnimationRunner(mHandler, fromUnlock);
}
/**
@@ -701,7 +720,8 @@
}
/**
- * Creates an animator that modifies Launcher as a result from {@link #getWallpaperOpenRunner}.
+ * Creates an animator that modifies Launcher as a result from
+ * {@link #createWallpaperOpenRunner}.
*/
private void createLauncherResumeAnimation(AnimatorSet anim) {
if (mLauncher.isInState(LauncherState.ALL_APPS)) {
@@ -761,18 +781,70 @@
}
/**
+ * Used with WrappedLauncherAnimationRunner as an interface for the runner to call back to the
+ * implementation.
+ */
+ protected interface WrappedAnimationRunnerImpl {
+ Handler getHandler();
+ void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ LauncherAnimationRunner.AnimationResult result);
+ }
+
+ /**
+ * This class is needed to wrap any animation runner that is a part of the
+ * RemoteAnimationDefinition:
+ * - Launcher creates a new instance of the LauncherAppTransitionManagerImpl whenever it is
+ * created, which in turn registers a new definition
+ * - When the definition is registered, window manager retains a strong binder reference to the
+ * runner passed in
+ * - If the Launcher activity is recreated, the new definition registered will replace the old
+ * reference in the system's activity record, but until the system server is GC'd, the binder
+ * reference will still exist, which references the runner in the Launcher process, which
+ * references the (old) Launcher activity through this class
+ *
+ * Instead we make the runner provided to the definition static only holding a weak reference to
+ * the runner implementation. When this animation manager is destroyed, we remove the Launcher
+ * reference to the runner, leaving only the weak ref from the runner.
+ */
+ protected static class WrappedLauncherAnimationRunner<R extends WrappedAnimationRunnerImpl>
+ extends LauncherAnimationRunner {
+ private WeakReference<R> mImpl;
+
+ public WrappedLauncherAnimationRunner(R animationRunnerImpl, boolean startAtFrontOfQueue) {
+ super(animationRunnerImpl.getHandler(), startAtFrontOfQueue);
+ mImpl = new WeakReference<>(animationRunnerImpl);
+ }
+
+ @Override
+ public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) {
+ R animationRunnerImpl = mImpl.get();
+ if (animationRunnerImpl != null) {
+ animationRunnerImpl.onCreateAnimation(appTargets, wallpaperTargets, result);
+ }
+ }
+ }
+
+ /**
* Remote animation runner for animation from the app to Launcher, including recents.
*/
- class WallpaperOpenLauncherAnimationRunner extends LauncherAnimationRunner {
+ protected class WallpaperOpenLauncherAnimationRunner implements WrappedAnimationRunnerImpl {
+
+ private final Handler mHandler;
private final boolean mFromUnlock;
- public WallpaperOpenLauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue,
- boolean fromUnlock) {
- super(handler, startAtFrontOfQueue);
+ public WallpaperOpenLauncherAnimationRunner(Handler handler, boolean fromUnlock) {
+ mHandler = handler;
mFromUnlock = fromUnlock;
}
@Override
+ public Handler getHandler() {
+ return mHandler;
+ }
+
+ @Override
public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
LauncherAnimationRunner.AnimationResult result) {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index ab6393a..71d77fc 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -43,6 +43,7 @@
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import com.android.quickstep.views.RecentsView;
+import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -51,10 +52,18 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
+ private int mLauncherPid;
+
@Before
public void setUp() throws Exception {
super.setUp();
TaplTestsLauncher3.initialize(this);
+ mLauncherPid = mLauncher.getPid();
+ }
+
+ @After
+ public void teardown() {
+ assertEquals("Launcher crashed, pid mismatch:", mLauncherPid, mLauncher.getPid());
}
private void startTestApps() throws Exception {
diff --git a/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
index 83b8599..6223760 100644
--- a/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
@@ -23,12 +23,14 @@
import android.database.sqlite.SQLiteDatabase;
+import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.util.LauncherModelHelper;
import com.android.launcher3.util.LauncherRoboTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.LooperMode;
/**
@@ -44,7 +46,8 @@
@Before
public void setUp() {
mModelHelper = new LauncherModelHelper();
- mDb = mModelHelper.provider.getDbWithRestoreDbTask();
+ RestoreDbTask.setPending(RuntimeEnvironment.application, true);
+ mDb = mModelHelper.provider.getDb();
}
@Test
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
index 655055c..e8b7157 100644
--- a/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
@@ -28,6 +28,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.Settings;
@@ -276,6 +277,8 @@
Context context = RuntimeEnvironment.application;
LauncherSettings.Settings.call(context.getContentResolver(),
LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
+ LauncherSettings.Settings.call(context.getContentResolver(),
+ LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
int[][][] ids = new int[typeArray.length][][];
for (int i = 0; i < typeArray.length; i++) {
@@ -312,7 +315,6 @@
idp.numRows = idp.numColumns = idp.numHotseatIcons = DEFAULT_GRID_SIZE;
idp.iconBitmapSize = DEFAULT_BITMAP_SIZE;
- provider.setAllowLoadDefaultFavorites(true);
Settings.Secure.putString(context.getContentResolver(),
"launcher3.layout.provider", TEST_PROVIDER_AUTHORITY);
@@ -340,4 +342,20 @@
filter.addCategory(Intent.CATEGORY_DEFAULT);
spm.addIntentFilterForActivity(cn, filter);
}
+
+ /**
+ * An extension of LauncherProvider backed up by in-memory database.
+ */
+ public static class TestLauncherProvider extends LauncherProvider {
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ public SQLiteDatabase getDb() {
+ createDbIfNotExists();
+ return mOpenHelper.getWritableDatabase();
+ }
+ }
}
diff --git a/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java b/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
deleted file mode 100644
index 8ae6528..0000000
--- a/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.android.launcher3.util;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-
-import com.android.launcher3.LauncherProvider;
-import com.android.launcher3.provider.RestoreDbTask;
-
-/**
- * An extension of LauncherProvider backed up by in-memory database.
- */
-public class TestLauncherProvider extends LauncherProvider {
-
- private boolean mAllowLoadDefaultFavorites;
-
- @Override
- public boolean onCreate() {
- return true;
- }
-
- @Override
- protected synchronized void createDbIfNotExists() {
- if (mOpenHelper == null) {
- mOpenHelper = new MyDatabaseHelper(getContext(), mAllowLoadDefaultFavorites);
- }
- }
-
- public void setAllowLoadDefaultFavorites(boolean allowLoadDefaultFavorites) {
- mAllowLoadDefaultFavorites = allowLoadDefaultFavorites;
- }
-
- public SQLiteDatabase getDb() {
- createDbIfNotExists();
- return mOpenHelper.getWritableDatabase();
- }
-
- public SQLiteDatabase getDbWithRestoreDbTask() {
- RestoreDbTask.setPending(getContext(), true);
- super.createDbIfNotExists();
- return mOpenHelper.getWritableDatabase();
- }
-
- private static class MyDatabaseHelper extends DatabaseHelper {
-
- private final boolean mAllowLoadDefaultFavorites;
-
- MyDatabaseHelper(Context context, boolean allowLoadDefaultFavorites) {
- super(context, null);
- mAllowLoadDefaultFavorites = allowLoadDefaultFavorites;
- initIds();
- }
-
- @Override
- public long getDefaultUserSerial() {
- return 0;
- }
-
- @Override
- protected void onEmptyDbCreated() {
- if (mAllowLoadDefaultFavorites) {
- super.onEmptyDbCreated();
- }
- }
-
- @Override
- protected void handleOneTimeDataUpgrade(SQLiteDatabase db) { }
- }
-}
diff --git a/settings.gradle b/settings.gradle
index b52bd4f..ce13bfb 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,5 @@
include ':IconLoader'
project(':IconLoader').projectDir = new File(rootDir, 'iconloaderlib')
+
+include ':SharedLibWrapper'
+project(':SharedLibWrapper').projectDir = new File(rootDir, 'SharedLibWrapper')
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index ea63fa7..3ca4f59 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -286,7 +286,7 @@
/**
* Used to set the override visibility state, used only to handle the transition home with the
* recents animation.
- * @see QuickstepAppTransitionManagerImpl#getWallpaperOpenRunner
+ * @see QuickstepAppTransitionManagerImpl#createWallpaperOpenRunner
*/
public void addForceInvisibleFlag(@InvisibilityFlags int flag) {
mForceInvisible |= flag;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f5fafbf..8066d38 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -373,6 +373,7 @@
mPopupDataProvider = new PopupDataProvider(this);
mAppTransitionManager = LauncherAppTransitionManager.newInstance(this);
+ mAppTransitionManager.registerRemoteAnimations();
boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this);
if (internalStateHandled) {
@@ -1545,6 +1546,7 @@
LauncherAppState.getIDP(this).removeOnChangeListener(this);
mOverlayManager.onActivityDestroyed(this);
+ mAppTransitionManager.unregisterRemoteAnimations();
}
public LauncherAccessibilityDelegate getAccessibilityDelegate() {
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
index c55c120..9148c2f 100644
--- a/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -67,4 +67,18 @@
public Animator createStateElementAnimation(int index, float... values) {
throw new RuntimeException("Unknown gesture animation " + index);
}
+
+ /**
+ * Registers remote animations for certain system transitions.
+ */
+ public void registerRemoteAnimations() {
+ // Do nothing
+ }
+
+ /**
+ * Unregisters all remote animations.
+ */
+ public void unregisterRemoteAnimations() {
+ // Do nothing
+ }
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index b589560..b0ab35c 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.annotation.TargetApi;
import android.app.backup.BackupManager;
@@ -45,6 +46,7 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -87,6 +89,8 @@
private static final boolean LOGD = false;
private static final String DOWNGRADE_SCHEMA_FILE = "downgrade_schema.json";
+ private static final String TOKEN_RESTORE_BACKUP_TABLE = "restore_backup_table";
+ private static final long RESTORE_BACKUP_TABLE_DELAY = 60000;
/**
* Represents the schema of the database. Changes in scheme need not be backwards compatible.
@@ -388,8 +392,11 @@
return null;
}
case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
- RestoreDbTask.restoreIfPossible(
- getContext(), mOpenHelper, new BackupManager(getContext()));
+ final Handler handler = MODEL_EXECUTOR.getHandler();
+ handler.removeCallbacksAndMessages(TOKEN_RESTORE_BACKUP_TABLE);
+ handler.postDelayed(() -> RestoreDbTask.restoreIfPossible(
+ getContext(), mOpenHelper, new BackupManager(getContext())),
+ TOKEN_RESTORE_BACKUP_TABLE, RESTORE_BACKUP_TABLE_DELAY);
return null;
}
}
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index f0bae02..89f0a3d 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -78,6 +78,7 @@
}
InstallSessionHelper packageInstallerCompat = InstallSessionHelper.INSTANCE.get(context);
+ packageInstallerCompat.restoreDbIfApplicable(info);
if (TextUtils.isEmpty(info.getAppPackageName())
|| info.getInstallReason() != PackageManager.INSTALL_REASON_USER
|| packageInstallerCompat.promiseIconAddedForId(info.getSessionId())) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 81dcba3..75609fe 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -136,6 +136,10 @@
public static final TogglableFlag ENABLE_OVERVIEW_ACTIONS = new TogglableFlag(
"ENABLE_OVERVIEW_ACTIONS", false, "Show app actions in Overview");
+ public static final TogglableFlag ENABLE_DATABASE_RESTORE = new TogglableFlag(
+ "ENABLE_DATABASE_RESTORE", true,
+ "Enable database restore when new restore session is created");
+
public static void initialize(Context context) {
// Avoid the disk read for user builds
if (Utilities.IS_DEBUG_DEVICE) {
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 186293f..976d7ba 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -29,6 +29,10 @@
import android.os.UserHandle;
import android.text.TextUtils;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.android.launcher3.LauncherSettings;
import com.android.launcher3.SessionCommitReceiver;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -52,6 +56,8 @@
// Set<String> of session ids of promise icons that have been added to the home screen
// as FLAG_PROMISE_NEW_INSTALLS.
protected static final String PROMISE_ICON_IDS = "promise_icon_ids";
+ public static final String KEY_INSTALL_SESSION_CREATED_TIMESTAMP =
+ "key_install_session_created_timestamp";
private static final boolean DEBUG = false;
@@ -159,6 +165,34 @@
return list;
}
+ /**
+ * Attempt to restore workspace layout if the session is triggered due to device restore and it
+ * has a newer timestamp.
+ */
+ public boolean restoreDbIfApplicable(@NonNull final SessionInfo info) {
+ if (!Utilities.ATLEAST_OREO || !FeatureFlags.ENABLE_DATABASE_RESTORE.get()) {
+ return false;
+ }
+ if (isRestore(info) && hasNewerTimestamp(mAppContext, info)) {
+ LauncherSettings.Settings.call(mAppContext.getContentResolver(),
+ LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE);
+ return true;
+ }
+ return false;
+ }
+
+ @RequiresApi(26)
+ private static boolean isRestore(@NonNull final SessionInfo info) {
+ return info.getInstallReason() == PackageManager.INSTALL_REASON_DEVICE_RESTORE;
+ }
+
+ private static boolean hasNewerTimestamp(
+ @NonNull final Context context, @NonNull final SessionInfo info) {
+ return PackageManagerHelper.getSessionCreatedTimeInMillis(info)
+ > Utilities.getDevicePrefs(context).getLong(
+ KEY_INSTALL_SESSION_CREATED_TIMESTAMP, 0);
+ }
+
public boolean promiseIconAddedForId(int sessionId) {
return mPromiseIconIds.contains(sessionId);
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 7ee30cc..407ff31 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -16,6 +16,7 @@
package com.android.launcher3.provider;
+import static com.android.launcher3.pm.InstallSessionHelper.KEY_INSTALL_SESSION_CREATED_TIMESTAMP;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import android.app.backup.BackupManager;
@@ -86,6 +87,8 @@
*/
public static boolean restoreIfPossible(@NonNull Context context,
@NonNull DatabaseHelper helper, @NonNull BackupManager backupManager) {
+ Utilities.getDevicePrefs(context).edit().putLong(
+ KEY_INSTALL_SESSION_CREATED_TIMESTAMP, System.currentTimeMillis()).apply();
final SQLiteDatabase db = helper.getWritableDatabase();
try (SQLiteTransaction t = new SQLiteTransaction(db)) {
RestoreDbTask task = new RestoreDbTask();
diff --git a/src/com/android/launcher3/shortcuts/ShortcutRequest.java b/src/com/android/launcher3/shortcuts/ShortcutRequest.java
index e6203b4..5291ce4 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutRequest.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutRequest.java
@@ -58,10 +58,20 @@
mUserHandle = userHandle;
}
+ /** @see #forPackage(String, List) */
+ public ShortcutRequest forPackage(String packageName) {
+ return forPackage(packageName, (List<String>) null);
+ }
+
+ /** @see #forPackage(String, List) */
public ShortcutRequest forPackage(String packageName, String... shortcutIds) {
return forPackage(packageName, Arrays.asList(shortcutIds));
}
+ /**
+ * @param shortcutIds If null, match all shortcuts, otherwise only match the given id's.
+ * @return A list of ShortcutInfo's associated with the given package.
+ */
public ShortcutRequest forPackage(String packageName, @Nullable List<String> shortcutIds) {
if (!GO_DISABLE_WIDGETS && packageName != null) {
mQuery.setPackage(packageName);
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index ecfc77c..506830d 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -126,11 +126,11 @@
case TestProtocol.REQUEST_APPS_LIST_SCROLL_Y: {
try {
- final int deferUpdatesFlags = MAIN_EXECUTOR.submit(() ->
+ final int scroll = MAIN_EXECUTOR.submit(() ->
mLauncher.getAppsView().getActiveRecyclerView().getCurrentScrollY())
.get();
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- deferUpdatesFlags);
+ scroll);
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
diff --git a/src/com/android/launcher3/testing/TestLogging.java b/src/com/android/launcher3/testing/TestLogging.java
index 024110d..fd066c1 100644
--- a/src/com/android/launcher3/testing/TestLogging.java
+++ b/src/com/android/launcher3/testing/TestLogging.java
@@ -21,7 +21,7 @@
import com.android.launcher3.Utilities;
public final class TestLogging {
- public static synchronized void recordEvent(String event) {
+ public static void recordEvent(String event) {
if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
Log.d(TestProtocol.TAPL_EVENTS_TAG, event);
}
diff --git a/src/com/android/launcher3/touch/ItemLongClickListener.java b/src/com/android/launcher3/touch/ItemLongClickListener.java
index bee7853..ba1bfa5 100644
--- a/src/com/android/launcher3/touch/ItemLongClickListener.java
+++ b/src/com/android/launcher3/touch/ItemLongClickListener.java
@@ -33,7 +33,6 @@
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.folder.Folder;
-import com.android.launcher3.testing.TestLogging;
/**
* Class to handle long-clicks on workspace items and start drag as a result.
@@ -47,7 +46,6 @@
ItemLongClickListener::onAllAppsItemLongClick;
private static boolean onWorkspaceItemLongClick(View v) {
- TestLogging.recordEvent("onWorkspaceItemLongClick");
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!canStartDrag(launcher)) return false;
if (!launcher.isInState(NORMAL) && !launcher.isInState(OVERVIEW)) return false;
@@ -77,7 +75,6 @@
}
private static boolean onAllAppsItemLongClick(View v) {
- TestLogging.recordEvent("onAllAppsItemLongClick");
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!canStartDrag(launcher)) return false;
// When we have exited all apps or are in transition, disregard long clicks
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index 61ce046..310d598 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -38,7 +38,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -166,7 +165,6 @@
@Override
public void onLongPress(MotionEvent event) {
- TestLogging.recordEvent("Workspace.longPress");
if (mLongPressState == STATE_REQUESTED) {
if (canHandleLongPress()) {
mLongPressState = STATE_PENDING_PARENT_INFORM;
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 8b2ee36..6c18747 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -16,6 +16,7 @@
package com.android.launcher3.util;
+import static android.content.pm.PackageInstaller.SessionInfo;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import android.app.AppOpsManager;
@@ -44,6 +45,8 @@
import android.util.Pair;
import android.widget.Toast;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.AppInfo;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppWidgetInfo;
@@ -345,4 +348,15 @@
}
return false;
}
+
+ /**
+ * Returns the created time in millis of given session info. Returns 0 if not available.
+ */
+ public static long getSessionCreatedTimeInMillis(@NonNull final SessionInfo info) {
+ try {
+ return (long) SessionInfo.class.getDeclaredMethod("getCreatedMillis").invoke(info);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 3758cb8..6cae43d 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -35,7 +35,6 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -91,7 +90,6 @@
@Override
public boolean onLongClick(View v) {
- TestLogging.recordEvent("Widgets.onLongClick");
if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
if (v instanceof WidgetCell) {
diff --git a/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java b/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java
new file mode 100644
index 0000000..56c885d
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util.rule;
+
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import androidx.test.uiautomator.UiDevice;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+class FailureInvestigator {
+ private static boolean matches(String regex, CharSequence string) {
+ return Pattern.compile(regex).matcher(string).find();
+ }
+
+ static int getBugForFailure(CharSequence exception, String testsStartTime) {
+ final String logSinceTestsStart;
+ try {
+ logSinceTestsStart =
+ UiDevice.getInstance(getInstrumentation())
+ .executeShellCommand("logcat -d -t " + testsStartTime.replace(" ", ""));
+ } catch (IOException e) {
+ return 0;
+ }
+
+ if (matches(
+ "java.lang.AssertionError: http://go/tapl : Tests are broken by a non-Launcher "
+ + "system error: Phone is locked",
+ exception)) {
+ if (matches(
+ "BroadcastQueue: Can't deliver broadcast to com.android.systemui.*Crashing it",
+ logSinceTestsStart)) {
+ return 147845913;
+ }
+ }
+
+ return 0;
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index cdda0f0..feb89b9 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -8,10 +8,13 @@
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
public class FailureWatcher extends TestWatcher {
private static final String TAG = "FailureWatcher";
@@ -35,6 +38,30 @@
}
}
+ private static final String testsStartTime =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } catch (Throwable e) {
+ final int bug =
+ FailureInvestigator.getBugForFailure(e.toString(), testsStartTime);
+ if (bug == 0) throw e;
+
+ Log.e(TAG, "Known bug found for the original failure "
+ + android.util.Log.getStackTraceString(e));
+ throw new AssertionError(
+ "Detected a failure that matches a known bug b/" + bug);
+ }
+ }
+ };
+ }
+
@Override
protected void failed(Throwable e, Description description) {
onError(mDevice, description, e);
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index 03d1600..afb50e0 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -37,8 +37,10 @@
}
public void addAutomatically() {
- mLauncher.waitForObjectInContainer(
- mWidgetCell.getParent().getParent().getParent().getParent(),
- By.text(ADD_AUTOMATICALLY)).click();
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.waitForObjectInContainer(
+ mWidgetCell.getParent().getParent().getParent().getParent(),
+ By.text(ADD_AUTOMATICALLY)).click();
+ }
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 3bdeb14..4a2d699 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -99,8 +99,9 @@
*/
@NonNull
public AppIcon getAppIcon(String appName) {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "getting app icon " + appName + " on all apps")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "getting app icon " + appName + " on all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
final UiObject2 appListRecycler = mLauncher.waitForObjectInContainer(allAppsContainer,
"apps_list_view");
@@ -130,6 +131,9 @@
searchBox.getVisibleBounds().bottom
- allAppsContainer.getVisibleBounds().top);
final int newScroll = getAllAppsScroll();
+ mLauncher.assertTrue(
+ "Scrolled in a wrong direction in AllApps: from " + scroll + " to "
+ + newScroll, newScroll >= scroll);
if (newScroll == scroll) break;
mLauncher.assertTrue(
@@ -197,7 +201,8 @@
* Flings forward (down) and waits the fling's end.
*/
public void flingForward() {
- try (LauncherInstrumentation.Closable c =
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling forward in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center to avoid starting at elements near the top.
@@ -211,7 +216,8 @@
* Flings backward (up) and waits the fling's end.
*/
public void flingBackward() {
- try (LauncherInstrumentation.Closable c =
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling backward in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center, for symmetry with forward.
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
index f48d4dd..8f9fec9 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
@@ -42,8 +42,9 @@
*/
@NonNull
public Overview switchBackToOverview() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to switch back from all apps to overview")) {
+ 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(
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index bf68f71..0a6ed7f 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -22,15 +22,11 @@
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
-import java.util.regex.Pattern;
-
/**
* App icon, whether in all apps or in workspace/
*/
public final class AppIcon extends Launchable {
- private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onAllAppsItemLongClick");
-
AppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
super(launcher, icon);
}
@@ -43,13 +39,10 @@
* Long-clicks the icon to open its menu.
*/
public AppIconMenu openMenu() {
- return new AppIconMenu(mLauncher, mLauncher.clickAndGet(
- mObject, "deep_shortcuts_container"));
- }
-
- @Override
- protected void addExpectedEventsForLongClick() {
- mLauncher.expectEvent(LONG_CLICK_EVENT);
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ return new AppIconMenu(mLauncher, mLauncher.clickAndGet(
+ mObject, "deep_shortcuts_container"));
+ }
}
@Override
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
index 597be90..ba9c10e 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
@@ -34,10 +34,6 @@
}
@Override
- protected void addExpectedEventsForLongClick() {
- }
-
- @Override
protected String getLongPressIndicator() {
return "drop_target_bar";
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index d9ae778..50bdf5c 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -52,8 +52,9 @@
*/
@NonNull
public BaseOverview switchToOverview() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to switch from background to overview")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to switch from background to overview")) {
verifyActiveContainer();
goToOverviewUnchecked();
return mLauncher.isFallbackOverview() ?
@@ -124,8 +125,9 @@
* Swipes right or double presses the square button to switch to the previous app.
*/
public Background quickSwitchToPreviousApp() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to quick switch to the previous app")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to quick switch to the previous app")) {
verifyActiveContainer();
quickSwitchToPreviousApp(getExpectedStateForQuickSwitch());
return new Background(mLauncher);
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 339e14f..e13ea52 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -48,6 +48,12 @@
* Flings forward (left) and waits the fling's end.
*/
public void flingForward() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ flingForwardImpl();
+ }
+ }
+
+ private void flingForwardImpl() {
try (LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling forward in overview")) {
LauncherInstrumentation.log("Overview.flingForward before fling");
@@ -65,14 +71,15 @@
* Dismissed all tasks by scrolling to Clear-all button and pressing it.
*/
public void dismissAllTasks() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "dismissing all tasks")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "dismissing all tasks")) {
final BySelector clearAllSelector = mLauncher.getOverviewObjectSelector("clear_all");
for (int i = 0;
i < FLINGS_FOR_DISMISS_LIMIT
&& !verifyActiveContainer().hasObject(clearAllSelector);
++i) {
- flingForward();
+ flingForwardImpl();
}
mLauncher.waitForObjectInContainer(verifyActiveContainer(), clearAllSelector).click();
@@ -83,7 +90,8 @@
* Flings backward (right) and waits the fling's end.
*/
public void flingBackward() {
- try (LauncherInstrumentation.Closable c =
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling backward in overview")) {
LauncherInstrumentation.log("Overview.flingBackward before fling");
final UiObject2 overview = verifyActiveContainer();
diff --git a/tests/tapl/com/android/launcher3/tapl/Home.java b/tests/tapl/com/android/launcher3/tapl/Home.java
index 1e4d937..1a0fe3d 100644
--- a/tests/tapl/com/android/launcher3/tapl/Home.java
+++ b/tests/tapl/com/android/launcher3/tapl/Home.java
@@ -48,8 +48,9 @@
@NonNull
@Override
public Overview switchToOverview() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to switch from home to overview")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to switch from home to overview")) {
verifyActiveContainer();
goToOverviewUnchecked();
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 9327cb3..f88a616 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -46,7 +46,9 @@
* Clicks the object to launch its app.
*/
public Background launch(String expectedPackageName) {
- return launch(By.pkg(expectedPackageName));
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ return launch(By.pkg(expectedPackageName));
+ }
}
private Background launch(BySelector selector) {
@@ -73,7 +75,6 @@
final Point launchableCenter = getObject().getVisibleCenter();
final Point displaySize = mLauncher.getRealDisplaySize();
final int width = displaySize.x / 2;
- addExpectedEventsForLongClick();
Workspace.dragIconToWorkspace(
mLauncher,
this,
@@ -86,7 +87,5 @@
}
}
- protected abstract void addExpectedEventsForLongClick();
-
protected abstract String getLongPressIndicator();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index bd3671b..3670392 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -560,61 +560,63 @@
* @return the Workspace object.
*/
public Workspace pressHome() {
- // Click home, then wait for any accessibility event, then wait until accessibility events
- // stop.
- // We need waiting for any accessibility event generated after pressing Home because
- // otherwise waitForIdle may return immediately in case when there was a big enough pause in
- // accessibility events prior to pressing Home.
- final String action;
- if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
- checkForAnomaly();
+ try (LauncherInstrumentation.Closable e = eventsCheck()) {
+ // Click home, then wait for any accessibility event, then wait until accessibility
+ // events stop.
+ // We need waiting for any accessibility event generated after pressing Home because
+ // otherwise waitForIdle may return immediately in case when there was a big enough
+ // pause in accessibility events prior to pressing Home.
+ final String action;
+ if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
+ checkForAnomaly();
- final Point displaySize = getRealDisplaySize();
+ final Point displaySize = getRealDisplaySize();
- if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
- linearGesture(
- displaySize.x / 2, displaySize.y - 1,
- displaySize.x / 2, 0,
- ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME,
- false);
- try (LauncherInstrumentation.Closable c = addContextLayer(
- "Swiped up from context menu to home")) {
- waitUntilGone(CONTEXT_MENU_RES_ID);
- }
- }
- if (hasLauncherObject(WORKSPACE_RES_ID)) {
- log(action = "already at home");
- } else {
- log("Hierarchy before swiping up to home:");
- dumpViewHierarchy();
- log(action = "swiping up to home from " + getVisibleStateMessage());
-
- try (LauncherInstrumentation.Closable c = addContextLayer(action)) {
- swipeToState(
+ if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
+ linearGesture(
displaySize.x / 2, displaySize.y - 1,
displaySize.x / 2, 0,
- ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL);
+ ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME,
+ false);
+ try (LauncherInstrumentation.Closable c = addContextLayer(
+ "Swiped up from context menu to home")) {
+ waitUntilGone(CONTEXT_MENU_RES_ID);
+ }
+ }
+ if (hasLauncherObject(WORKSPACE_RES_ID)) {
+ log(action = "already at home");
+ } else {
+ log("Hierarchy before swiping up to home:");
+ dumpViewHierarchy();
+ log(action = "swiping up to home from " + getVisibleStateMessage());
+
+ try (LauncherInstrumentation.Closable c = addContextLayer(action)) {
+ swipeToState(
+ displaySize.x / 2, displaySize.y - 1,
+ displaySize.x / 2, 0,
+ ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL);
+ }
+ }
+ } else {
+ log("Hierarchy before clicking home:");
+ dumpViewHierarchy();
+ log(action = "clicking home button from " + getVisibleStateMessage());
+ try (LauncherInstrumentation.Closable c = addContextLayer(action)) {
+ mDevice.waitForIdle();
+ runToState(
+ waitForSystemUiObject("home")::click,
+ NORMAL_STATE_ORDINAL,
+ !hasLauncherObject(WORKSPACE_RES_ID)
+ && (hasLauncherObject(APPS_RES_ID)
+ || hasLauncherObject(OVERVIEW_RES_ID)));
+ mDevice.waitForIdle();
}
}
- } else {
- log("Hierarchy before clicking home:");
- dumpViewHierarchy();
- log(action = "clicking home button from " + getVisibleStateMessage());
- try (LauncherInstrumentation.Closable c = addContextLayer(action)) {
- mDevice.waitForIdle();
- runToState(
- waitForSystemUiObject("home")::click,
- NORMAL_STATE_ORDINAL,
- !hasLauncherObject(WORKSPACE_RES_ID)
- && (hasLauncherObject(APPS_RES_ID)
- || hasLauncherObject(OVERVIEW_RES_ID)));
- mDevice.waitForIdle();
+ try (LauncherInstrumentation.Closable c = addContextLayer(
+ "performed action to switch to Home - " + action)) {
+ return getWorkspace();
}
}
- try (LauncherInstrumentation.Closable c = addContextLayer(
- "performed action to switch to Home - " + action)) {
- return getWorkspace();
- }
}
/**
@@ -1221,6 +1223,6 @@
private String formatEventMismatchMessage(String message, List<String> actual, int position) {
return message + ", pos=" + position
+ ", expected=" + mExpectedEvents
- + ", actual" + actual;
+ + ", actual=" + actual;
}
}
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
index 8527d05..461610d 100644
--- a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
@@ -35,12 +35,14 @@
*/
@NonNull
public void launch(@NonNull String expectedPackageName) {
- LauncherInstrumentation.log("OptionsPopupMenuItem before click "
- + mObject.getVisibleCenter() + " in " + mObject.getVisibleBounds());
- mObject.click();
- mLauncher.assertTrue(
- "App didn't start: " + By.pkg(expectedPackageName),
- mLauncher.getDevice().wait(Until.hasObject(By.pkg(expectedPackageName)),
- LauncherInstrumentation.WAIT_TIME_MS));
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ LauncherInstrumentation.log("OptionsPopupMenuItem before click "
+ + mObject.getVisibleCenter() + " in " + mObject.getVisibleBounds());
+ mObject.click();
+ mLauncher.assertTrue(
+ "App didn't start: " + By.pkg(expectedPackageName),
+ mLauncher.getDevice().wait(Until.hasObject(By.pkg(expectedPackageName)),
+ LauncherInstrumentation.WAIT_TIME_MS));
+ }
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java
index 16a64a7..6622c6e 100644
--- a/tests/tapl/com/android/launcher3/tapl/Overview.java
+++ b/tests/tapl/com/android/launcher3/tapl/Overview.java
@@ -45,8 +45,9 @@
*/
@NonNull
public AllAppsFromOverview switchToAllApps() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to switch from overview to all apps")) {
+ 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.
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 46f8ba5..0d93cbc 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -45,8 +45,9 @@
* Swipes the task up.
*/
public void dismiss() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to dismiss a task")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to dismiss a task")) {
verifyActiveContainer();
// Dismiss the task via flinging it up.
final Rect taskBounds = mTask.getVisibleBounds();
@@ -61,15 +62,17 @@
* Clicks at the task.
*/
public Background open() {
- verifyActiveContainer();
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "clicking an overview task")) {
- mLauncher.executeAndWaitForEvent(
- () -> mTask.click(),
- event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
- () -> "Launching task didn't open a new window: "
- + mTask.getParent().getContentDescription());
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ verifyActiveContainer();
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "clicking an overview task")) {
+ mLauncher.executeAndWaitForEvent(
+ () -> mTask.click(),
+ event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ () -> "Launching task didn't open a new window: "
+ + mTask.getParent().getContentDescription());
+ }
+ return new Background(mLauncher);
}
- return new Background(mLauncher);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java
index e0db16d..dfd74ed 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widget.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widget.java
@@ -18,15 +18,11 @@
import androidx.test.uiautomator.UiObject2;
-import java.util.regex.Pattern;
-
/**
* Widget in workspace or a widget list.
*/
public final class Widget extends Launchable {
- private static final Pattern LONG_CLICK_EVENT = Pattern.compile("Widgets.onLongClick");
-
Widget(LauncherInstrumentation launcher, UiObject2 icon) {
super(launcher, icon);
}
@@ -35,9 +31,4 @@
protected String getLongPressIndicator() {
return "drop_target_bar";
}
-
- @Override
- protected void addExpectedEventsForLongClick() {
- mLauncher.expectEvent(LONG_CLICK_EVENT);
- }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index d208c66..ede5bd9 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -41,8 +41,9 @@
* Flings forward (down) and waits the fling's end.
*/
public void flingForward() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to fling forward in widgets")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to fling forward in widgets")) {
LauncherInstrumentation.log("Widgets.flingForward enter");
final UiObject2 widgetsContainer = verifyActiveContainer();
mLauncher.scroll(
@@ -62,8 +63,9 @@
* Flings backward (up) and waits the fling's end.
*/
public void flingBackward() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to fling backwards in widgets")) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to fling backwards in widgets")) {
LauncherInstrumentation.log("Widgets.flingBackward enter");
final UiObject2 widgetsContainer = verifyActiveContainer();
mLauncher.scroll(
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index af7e552..1d2c821 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -85,7 +85,8 @@
*/
@NonNull
public AllApps switchToAllApps() {
- try (LauncherInstrumentation.Closable c =
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to switch from workspace to all apps")) {
verifyActiveContainer();
final int deviceHeight = mLauncher.getDevice().getDisplayHeight();
@@ -156,21 +157,23 @@
* second screen.
*/
public void ensureWorkspaceIsScrollable() {
- final UiObject2 workspace = verifyActiveContainer();
- if (!isWorkspaceScrollable(workspace)) {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "dragging icon to a second page of workspace to make it scrollable")) {
- dragIconToWorkspace(
- mLauncher,
- getHotseatAppIcon("Chrome"),
- new Point(mLauncher.getDevice().getDisplayWidth(),
- workspace.getVisibleBounds().centerY()),
- "deep_shortcuts_container");
- verifyActiveContainer();
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ final UiObject2 workspace = verifyActiveContainer();
+ if (!isWorkspaceScrollable(workspace)) {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "dragging icon to a second page of workspace to make it scrollable")) {
+ dragIconToWorkspace(
+ mLauncher,
+ getHotseatAppIcon("Chrome"),
+ new Point(mLauncher.getDevice().getDisplayWidth(),
+ workspace.getVisibleBounds().centerY()),
+ "deep_shortcuts_container");
+ verifyActiveContainer();
+ }
}
+ assertTrue("Home screen workspace didn't become scrollable",
+ isWorkspaceScrollable(workspace));
}
- assertTrue("Home screen workspace didn't become scrollable",
- isWorkspaceScrollable(workspace));
}
private boolean isWorkspaceScrollable(UiObject2 workspace) {
@@ -213,11 +216,13 @@
* recoil to complete.
*/
public void flingForward() {
- final UiObject2 workspace = verifyActiveContainer();
- mLauncher.scroll(workspace, Direction.RIGHT,
- new Rect(0, 0, mLauncher.getEdgeSensitivityWidth() + 1, 0),
- FLING_STEPS, false);
- verifyActiveContainer();
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ final UiObject2 workspace = verifyActiveContainer();
+ mLauncher.scroll(workspace, Direction.RIGHT,
+ new Rect(0, 0, mLauncher.getEdgeSensitivityWidth() + 1, 0),
+ FLING_STEPS, false);
+ verifyActiveContainer();
+ }
}
/**
@@ -225,11 +230,13 @@
* recoil to complete.
*/
public void flingBackward() {
- final UiObject2 workspace = verifyActiveContainer();
- mLauncher.scroll(workspace, Direction.LEFT,
- new Rect(mLauncher.getEdgeSensitivityWidth() + 1, 0, 0, 0),
- FLING_STEPS, false);
- verifyActiveContainer();
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ final UiObject2 workspace = verifyActiveContainer();
+ mLauncher.scroll(workspace, Direction.LEFT,
+ new Rect(mLauncher.getEdgeSensitivityWidth() + 1, 0, 0, 0),
+ FLING_STEPS, false);
+ verifyActiveContainer();
+ }
}
/**
@@ -239,10 +246,12 @@
*/
@NonNull
public Widgets openAllWidgets() {
- verifyActiveContainer();
- mLauncher.getDevice().pressKeyCode(KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON);
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("pressed Ctrl+W")) {
- return new Widgets(mLauncher);
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ verifyActiveContainer();
+ mLauncher.getDevice().pressKeyCode(KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON);
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("pressed Ctrl+W")) {
+ return new Widgets(mLauncher);
+ }
}
}