Merge "Automatically diagnosing known flakes" into ub-launcher3-master
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/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/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/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index cab7f54..4a2d699 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -131,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(