Merge "Removing static instance of LauncherAppsCompat and unnecessary wrapper classes" into ub-launcher3-master
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index ae8fd82..f2aa842 100644
--- a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -89,5 +89,5 @@
return RotationMode.NORMAL;
}
- public static void clearSwipeSharedState(boolean finishAnimation) {}
+ public static void clearSwipeSharedState(Launcher launcher, boolean finishAnimation) { }
}
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index ddf0fff..b1a3881 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -32,7 +32,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.LauncherAnimationRunner;
import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
import com.android.quickstep.views.IconRecentsView;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
@@ -113,8 +113,8 @@
return anim;
}
- RemoteAnimationTargetSet targetSet =
- new RemoteAnimationTargetSet(appTargets, wallpaperTargets, MODE_CLOSING);
+ RemoteAnimationTargets targetSet =
+ new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_CLOSING);
mRecentsView.setTransitionedFromApp(!targetSet.isAnimatingHome());
RemoteAnimationTargetCompat recentsTarget = null;
diff --git a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
index 4994526..37c2c04 100644
--- a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -27,7 +27,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ActivityInitListener;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
import com.android.quickstep.views.IconRecentsView;
import java.util.function.BiPredicate;
@@ -59,7 +59,7 @@
boolean isAnimatingToRecents = false;
@Override
- public void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) {
+ public void onRemoteAnimationReceived(RemoteAnimationTargets targets) {
isAnimatingToRecents = targets != null && targets.isAnimatingHome();
if (!isAnimatingToRecents) {
rv.setAlpha(1);
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 19dd82f..6b936cb 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -34,6 +34,8 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.DefaultDisplay;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -44,15 +46,6 @@
public class TouchInteractionService extends Service {
private static final String TAG = "GoTouchInteractionService";
- private boolean mIsUserUnlocked;
- private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
- initWhenUserUnlocked();
- }
- }
- };
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
@@ -68,21 +61,21 @@
@Override
public void onOverviewToggle() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewCommandHelper.onOverviewToggle();
}
}
@Override
public void onOverviewShown(boolean triggeredFromAltTab) {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewCommandHelper.onOverviewShown(triggeredFromAltTab);
}
}
@Override
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- if (mIsUserUnlocked && triggeredFromAltTab && !triggeredFromHomeKey) {
+ if (mDeviceState.isUserUnlocked() && triggeredFromAltTab && !triggeredFromHomeKey) {
// onOverviewShownFromAltTab hides the overview and ends at the target app
mOverviewCommandHelper.onOverviewHidden();
}
@@ -90,7 +83,7 @@
@Override
public void onTip(int actionType, int viewType) {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewCommandHelper.onTip(actionType, viewType);
}
}
@@ -140,35 +133,30 @@
private RecentsModel mRecentsModel;
private OverviewComponentObserver mOverviewComponentObserver;
private OverviewCommandHelper mOverviewCommandHelper;
+ private RecentsAnimationDeviceState mDeviceState;
@Override
public void onCreate() {
super.onCreate();
- if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
- initWhenUserUnlocked();
- } else {
- mIsUserUnlocked = false;
- registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
- }
+ mDeviceState = new RecentsAnimationDeviceState(this);
+ mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
sConnected = true;
}
- private void initWhenUserUnlocked() {
+ public void onUserUnlocked() {
mRecentsModel = RecentsModel.INSTANCE.get(this);
- mOverviewComponentObserver = new OverviewComponentObserver(this);
+ mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
mOverviewCommandHelper = new OverviewCommandHelper(this,
mOverviewComponentObserver);
- mIsUserUnlocked = true;
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
}
@Override
public void onDestroy() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewComponentObserver.onDestroy();
}
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
+ mDeviceState.destroy();
sConnected = false;
super.onDestroy();
}
diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
index fc7d6b3..f491ed7 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
@@ -22,6 +22,7 @@
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
+
import androidx.annotation.NonNull;
/**
@@ -35,6 +36,8 @@
static final boolean ATLEAST_OREO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
+ private static final float ICON_BADGE_SCALE = 0.444f;
+
private final Rect mOldBounds = new Rect();
protected final Context mContext;
private final Canvas mCanvas;
@@ -254,7 +257,7 @@
* Adds the {@param badge} on top of {@param target} using the badge dimensions.
*/
public void badgeWithDrawable(Canvas target, Drawable badge) {
- int badgeSize = mContext.getResources().getDimensionPixelSize(R.dimen.profile_badge_size);
+ int badgeSize = getBadgeSizeForIconSize(mIconBitmapSize);
badge.setBounds(mIconBitmapSize - badgeSize, mIconBitmapSize - badgeSize,
mIconBitmapSize, mIconBitmapSize);
badge.draw(target);
@@ -335,6 +338,13 @@
}
/**
+ * Returns the correct badge size given an icon size
+ */
+ public static int getBadgeSizeForIconSize(int iconSize) {
+ return (int) (ICON_BADGE_SCALE * iconSize);
+ }
+
+ /**
* An extension of {@link BitmapDrawable} which returns the bitmap pixel size as intrinsic size.
* This allows the badging to be done based on the action bitmap size rather than
* the scaled bitmap size.
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 3384397..d842484 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -36,7 +36,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.SpringAnimationBuilder;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -71,7 +71,7 @@
TaskView taskView = findTaskViewToLaunch(mLauncher, v, appTargets);
- ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher);
+ AppWindowAnimationHelper helper = new AppWindowAnimationHelper(mLauncher);
anim.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, appTargets,
wallpaperTargets, helper).setDuration(RECENTS_LAUNCH_DURATION));
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 46e883a..2f8af44 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;
@@ -196,11 +197,15 @@
return new RecentsViewStateController(launcher);
}
- /**
- * Clears the swipe shared state for the current swipe gesture.
- */
- public static void clearSwipeSharedState(boolean finishAnimation) {
- TouchInteractionService.getSwipeSharedState().clearAllState(finishAnimation);
+ /** Clears the swipe shared state for the current swipe gesture. */
+ public static void clearSwipeSharedState(Launcher launcher, boolean finishAnimation) {
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ launcher.<RecentsView>getOverviewPanel().switchToScreenshot(
+ () -> TouchInteractionService.getSwipeSharedState().clearAllState(
+ finishAnimation));
+ } else {
+ TouchInteractionService.getSwipeSharedState().clearAllState(finishAnimation);
+ }
}
/**
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 468b8af..e4e60a0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -78,7 +78,7 @@
} else {
dummyTask = recentsView.getTaskViewAt(0);
}
- return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask)
+ return recentsView.getTempAppWindowAnimationHelper().updateForFullscreenOverview(dummyTask)
.getScaleAndTranslation();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index b939898..1b49732 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -30,9 +30,9 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
@@ -115,7 +115,7 @@
return anim;
}
- RemoteAnimationTargetSet targetSet = new RemoteAnimationTargetSet(appTargets,
+ RemoteAnimationTargets targetSet = new RemoteAnimationTargets(appTargets,
wallpaperTargets, MODE_CLOSING);
// Use the top closing app to determine the insets for the animation
@@ -126,7 +126,7 @@
return anim;
}
- final ClipAnimationHelper clipHelper = new ClipAnimationHelper(mActivity);
+ final AppWindowAnimationHelper clipHelper = new AppWindowAnimationHelper(mActivity);
// At this point, the activity is already started and laid-out. Get the home-bounds
// relative to the screen using the rootView of the activity.
@@ -142,19 +142,21 @@
clipHelper.updateTargetRect(targetRect);
clipHelper.prepareAnimation(mActivity.getDeviceProfile(), false /* isOpening */);
- ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
+ AppWindowAnimationHelper.TransformParams params = new AppWindowAnimationHelper.TransformParams()
.setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView));
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
valueAnimator.addUpdateListener((v) -> {
- params.setProgress((float) v.getAnimatedValue());
- clipHelper.applyTransform(targetSet, params);
+ params.setProgress((float) v.getAnimatedValue())
+ .setTargetSet(targetSet)
+ .setLauncherOnTop(true);
+ clipHelper.applyTransform(params);
});
if (targetSet.isAnimatingHome()) {
// If we are animating home, fade in the opening targets
- RemoteAnimationTargetSet openingSet = new RemoteAnimationTargetSet(appTargets,
+ RemoteAnimationTargets openingSet = new RemoteAnimationTargets(appTargets,
wallpaperTargets, MODE_OPENING);
TransactionCompat transaction = new TransactionCompat();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index d524b5d..770857b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -61,12 +61,12 @@
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.util.ActivityInitListener;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
+import com.android.quickstep.util.AppWindowAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.util.RemoteAnimationTargets;
+import com.android.quickstep.util.RecentsAnimationTargets;
+import com.android.quickstep.util.RecentsAnimationCallbacks.RecentsAnimationListener;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.InputConsumerController;
@@ -80,7 +80,7 @@
*/
@TargetApi(Build.VERSION_CODES.Q)
public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q extends RecentsView>
- implements SwipeAnimationListener {
+ implements RecentsAnimationListener {
private static final String TAG = "BaseSwipeUpHandler";
protected static final Rect TEMP_RECT = new Rect();
@@ -102,7 +102,7 @@
protected final RecentsModel mRecentsModel;
protected final int mRunningTaskId;
- protected final ClipAnimationHelper mClipAnimationHelper;
+ protected final AppWindowAnimationHelper mAppWindowAnimationHelper;
protected final TransformParams mTransformParams = new TransformParams();
private final Vibrator mVibrator;
@@ -144,7 +144,7 @@
this::createNewInputProxyHandler);
mMode = SysUINavigationMode.getMode(context);
- mClipAnimationHelper = new ClipAnimationHelper(context);
+ mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
mVibrator = context.getSystemService(Vibrator.class);
initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
@@ -220,7 +220,7 @@
}
});
mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper);
- mRecentsView.setClipAnimationHelper(mClipAnimationHelper);
+ mRecentsView.setAppWindowAnimationHelper(mAppWindowAnimationHelper);
}
protected void startNewTask(int successStateFlag, Consumer<Boolean> resultCallback) {
@@ -257,7 +257,7 @@
}
@Override
- public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+ public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
final Rect overviewStackBounds;
RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
@@ -275,10 +275,10 @@
dp.updateInsets(targetSet.homeContentInsets);
dp.updateIsSeascape(mContext);
if (runningTaskTarget != null) {
- mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
+ mAppWindowAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
}
- mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */);
+ mAppWindowAnimationHelper.prepareAnimation(dp, false /* isOpening */);
initTransitionEndpoints(dp);
mRecentsAnimationWrapper.setController(targetSet);
@@ -306,9 +306,9 @@
// screen of the launcher window may be stale (position is not updated until first
// traversal after the window is resized). We only do this for non-multiwindow because
// we otherwise use the minimized home bounds provided by the system.
- mClipAnimationHelper.updateHomeBounds(getStackBounds(dp));
+ mAppWindowAnimationHelper.updateHomeBounds(getStackBounds(dp));
}
- mClipAnimationHelper.updateTargetRect(TEMP_RECT);
+ mAppWindowAnimationHelper.updateTargetRect(TEMP_RECT);
if (mMode == Mode.NO_BUTTON) {
// We can drag all the way to the top of the screen.
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
@@ -366,10 +366,13 @@
float shift = mCurrentShift.value;
float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset();
float offsetScale = getTaskCurveScaleForOffsetX(offsetX,
- mClipAnimationHelper.getTargetRect().width());
- mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale);
- mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet,
- mTransformParams);
+ mAppWindowAnimationHelper.getTargetRect().width());
+ mTransformParams.setProgress(shift)
+ .setOffsetX(offsetX)
+ .setOffsetScale(offsetScale)
+ .setTargetSet(mRecentsAnimationWrapper.targetSet)
+ .setLauncherOnTop(true);
+ mAppWindowAnimationHelper.applyTransform(mTransformParams);
}
private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) {
@@ -385,9 +388,12 @@
*/
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
HomeAnimationFactory homeAnimationFactory) {
- final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
- final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet,
- mTransformParams.setProgress(startProgress), false /* launcherOnTop */));
+ final RemoteAnimationTargets targetSet = mRecentsAnimationWrapper.targetSet;
+ final RectF startRect = new RectF(
+ mAppWindowAnimationHelper.applyTransform(
+ mTransformParams.setProgress(startProgress)
+ .setTargetSet(targetSet)
+ .setLauncherOnTop(false)));
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
final View floatingView = homeAnimationFactory.getFloatingView();
@@ -403,7 +409,7 @@
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
// rounding at the end of the animation.
- float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
+ float startRadius = mAppWindowAnimationHelper.getCurrentCornerRadius();
float endRadius = startRect.width() / 6f;
// We want the window alpha to be 0 once this threshold is met, so that the
// FolderIconView can be seen morphing into the icon shape.
@@ -434,12 +440,11 @@
mTransformParams.setCornerRadius(endRadius * progress + startRadius
* (1f - progress));
}
- mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
- false /* launcherOnTop */);
+ mAppWindowAnimationHelper.applyTransform(mTransformParams);
if (isFloatingIconView) {
((FloatingIconView) floatingView).update(currentRect, 1f, progress,
- windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(),
+ windowAlphaThreshold, mAppWindowAnimationHelper.getCurrentCornerRadius(),
false);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
index 33180a9..04ece7c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -37,7 +37,7 @@
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.LayoutUtils;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -138,7 +138,7 @@
boolean isAnimatingToRecents = false;
@Override
- public void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) {
+ public void onRemoteAnimationReceived(RemoteAnimationTargets targets) {
isAnimatingToRecents = targets != null && targets.isAnimatingHome();
if (!isAnimatingToRecents) {
rv.setContentAlpha(1);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index e7005a6..c749761 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -38,7 +38,6 @@
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Region;
import android.os.UserHandle;
import android.view.MotionEvent;
import android.view.View;
@@ -67,6 +66,7 @@
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.plugins.shared.LauncherOverlayManager;
+import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.function.BiPredicate;
@@ -440,8 +440,8 @@
}
@Override
- public boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
- return activeNavBarRegion.contains((int) ev.getX(), (int) ev.getY());
+ public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+ return deviceState.isInDeferredGestureRegion(ev);
}
@Override
@@ -491,4 +491,24 @@
om.hideOverlay(150);
}
}
+
+ @Override
+ public void switchToScreenshot(ThumbnailData thumbnailData, Runnable runnable) {
+ Launcher launcher = getCreatedActivity();
+ RecentsView recentsView = launcher.getOverviewPanel();
+ if (recentsView == null) {
+ if (runnable != null) {
+ runnable.run();
+ }
+ return;
+ }
+ TaskView taskView = recentsView.getRunningTaskView();
+ if (taskView != null) {
+ taskView.setShowScreenshot(true);
+ taskView.getThumbnail().setThumbnail(taskView.getTask(), thumbnailData);
+ ViewUtils.postDraw(taskView, runnable);
+ } else if (runnable != null) {
+ runnable.run();
+ }
+ }
}
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
index c4f375a..6ac7546 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -5,10 +5,12 @@
import android.content.Context;
import android.os.Bundle;
+import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.testing.TestInformationHandler;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
+import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -78,7 +80,8 @@
}
private RecentsView getRecentsView() {
- OverviewComponentObserver observer = new OverviewComponentObserver(mContext);
+ OverviewComponentObserver observer = new OverviewComponentObserver(mContext,
+ new RecentsAnimationDeviceState(mContext));
try {
return observer.getActivityControlHelper().getCreatedActivity().getOverviewPanel();
} finally {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index 4a9aa2d..7b8ec4d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -42,7 +42,7 @@
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsRootView;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityOptionsCompat;
@@ -177,7 +177,7 @@
RemoteAnimationTargetCompat[] wallpaperTargets) {
AnimatorSet target = new AnimatorSet();
boolean activityClosing = taskIsATargetWithMode(appTargets, getTaskId(), MODE_CLOSING);
- ClipAnimationHelper helper = new ClipAnimationHelper(this);
+ AppWindowAnimationHelper helper = new AppWindowAnimationHelper(this);
target.play(getRecentsWindowAnimator(taskView, !activityClosing, appTargets,
wallpaperTargets, helper).setDuration(RECENTS_LAUNCH_DURATION));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index c4d3fa0..43c4a0b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -29,7 +29,7 @@
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.inputconsumers.InputConsumer;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.RecentsAnimationTargets;
import com.android.systemui.shared.system.InputConsumerController;
import java.util.ArrayList;
@@ -46,7 +46,7 @@
// than the state callbacks as these run on the current worker thread.
private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
- public SwipeAnimationTargetSet targetSet;
+ public RecentsAnimationTargets targetSet;
private boolean mWindowThresholdCrossed = false;
@@ -69,7 +69,7 @@
}
@UiThread
- public synchronized void setController(SwipeAnimationTargetSet targetSet) {
+ public synchronized void setController(RecentsAnimationTargets targetSet) {
Preconditions.assertUIThread();
this.targetSet = targetSet;
@@ -127,7 +127,7 @@
private void finishAndClear(boolean toRecents, Runnable onFinishComplete,
boolean sendUserLeaveHint) {
- SwipeAnimationTargetSet controller = targetSet;
+ RecentsAnimationTargets controller = targetSet;
targetSet = null;
disableInputProxy();
if (controller != null) {
@@ -221,7 +221,7 @@
}
}
- public SwipeAnimationTargetSet getController() {
+ public RecentsAnimationTargets getController() {
return targetSet;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
index 8783ee3..6b98a89 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
@@ -22,21 +22,26 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.Preconditions;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.util.RecentsAnimationCallbacks;
+import com.android.quickstep.util.RecentsAnimationTargets;
+import com.android.quickstep.util.RecentsAnimationCallbacks.RecentsAnimationListener;
+
+import com.android.systemui.shared.recents.model.ThumbnailData;
import java.io.PrintWriter;
/**
* Utility class used to store state information shared across multiple transitions.
*/
-public class SwipeSharedState implements SwipeAnimationListener {
+public class SwipeSharedState implements RecentsAnimationListener {
private OverviewComponentObserver mOverviewComponentObserver;
- private RecentsAnimationListenerSet mRecentsAnimationListener;
- private SwipeAnimationTargetSet mLastAnimationTarget;
+ private RecentsAnimationCallbacks mRecentsAnimationListener;
+ private RecentsAnimationTargets mLastAnimationTarget;
+
+ // TODO: Remove
+ private Runnable mRecentsAnimationCanceledCallback;
private boolean mLastAnimationCancelled = false;
private boolean mLastAnimationRunning = false;
@@ -52,7 +57,7 @@
}
@Override
- public final void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+ public final void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
mLastAnimationTarget = targetSet;
mLastAnimationCancelled = false;
@@ -67,11 +72,30 @@
}
@Override
- public final void onRecentsAnimationCanceled() {
+ public final void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
+ if (thumbnailData != null) {
+ mOverviewComponentObserver.getActivityControlHelper().switchToScreenshot(thumbnailData,
+ () -> {
+ if (mRecentsAnimationCanceledCallback != null) {
+ mRecentsAnimationCanceledCallback.run();
+ }
+ clearAnimationState();
+ });
+ } else {
+ clearAnimationState();
+ }
+ }
+
+ public void setRecentsAnimationCanceledCallback(Runnable callback) {
+ mRecentsAnimationCanceledCallback = callback;
+ }
+
+ private void clearAnimationState() {
clearAnimationTarget();
mLastAnimationCancelled = true;
mLastAnimationRunning = false;
+ mRecentsAnimationCanceledCallback = null;
}
private void clearListenerState(boolean finishAnimation) {
@@ -92,13 +116,13 @@
mLastAnimationRunning = false;
}
- private void onSwipeAnimationFinished(SwipeAnimationTargetSet targetSet) {
+ private void onSwipeAnimationFinished(RecentsAnimationTargets targetSet) {
if (mLastAnimationTarget == targetSet) {
mLastAnimationRunning = false;
}
}
- public RecentsAnimationListenerSet newRecentsAnimationListenerSet() {
+ public RecentsAnimationCallbacks newRecentsAnimationListenerSet() {
Preconditions.assertUIThread();
if (mLastAnimationRunning) {
@@ -113,21 +137,21 @@
clearListenerState(false /* finishAnimation */);
boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false
: mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen();
- mRecentsAnimationListener = new RecentsAnimationListenerSet(
+ mRecentsAnimationListener = new RecentsAnimationCallbacks(
shouldMinimiseSplitScreen, this::onSwipeAnimationFinished);
mRecentsAnimationListener.addListener(this);
return mRecentsAnimationListener;
}
- public RecentsAnimationListenerSet getActiveListener() {
+ public RecentsAnimationCallbacks getActiveListener() {
return mRecentsAnimationListener;
}
- public void applyActiveRecentsAnimationState(SwipeAnimationListener listener) {
+ public void applyActiveRecentsAnimationState(RecentsAnimationListener listener) {
if (mLastAnimationTarget != null) {
listener.onRecentsAnimationStart(mLastAnimationTarget);
} else if (mLastAnimationCancelled) {
- listener.onRecentsAnimationCanceled();
+ listener.onRecentsAnimationCanceled(null);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index 00fa0f2..b55fd8b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.Animator;
@@ -30,14 +31,19 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Utilities;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.MultiValueUpdateListener;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/**
* Utility class for helpful methods related to {@link TaskView} objects and their tasks.
@@ -112,15 +118,17 @@
*/
public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets, final ClipAnimationHelper inOutHelper) {
+ RemoteAnimationTargetCompat[] wallpaperTargets, final AppWindowAnimationHelper inOutHelper) {
SyncRtSurfaceTransactionApplierCompat applier =
new SyncRtSurfaceTransactionApplierCompat(v);
- ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
- .setSyncTransactionApplier(applier);
-
- final RemoteAnimationTargetSet targetSet =
- new RemoteAnimationTargetSet(appTargets, wallpaperTargets, MODE_OPENING);
+ final RemoteAnimationTargets targetSet =
+ new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_OPENING);
targetSet.addDependentTransactionApplier(applier);
+ AppWindowAnimationHelper.TransformParams params =
+ new AppWindowAnimationHelper.TransformParams()
+ .setSyncTransactionApplier(applier)
+ .setTargetSet(targetSet)
+ .setLauncherOnTop(true);
final RecentsView recentsView = v.getRecentsView();
final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
@@ -152,7 +160,33 @@
public void onUpdate(float percent) {
// TODO: Take into account the current fullscreen progress for animating the insets
params.setProgress(1 - percent);
- RectF taskBounds = inOutHelper.applyTransform(targetSet, params);
+ RectF taskBounds;
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ List<SurfaceParams> surfaceParamsList = new ArrayList<>();
+ // Append the surface transform params for the app that's being opened.
+ Collections.addAll(surfaceParamsList, inOutHelper.getSurfaceParams(params));
+
+ AppWindowAnimationHelper liveTileAnimationHelper =
+ v.getRecentsView().getClipAnimationHelper();
+ if (liveTileAnimationHelper != null) {
+ // Append the surface transform params for the live tile app.
+ AppWindowAnimationHelper.TransformParams liveTileParams =
+ v.getRecentsView().getLiveTileParams(true /* mightNeedToRefill */);
+ if (liveTileParams != null) {
+ Collections.addAll(surfaceParamsList,
+ liveTileAnimationHelper.getSurfaceParams(liveTileParams));
+ }
+ }
+ // Apply surface transform using the surface params list.
+ AppWindowAnimationHelper.applySurfaceParams(params.syncTransactionApplier,
+ surfaceParamsList.toArray(new SurfaceParams[surfaceParamsList.size()]));
+ // Get the task bounds for the app that's being opened after surface transform
+ // update.
+ taskBounds = inOutHelper.updateCurrentRect(params);
+ } else {
+ taskBounds = inOutHelper.applyTransform(params);
+ }
+
int taskIndex = recentsView.indexOfChild(v);
int centerTaskIndex = recentsView.getCurrentPage();
boolean parallaxCenterAndAdjacentTask = taskIndex != centerTaskIndex;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 7c1bc4e..4ca8055 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -27,15 +27,6 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
import android.annotation.TargetApi;
@@ -43,48 +34,35 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.app.TaskInfo;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Process;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
import android.view.Choreographer;
import android.view.InputEvent;
import android.view.MotionEvent;
-import android.view.Surface;
-import androidx.annotation.BinderThread;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.R;
-import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.logging.EventLogArray;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.DejankBinderTracker;
-import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
-import com.android.quickstep.inputconsumers.AssistantTouchConsumer;
+import com.android.quickstep.inputconsumers.AssistantInputConsumer;
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
import com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer;
import com.android.quickstep.inputconsumers.InputConsumer;
@@ -99,10 +77,7 @@
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
-import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.RecentsAnimationListener;
-import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
import com.android.systemui.shared.system.TaskInfoCompat;
import java.io.FileDescriptor;
@@ -133,7 +108,7 @@
*/
@TargetApi(Build.VERSION_CODES.Q)
public class TouchInteractionService extends Service implements
- NavigationModeChangeListener, DefaultDisplay.DisplayInfoChangeListener {
+ NavigationModeChangeListener {
/**
* NOTE: This value should be kept same as
@@ -154,10 +129,6 @@
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
- public void onActiveNavBarRegionChanges(Region region) {
- mActiveNavBarRegion = region;
- }
-
public void onInitialize(Bundle bundle) {
mISystemUiProxy = ISystemUiProxy.Stub
.asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
@@ -192,14 +163,14 @@
@Override
public void onAssistantAvailable(boolean available) {
- mAssistantAvailable = available;
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setAssistantAvailable(available));
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::onAssistantVisibilityChanged);
}
@Override
public void onAssistantVisibilityChanged(float visibility) {
- mLastAssistantVisibility = visibility;
- MAIN_EXECUTOR.execute(
- TouchInteractionService.this::onAssistantVisibilityChanged);
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setAssistantVisibility(visibility));
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::onAssistantVisibilityChanged);
}
public void onBackAction(boolean completed, int downX, int downY, boolean isButton,
@@ -219,10 +190,14 @@
}
public void onSystemUiStateChanged(int stateFlags) {
- mSystemUiStateFlags = stateFlags;
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setSystemUiFlags(stateFlags));
MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
}
+ public void onActiveNavBarRegionChanges(Region region) {
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
+ }
+
/** Deprecated methods **/
public void onQuickStep(MotionEvent motionEvent) { }
@@ -272,71 +247,28 @@
private OverviewCommandHelper mOverviewCommandHelper;
private OverviewComponentObserver mOverviewComponentObserver;
private OverviewInteractionState mOverviewInteractionState;
- private TaskOverlayFactory mTaskOverlayFactory;
private InputConsumerController mInputConsumer;
- private boolean mAssistantAvailable;
- private float mLastAssistantVisibility = 0;
- private @SystemUiStateFlags int mSystemUiStateFlags;
-
- private boolean mIsUserUnlocked;
- private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
- initWhenUserUnlocked();
- }
- }
- };
+ private RecentsAnimationDeviceState mDeviceState;
private InputConsumer mUncheckedConsumer = InputConsumer.NO_OP;
private InputConsumer mConsumer = InputConsumer.NO_OP;
private Choreographer mMainChoreographer;
- private Region mActiveNavBarRegion = new Region();
-
private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver;
private Mode mMode = Mode.THREE_BUTTONS;
- private int mDefaultDisplayId;
- private final RectF mSwipeTouchRegion = new RectF();
- private final RectF mAssistantLeftRegion = new RectF();
- private final RectF mAssistantRightRegion = new RectF();
-
- private ComponentName mGestureBlockingActivity;
-
- private Region mExclusionRegion;
- private SystemGestureExclusionListenerCompat mExclusionListener;
@Override
public void onCreate() {
super.onCreate();
+ mDeviceState = new RecentsAnimationDeviceState(this);
+ mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
// Initialize anything here that is needed in direct boot mode.
- // Everything else should be initialized in initWhenUserUnlocked() below.
+ // Everything else should be initialized in onUserUnlocked() below.
mMainChoreographer = Choreographer.getInstance();
mAM = ActivityManagerWrapper.getInstance();
- if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
- initWhenUserUnlocked();
- } else {
- mIsUserUnlocked = false;
- registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
- }
-
- mDefaultDisplayId = DefaultDisplay.INSTANCE.get(this).getInfo().id;
- String blockingActivity = getString(R.string.gesture_blocking_activity);
- mGestureBlockingActivity = TextUtils.isEmpty(blockingActivity) ? null :
- ComponentName.unflattenFromString(blockingActivity);
-
- mExclusionListener = new SystemGestureExclusionListenerCompat(mDefaultDisplayId) {
- @Override
- @BinderThread
- public void onExclusionChanged(Region region) {
- // Assignments are atomic, it should be safe on binder thread
- mExclusionRegion = region;
- }
- };
-
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this));
sConnected = true;
}
@@ -359,17 +291,18 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1");
}
+ disposeEventHandlers();
if (!mMode.hasGestures || mISystemUiProxy == null) {
return;
}
- disposeEventHandlers();
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2");
}
try {
mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy
- .monitorGestureInput("swipe-up", mDefaultDisplayId), KEY_EXTRA_INPUT_MONITOR);
+ .monitorGestureInput("swipe-up", mDeviceState.getDisplayId()),
+ KEY_EXTRA_INPUT_MONITOR);
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
mMainChoreographer, this::onInputEvent);
if (TestProtocol.sDebugTracing) {
@@ -378,55 +311,8 @@
} catch (RemoteException e) {
Log.e(TAG, "Unable to create input monitor", e);
}
- initTouchBounds();
- }
- private int getNavbarSize(String resName) {
- return ResourceUtils.getNavbarSize(resName, getResources());
- }
-
- private void initTouchBounds() {
- if (!mMode.hasGestures) {
- return;
- }
-
- DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(this).getInfo();
- Point realSize = new Point(displayInfo.realSize);
- mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y);
- if (mMode == Mode.NO_BUTTON) {
- int touchHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
- mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - touchHeight;
-
- final int assistantWidth = getResources()
- .getDimensionPixelSize(R.dimen.gestures_assistant_width);
- final float assistantHeight = Math.max(touchHeight,
- QuickStepContract.getWindowCornerRadius(getResources()));
- mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mSwipeTouchRegion.bottom;
- mAssistantLeftRegion.top = mAssistantRightRegion.top =
- mSwipeTouchRegion.bottom - assistantHeight;
-
- mAssistantLeftRegion.left = 0;
- mAssistantLeftRegion.right = assistantWidth;
-
- mAssistantRightRegion.right = mSwipeTouchRegion.right;
- mAssistantRightRegion.left = mSwipeTouchRegion.right - assistantWidth;
- } else {
- mAssistantLeftRegion.setEmpty();
- mAssistantRightRegion.setEmpty();
- switch (displayInfo.rotation) {
- case Surface.ROTATION_90:
- mSwipeTouchRegion.left = mSwipeTouchRegion.right
- - getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
- break;
- case Surface.ROTATION_270:
- mSwipeTouchRegion.right = mSwipeTouchRegion.left
- + getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
- break;
- default:
- mSwipeTouchRegion.top = mSwipeTouchRegion.bottom
- - getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
- }
- }
+ mDeviceState.updateGestureTouchRegions();
}
@Override
@@ -434,43 +320,17 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onNavigationModeChanged " + newMode);
}
- if (mMode.hasGestures != newMode.hasGestures) {
- if (newMode.hasGestures) {
- DefaultDisplay.INSTANCE.get(this).addChangeListener(this);
- } else {
- DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
- }
- }
mMode = newMode;
-
- disposeEventHandlers();
initInputMonitor();
-
- if (mMode == Mode.NO_BUTTON) {
- mExclusionListener.register();
- } else {
- mExclusionListener.unregister();
- }
}
- @Override
- public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
- if (info.id != mDefaultDisplayId) {
- return;
- }
-
- initTouchBounds();
- }
-
- private void initWhenUserUnlocked() {
+ public void onUserUnlocked() {
mRecentsModel = RecentsModel.INSTANCE.get(this);
- mOverviewComponentObserver = new OverviewComponentObserver(this);
+ mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
- mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
- mIsUserUnlocked = true;
sSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
mInputConsumer.registerInputConsumer();
@@ -482,13 +342,11 @@
// new ModelPreload().start(this);
mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this)
.getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT));
-
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
}
@UiThread
private void onSystemUiProxySet() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
}
@@ -496,37 +354,32 @@
@UiThread
private void onSystemUiFlagsChanged() {
- if (mIsUserUnlocked) {
- mOverviewInteractionState.setSystemUiStateFlags(mSystemUiStateFlags);
- mOverviewComponentObserver.onSystemUiStateChanged(mSystemUiStateFlags);
+ if (mDeviceState.isUserUnlocked()) {
+ mOverviewInteractionState.setSystemUiStateFlags(mDeviceState.getSystemUiStateFlags());
+ mOverviewComponentObserver.onSystemUiStateChanged();
}
}
@UiThread
private void onAssistantVisibilityChanged() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged(
- mLastAssistantVisibility);
+ mDeviceState.getAssistantVisibility());
}
}
@Override
public void onDestroy() {
sIsInitialized = false;
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mInputConsumer.unregisterInputConsumer();
mOverviewComponentObserver.onDestroy();
}
disposeEventHandlers();
- if (mMode.hasGestures) {
- DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
- }
+ SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
+ mDeviceState.destroy();
sConnected = false;
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
- SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
- mExclusionListener.unregister();
-
super.onDestroy();
}
@@ -551,19 +404,19 @@
mLogId = TOUCH_INTERACTION_LOG.generateAndSetLogId();
sSwipeSharedState.setLogTraceId(mLogId);
- if (mSwipeTouchRegion.contains(event.getX(), event.getY())) {
+ if (mDeviceState.isInSwipeUpTouchRegion(event)) {
boolean useSharedState = mConsumer.useSharedSwipeState();
mConsumer.onConsumerAboutToBeSwitched();
mConsumer = newConsumer(useSharedState, event);
TOUCH_INTERACTION_LOG.addLog("setInputConsumer", mConsumer.getType());
mUncheckedConsumer = mConsumer;
- } else if (mIsUserUnlocked && mMode == Mode.NO_BUTTON
- && canTriggerAssistantAction(event)) {
+ } else if (mDeviceState.isUserUnlocked() && mMode == Mode.NO_BUTTON
+ && mDeviceState.canTriggerAssistantAction(event)) {
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we should
// not interrupt it. QuickSwitch assumes that interruption can only happen if the
// next gesture is also quick switch.
mUncheckedConsumer =
- new AssistantTouchConsumer(this, mISystemUiProxy,
+ new AssistantInputConsumer(this, mISystemUiProxy,
mOverviewComponentObserver.getActivityControlHelper(),
InputConsumer.NO_OP, mInputMonitorCompat);
} else {
@@ -576,27 +429,11 @@
DejankBinderTracker.disallowBinderTrackingInTests();
}
- private boolean validSystemUiFlags() {
- return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
- && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
- || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
- }
-
- private boolean canTriggerAssistantAction(MotionEvent ev) {
- return mAssistantAvailable
- && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
- && (mAssistantLeftRegion.contains(ev.getX(), ev.getY()) ||
- mAssistantRightRegion.contains(ev.getX(), ev.getY()))
- && !ActivityManagerWrapper.getInstance().isLockToAppActive();
- }
-
private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
- boolean isInValidSystemUiState = validSystemUiFlags();
+ boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
- if (!mIsUserUnlocked) {
- if (isInValidSystemUiState) {
+ if (!mDeviceState.isUserUnlocked()) {
+ if (canStartSystemGesture) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps
// launched while device is locked even after exiting direct boot mode (e.g. camera).
return createDeviceLockedInputConsumer(mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
@@ -607,29 +444,28 @@
// When using sharedState, bypass systemState check as this is a followup gesture and the
// first gesture started in a valid system state.
- InputConsumer base = isInValidSystemUiState || useSharedState
+ InputConsumer base = canStartSystemGesture || useSharedState
? newBaseConsumer(useSharedState, event) : mResetGestureInputConsumer;
if (mMode == Mode.NO_BUTTON) {
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
- if (canTriggerAssistantAction(event)) {
- base = new AssistantTouchConsumer(this, mISystemUiProxy, activityControl, base,
+ if (mDeviceState.canTriggerAssistantAction(event)) {
+ base = new AssistantInputConsumer(this, mISystemUiProxy, activityControl, base,
mInputMonitorCompat);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+ if (mDeviceState.isScreenPinningActive()) {
// Note: we only allow accessibility to wrap this, and it replaces the previous
// base input consumer (which should be NO_OP anyway since topTaskLocked == true).
base = new ScreenPinnedInputConsumer(this, mISystemUiProxy, activityControl);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
- base = new AccessibilityInputConsumer(this, mISystemUiProxy,
- (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0, base,
- mInputMonitorCompat, mSwipeTouchRegion);
+ if (mDeviceState.isAccessibilityMenuAvailable()) {
+ base = new AccessibilityInputConsumer(this, mDeviceState, mISystemUiProxy, base,
+ mInputMonitorCompat);
}
} else {
- if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+ if (mDeviceState.isScreenPinningActive()) {
base = mResetGestureInputConsumer;
}
}
@@ -642,7 +478,7 @@
if (!useSharedState) {
sSwipeSharedState.clearAllState(false /* finishAnimation */);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0) {
+ if (mDeviceState.isKeyguardShowingOccluded()) {
// This handles apps showing over the lockscreen (e.g. camera)
return createDeviceLockedInputConsumer(runningTaskInfo);
}
@@ -678,8 +514,7 @@
return createOverviewInputConsumer(event);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
return createOverviewInputConsumer(event);
- } else if (mGestureBlockingActivity != null && runningTaskInfo != null
- && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
+ } else if (mDeviceState.isGestureBlockedActivity(runningTaskInfo)) {
return mResetGestureInputConsumer;
} else {
return createOtherActivityInputConsumer(event, runningTaskInfo);
@@ -692,13 +527,6 @@
&& (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
}
- private boolean disableHorizontalSwipe(MotionEvent event) {
- // mExclusionRegion can change on binder thread, use a local instance here.
- Region exclusionRegion = mExclusionRegion;
- return mMode == Mode.NO_BUTTON && exclusionRegion != null
- && exclusionRegion.contains((int) event.getX(), (int) event.getY());
- }
-
private InputConsumer createOtherActivityInputConsumer(MotionEvent event,
RunningTaskInfo runningTaskInfo) {
@@ -711,19 +539,20 @@
shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted;
factory = mFallbackNoButtonFactory;
} else {
- shouldDefer = activityControlHelper.deferStartingActivity(mActiveNavBarRegion, event);
+ shouldDefer = activityControlHelper.deferStartingActivity(mDeviceState, event);
factory = mWindowTreansformFactory;
}
- return new OtherActivityInputConsumer(this, runningTaskInfo, shouldDefer,
- this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
- disableHorizontalSwipe(event), activityControlHelper, factory, mLogId);
+ final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
+ return new OtherActivityInputConsumer(this, mDeviceState, runningTaskInfo, shouldDefer,
+ this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat,
+ disableHorizontalSwipe, activityControlHelper, factory, mLogId);
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
if (mMode == Mode.NO_BUTTON && taskInfo != null) {
- return new DeviceLockedInputConsumer(this, sSwipeSharedState, mInputMonitorCompat,
- mSwipeTouchRegion, taskInfo.taskId, mLogId);
+ return new DeviceLockedInputConsumer(this, mDeviceState, sSwipeSharedState,
+ mInputMonitorCompat, taskInfo.taskId, mLogId);
} else {
return mResetGestureInputConsumer;
}
@@ -741,8 +570,9 @@
return new OverviewInputConsumer(activity, mInputMonitorCompat,
false /* startingInActivityBounds */, activityControl);
} else {
+ final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
return new OverviewWithoutFocusInputConsumer(activity, mInputMonitorCompat,
- activityControl, disableHorizontalSwipe(event));
+ activityControl, disableHorizontalSwipe);
}
}
@@ -757,7 +587,7 @@
}
private void preloadOverview(boolean fromInit) {
- if (!mIsUserUnlocked) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
if (!mMode.hasGestures && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
@@ -793,7 +623,7 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
- if (!mIsUserUnlocked) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
final ActivityControlHelper activityControl =
@@ -826,15 +656,9 @@
}
} else {
// Dump everything
+ mDeviceState.dump(pw);
pw.println("TouchState:");
pw.println(" navMode=" + mMode);
- pw.println(" validSystemUiFlags=" + validSystemUiFlags());
- pw.println(" systemUiFlags=" + mSystemUiStateFlags);
- pw.println(" systemUiFlagsDesc="
- + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
- pw.println(" assistantAvailable=" + mAssistantAvailable);
- pw.println(" assistantDisabled="
- + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
boolean resumed = mOverviewComponentObserver != null
&& mOverviewComponentObserver.getActivityControlHelper().isResumed();
pw.println(" resumed=" + resumed);
@@ -870,7 +694,7 @@
private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask,
long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) {
- return new WindowTransformSwipeHandler(runningTask, this, touchTimeMs,
+ return new WindowTransformSwipeHandler(mDeviceState, runningTask, this, touchTimeMs,
mOverviewComponentObserver, continuingLastGesture, mInputConsumer, mRecentsModel);
}
@@ -882,7 +706,7 @@
protected boolean shouldNotifyBackGesture() {
return mBackGestureNotificationCounter > 0 &&
- mGestureBlockingActivity != null;
+ mDeviceState.getGestureBlockedActivityPackage() != null;
}
@WorkerThread
@@ -892,7 +716,7 @@
Utilities.getDevicePrefs(this).edit()
.putInt(KEY_BACK_NOTIFICATION_COUNT, mBackGestureNotificationCounter).apply();
sendBroadcast(new Intent(NOTIFY_ACTION_BACK).setPackage(
- mGestureBlockingActivity.getPackageName()));
+ mDeviceState.getGestureBlockedActivityPackage()));
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/ViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/ViewUtils.java
new file mode 100644
index 0000000..cbb6ad4
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/ViewUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 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;
+
+import android.graphics.Canvas;
+import android.view.View;
+
+import com.android.systemui.shared.system.WindowCallbacksCompat;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Utility class for helpful methods related to {@link View} objects.
+ */
+public class ViewUtils {
+
+ /** See {@link #postDraw(View, Runnable, BooleanSupplier)}} */
+ public static boolean postDraw(View view, Runnable onFinishRunnable) {
+ return postDraw(view, onFinishRunnable, () -> false);
+ }
+
+ /**
+ * Inject some addition logic in order to make sure that the view is updated smoothly post
+ * draw, and allow addition task to be run after view update.
+ *
+ * @param onFinishRunnable runnable to be run right after the view finishes drawing.
+ */
+ public static boolean postDraw(View view, Runnable onFinishRunnable, BooleanSupplier canceled) {
+ // Defer finishing the animation until the next launcher frame with the
+ // new thumbnail
+ return new WindowCallbacksCompat(view) {
+ // The number of frames to defer until we actually finish the animation
+ private int mDeferFrameCount = 2;
+
+ @Override
+ public void onPostDraw(Canvas canvas) {
+ // If we were cancelled after this was attached, do not update
+ // the state.
+ if (canceled.getAsBoolean()) {
+ detach();
+ return;
+ }
+
+ if (mDeferFrameCount > 0) {
+ mDeferFrameCount--;
+ // Workaround, detach and reattach to invalidate the root node for
+ // another draw
+ detach();
+ attach();
+ view.invalidate();
+ return;
+ }
+
+ if (onFinishRunnable != null) {
+ onFinishRunnable.run();
+ }
+ detach();
+ }
+ }.attach();
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index db8eb27..5cf987a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -35,7 +35,6 @@
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.NEW_TASK;
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.RECENTS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -45,7 +44,6 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.Intent;
-import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Build;
@@ -80,9 +78,9 @@
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
-import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider;
+import com.android.quickstep.util.AppWindowAnimationHelper.TargetAlphaProvider;
import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.RecentsAnimationTargets;
import com.android.quickstep.views.LiveTileOverlay;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -90,12 +88,10 @@
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.WindowCallbacksCompat;
@TargetApi(Build.VERSION_CODES.O)
public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
- extends BaseSwipeUpHandler<T, RecentsView>
- implements OnApplyWindowInsetsListener {
+ extends BaseSwipeUpHandler<T, RecentsView> implements OnApplyWindowInsetsListener {
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null;
@@ -201,6 +197,8 @@
*/
private static final int LOG_NO_OP_PAGE_INDEX = -1;
+ private RecentsAnimationDeviceState mDeviceState;
+
private GestureEndTarget mGestureEndTarget;
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
private RunningWindowAnim mRunningWindowAnim;
@@ -232,11 +230,12 @@
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
- public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
- long touchTimeMs, OverviewComponentObserver overviewComponentObserver,
- boolean continuingLastGesture,
+ public WindowTransformSwipeHandler(RecentsAnimationDeviceState deviceState,
+ RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
+ OverviewComponentObserver overviewComponentObserver, boolean continuingLastGesture,
InputConsumerController inputConsumer, RecentsModel recentsModel) {
super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id);
+ mDeviceState = deviceState;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
initStateCallbacks();
@@ -550,7 +549,7 @@
@Override
public void updateFinalShift() {
- SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
+ RecentsAnimationTargets controller = mRecentsAnimationWrapper.getController();
if (controller != null) {
applyTransformUnchecked();
updateSysUiFlags(mCurrentShift.value);
@@ -558,8 +557,8 @@
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
if (mRecentsAnimationWrapper.getController() != null) {
- mLiveTileOverlay.update(mClipAnimationHelper.getCurrentRectWithInsets(),
- mClipAnimationHelper.getCurrentCornerRadius());
+ mLiveTileOverlay.update(mAppWindowAnimationHelper.getCurrentRectWithInsets(),
+ mAppWindowAnimationHelper.getCurrentCornerRadius());
}
}
@@ -608,7 +607,7 @@
}
@Override
- public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+ public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
super.onRecentsAnimationStart(targetSet);
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimationCallback", targetSet.apps.length);
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
@@ -617,7 +616,7 @@
}
@Override
- public void onRecentsAnimationCanceled() {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
mRecentsAnimationWrapper.setController(null);
mActivityInitListener.unregister();
setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
@@ -758,9 +757,7 @@
}
}
- int stateFlags = OverviewInteractionState.INSTANCE.get(mActivity).getSystemUiStateFlags();
- if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0
- && (endTarget == RECENTS || endTarget == LAST_TASK)) {
+ if (mDeviceState.isOverviewDisabled() && (endTarget == RECENTS || endTarget == LAST_TASK)) {
return LAST_TASK;
}
return endTarget;
@@ -889,7 +886,7 @@
@NonNull
@Override
public RectF getWindowTargetRect() {
- RectF fallbackTarget = new RectF(mClipAnimationHelper.getTargetRect());
+ RectF fallbackTarget = new RectF(mAppWindowAnimationHelper.getTargetRect());
Utilities.scaleRectFAboutCenter(fallbackTarget, 0.25f);
return fallbackTarget;
}
@@ -927,7 +924,15 @@
windowAnim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
- setStateOnUiThread(target.endState);
+ if (target == NEW_TASK && mRecentsView != null
+ && mRecentsView.getNextPage() == mRecentsView.getRunningTaskIndex()) {
+ // We are about to launch the current running task, so use LAST_TASK state
+ // instead of NEW_TASK. This could happen, for example, if our scroll is
+ // aborted after we determined the target to be NEW_TASK.
+ setStateOnUiThread(LAST_TASK.endState);
+ } else {
+ setStateOnUiThread(target.endState);
+ }
}
});
windowAnim.start();
@@ -1007,6 +1012,10 @@
}
}
+ public boolean isCanceled() {
+ return mCanceled;
+ }
+
@UiThread
private void resumeLastTask() {
mRecentsAnimationWrapper.finish(false /* toRecents */, null);
@@ -1099,14 +1108,21 @@
}
private void switchToScreenshot() {
+ RecentsAnimationTargets controller = mRecentsAnimationWrapper.getController();
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ if (controller != null) {
+ // Update the screenshot of the task
+ if (mTaskSnapshot == null) {
+ mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
+ }
+ mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot, false /* refreshNow */);
+ }
setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
} else if (!mRecentsAnimationWrapper.hasTargets()) {
// If there are no targets, then we don't need to capture anything
setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
} else {
boolean finishTransitionPosted = false;
- SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
if (controller != null) {
// Update the screenshot of the task
if (mTaskSnapshot == null) {
@@ -1123,34 +1139,8 @@
if (taskView != null && !mCanceled) {
// Defer finishing the animation until the next launcher frame with the
// new thumbnail
- finishTransitionPosted = new WindowCallbacksCompat(taskView) {
-
- // The number of frames to defer until we actually finish the animation
- private int mDeferFrameCount = 2;
-
- @Override
- public void onPostDraw(Canvas canvas) {
- // If we were cancelled after this was attached, do not update
- // the state.
- if (mCanceled) {
- detach();
- return;
- }
-
- if (mDeferFrameCount > 0) {
- mDeferFrameCount--;
- // Workaround, detach and reattach to invalidate the root node for
- // another draw
- detach();
- attach();
- taskView.invalidate();
- return;
- }
-
- setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
- detach();
- }
- }.attach();
+ finishTransitionPosted = ViewUtils.postDraw(taskView,
+ () -> setStateOnUiThread(STATE_SCREENSHOT_CAPTURED), this::isCanceled);
}
}
if (!finishTransitionPosted) {
@@ -1201,7 +1191,7 @@
}
private void setTargetAlphaProvider(TargetAlphaProvider provider) {
- mClipAnimationHelper.setTaskAlphaCallback(provider);
+ mAppWindowAnimationHelper.setTaskAlphaCallback(provider);
updateFinalShift();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 7f1aae5..79e71a1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -142,7 +142,7 @@
mZoomTranslationY = 0f;
} else {
TaskView dummyTask = getTaskViewAt(0);
- ScaleAndTranslation sat = getTempClipAnimationHelper()
+ ScaleAndTranslation sat = getTempAppWindowAnimationHelper()
.updateForFullscreenOverview(dummyTask)
.getScaleAndTranslation();
mZoomScale = sat.scale;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
index 1f73a28..92bcfb5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
@@ -23,7 +23,6 @@
import static android.view.MotionEvent.ACTION_UP;
import android.content.Context;
-import android.graphics.RectF;
import android.os.RemoteException;
import android.util.Log;
import android.view.Display;
@@ -32,12 +31,13 @@
import android.view.ViewConfiguration;
import com.android.launcher3.R;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
- * Touch consumer for two finger swipe actions for accessibility actions
+ * Input consumer for two finger swipe actions for accessibility actions
*/
public class AccessibilityInputConsumer extends DelegateInputConsumer {
@@ -46,8 +46,7 @@
private final ISystemUiProxy mSystemUiProxy;
private final VelocityTracker mVelocityTracker;
private final MotionPauseDetector mMotionPauseDetector;
- private final boolean mAllowLongClick;
- private final RectF mSwipeTouchRegion;
+ private final RecentsAnimationDeviceState mDeviceState;
private final float mMinGestureDistance;
private final float mMinFlingVelocity;
@@ -56,19 +55,17 @@
private float mDownY;
private float mTotalY;
- public AccessibilityInputConsumer(Context context, ISystemUiProxy systemUiProxy,
- boolean allowLongClick, InputConsumer delegate, InputMonitorCompat inputMonitor,
- RectF swipeTouchRegion) {
+ public AccessibilityInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
+ ISystemUiProxy systemUiProxy, InputConsumer delegate, InputMonitorCompat inputMonitor) {
super(delegate, inputMonitor);
mSystemUiProxy = systemUiProxy;
mVelocityTracker = VelocityTracker.obtain();
mMinGestureDistance = context.getResources()
.getDimension(R.dimen.accessibility_gesture_min_swipe_distance);
mMinFlingVelocity = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
- mSwipeTouchRegion = swipeTouchRegion;
+ mDeviceState = deviceState;
mMotionPauseDetector = new MotionPauseDetector(context);
- mAllowLongClick = allowLongClick;
}
@Override
@@ -103,7 +100,7 @@
case ACTION_POINTER_DOWN: {
if (mState == STATE_INACTIVE) {
int pointerIndex = ev.getActionIndex();
- if (mSwipeTouchRegion.contains(ev.getX(pointerIndex), ev.getY(pointerIndex))
+ if (mDeviceState.isInSwipeUpTouchRegion(ev, pointerIndex)
&& mDelegate.allowInterceptByParent()) {
setActive(ev);
@@ -116,7 +113,7 @@
break;
}
case ACTION_MOVE: {
- if (mState == STATE_ACTIVE && mAllowLongClick) {
+ if (mState == STATE_ACTIVE && mDeviceState.isAccessibilityMenuShortcutAvailable()) {
int pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) {
break;
@@ -130,7 +127,8 @@
case ACTION_UP:
if (mState == STATE_ACTIVE) {
try {
- if (mAllowLongClick && mMotionPauseDetector.isPaused()) {
+ if (mDeviceState.isAccessibilityMenuShortcutAvailable()
+ && mMotionPauseDetector.isPaused()) {
mSystemUiProxy.notifyAccessibilityButtonLongClicked();
} else {
mTotalY += (ev.getY() - mDownY);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
similarity index 98%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index 346969e..a2a1c43 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -57,9 +57,9 @@
/**
* Touch consumer for handling events to launch assistant from launcher
*/
-public class AssistantTouchConsumer extends DelegateInputConsumer {
+public class AssistantInputConsumer extends DelegateInputConsumer {
- private static final String TAG = "AssistantTouchConsumer";
+ private static final String TAG = "AssistantInputConsumer";
private static final long RETRACT_ANIMATION_DURATION_MS = 300;
// From //java/com/google/android/apps/gsa/search/shared/util/OpaContract.java.
@@ -92,7 +92,7 @@
private final Context mContext;
private final GestureDetector mGestureDetector;
- public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy,
+ public AssistantInputConsumer(Context context, ISystemUiProxy systemUiProxy,
ActivityControlHelper activityControlHelper, InputConsumer delegate,
InputMonitorCompat inputMonitor) {
super(delegate, inputMonitor);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index b24c788..ba2d6d1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -32,7 +32,6 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
@@ -42,10 +41,13 @@
import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.LockScreenRecentsActivity;
import com.android.quickstep.MultiStateCallback;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeSharedState;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.AppWindowAnimationHelper;
+import com.android.quickstep.util.RecentsAnimationCallbacks;
+import com.android.quickstep.util.RecentsAnimationTargets;
+
+import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -53,7 +55,7 @@
* A dummy input consumer used when the device is still locked, e.g. from secure camera.
*/
public class DeviceLockedInputConsumer implements InputConsumer,
- SwipeAnimationTargetSet.SwipeAnimationListener {
+ RecentsAnimationCallbacks.RecentsAnimationListener {
private static final float SCALE_DOWN = 0.75f;
@@ -71,17 +73,17 @@
getFlagForIndex(1, "STATE_HANDLER_INVALIDATED");
private final Context mContext;
+ private final RecentsAnimationDeviceState mDeviceState;
private final float mTouchSlopSquared;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat;
private final PointF mTouchDown = new PointF();
- private final ClipAnimationHelper mClipAnimationHelper;
+ private final AppWindowAnimationHelper mAppWindowAnimationHelper;
private int mLogId;
- private final ClipAnimationHelper.TransformParams mTransformParams;
+ private final AppWindowAnimationHelper.TransformParams mTransformParams;
private final Point mDisplaySize;
private final MultiStateCallback mStateCallback;
- private final RectF mSwipeTouchRegion;
public final int mRunningTaskId;
private VelocityTracker mVelocityTracker;
@@ -89,19 +91,19 @@
private boolean mThresholdCrossed = false;
- private SwipeAnimationTargetSet mTargetSet;
+ private RecentsAnimationTargets mTargetSet;
- public DeviceLockedInputConsumer(Context context, SwipeSharedState swipeSharedState,
- InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId,
- int logId) {
+ public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
+ SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
+ int runningTaskId, int logId) {
mContext = context;
+ mDeviceState = deviceState;
mTouchSlopSquared = squaredTouchSlop(context);
mSwipeSharedState = swipeSharedState;
- mClipAnimationHelper = new ClipAnimationHelper(context);
+ mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
mLogId = logId;
- mTransformParams = new ClipAnimationHelper.TransformParams();
+ mTransformParams = new AppWindowAnimationHelper.TransformParams();
mInputMonitorCompat = inputMonitorCompat;
- mSwipeTouchRegion = swipeTouchRegion;
mRunningTaskId = runningTaskId;
// Do not use DeviceProfile as the user data might be locked
@@ -137,7 +139,7 @@
if (!mThresholdCrossed) {
// Cancel interaction in case of multi-touch interaction
int ptrIdx = ev.getActionIndex();
- if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
+ if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
int action = ev.getAction();
ev.setAction(ACTION_CANCEL);
finishTouchTracking(ev);
@@ -155,9 +157,7 @@
float dy = Math.max(mTouchDown.y - y, 0);
mProgress = dy / mDisplaySize.y;
mTransformParams.setProgress(mProgress);
- if (mTargetSet != null) {
- mClipAnimationHelper.applyTransform(mTargetSet, mTransformParams);
- }
+ mAppWindowAnimationHelper.applyTransform(mTransformParams);
}
break;
}
@@ -202,7 +202,7 @@
private void startRecentsTransition() {
mThresholdCrossed = true;
- RecentsAnimationListenerSet newListenerSet =
+ RecentsAnimationCallbacks newListenerSet =
mSwipeSharedState.newRecentsAnimationListenerSet();
newListenerSet.addListener(this);
Intent intent = new Intent(Intent.ACTION_MAIN)
@@ -216,25 +216,27 @@
}
@Override
- public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+ public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
mTargetSet = targetSet;
Rect displaySize = new Rect(0, 0, mDisplaySize.x, mDisplaySize.y);
RemoteAnimationTargetCompat targetCompat = targetSet.findTask(mRunningTaskId);
if (targetCompat != null) {
- mClipAnimationHelper.updateSource(displaySize, targetCompat);
+ mAppWindowAnimationHelper.updateSource(displaySize, targetCompat);
}
Utilities.scaleRectAboutCenter(displaySize, SCALE_DOWN);
displaySize.offsetTo(displaySize.left, 0);
- mClipAnimationHelper.updateTargetRect(displaySize);
- mClipAnimationHelper.applyTransform(mTargetSet, mTransformParams);
+ mTransformParams.setTargetSet(mTargetSet)
+ .setLauncherOnTop(true);
+ mAppWindowAnimationHelper.updateTargetRect(displaySize);
+ mAppWindowAnimationHelper.applyTransform(mTransformParams);
mStateCallback.setState(STATE_TARGET_RECEIVED);
}
@Override
- public void onRecentsAnimationCanceled() {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
mTargetSet = null;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
index 6275d21..59efb2d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
@@ -49,7 +49,7 @@
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.RecentsAnimationTargets;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -127,9 +127,9 @@
mSwipeUpOverHome = mRunningOverHome && !mInQuickSwitchMode;
if (mSwipeUpOverHome) {
- mClipAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
+ mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
} else {
- mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
+ mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
}
initStateCallbacks();
@@ -414,12 +414,12 @@
}
@Override
- public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+ public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
super.onRecentsAnimationStart(targetSet);
mRecentsAnimationWrapper.enableInputConsumer();
if (mRunningOverHome) {
- mClipAnimationHelper.prepareAnimation(mDp, true);
+ mAppWindowAnimationHelper.prepareAnimation(mDp, true);
}
applyTransformUnchecked();
@@ -427,7 +427,7 @@
}
@Override
- public void onRecentsAnimationCanceled() {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
mRecentsAnimationWrapper.setController(null);
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index f06702d..6776e84 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -38,7 +38,6 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.PointF;
-import android.graphics.RectF;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -55,13 +54,14 @@
import com.android.quickstep.ActivityControlHelper;
import com.android.quickstep.BaseSwipeUpHandler;
import com.android.quickstep.BaseSwipeUpHandler.Factory;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
+import com.android.quickstep.util.RecentsAnimationCallbacks;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
@@ -79,12 +79,12 @@
// TODO: Move to quickstep contract
public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3;
+ private final RecentsAnimationDeviceState mDeviceState;
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
private final RunningTaskInfo mRunningTask;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat;
private final SysUINavigationMode.Mode mMode;
- private final RectF mSwipeTouchRegion;
private final ActivityControlHelper mActivityControlHelper;
private final BaseSwipeUpHandler.Factory mHandlerFactory;
@@ -124,19 +124,19 @@
};
private int mLogId;
- public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
- boolean isDeferredDownTarget, Consumer<OtherActivityInputConsumer> onCompleteCallback,
+ public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState,
+ RunningTaskInfo runningTaskInfo, boolean isDeferredDownTarget,
+ Consumer<OtherActivityInputConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
- RectF swipeTouchRegion, boolean disableHorizontalSwipe,
- ActivityControlHelper activityControlHelper,
+ boolean disableHorizontalSwipe, ActivityControlHelper activityControlHelper,
Factory handlerFactory, int logId) {
super(base);
mLogId = logId;
+ mDeviceState = deviceState;
mMainThreadHandler = new Handler(Looper.getMainLooper());
mRunningTask = runningTaskInfo;
mMode = SysUINavigationMode.getMode(base);
- mSwipeTouchRegion = swipeTouchRegion;
mHandlerFactory = handlerFactory;
mActivityControlHelper = activityControlHelper;
@@ -217,7 +217,7 @@
if (!mPassedPilferInputSlop) {
// Cancel interaction in case of multi-touch interaction
int ptrIdx = ev.getActionIndex();
- if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
+ if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
forceCancelGesture(ev);
}
}
@@ -329,7 +329,7 @@
long touchTimeMs, boolean isLikelyToStartNewTask) {
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
- RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
+ RecentsAnimationCallbacks listenerSet = mSwipeSharedState.getActiveListener();
final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs,
listenerSet != null, isLikelyToStartNewTask);
@@ -343,7 +343,7 @@
mSwipeSharedState.applyActiveRecentsAnimationState(handler);
notifyGestureStarted();
} else {
- RecentsAnimationListenerSet newListenerSet =
+ RecentsAnimationCallbacks newListenerSet =
mSwipeSharedState.newRecentsAnimationListenerSet();
newListenerSet.addListener(handler);
Intent intent = handler.getLaunchIntent();
@@ -416,7 +416,7 @@
}
private void removeListener() {
- RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
+ RecentsAnimationCallbacks listenerSet = mSwipeSharedState.getActiveListener();
if (listenerSet != null) {
listenerSet.removeListener(mInteractionHandler);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
similarity index 90%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index cae273a..dddfc8d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -50,13 +50,11 @@
import com.android.systemui.shared.system.TransactionCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import java.util.function.BiFunction;
-
/**
* Utility class to handle window clip animation
*/
@TargetApi(Build.VERSION_CODES.P)
-public class ClipAnimationHelper {
+public class AppWindowAnimationHelper {
// The bounds of the source app in device coordinates
private final Rect mSourceStackBounds = new Rect();
@@ -102,7 +100,7 @@
private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1;
- public ClipAnimationHelper(Context context) {
+ public AppWindowAnimationHelper(Context context) {
mWindowCornerRadius = getWindowCornerRadius(context.getResources());
mSupportsRoundedCornersOnWindows = supportsRoundedCornersOnWindows(context.getResources());
mTaskCornerRadius = TaskCornerRadius.get(context);
@@ -157,12 +155,75 @@
mUseRoundedCornersOnWindows = mSupportsRoundedCornersOnWindows && !dp.isMultiWindowMode;
}
- public RectF applyTransform(RemoteAnimationTargetSet targetSet, TransformParams params) {
- return applyTransform(targetSet, params, true /* launcherOnTop */);
+ public RectF applyTransform(TransformParams params) {
+ SurfaceParams[] surfaceParams = getSurfaceParams(params);
+ if (surfaceParams == null) {
+ return null;
+ }
+ applySurfaceParams(params.syncTransactionApplier, surfaceParams);
+ return params.currentRect;
}
- public RectF applyTransform(RemoteAnimationTargetSet targetSet, TransformParams params,
- boolean launcherOnTop) {
+ public SurfaceParams[] getSurfaceParams(TransformParams params) {
+ if (params.targetSet == null) {
+ return null;
+ }
+
+ float progress = params.progress;
+ updateCurrentRect(params);
+
+ SurfaceParams[] surfaceParams = new SurfaceParams[params.targetSet.unfilteredApps.length];
+ for (int i = 0; i < params.targetSet.unfilteredApps.length; i++) {
+ RemoteAnimationTargetCompat app = params.targetSet.unfilteredApps[i];
+ mTmpMatrix.setTranslate(app.position.x, app.position.y);
+ Rect crop = mTmpRect;
+ crop.set(app.sourceContainerBounds);
+ crop.offsetTo(0, 0);
+ float alpha;
+ int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
+ float cornerRadius = 0f;
+ float scale = Math.max(params.currentRect.width(), mTargetRect.width()) / crop.width();
+ if (app.mode == params.targetSet.targetMode) {
+ alpha = mTaskAlphaCallback.getAlpha(app, params.targetAlpha);
+ if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
+ mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL);
+ mTmpMatrix.postTranslate(app.position.x, app.position.y);
+ mClipRectF.roundOut(crop);
+ if (mSupportsRoundedCornersOnWindows) {
+ if (params.cornerRadius > -1) {
+ cornerRadius = params.cornerRadius;
+ scale = params.currentRect.width() / crop.width();
+ } else {
+ float windowCornerRadius = mUseRoundedCornersOnWindows
+ ? mWindowCornerRadius : 0;
+ cornerRadius = Utilities.mapRange(progress, windowCornerRadius,
+ mTaskCornerRadius);
+ }
+ mCurrentCornerRadius = cornerRadius;
+ }
+ } else if (params.targetSet.hasRecents) {
+ // If home has a different target then recents, reverse anim the
+ // home target.
+ alpha = 1 - (progress * params.targetAlpha);
+ }
+ } else {
+ alpha = mBaseAlphaCallback.getAlpha(app, progress);
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && params.launcherOnTop) {
+ crop = null;
+ layer = Integer.MAX_VALUE;
+ }
+ }
+
+ // Since radius is in Surface space, but we draw the rounded corners in screen space, we
+ // have to undo the scale.
+ surfaceParams[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, layer,
+ cornerRadius / scale);
+ }
+ applySurfaceParams(params.syncTransactionApplier, surfaceParams);
+ return surfaceParams;
+ }
+
+ public RectF updateCurrentRect(TransformParams params) {
float progress = params.progress;
if (params.currentRect == null) {
RectF currentRect;
@@ -183,55 +244,6 @@
mSourceStackBounds.height() - (sourceWindowClipInsets.bottom * progress);
params.setCurrentRectAndTargetAlpha(currentRect, 1);
}
-
- SurfaceParams[] surfaceParams = new SurfaceParams[targetSet.unfilteredApps.length];
- for (int i = 0; i < targetSet.unfilteredApps.length; i++) {
- RemoteAnimationTargetCompat app = targetSet.unfilteredApps[i];
- mTmpMatrix.setTranslate(app.position.x, app.position.y);
- Rect crop = mTmpRect;
- crop.set(app.sourceContainerBounds);
- crop.offsetTo(0, 0);
- float alpha;
- int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
- float cornerRadius = 0f;
- float scale = Math.max(params.currentRect.width(), mTargetRect.width()) / crop.width();
- if (app.mode == targetSet.targetMode) {
- alpha = mTaskAlphaCallback.getAlpha(app, params.targetAlpha);
- if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
- mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL);
- mTmpMatrix.postTranslate(app.position.x, app.position.y);
- mClipRectF.roundOut(crop);
- if (mSupportsRoundedCornersOnWindows) {
- if (params.cornerRadius > -1) {
- cornerRadius = params.cornerRadius;
- scale = params.currentRect.width() / crop.width();
- } else {
- float windowCornerRadius = mUseRoundedCornersOnWindows
- ? mWindowCornerRadius : 0;
- cornerRadius = Utilities.mapRange(progress, windowCornerRadius,
- mTaskCornerRadius);
- }
- mCurrentCornerRadius = cornerRadius;
- }
- } else if (targetSet.hasRecents) {
- // If home has a different target then recents, reverse anim the
- // home target.
- alpha = 1 - (progress * params.targetAlpha);
- }
- } else {
- alpha = mBaseAlphaCallback.getAlpha(app, progress);
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) {
- crop = null;
- layer = Integer.MAX_VALUE;
- }
- }
-
- // Since radius is in Surface space, but we draw the rounded corners in screen space, we
- // have to undo the scale.
- surfaceParams[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, layer,
- cornerRadius / scale);
- }
- applySurfaceParams(params.syncTransactionApplier, surfaceParams);
return params.currentRect;
}
@@ -240,7 +252,7 @@
return mCurrentRectWithInsets;
}
- private void applySurfaceParams(@Nullable SyncRtSurfaceTransactionApplierCompat
+ public static void applySurfaceParams(@Nullable SyncRtSurfaceTransactionApplierCompat
syncTransactionApplier, SurfaceParams[] params) {
if (syncTransactionApplier != null) {
syncTransactionApplier.scheduleApply(params);
@@ -305,7 +317,7 @@
/**
* Compute scale and translation y such that the specified task view fills the screen.
*/
- public ClipAnimationHelper updateForFullscreenOverview(TaskView v) {
+ public AppWindowAnimationHelper updateForFullscreenOverview(TaskView v) {
TaskThumbnailView thumbnailView = v.getThumbnail();
RecentsView recentsView = v.getRecentsView();
fromTaskThumbnailView(thumbnailView, recentsView);
@@ -375,12 +387,14 @@
float progress;
public float offsetX;
public float offsetScale;
- @Nullable RectF currentRect;
+ public @Nullable RectF currentRect;
float targetAlpha;
boolean forLiveTile;
float cornerRadius;
+ boolean launcherOnTop;
- SyncRtSurfaceTransactionApplierCompat syncTransactionApplier;
+ public RemoteAnimationTargets targetSet;
+ public SyncRtSurfaceTransactionApplierCompat syncTransactionApplier;
public TransformParams() {
progress = 0;
@@ -390,6 +404,7 @@
targetAlpha = 0;
forLiveTile = false;
cornerRadius = -1;
+ launcherOnTop = false;
}
public TransformParams setProgress(float progress) {
@@ -424,6 +439,16 @@
return this;
}
+ public TransformParams setLauncherOnTop(boolean launcherOnTop) {
+ this.launcherOnTop = launcherOnTop;
+ return this;
+ }
+
+ public TransformParams setTargetSet(RemoteAnimationTargets targetSet) {
+ this.targetSet = targetSet;
+ return this;
+ }
+
public TransformParams setSyncTransactionApplier(
SyncRtSurfaceTransactionApplierCompat applier) {
this.syncTransactionApplier = applier;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationCallbacks.java
similarity index 64%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationCallbacks.java
index 71ad8ba..415f767 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationCallbacks.java
@@ -25,48 +25,44 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.util.Preconditions;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.TouchInteractionService;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
-import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.Set;
import java.util.function.Consumer;
/**
- * Wrapper around {@link RecentsAnimationListener} which delegates callbacks to multiple listeners
+ * Wrapper around {@link com.android.systemui.shared.system.RecentsAnimationListener} which delegates callbacks to multiple listeners
* on the main thread
*/
-public class RecentsAnimationListenerSet implements RecentsAnimationListener {
+public class RecentsAnimationCallbacks implements
+ com.android.systemui.shared.system.RecentsAnimationListener {
- // The actual app surface is replaced by a screenshot upon recents animation cancelation when
- // the thumbnailData exists. Launcher takes the responsibility to clean up this screenshot
- // after app transition is finished. This delay is introduced to cover the app transition
- // period of time.
- private final int TRANSITION_DELAY = 100;
-
- private final Set<SwipeAnimationListener> mListeners = new ArraySet<>();
+ private final Set<RecentsAnimationListener> mListeners = new ArraySet<>();
private final boolean mShouldMinimizeSplitScreen;
- private final Consumer<SwipeAnimationTargetSet> mOnFinishListener;
+ private final Consumer<RecentsAnimationTargets> mOnFinishListener;
private RecentsAnimationControllerCompat mController;
private boolean mCancelled;
- public RecentsAnimationListenerSet(boolean shouldMinimizeSplitScreen,
- Consumer<SwipeAnimationTargetSet> onFinishListener) {
+ public RecentsAnimationCallbacks(boolean shouldMinimizeSplitScreen,
+ Consumer<RecentsAnimationTargets> onFinishListener) {
mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen;
mOnFinishListener = onFinishListener;
+ TouchInteractionService.getSwipeSharedState().setRecentsAnimationCanceledCallback(
+ () -> mController.cleanupScreenshot());
}
@UiThread
- public void addListener(SwipeAnimationListener listener) {
+ public void addListener(RecentsAnimationListener listener) {
Preconditions.assertUIThread();
mListeners.add(listener);
}
@UiThread
- public void removeListener(SwipeAnimationListener listener) {
+ public void removeListener(RecentsAnimationListener listener) {
Preconditions.assertUIThread();
mListeners.remove(listener);
}
@@ -78,7 +74,7 @@
RemoteAnimationTargetCompat[] wallpaperTargets,
Rect homeContentInsets, Rect minimizedHomeBounds) {
mController = controller;
- SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, appTargets,
+ RecentsAnimationTargets targetSet = new RecentsAnimationTargets(controller, appTargets,
wallpaperTargets, homeContentInsets, minimizedHomeBounds,
mShouldMinimizeSplitScreen, mOnFinishListener);
@@ -86,7 +82,7 @@
targetSet.cancelAnimation();
} else {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
- for (SwipeAnimationListener listener : getListeners()) {
+ for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationStart(targetSet);
}
});
@@ -107,23 +103,31 @@
@Override
public final void onAnimationCanceled(ThumbnailData thumbnailData) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
- for (SwipeAnimationListener listener : getListeners()) {
- listener.onRecentsAnimationCanceled();
+ for (RecentsAnimationListener listener : getListeners()) {
+ listener.onRecentsAnimationCanceled(thumbnailData);
}
});
- // TODO: handle the transition better instead of simply using a transition delay.
- if (thumbnailData != null) {
- MAIN_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
- TRANSITION_DELAY);
- }
}
- private SwipeAnimationListener[] getListeners() {
- return mListeners.toArray(new SwipeAnimationListener[mListeners.size()]);
+ private RecentsAnimationListener[] getListeners() {
+ return mListeners.toArray(new RecentsAnimationListener[mListeners.size()]);
}
public void cancelListener() {
mCancelled = true;
onAnimationCanceled(null);
}
+
+ /**
+ * Listener for the recents animation callbacks.
+ */
+ public interface RecentsAnimationListener {
+ void onRecentsAnimationStart(RecentsAnimationTargets targetSet);
+
+ /**
+ * Callback from the system when the recents animation is canceled. {@param thumbnailData}
+ * is passed back for rendering screenshot to replace live tile.
+ */
+ void onRecentsAnimationCanceled(ThumbnailData thumbnailData);
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationTargets.java
similarity index 86%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationTargets.java
index 3da6b78..187a404 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationTargets.java
@@ -28,22 +28,22 @@
import java.util.function.Consumer;
/**
- * Extension of {@link RemoteAnimationTargetSet} with additional information about swipe
+ * Extension of {@link RemoteAnimationTargets} with additional information about swipe
* up animation
*/
-public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet {
+public class RecentsAnimationTargets extends RemoteAnimationTargets {
private final boolean mShouldMinimizeSplitScreen;
- private final Consumer<SwipeAnimationTargetSet> mOnFinishListener;
+ private final Consumer<RecentsAnimationTargets> mOnFinishListener;
public final RecentsAnimationControllerCompat controller;
public final Rect homeContentInsets;
public final Rect minimizedHomeBounds;
- public SwipeAnimationTargetSet(RecentsAnimationControllerCompat controller,
+ public RecentsAnimationTargets(RecentsAnimationControllerCompat controller,
RemoteAnimationTargetCompat[] apps, RemoteAnimationTargetCompat[] wallpapers,
Rect homeContentInsets, Rect minimizedHomeBounds, boolean shouldMinimizeSplitScreen,
- Consumer<SwipeAnimationTargetSet> onFinishListener) {
+ Consumer<RecentsAnimationTargets> onFinishListener) {
super(apps, wallpapers, MODE_CLOSING);
this.controller = controller;
this.homeContentInsets = homeContentInsets;
@@ -60,8 +60,8 @@
* Clones the target set without any actual targets. Used only when continuing a gesture after
* the actual recents animation has finished.
*/
- public SwipeAnimationTargetSet cloneWithoutTargets() {
- return new SwipeAnimationTargetSet(controller, new RemoteAnimationTargetCompat[0],
+ public RecentsAnimationTargets cloneWithoutTargets() {
+ return new RecentsAnimationTargets(controller, new RemoteAnimationTargetCompat[0],
new RemoteAnimationTargetCompat[0], homeContentInsets, minimizedHomeBounds,
mShouldMinimizeSplitScreen, mOnFinishListener);
}
@@ -109,11 +109,4 @@
public void finishAnimation() {
finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
}
-
- public interface SwipeAnimationListener {
-
- void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet);
-
- void onRecentsAnimationCanceled();
- }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 0f9fc17..0f9184f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -48,8 +48,8 @@
import com.android.launcher3.uioverrides.DejankBinderTracker;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
+import com.android.quickstep.util.AppWindowAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
import com.android.quickstep.util.LayoutUtils;
/**
@@ -78,7 +78,12 @@
@Override
public void startHome() {
- mActivity.getStateManager().goToState(NORMAL);
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ switchToScreenshot(() -> finishRecentsAnimation(true /* toRecents */,
+ () -> mActivity.getStateManager().goToState(NORMAL)));
+ } else {
+ mActivity.getStateManager().goToState(NORMAL);
+ }
}
@Override
@@ -115,7 +120,7 @@
*/
@Override
public AnimatorSet createAdjacentPageAnimForTaskLaunch(TaskView tv,
- ClipAnimationHelper helper) {
+ AppWindowAnimationHelper helper) {
AnimatorSet anim = super.createAdjacentPageAnimForTaskLaunch(tv, helper);
if (!SysUINavigationMode.getMode(mActivity).hasGestures) {
@@ -169,12 +174,11 @@
@Override
protected void onTaskLaunchAnimationUpdate(float progress, TaskView tv) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- if (mRecentsAnimationWrapper.targetSet != null && tv.isRunningTask()) {
+ if (tv.isRunningTask()) {
mTransformParams.setProgress(1 - progress)
.setSyncTransactionApplier(mSyncTransactionApplier)
.setForLiveTile(true);
- mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet,
- mTransformParams);
+ mAppWindowAnimationHelper.applyTransform(mTransformParams);
} else {
redrawLiveTile(true);
}
@@ -207,9 +211,18 @@
@Override
public void redrawLiveTile(boolean mightNeedToRefill) {
+ AppWindowAnimationHelper.TransformParams transformParams = getLiveTileParams(mightNeedToRefill);
+ if (transformParams != null) {
+ mAppWindowAnimationHelper.applyTransform(transformParams);
+ }
+ }
+
+ @Override
+ public AppWindowAnimationHelper.TransformParams getLiveTileParams(
+ boolean mightNeedToRefill) {
if (!mEnableDrawingLiveTile || mRecentsAnimationWrapper == null
- || mClipAnimationHelper == null) {
- return;
+ || mAppWindowAnimationHelper == null) {
+ return null;
}
TaskView taskView = getRunningTaskView();
if (taskView != null) {
@@ -231,12 +244,11 @@
mTempRectF.set(mTempRect);
mTransformParams.setProgress(1f)
.setCurrentRectAndTargetAlpha(mTempRectF, taskView.getAlpha())
- .setSyncTransactionApplier(mSyncTransactionApplier);
- if (mRecentsAnimationWrapper.targetSet != null) {
- mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet,
- mTransformParams);
- }
+ .setSyncTransactionApplier(mSyncTransactionApplier)
+ .setTargetSet(mRecentsAnimationWrapper.targetSet)
+ .setLauncherOnTop(true);
}
+ return mTransformParams;
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 554f437..cefe264 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -17,7 +17,6 @@
package com.android.quickstep.views;
import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_PIXELS;
-
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
@@ -107,7 +106,8 @@
import com.android.quickstep.RecentsModel.TaskThumbnailChangeListener;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.ViewUtils;
+import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -156,7 +156,7 @@
};
protected RecentsAnimationWrapper mRecentsAnimationWrapper;
- protected ClipAnimationHelper mClipAnimationHelper;
+ protected AppWindowAnimationHelper mAppWindowAnimationHelper;
protected SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
protected int mTaskWidth;
protected int mTaskHeight;
@@ -176,7 +176,7 @@
private final ClearAllButton mClearAllButton;
private final Rect mClearAllButtonDeadZoneRect = new Rect();
private final Rect mTaskViewDeadZoneRect = new Rect();
- protected final ClipAnimationHelper mTempClipAnimationHelper;
+ protected final AppWindowAnimationHelper mTempAppWindowAnimationHelper;
private final ScrollState mScrollState = new ScrollState();
// Keeps track of the previously known visible tasks for purposes of loading/unloading task data
@@ -327,7 +327,7 @@
mActivity = (T) BaseActivity.fromContext(context);
mModel = RecentsModel.INSTANCE.get(context);
mIdp = InvariantDeviceProfile.INSTANCE.get(context);
- mTempClipAnimationHelper = new ClipAnimationHelper(context);
+ mTempAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
.inflate(R.layout.overview_clear_all_button, this, false);
@@ -380,14 +380,23 @@
return null;
}
- public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData) {
+ /**
+ * Update the thumbnail of the task.
+ * @param refreshNow Refresh immediately if it's true.
+ */
+ public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData, boolean refreshNow) {
TaskView taskView = getTaskView(taskId);
if (taskView != null) {
- taskView.getThumbnail().setThumbnail(taskView.getTask(), thumbnailData);
+ taskView.getThumbnail().setThumbnail(taskView.getTask(), thumbnailData, refreshNow);
}
return taskView;
}
+ /** See {@link #updateThumbnail(int, ThumbnailData, boolean)} */
+ public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData) {
+ return updateThumbnail(taskId, thumbnailData, true /* refreshNow */);
+ }
+
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
@@ -573,11 +582,14 @@
taskView.bind(task);
}
- TaskView runningTaskView = getRunningTaskView();
- if (runningTaskView != null) {
- setCurrentPage(indexOfChild(runningTaskView));
- } else if (getTaskViewCount() > 0) {
- setCurrentPage(indexOfChild(getTaskViewAt(0)));
+ if (mNextPage == INVALID_PAGE) {
+ // Set the current page to the running task, but not if settling on new task.
+ TaskView runningTaskView = getRunningTaskView();
+ if (runningTaskView != null) {
+ setCurrentPage(indexOfChild(runningTaskView));
+ } else if (getTaskViewCount() > 0) {
+ setCurrentPage(indexOfChild(getTaskViewAt(0)));
+ }
}
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
@@ -796,7 +808,7 @@
mTaskListChangeId = -1;
mRecentsAnimationWrapper = null;
- mClipAnimationHelper = null;
+ mAppWindowAnimationHelper = null;
unloadVisibleTaskData();
setCurrentPage(0);
@@ -859,7 +871,9 @@
setEnableFreeScroll(true);
setEnableDrawingLiveTile(true);
setOnScrollChangeListener(null);
- setRunningTaskViewShowScreenshot(true);
+ if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ setRunningTaskViewShowScreenshot(true);
+ }
setRunningTaskHidden(false);
animateUpRunningTaskIconScale();
}
@@ -1505,14 +1519,14 @@
* to the right.
*/
public AnimatorSet createAdjacentPageAnimForTaskLaunch(
- TaskView tv, ClipAnimationHelper clipAnimationHelper) {
+ TaskView tv, AppWindowAnimationHelper appWindowAnimationHelper) {
AnimatorSet anim = new AnimatorSet();
int taskIndex = indexOfChild(tv);
int centerTaskIndex = getCurrentPage();
boolean launchingCenterTask = taskIndex == centerTaskIndex;
- LauncherState.ScaleAndTranslation toScaleAndTranslation = clipAnimationHelper
+ LauncherState.ScaleAndTranslation toScaleAndTranslation = appWindowAnimationHelper
.getScaleAndTranslation();
float toScale = toScaleAndTranslation.scale;
float toTranslationY = toScaleAndTranslation.translationY;
@@ -1572,10 +1586,10 @@
}
});
- ClipAnimationHelper clipAnimationHelper = new ClipAnimationHelper(mActivity);
- clipAnimationHelper.fromTaskThumbnailView(tv.getThumbnail(), this);
- clipAnimationHelper.prepareAnimation(mActivity.getDeviceProfile(), true /* isOpening */);
- AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv, clipAnimationHelper);
+ AppWindowAnimationHelper appWindowAnimationHelper = new AppWindowAnimationHelper(mActivity);
+ appWindowAnimationHelper.fromTaskThumbnailView(tv.getThumbnail(), this);
+ appWindowAnimationHelper.prepareAnimation(mActivity.getDeviceProfile(), true /* isOpening */);
+ AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv, appWindowAnimationHelper);
anim.play(progressAnim);
anim.setDuration(duration);
@@ -1682,8 +1696,8 @@
mRecentsAnimationWrapper = recentsAnimationWrapper;
}
- public void setClipAnimationHelper(ClipAnimationHelper clipAnimationHelper) {
- mClipAnimationHelper = clipAnimationHelper;
+ public void setAppWindowAnimationHelper(AppWindowAnimationHelper appWindowAnimationHelper) {
+ mAppWindowAnimationHelper = appWindowAnimationHelper;
}
public void setLiveTileOverlay(LiveTileOverlay liveTileOverlay) {
@@ -1791,8 +1805,17 @@
}
}
- public ClipAnimationHelper getTempClipAnimationHelper() {
- return mTempClipAnimationHelper;
+ public AppWindowAnimationHelper getClipAnimationHelper() {
+ return mAppWindowAnimationHelper;
+ }
+
+ public AppWindowAnimationHelper getTempAppWindowAnimationHelper() {
+ return mTempAppWindowAnimationHelper;
+ }
+
+ public AppWindowAnimationHelper.TransformParams getLiveTileParams(
+ boolean mightNeedToRefill) {
+ return null;
}
private void updateEnabledOverlays() {
@@ -1819,4 +1842,19 @@
final WindowInsets insets = getRootWindowInsets();
return Math.max(insets.getSystemGestureInsets().right, insets.getSystemWindowInsetRight());
}
+
+ /** If it's in the live tile mode, switch the running task into screenshot mode. */
+ public void switchToScreenshot(Runnable onFinishRunnable) {
+ TaskView taskView = getRunningTaskView();
+ if (taskView == null) {
+ if (onFinishRunnable != null) {
+ onFinishRunnable.run();
+ }
+ return;
+ }
+
+ taskView.setShowScreenshot(true);
+ taskView.getThumbnail().refresh();
+ ViewUtils.postDraw(taskView, onFinishRunnable);
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 5799c01..adeb974 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -134,16 +134,35 @@
}
/**
- * Updates this thumbnail.
+ * Updates the thumbnail.
+ * @param refreshNow whether the {@code thumbnailData} will be used to redraw immediately.
+ * In most cases, we use the {@link #setThumbnail(Task, ThumbnailData)}
+ * version with {@code refreshNow} is true. The only exception is
+ * in the live tile case that we grab a screenshot when user enters Overview
+ * upon swipe up so that a usable screenshot is accessible immediately when
+ * recents animation needs to be finished / cancelled.
*/
- public void setThumbnail(Task task, ThumbnailData thumbnailData) {
+ public void setThumbnail(Task task, ThumbnailData thumbnailData, boolean refreshNow) {
mTask = task;
- if (thumbnailData != null && thumbnailData.thumbnail != null) {
- Bitmap bm = thumbnailData.thumbnail;
+ mThumbnailData =
+ (thumbnailData != null && thumbnailData.thumbnail != null) ? thumbnailData : null;
+ if (refreshNow) {
+ refresh();
+ }
+ }
+
+ /** See {@link #setThumbnail(Task, ThumbnailData, boolean)} */
+ public void setThumbnail(Task task, ThumbnailData thumbnailData) {
+ setThumbnail(task, thumbnailData, true /* refreshNow */);
+ }
+
+ /** Updates the shader, paint, matrix to redraw. */
+ public void refresh() {
+ if (mThumbnailData != null && mThumbnailData.thumbnail != null) {
+ Bitmap bm = mThumbnailData.thumbnail;
bm.prepareToDraw();
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
- mThumbnailData = thumbnailData;
updateThumbnailMatrix();
} else {
mBitmapShader = null;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 51802df..bfb9613 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -53,7 +53,6 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 7cd8786..af75364 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -71,7 +71,7 @@
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.QuickStepContract;
@@ -433,7 +433,7 @@
Rect crop = new Rect();
Matrix matrix = new Matrix();
- RemoteAnimationTargetSet openingTargets = new RemoteAnimationTargetSet(appTargets,
+ RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets,
wallpaperTargets, MODE_OPENING);
SyncRtSurfaceTransactionApplierCompat surfaceApplier =
new SyncRtSurfaceTransactionApplierCompat(floatingView);
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 2d4b136..132d6ab 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Region;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
@@ -33,7 +32,8 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.quickstep.util.ActivityInitListener;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
+import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.function.BiPredicate;
@@ -80,7 +80,7 @@
boolean shouldMinimizeSplitScreen();
- default boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+ default boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
return true;
}
@@ -97,6 +97,8 @@
default void closeOverlay() { }
+ default void switchToScreenshot(ThumbnailData thumbnailData, Runnable runnable) {}
+
interface AnimationFactory {
enum ShelfAnimState {
@@ -109,7 +111,7 @@
public final boolean shouldPreformHaptic;
}
- default void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) { }
+ default void onRemoteAnimationReceived(RemoteAnimationTargets targets) { }
void createActivityController(long transitionLength);
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 88a4eb6..331183a 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -57,6 +56,7 @@
}
};
private final Context mContext;
+ private final RecentsAnimationDeviceState mDeviceState;
private final Intent mCurrentHomeIntent;
private final Intent mMyHomeIntent;
private final Intent mFallbackIntent;
@@ -64,12 +64,13 @@
private String mUpdateRegisteredPackage;
private ActivityControlHelper mActivityControlHelper;
private Intent mOverviewIntent;
- private int mSystemUiStateFlags;
private boolean mIsHomeAndOverviewSame;
private boolean mIsDefaultHome;
+ private boolean mIsHomeDisabled;
- public OverviewComponentObserver(Context context) {
+ public OverviewComponentObserver(Context context, RecentsAnimationDeviceState deviceState) {
mContext = context;
+ mDeviceState = deviceState;
mCurrentHomeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
@@ -98,11 +99,8 @@
updateOverviewTargets();
}
- public void onSystemUiStateChanged(int stateFlags) {
- boolean homeDisabledChanged = (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED)
- != (stateFlags & SYSUI_STATE_HOME_DISABLED);
- mSystemUiStateFlags = stateFlags;
- if (homeDisabledChanged) {
+ public void onSystemUiStateChanged() {
+ if (mDeviceState.isHomeDisabled() != mIsHomeDisabled) {
updateOverviewTargets();
}
}
@@ -115,6 +113,7 @@
ComponentName defaultHome = PackageManagerWrapper.getInstance()
.getHomeActivities(new ArrayList<>());
+ mIsHomeDisabled = mDeviceState.isHomeDisabled();
mIsDefaultHome = Objects.equals(mMyHomeIntent.getComponent(), defaultHome);
// Set assistant visibility to 0 from launcher's perspective, ensures any elements that
@@ -124,8 +123,7 @@
mActivityControlHelper.onAssistantVisibilityChanged(0.f);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
- && (defaultHome == null || mIsDefaultHome)) {
+ if (!mDeviceState.isHomeDisabled() && (defaultHome == null || mIsDefaultHome)) {
// User default home is same as out home app. Use Overview integrated in Launcher.
mActivityControlHelper = new LauncherActivityControllerHelper();
mIsHomeAndOverviewSame = true;
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 858c3b6..17462ab 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -86,6 +86,7 @@
mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
}
+ // TODO(141886704): See if we can remove this
public void setSystemUiStateFlags(int stateFlags) {
mSystemUiStateFlags = stateFlags;
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
new file mode 100644
index 0000000..9b094f6
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static android.content.Intent.ACTION_USER_UNLOCKED;
+import static com.android.launcher3.ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE;
+import static com.android.launcher3.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.os.Process;
+import android.text.TextUtils;
+import android.view.MotionEvent;
+import android.view.Surface;
+import androidx.annotation.BinderThread;
+import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.DefaultDisplay;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Manages the state of the system during a swipe up gesture.
+ */
+public class RecentsAnimationDeviceState implements
+ SysUINavigationMode.NavigationModeChangeListener,
+ DefaultDisplay.DisplayInfoChangeListener {
+
+ private Context mContext;
+ private UserManagerCompat mUserManager;
+ private SysUINavigationMode mSysUiNavMode;
+ private DefaultDisplay mDefaultDisplay;
+ private int mDisplayId;
+
+ private @SystemUiStateFlags int mSystemUiStateFlags;
+ private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
+
+ private final RectF mSwipeUpTouchRegion = new RectF();
+ private final Region mDeferredGestureRegion = new Region();
+ private final RectF mAssistantLeftRegion = new RectF();
+ private final RectF mAssistantRightRegion = new RectF();
+ private boolean mAssistantAvailable;
+ private float mAssistantVisibility;
+
+ private boolean mIsUserUnlocked;
+ private final ArrayList<Runnable> mUserUnlockedActions = new ArrayList<>();
+ private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+ mIsUserUnlocked = true;
+ notifyUserUnlocked();
+ }
+ }
+ };
+
+ private Region mExclusionRegion;
+ private SystemGestureExclusionListenerCompat mExclusionListener;
+
+ private ComponentName mGestureBlockedActivity;
+
+ public RecentsAnimationDeviceState(Context context) {
+ mContext = context;
+ mUserManager = UserManagerCompat.getInstance(context);
+ mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
+ mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
+ mDisplayId = mDefaultDisplay.getInfo().id;
+
+ // Register for user unlocked if necessary
+ mIsUserUnlocked = mUserManager.isUserUnlocked(Process.myUserHandle());
+ if (!mIsUserUnlocked) {
+ mContext.registerReceiver(mUserUnlockedReceiver,
+ new IntentFilter(ACTION_USER_UNLOCKED));
+ }
+
+ // Register for exclusion updates
+ mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) {
+ @Override
+ @BinderThread
+ public void onExclusionChanged(Region region) {
+ // Assignments are atomic, it should be safe on binder thread
+ mExclusionRegion = region;
+ }
+ };
+ onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
+
+ // Add any blocked activities
+ String blockingActivity = context.getString(R.string.gesture_blocking_activity);
+ if (!TextUtils.isEmpty(blockingActivity)) {
+ mGestureBlockedActivity = ComponentName.unflattenFromString(blockingActivity);
+ }
+ }
+
+ /**
+ * Cleans up all the registered listeners and receivers.
+ */
+ public void destroy() {
+ Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
+ mSysUiNavMode.removeModeChangeListener(this);
+ mDefaultDisplay.removeChangeListener(this);
+ mExclusionListener.unregister();
+ }
+
+ @Override
+ public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
+ mDefaultDisplay.removeChangeListener(this);
+ if (newMode.hasGestures) {
+ mDefaultDisplay.addChangeListener(this);
+ }
+
+ if (mMode == NO_BUTTON) {
+ mExclusionListener.register();
+ } else {
+ mExclusionListener.unregister();
+ }
+ mMode = newMode;
+ }
+
+ @Override
+ public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+ if (info.id != getDisplayId()) {
+ return;
+ }
+
+ updateGestureTouchRegions();
+ }
+
+ /**
+ * @return the display id for the display that Launcher is running on.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
+ * Adds a callback for when a user is unlocked. If the user is already unlocked, this listener
+ * will be called back immediately.
+ */
+ public void runOnUserUnlocked(Runnable action) {
+ if (mIsUserUnlocked) {
+ action.run();
+ } else {
+ mUserUnlockedActions.add(action);
+ }
+ }
+
+ /**
+ * @return whether the user is unlocked.
+ */
+ public boolean isUserUnlocked() {
+ return mIsUserUnlocked;
+ }
+
+ private void notifyUserUnlocked() {
+ for (Runnable action : mUserUnlockedActions) {
+ action.run();
+ }
+ mUserUnlockedActions.clear();
+ Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
+ }
+
+ /**
+ * @return whether the given running task info matches the gesture-blocked activity.
+ */
+ public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) {
+ return runningTaskInfo != null
+ && mGestureBlockedActivity.equals(runningTaskInfo.topActivity);
+ }
+
+ /**
+ * @return the package of the gesture-blocked activity or {@code null} if there is none.
+ */
+ public String getGestureBlockedActivityPackage() {
+ return (mGestureBlockedActivity != null)
+ ? mGestureBlockedActivity.getPackageName()
+ : null;
+ }
+
+ /**
+ * Updates the system ui state flags from SystemUI.
+ */
+ public void setSystemUiFlags(int stateFlags) {
+ mSystemUiStateFlags = stateFlags;
+ }
+
+ /**
+ * @return the system ui state flags.
+ */
+ // TODO(141886704): See if we can remove this
+ public @SystemUiStateFlags int getSystemUiStateFlags() {
+ return mSystemUiStateFlags;
+ }
+
+ /**
+ * @return whether SystemUI is in a state where we can start a system gesture.
+ */
+ public boolean canStartSystemGesture() {
+ return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
+ && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
+ || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
+ }
+
+ /**
+ * @return whether the keyguard is showing and is occluded by an app showing above the keyguard
+ * (like camera or maps)
+ */
+ public boolean isKeyguardShowingOccluded() {
+ return (mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
+ }
+
+ /**
+ * @return whether screen pinning is enabled and active
+ */
+ public boolean isScreenPinningActive() {
+ return (mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
+ }
+
+ /**
+ * @return whether lock-task mode is active
+ */
+ public boolean isLockToAppActive() {
+ return ActivityManagerWrapper.getInstance().isLockToAppActive();
+ }
+
+ /**
+ * @return whether the accessibility menu is available.
+ */
+ public boolean isAccessibilityMenuAvailable() {
+ return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+ }
+
+ /**
+ * @return whether the accessibility menu shortcut is available.
+ */
+ public boolean isAccessibilityMenuShortcutAvailable() {
+ return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+ }
+
+ /**
+ * @return whether home is disabled (either by SUW/SysUI/device policy)
+ */
+ public boolean isHomeDisabled() {
+ return (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
+ }
+
+ /**
+ * @return whether overview is disabled (either by SUW/SysUI/device policy)
+ */
+ public boolean isOverviewDisabled() {
+ return (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+ }
+
+ /**
+ * Updates the regions for detecting the swipe up/quickswitch and assistant gestures.
+ */
+ public void updateGestureTouchRegions() {
+ if (!mMode.hasGestures) {
+ return;
+ }
+
+ Resources res = mContext.getResources();
+ DefaultDisplay.Info displayInfo = mDefaultDisplay.getInfo();
+ Point realSize = new Point(displayInfo.realSize);
+ mSwipeUpTouchRegion.set(0, 0, realSize.x, realSize.y);
+ if (mMode == NO_BUTTON) {
+ int touchHeight = ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE, res);
+ mSwipeUpTouchRegion.top = mSwipeUpTouchRegion.bottom - touchHeight;
+
+ final int assistantWidth = res.getDimensionPixelSize(R.dimen.gestures_assistant_width);
+ final float assistantHeight = Math.max(touchHeight,
+ QuickStepContract.getWindowCornerRadius(res));
+ mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mSwipeUpTouchRegion.bottom;
+ mAssistantLeftRegion.top = mAssistantRightRegion.top =
+ mSwipeUpTouchRegion.bottom - assistantHeight;
+
+ mAssistantLeftRegion.left = 0;
+ mAssistantLeftRegion.right = assistantWidth;
+
+ mAssistantRightRegion.right = mSwipeUpTouchRegion.right;
+ mAssistantRightRegion.left = mSwipeUpTouchRegion.right - assistantWidth;
+ } else {
+ mAssistantLeftRegion.setEmpty();
+ mAssistantRightRegion.setEmpty();
+ switch (displayInfo.rotation) {
+ case Surface.ROTATION_90:
+ mSwipeUpTouchRegion.left = mSwipeUpTouchRegion.right
+ - ResourceUtils.getNavbarSize(NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE, res);
+ break;
+ case Surface.ROTATION_270:
+ mSwipeUpTouchRegion.right = mSwipeUpTouchRegion.left
+ + ResourceUtils.getNavbarSize(NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE, res);
+ break;
+ default:
+ mSwipeUpTouchRegion.top = mSwipeUpTouchRegion.bottom
+ - ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE, res);
+ }
+ }
+ }
+
+ /**
+ * @return whether the coordinates of the {@param event} is in the swipe up gesture region.
+ */
+ public boolean isInSwipeUpTouchRegion(MotionEvent event) {
+ return mSwipeUpTouchRegion.contains(event.getX(), event.getY());
+ }
+
+ /**
+ * @return whether the coordinates of the {@param event} with the given {@param pointerIndex}
+ * is in the swipe up gesture region.
+ */
+ public boolean isInSwipeUpTouchRegion(MotionEvent event, int pointerIndex) {
+ return mSwipeUpTouchRegion.contains(event.getX(pointerIndex), event.getY(pointerIndex));
+ }
+
+ /**
+ * Sets the region in screen space where the gestures should be deferred (ie. due to specific
+ * nav bar ui).
+ */
+ public void setDeferredGestureRegion(Region deferredGestureRegion) {
+ mDeferredGestureRegion.set(deferredGestureRegion);
+ }
+
+ /**
+ * @return whether the given {@param event} is in the deferred gesture region indicating that
+ * the Launcher should not immediately start the recents animation until the gesture
+ * passes a certain threshold.
+ */
+ public boolean isInDeferredGestureRegion(MotionEvent event) {
+ return mDeferredGestureRegion.contains((int) event.getX(), (int) event.getY());
+ }
+
+ /**
+ * @return whether the given {@param event} is in the app-requested gesture-exclusion region.
+ * This is only used for quickswitch, and not swipe up.
+ */
+ public boolean isInExclusionRegion(MotionEvent event) {
+ // mExclusionRegion can change on binder thread, use a local instance here.
+ Region exclusionRegion = mExclusionRegion;
+ return mMode == NO_BUTTON && exclusionRegion != null
+ && exclusionRegion.contains((int) event.getX(), (int) event.getY());
+ }
+
+ /**
+ * Sets whether the assistant is available.
+ */
+ public void setAssistantAvailable(boolean assistantAvailable) {
+ mAssistantAvailable = assistantAvailable;
+ }
+
+ /**
+ * Sets the visibility fraction of the assistant.
+ */
+ public void setAssistantVisibility(float visibility) {
+ mAssistantVisibility = visibility;
+ }
+
+ /**
+ * @return the visibility fraction of the assistant.
+ */
+ public float getAssistantVisibility() {
+ return mAssistantVisibility;
+ }
+
+ /**
+ * @param ev An ACTION_DOWN motion event
+ * @return whether the given motion event can trigger the assistant.
+ */
+ public boolean canTriggerAssistantAction(MotionEvent ev) {
+ return mAssistantAvailable
+ && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
+ && (mAssistantLeftRegion.contains(ev.getX(), ev.getY())
+ || mAssistantRightRegion.contains(ev.getX(), ev.getY()))
+ && !isLockToAppActive();
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println("DeviceState:");
+ pw.println(" canStartSystemGesture=" + canStartSystemGesture());
+ pw.println(" systemUiFlags=" + mSystemUiStateFlags);
+ pw.println(" systemUiFlagsDesc="
+ + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
+ pw.println(" assistantAvailable=" + mAssistantAvailable);
+ pw.println(" assistantDisabled="
+ + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index bf3cd8a..8e5ed1a 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -29,12 +29,16 @@
import android.stats.launcher.nano.Launcher;
import android.stats.launcher.nano.LauncherExtension;
import android.stats.launcher.nano.LauncherTarget;
+import android.util.Log;
import android.view.View;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import com.android.launcher3.util.ComponentKey;
import com.android.systemui.shared.system.StatsLogCompat;
import com.google.protobuf.nano.MessageNano;
@@ -50,6 +54,8 @@
public class StatsLogCompatManager extends StatsLogManager {
private static final int SUPPORTED_TARGET_DEPTH = 2;
+ private static final String TAG = "StatsLogCompatManager";
+ private static final boolean DEBUG = false;
public StatsLogCompatManager(Context context) { }
@@ -59,6 +65,9 @@
ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
int srcState = mStateProvider.getCurrentState();
fillInLauncherExtension(v, ext);
+ if (ext.srcTarget[0] != null) {
+ ext.srcTarget[0].item = LauncherTarget.APP_ICON;
+ }
StatsLogCompat.write(LAUNCH_APP, srcState, BACKGROUND /* dstState */,
MessageNano.toByteArray(ext), true);
}
@@ -95,28 +104,132 @@
}
public static boolean fillInLauncherExtension(View v, LauncherExtension extension) {
+ if (DEBUG) {
+ Log.d(TAG, "fillInLauncherExtension");
+ }
+
StatsLogUtils.LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v);
if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
+ if (DEBUG) {
+ Log.d(TAG, "View or provider is null, or view doesn't have an ItemInfo tag.");
+ }
+
return false;
}
ItemInfo itemInfo = (ItemInfo) v.getTag();
Target child = new Target();
Target parent = new Target();
provider.fillInLogContainerData(v, itemInfo, child, parent);
+ extension.srcTarget[0] = new LauncherTarget();
+ extension.srcTarget[1] = new LauncherTarget();
copy(child, extension.srcTarget[0]);
copy(parent, extension.srcTarget[1]);
return true;
}
public static boolean fillInLauncherExtensionWithPageId(LauncherExtension ext, int pageId) {
+ if (DEBUG) {
+ Log.d(TAG, "fillInLauncherExtensionWithPageId, pageId = " + pageId);
+ }
+
Target target = new Target();
target.pageIndex = pageId;
+ ext.srcTarget[0] = new LauncherTarget();
copy(target, ext.srcTarget[0]);
return true;
}
private static void copy(Target src, LauncherTarget dst) {
- // fill in
+ if (DEBUG) {
+ Log.d(TAG, "copy target information from clearcut Target to LauncherTarget.");
+ }
+
+ // Fill in type
+ switch (src.type) {
+ case Target.Type.ITEM:
+ dst.type = LauncherTarget.ITEM_TYPE;
+ break;
+ case Target.Type.CONTROL:
+ dst.type = LauncherTarget.CONTROL_TYPE;
+ break;
+ case Target.Type.CONTAINER:
+ dst.type = LauncherTarget.CONTAINER_TYPE;
+ break;
+ default:
+ dst.type = LauncherTarget.NONE;
+ break;
+ }
+
+ // Fill in item
+ switch (src.itemType) {
+ case ItemType.APP_ICON:
+ dst.item = LauncherTarget.APP_ICON;
+ break;
+ case ItemType.SHORTCUT:
+ dst.item = LauncherTarget.SHORTCUT;
+ break;
+ case ItemType.WIDGET:
+ dst.item = LauncherTarget.WIDGET;
+ break;
+ case ItemType.FOLDER_ICON:
+ dst.item = LauncherTarget.FOLDER_ICON;
+ break;
+ case ItemType.DEEPSHORTCUT:
+ dst.item = LauncherTarget.DEEPSHORTCUT;
+ break;
+ case ItemType.SEARCHBOX:
+ dst.item = LauncherTarget.SEARCHBOX;
+ break;
+ case ItemType.EDITTEXT:
+ dst.item = LauncherTarget.EDITTEXT;
+ break;
+ case ItemType.NOTIFICATION:
+ dst.item = LauncherTarget.NOTIFICATION;
+ break;
+ case ItemType.TASK:
+ dst.item = LauncherTarget.TASK;
+ break;
+ default:
+ dst.item = LauncherTarget.DEFAULT_ITEM;
+ break;
+ }
+
+ // Fill in container
+ switch (src.containerType) {
+ case ContainerType.HOTSEAT:
+ dst.container = LauncherTarget.HOTSEAT;
+ break;
+ case ContainerType.FOLDER:
+ dst.container = LauncherTarget.FOLDER;
+ break;
+ case ContainerType.PREDICTION:
+ dst.container = LauncherTarget.PREDICTION;
+ break;
+ case ContainerType.SEARCHRESULT:
+ dst.container = LauncherTarget.SEARCHRESULT;
+ break;
+ default:
+ dst.container = LauncherTarget.DEFAULT_CONTAINER;
+ break;
+ }
+
+ // Fill in control
+ switch (src.controlType) {
+ case ControlType.UNINSTALL_TARGET:
+ dst.control = LauncherTarget.UNINSTALL;
+ break;
+ case ControlType.REMOVE_TARGET:
+ dst.control = LauncherTarget.REMOVE;
+ break;
+ default:
+ dst.control = LauncherTarget.DEFAULT_CONTROL;
+ break;
+ }
+
+ // Fill in other fields
+ dst.pageId = src.pageIndex;
+ dst.gridX = src.gridX;
+ dst.gridY = src.gridY;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargets.java
similarity index 96%
rename from quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java
rename to quickstep/src/com/android/quickstep/util/RemoteAnimationTargets.java
index d769248..ff726a1 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargets.java
@@ -25,7 +25,7 @@
/**
* Holds a collection of RemoteAnimationTargets, filtered by different properties.
*/
-public class RemoteAnimationTargetSet {
+public class RemoteAnimationTargets {
private final Queue<SyncRtSurfaceTransactionApplierCompat> mDependentTransactionAppliers =
new ArrayDeque<>(1);
@@ -36,7 +36,7 @@
public final int targetMode;
public final boolean hasRecents;
- public RemoteAnimationTargetSet(RemoteAnimationTargetCompat[] apps,
+ public RemoteAnimationTargets(RemoteAnimationTargetCompat[] apps,
RemoteAnimationTargetCompat[] wallpapers, int targetMode) {
ArrayList<RemoteAnimationTargetCompat> filteredApps = new ArrayList<>();
boolean hasRecents = false;
diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
index 1d0851c..7f6aba9 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
@@ -29,12 +29,12 @@
*/
public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener {
- private final RemoteAnimationTargetSet mTarget;
+ private final RemoteAnimationTargets mTarget;
private boolean mFirstFrame = true;
public RemoteFadeOutAnimationListener(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets) {
- mTarget = new RemoteAnimationTargetSet(appTargets, wallpaperTargets, MODE_CLOSING);
+ mTarget = new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_CLOSING);
}
@Override
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index e295527..c2197ab 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -181,7 +181,7 @@
SysUINavigationMode.INSTANCE.get(targetContext);
targetContext.getMainExecutor().execute(() ->
sysUINavigationMode.addModeChangeListener(listener));
- latch.await(10, TimeUnit.SECONDS);
+ latch.await(60, TimeUnit.SECONDS);
targetContext.getMainExecutor().execute(() ->
sysUINavigationMode.removeModeChangeListener(listener));
assertTrue("Navigation mode didn't change to " + expectedMode,
diff --git a/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java b/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
index a46617e..b7340cf 100644
--- a/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
@@ -130,7 +130,7 @@
}
helper.close();
- helper = new DatabaseHelper(mContext, null, DB_FILE) {
+ helper = new DatabaseHelper(mContext, DB_FILE) {
@Override
public void onOpen(SQLiteDatabase db) { }
};
@@ -161,7 +161,7 @@
DbDowngradeHelper.updateSchemaFile(mSchemaFile, LauncherProvider.SCHEMA_VERSION, mContext);
- DatabaseHelper dbHelper = new DatabaseHelper(mContext, null, DB_FILE) {
+ DatabaseHelper dbHelper = new DatabaseHelper(mContext, DB_FILE) {
@Override
public void onOpen(SQLiteDatabase db) { }
};
diff --git a/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java b/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
index 9f833b1..a9c1a7c 100644
--- a/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
+++ b/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
@@ -29,7 +29,7 @@
private static class MyDatabaseHelper extends DatabaseHelper {
public MyDatabaseHelper(Context context) {
- super(context, null, null);
+ super(context, null);
initIds();
}
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 8fddf3c..af2cdc3 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
@@ -30,6 +29,7 @@
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
import androidx.annotation.IntDef;
@@ -171,7 +171,7 @@
targetInfo.first, TYPE_WINDOW_STATE_CHANGED, targetInfo.second);
if (mIsOpen) {
- sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
+ performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
}
ActivityContext.lookupContext(getContext()).getDragLayer()
.sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index c034d2d..736142f 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -111,6 +111,7 @@
// All apps
public int allAppsCellHeightPx;
+ public int allAppsCellWidthPx;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
public float allAppsIconTextSizePx;
@@ -349,6 +350,7 @@
allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
allAppsCellHeightPx = getCellSize().y;
}
+ allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;
if (isVerticalBarLayout()) {
// Always hide the Workspace text with vertical bar layout.
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 638b505..8ebf464 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -69,7 +69,6 @@
public static final int FLAG_ACTIVITY_PAUSED = 1;
public static final int FLAG_LOADER_RUNNING = 2;
public static final int FLAG_DRAG_AND_DROP = 4;
- public static final int FLAG_BULK_ADD = 4;
// Determines whether to defer installing shortcuts immediately until
// processAllPendingInstalls() is called.
@@ -110,8 +109,7 @@
@WorkerThread
private static void flushQueueInBackground(Context context) {
- LauncherModel model = LauncherAppState.getInstance(context).getModel();
- if (model.getCallback() == null) {
+ if (Launcher.ACTIVITY_TRACKER.getCreatedActivity() == null) {
// Launcher not loaded
return;
}
@@ -146,7 +144,8 @@
}
prefs.edit().remove(APPS_PENDING_INSTALL).apply();
if (!installQueue.isEmpty()) {
- model.addAndBindAddedWorkspaceItems(installQueue);
+ LauncherAppState.getInstance(context).getModel()
+ .addAndBindAddedWorkspaceItems(installQueue);
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5c72436..c92d917 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -173,7 +173,7 @@
* Default launcher application.
*/
public class Launcher extends BaseDraggingActivity implements LauncherExterns,
- Callbacks, LauncherProviderChangeListener, UserEventDelegate,
+ Callbacks, UserEventDelegate,
InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
public static final String TAG = "Launcher";
@@ -614,13 +614,6 @@
return mLauncherView.findViewById(id);
}
- @Override
- public void onAppWidgetHostReset() {
- if (mAppWidgetHost != null) {
- mAppWidgetHost.startListening();
- }
- }
-
private LauncherCallbacks mLauncherCallbacks;
/**
@@ -1896,7 +1889,7 @@
// recents animation into launcher. Defer launching the activity until Launcher is
// next resumed.
addOnResumeCallback(() -> startActivitySafely(v, intent, item, sourceContainer));
- UiFactory.clearSwipeSharedState(true /* finishAnimation */);
+ UiFactory.clearSwipeSharedState(this, true /* finishAnimation */);
return true;
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index f687c9d..c717d1a 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
import android.content.ComponentName;
-import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
@@ -72,10 +71,6 @@
}
private LauncherAppState(Context context) {
- if (getLocalProvider(context) == null) {
- throw new RuntimeException(
- "Initializing LauncherAppState in the absence of LauncherProvider");
- }
Log.v(Launcher.TAG, "LauncherAppState initiated");
Preconditions.assertUIThread();
mContext = context;
@@ -97,7 +92,10 @@
if (FeatureFlags.IS_DOGFOOD_BUILD) {
mModelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
}
+ // TODO: remove listener on terminate
FeatureFlags.APP_SEARCH_IMPROVEMENTS.addChangeListener(context, mModel::forceReload);
+ CustomWidgetManager.INSTANCE.get(mContext)
+ .setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
UserManagerCompat.getInstance(mContext).enableAndResetCache();
mInvariantDeviceProfile.addOnChangeListener(this::onIdpChanged);
@@ -145,16 +143,15 @@
mContext.unregisterReceiver(mModelChangeReceiver);
mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel);
mInstallSessionTracker.unregister();
+ CustomWidgetManager.INSTANCE.get(mContext).setWidgetRefreshCallback(null);
+
if (mNotificationDotsObserver != null) {
mNotificationDotsObserver.unregister();
}
}
LauncherModel setLauncher(Launcher launcher) {
- getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);
- CustomWidgetManager.INSTANCE.get(launcher)
- .setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
return mModel;
}
@@ -180,11 +177,4 @@
public static InvariantDeviceProfile getIDP(Context context) {
return InvariantDeviceProfile.INSTANCE.get(context);
}
-
- private static LauncherProvider getLocalProvider(Context context) {
- try (ContentProviderClient cl = context.getContentResolver()
- .acquireContentProviderClient(LauncherProvider.AUTHORITY)) {
- return (LauncherProvider) cl.getLocalContentProvider();
- }
- }
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index d78c1b3..42927ea 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -45,8 +45,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.Process;
import android.os.UserHandle;
import android.provider.BaseColumns;
@@ -69,7 +67,6 @@
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.NoLocaleSQLiteHelper;
import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Thunk;
import org.xmlpull.v1.XmlPullParser;
@@ -100,9 +97,6 @@
static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
- private final ChangeListenerWrapper mListenerWrapper = new ChangeListenerWrapper();
- private Handler mListenerHandler;
-
protected DatabaseHelper mOpenHelper;
/**
@@ -122,7 +116,6 @@
if (FeatureFlags.IS_DOGFOOD_BUILD) {
Log.d(TAG, "Launcher process started");
}
- mListenerHandler = new Handler(mListenerWrapper);
// The content provider exists for the entire duration of the launcher main process and
// is the first component to get created.
@@ -130,14 +123,6 @@
return true;
}
- /**
- * Sets a provider listener.
- */
- public void setLauncherProviderChangeListener(LauncherProviderChangeListener listener) {
- Preconditions.assertUIThread();
- mListenerWrapper.mListener = listener;
- }
-
@Override
public String getType(Uri uri) {
SqlArguments args = new SqlArguments(uri, null, null);
@@ -153,7 +138,7 @@
*/
protected synchronized void createDbIfNotExists() {
if (mOpenHelper == null) {
- mOpenHelper = new DatabaseHelper(getContext(), mListenerHandler);
+ mOpenHelper = new DatabaseHelper(getContext());
if (RestoreDbTask.isPending(getContext())) {
if (!RestoreDbTask.performRestore(getContext(), mOpenHelper,
@@ -552,15 +537,13 @@
* The class is subclassed in tests to create an in-memory db.
*/
public static class DatabaseHelper extends NoLocaleSQLiteHelper implements LayoutParserCallback {
- private final BackupManager mBackupManager;
- private final Handler mWidgetHostResetHandler;
private final Context mContext;
private int mMaxItemId = -1;
private int mMaxScreenId = -1;
private boolean mBackupTableExists;
- DatabaseHelper(Context context, Handler widgetHostResetHandler) {
- this(context, widgetHostResetHandler, LauncherFiles.LAUNCHER_DB);
+ DatabaseHelper(Context context) {
+ this(context, LauncherFiles.LAUNCHER_DB);
// Table creation sometimes fails silently, which leads to a crash loop.
// This way, we will try to create a table every time after crash, so the device
// would eventually be able to recover.
@@ -577,12 +560,9 @@
/**
* Constructor used in tests and for restore.
*/
- public DatabaseHelper(
- Context context, Handler widgetHostResetHandler, String tableName) {
+ public DatabaseHelper(Context context, String tableName) {
super(context, tableName, SCHEMA_VERSION);
mContext = context;
- mWidgetHostResetHandler = widgetHostResetHandler;
- mBackupManager = new BackupManager(mContext);
}
protected void initIds() {
@@ -621,13 +601,6 @@
* Overriden in tests.
*/
protected void onEmptyDbCreated() {
- // Database was just created, so wipe any previous widgets
- if (mWidgetHostResetHandler != null) {
- newLauncherWidgetHost().deleteHost();
- mWidgetHostResetHandler.sendEmptyMessage(
- ChangeListenerWrapper.MSG_APP_WIDGET_HOST_RESET);
- }
-
// Set the flag for empty DB
Utilities.getPrefs(mContext).edit().putBoolean(EMPTY_DATABASE_CREATED, true).commit();
}
@@ -1027,23 +1000,4 @@
}
}
}
-
- private static class ChangeListenerWrapper implements Handler.Callback {
-
- private static final int MSG_APP_WIDGET_HOST_RESET = 2;
-
- private LauncherProviderChangeListener mListener;
-
- @Override
- public boolean handleMessage(Message msg) {
- if (mListener != null) {
- switch (msg.what) {
- case MSG_APP_WIDGET_HOST_RESET:
- mListener.onAppWidgetHostReset();
- break;
- }
- }
- return true;
- }
- }
}
diff --git a/src/com/android/launcher3/LauncherProviderChangeListener.java b/src/com/android/launcher3/LauncherProviderChangeListener.java
deleted file mode 100644
index 6afe885..0000000
--- a/src/com/android/launcher3/LauncherProviderChangeListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.android.launcher3;
-
-/**
- * This class is a listener for {@link LauncherProvider} changes. It gets notified in the
- * sendNotify method. This listener is needed because by default the Launcher suppresses
- * standard data change callbacks.
- */
-public interface LauncherProviderChangeListener {
-
- void onAppWidgetHostReset();
-}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 5c790f3..ff2b400 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1088,7 +1088,9 @@
if (mFreeScroll) {
setCurrentPage(getNextPage());
} else if (wasFreeScroll) {
- snapToPage(getNextPage());
+ if (getScrollForPage(getNextPage()) != getScrollX()) {
+ snapToPage(getNextPage());
+ }
}
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index d87ff3e..92f8069 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -584,7 +584,7 @@
LauncherIcons li = LauncherIcons.obtain(appState.getContext());
Bitmap badge = li.getShortcutInfoBadge(si, appState.getIconCache()).iconBitmap;
li.recycle();
- float badgeSize = launcher.getResources().getDimension(R.dimen.profile_badge_size);
+ float badgeSize = iconSize * LauncherIcons.getBadgeSizeForIconSize(iconSize);
float insetFraction = (iconSize - badgeSize) / iconSize;
return new InsetDrawable(new FastBitmapDrawable(badge),
insetFraction, insetFraction, 0, 0);
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 76262da..c5e74ef 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -467,7 +467,7 @@
private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
int maxWidth, int maxHeight, Bitmap preview) {
- int iconSize = launcher.getDeviceProfile().iconSizePx;
+ int iconSize = launcher.getDeviceProfile().allAppsIconSizePx;
int padding = launcher.getResources()
.getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index 288749f..837301f 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -80,26 +80,25 @@
* Returns a drawable that can be used as a badge for the user or null.
*/
@UiThread
- public Drawable getBadgeForUser(UserHandle user, Context context) {
+ public Drawable getBadgeForUser(UserHandle user, Context context, int badgeSize) {
if (mMyUser.equals(user)) {
return null;
}
- Bitmap badgeBitmap = getUserBadge(user, context);
+ Bitmap badgeBitmap = getUserBadge(user, context, badgeSize);
FastBitmapDrawable d = new FastBitmapDrawable(badgeBitmap);
d.setFilterBitmap(true);
d.setBounds(0, 0, badgeBitmap.getWidth(), badgeBitmap.getHeight());
return d;
}
- protected synchronized Bitmap getUserBadge(UserHandle user, Context context) {
+ protected synchronized Bitmap getUserBadge(UserHandle user, Context context, int badgeSize) {
Bitmap badgeBitmap = mUserBadges.get(user);
if (badgeBitmap != null) {
return badgeBitmap;
}
final Resources res = context.getApplicationContext().getResources();
- int badgeSize = res.getDimensionPixelSize(R.dimen.profile_badge_size);
badgeBitmap = Bitmap.createBitmap(badgeSize, badgeSize, Bitmap.Config.ARGB_8888);
Drawable drawable = context.getPackageManager().getUserBadgedDrawableForDensity(
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 619293b..fa9cc3a 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -24,19 +24,21 @@
import android.graphics.Color;
import android.os.Bundle;
import android.os.Debug;
+import android.view.View;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.util.ResourceBasedOverride;
import java.util.LinkedList;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
public class TestInformationHandler implements ResourceBasedOverride {
@@ -137,6 +139,7 @@
}
case TestProtocol.REQUEST_TOTAL_PSS_KB: {
+ runGcAndFinalizersSync();
Debug.MemoryInfo mem = new Debug.MemoryInfo();
Debug.getMemoryInfo(mem);
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, mem.getTotalPss());
@@ -165,12 +168,44 @@
mLeaks.add(bitmap);
break;
}
+
+ case TestProtocol.REQUEST_VIEW_LEAK: {
+ if (mLeaks == null) mLeaks = new LinkedList();
+
+ mLeaks.add(new View(mContext));
+ break;
+ }
}
return response;
}
protected boolean isLauncherInitialized() {
- final LauncherModel model = LauncherAppState.getInstance(mContext).getModel();
- return model.getCallback() == null || model.isModelLoaded();
+ return Launcher.ACTIVITY_TRACKER.getCreatedActivity() == null
+ || LauncherAppState.getInstance(mContext).getModel().isModelLoaded();
+ }
+
+ private static void runGcAndFinalizersSync() {
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+
+ final CountDownLatch fence = new CountDownLatch(1);
+ new Object() {
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ fence.countDown();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+ try {
+ do {
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ } while (!fence.await(100, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
}
}
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index ac080c2..add4565 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -74,6 +74,7 @@
public static final String REQUEST_TOTAL_PSS_KB = "total_pss";
public static final String REQUEST_JAVA_LEAK = "java-leak";
public static final String REQUEST_NATIVE_LEAK = "native-leak";
+ public static final String REQUEST_VIEW_LEAK = "view-leak";
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index dc4af8c..6944879 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -37,6 +37,7 @@
import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.graphics.DrawableFactory;
+import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.model.WidgetItem;
/**
@@ -80,6 +81,7 @@
private Bitmap mDeferredBitmap;
protected final BaseActivity mActivity;
+ protected DeviceProfile mDeviceProfile;
public WidgetCell(Context context) {
this(context, null);
@@ -93,6 +95,7 @@
super(context, attrs, defStyle);
mActivity = BaseActivity.fromContext(context);
+ mDeviceProfile = mActivity.getDeviceProfile();
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
setContainerWidth();
@@ -102,8 +105,7 @@
}
private void setContainerWidth() {
- DeviceProfile profile = mActivity.getDeviceProfile();
- mCellSize = (int) (profile.cellWidthPx * WIDTH_SCALE);
+ mCellSize = (int) (mDeviceProfile.allAppsCellWidthPx * WIDTH_SCALE);
mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE);
}
@@ -180,8 +182,10 @@
return;
}
if (bitmap != null) {
- mWidgetImage.setBitmap(bitmap, DrawableFactory.INSTANCE.get(getContext())
- .getBadgeForUser(mItem.user, getContext()));
+ mWidgetImage.setBitmap(bitmap,
+ DrawableFactory.INSTANCE.get(getContext()).getBadgeForUser(mItem.user,
+ getContext(), BaseIconFactory.getBadgeSizeForIconSize(
+ mDeviceProfile.allAppsIconSizePx)));
if (mAnimatePreview) {
mWidgetImage.setAlpha(0f);
ViewPropertyAnimator anim = mWidgetImage.animate();
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index 467ae02..6d9ed88 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -96,7 +96,8 @@
public static void resetPendingActivityResults(Launcher launcher, int requestCode) { }
- public static void clearSwipeSharedState(boolean finishAnimation) {}
+ /** No-op. */
+ public static void clearSwipeSharedState(Launcher launcher, boolean finishAnimation) { }
public static Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 0b74dc4..56eca6d 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -62,6 +62,12 @@
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
+ <activity android:name="com.android.launcher3.testcomponent.CustomShortcutConfigActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.CREATE_SHORTCUT" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
<activity
android:name="com.android.launcher3.testcomponent.RequestPinItemActivity"
android:icon="@drawable/test_drawable_pin_item"
diff --git a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
index 6fa8d62..27990f4 100644
--- a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
+++ b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
@@ -1,8 +1,11 @@
package com.android.launcher3.provider;
+import static org.junit.Assert.assertEquals;
+
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
+
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
@@ -13,8 +16,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.assertEquals;
-
/**
* Tests for {@link RestoreDbTask}
*/
@@ -82,7 +83,7 @@
private final long mProfileId;
MyDatabaseHelper(long profileId) {
- super(InstrumentationRegistry.getContext(), null, null);
+ super(InstrumentationRegistry.getContext(), null);
mProfileId = profileId;
}
diff --git a/tests/src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java b/tests/src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java
new file mode 100644
index 0000000..b673faa
--- /dev/null
+++ b/tests/src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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.testcomponent;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+
+import com.android.launcher3.R;
+
+import java.util.UUID;
+
+/**
+ * A custom shortcut is a 1x1 widget that launches a specific intent when user tap on it.
+ * Custom shortcuts are replaced by deep shortcuts after api 25.
+ */
+public class CustomShortcutConfigActivity extends BaseTestingActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent launchIntent = new Intent(this, BaseTestingActivity.class)
+ .setAction("com.android.launcher3.intent.action.test_shortcut");
+ Intent shortcutIntent = createShortcutResultIntent(
+ this, UUID.randomUUID().toString(), "Shortcut",
+ R.drawable.ic_widget, launchIntent);
+ setResult(RESULT_OK, shortcutIntent);
+ finish();
+ }
+
+ private static Intent createShortcutResultIntent(
+ Context context, String uniqueId, String name, int iconId, Intent launchIntent) {
+ ShortcutInfo shortcutInfo =
+ createShortcutInfo(context, uniqueId, name, iconId, launchIntent);
+ ShortcutManager sm = context.getSystemService(ShortcutManager.class);
+ return sm.createShortcutResultIntent(shortcutInfo);
+ }
+
+ private static ShortcutInfo createShortcutInfo(
+ Context context, String uniqueId, String name, int iconId, Intent launchIntent) {
+ return new ShortcutInfo.Builder(context, uniqueId)
+ .setShortLabel(name)
+ .setLongLabel(name)
+ .setIcon(Icon.createWithResource(context, iconId))
+ .setIntent(launchIntent)
+ .build();
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 17763d0..62989a3 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -49,7 +49,6 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
@@ -183,7 +182,7 @@
public void verifyLauncherState() {
try {
// Limits UI tests affecting tests running after them.
- waitForModelLoaded();
+ mLauncher.waitForLauncherInitialized();
} catch (Throwable t) {
Log.e(TAG,
"Couldn't deinit after a test, exiting tests, see logs for failures that "
@@ -222,14 +221,7 @@
} catch (Throwable t) {
throw new IllegalArgumentException(t);
}
- waitForModelLoaded();
- }
-
- protected void waitForModelLoaded() {
- waitForLauncherCondition("Launcher model didn't load", launcher -> {
- final LauncherModel model = LauncherAppState.getInstance(mTargetContext).getModel();
- return model.getCallback() == null || model.isModelLoaded();
- });
+ mLauncher.waitForLauncherInitialized();
}
/**
@@ -258,7 +250,7 @@
// Launch the home activity
mDevice.pressHome();
- waitForModelLoaded();
+ mLauncher.waitForLauncherInitialized();
}
/**
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 2cf6c2b..709822b 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -342,6 +342,22 @@
}
}
+ /**
+ * Test dragging a custom shortcut to the workspace and launch it.
+ *
+ * A custom shortcut is a 1x1 widget that launches a specific intent when user tap on it.
+ * Custom shortcuts are replaced by deep shortcuts after api 25.
+ */
+ @Test
+ @PortraitLandscape
+ public void testDragCustomShortcut() {
+ mLauncher.getWorkspace().openAllWidgets()
+ .getWidget("com.android.launcher3.testcomponent.CustomShortcutConfigActivity")
+ .dragToWorkspace();
+ mLauncher.getWorkspace().getWorkspaceAppIcon("Shortcut")
+ .launch(getAppPackageName());
+ }
+
public static String getAppPackageName() {
return getInstrumentation().getContext().getPackageName();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index a03f8ab..41a5b49 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -495,7 +495,7 @@
}
}
- private void waitForLauncherInitialized() {
+ public void waitForLauncherInitialized() {
for (int i = 0; i < 100; ++i) {
if (getTestInfo(
TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED).
@@ -534,6 +534,9 @@
// accessibility events prior to pressing Home.
final String action;
if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
+ final String anomaly = getAnomalyMessage();
+ if (anomaly != null) fail("Can't swipe up to Home: " + anomaly);
+
final Point displaySize = getRealDisplaySize();
if (hasLauncherObject("deep_shortcuts_container")) {
@@ -541,13 +544,17 @@
displaySize.x / 2, displaySize.y - 1,
displaySize.x / 2, 0,
ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME);
- assertTrue("Context menu is still visible after swiping up to home",
- !hasLauncherObject("deep_shortcuts_container"));
+ try (LauncherInstrumentation.Closable c = addContextLayer(
+ "Swiped up from context menu to home")) {
+ waitUntilGone("deep_shortcuts_container");
+ }
}
if (hasLauncherObject(WORKSPACE_RES_ID)) {
log(action = "already at home");
} else {
- log(action = "swiping up to home");
+ log("Hierarchy before swiping up to home");
+ dumpViewHierarchy();
+ log(action = "swiping up to home from " + getVisibleStateMessage());
final int finalState = mDevice.hasObject(By.pkg(getLauncherPackageName()))
? NORMAL_STATE_ORDINAL : BACKGROUND_APP_STATE_ORDINAL;
@@ -994,4 +1001,8 @@
public void produceNativeLeak() {
getTestInfo(TestProtocol.REQUEST_NATIVE_LEAK);
}
+
+ public void produceViewLeak() {
+ getTestInfo(TestProtocol.REQUEST_VIEW_LEAK);
+ }
}
\ No newline at end of file