From 4dcda06542648f19ca496085a76c3184492d1d48 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 25 May 2018 10:32:40 -0700 Subject: Fixing launcher going to a different state when dragging an icon from different activity Bug: 80191074 Change-Id: I45ea646dc2bd21627e8b724dac9c9fc23c18797d --- .../LauncherAppTransitionManagerImpl.java | 9 +++- .../android/launcher3/LauncherInitListener.java | 6 ++- .../android/launcher3/uioverrides/UiFactory.java | 24 ++++++++++ .../util/RemoteFadeOutAnimationListener.java | 53 ++++++++++++++++++++++ .../launcher3/dragndrop/BaseItemDragListener.java | 2 +- .../launcher3/dragndrop/PinItemDragListener.java | 20 ++++++++ .../android/launcher3/uioverrides/UiFactory.java | 4 ++ 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 6703bb546..fe2a98fea 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -50,6 +50,7 @@ import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; +import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -236,8 +237,14 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag return bounds; } - public void setRemoteAnimationProvider(RemoteAnimationProvider animationProvider) { + public void setRemoteAnimationProvider(final RemoteAnimationProvider animationProvider, + CancellationSignal cancellationSignal) { mRemoteAnimationProvider = animationProvider; + cancellationSignal.setOnCancelListener(() -> { + if (animationProvider == mRemoteAnimationProvider) { + mRemoteAnimationProvider = null; + } + }); } /** diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java index e5e377f83..08b6bfc6a 100644 --- a/quickstep/src/com/android/launcher3/LauncherInitListener.java +++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.os.CancellationSignal; import android.os.Handler; import com.android.launcher3.states.InternalStateHandler; @@ -48,10 +49,11 @@ public class LauncherInitListener extends InternalStateHandler implements Activi // Set a one-time animation provider. After the first call, this will get cleared. // TODO: Probably also check the intended target id. + CancellationSignal cancellationSignal = new CancellationSignal(); appTransitionManager.setRemoteAnimationProvider((targets) -> { // On the first call clear the reference. - appTransitionManager.setRemoteAnimationProvider(null); + cancellationSignal.cancel(); RemoteAnimationProvider provider = mRemoteAnimationProvider; mRemoteAnimationProvider = null; @@ -59,7 +61,7 @@ public class LauncherInitListener extends InternalStateHandler implements Activi return provider.createWindowAnimation(targets); } return null; - }); + }, cancellationSignal); } OverviewCallbacks.get(launcher).onInitOverviewTransition(); return mOnInitListener.test(launcher, alreadyOnHome); diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java index d0c7b2117..dd5dcbeaf 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java @@ -25,14 +25,19 @@ import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_SEEN; import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN; +import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; +import android.animation.AnimatorSet; +import android.animation.ValueAnimator; import android.app.Activity; import android.content.Context; +import android.os.CancellationSignal; import android.util.Base64; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppTransitionManagerImpl; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager; import com.android.launcher3.LauncherStateManager.StateHandler; @@ -41,6 +46,8 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.util.TouchController; import com.android.quickstep.OverviewInteractionState; import com.android.quickstep.RecentsModel; +import com.android.quickstep.util.RemoteAnimationTargetSet; +import com.android.quickstep.util.RemoteFadeOutAnimationListener; import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.system.ActivityCompat; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -179,6 +186,23 @@ public class UiFactory { } } + public static void useFadeOutAnimationForLauncherStart(Launcher launcher, + CancellationSignal cancellationSignal) { + LauncherAppTransitionManagerImpl appTransitionManager = + (LauncherAppTransitionManagerImpl) launcher.getAppTransitionManager(); + appTransitionManager.setRemoteAnimationProvider((targets) -> { + + // On the first call clear the reference. + cancellationSignal.cancel(); + + ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0); + fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(targets)); + AnimatorSet anim = new AnimatorSet(); + anim.play(fadeAnimation); + return anim; + }, cancellationSignal); + } + public static boolean dumpActivity(Activity activity, PrintWriter writer) { if (!Utilities.IS_DEBUG_DEVICE) { return false; diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java new file mode 100644 index 000000000..40dd74bbb --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import static com.android.quickstep.util.RemoteAnimationProvider.prepareTargetsForFirstFrame; +import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; + +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; + +import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.TransactionCompat; + +/** + * Animation listener which fades out the closing targets + */ +public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener { + + private final RemoteAnimationTargetSet mTarget; + private boolean mFirstFrame = true; + + public RemoteFadeOutAnimationListener(RemoteAnimationTargetCompat[] targets) { + mTarget = new RemoteAnimationTargetSet(targets, MODE_CLOSING); + } + + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + TransactionCompat t = new TransactionCompat(); + if (mFirstFrame) { + prepareTargetsForFirstFrame(mTarget.unfilteredApps, t, MODE_CLOSING); + mFirstFrame = false; + } + + float alpha = 1 - valueAnimator.getAnimatedFraction(); + for (RemoteAnimationTargetCompat app : mTarget.apps) { + t.setAlpha(app.leash, alpha); + } + t.apply(); + } +} diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java index df4a7c1f5..1e84b416b 100644 --- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java @@ -159,7 +159,7 @@ public abstract class BaseItemDragListener extends InternalStateHandler implemen postCleanup(); } - private void postCleanup() { + protected void postCleanup() { clearReference(); if (mLauncher != null) { // Remove any drag params from the launcher intent since the drag operation is complete. diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java index 924bb4c25..07eb0d60b 100644 --- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java @@ -22,14 +22,17 @@ import android.content.pm.LauncherApps.PinItemRequest; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; +import android.os.CancellationSignal; import android.view.DragEvent; import android.view.View; import android.widget.RemoteViews; import com.android.launcher3.DragSource; import com.android.launcher3.ItemInfo; +import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.PendingAddItemInfo; +import com.android.launcher3.uioverrides.UiFactory; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; @@ -44,11 +47,13 @@ import com.android.launcher3.widget.WidgetAddFlowHandler; public class PinItemDragListener extends BaseItemDragListener { private final PinItemRequest mRequest; + private final CancellationSignal mCancelSignal; public PinItemDragListener(PinItemRequest request, Rect previewRect, int previewBitmapWidth, int previewViewWidth) { super(previewRect, previewBitmapWidth, previewViewWidth); mRequest = request; + mCancelSignal = new CancellationSignal(); } @Override @@ -59,6 +64,15 @@ public class PinItemDragListener extends BaseItemDragListener { return super.onDragStart(event); } + @Override + public boolean init(Launcher launcher, boolean alreadyOnHome) { + super.init(launcher, alreadyOnHome); + if (!alreadyOnHome) { + UiFactory.useFadeOutAnimationForLauncherStart(launcher, mCancelSignal); + } + return false; + } + @Override protected PendingItemDragHelper createDragHelper() { final PendingAddItemInfo item; @@ -95,6 +109,12 @@ public class PinItemDragListener extends BaseItemDragListener { targetParent.containerType = LauncherLogProto.ContainerType.PINITEM; } + @Override + protected void postCleanup() { + super.postCleanup(); + mCancelSignal.cancel(); + } + public static RemoteViews getPreview(PinItemRequest request) { Bundle extras = request.getExtras(); if (extras != null && diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java index db98f9a80..5a7e50fae 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java @@ -18,6 +18,7 @@ package com.android.launcher3.uioverrides; import android.app.Activity; import android.content.Context; +import android.os.CancellationSignal; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherStateManager.StateHandler; @@ -51,6 +52,9 @@ public class UiFactory { public static void onTrimMemory(Launcher launcher, int level) { } + public static void useFadeOutAnimationForLauncherStart(Launcher launcher, + CancellationSignal cancellationSignal) { } + public static boolean dumpActivity(Activity activity, PrintWriter writer) { return false; } -- cgit v1.2.3