Merge "Disable flakey fallback recents test" into tm-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 435eae4..6a2f622 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -469,13 +469,19 @@
}
});
mReturnAnimator.addListener(new AnimatorListenerAdapter() {
+ private boolean mCanceled = false;
+
@Override
public void onAnimationCancel(Animator animation) {
cleanUpSurface();
+ mCanceled = true;
}
@Override
public void onAnimationEnd(Animator animation) {
+ if (mCanceled) {
+ return;
+ }
cleanUpSurface();
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index 75cf5cb..bd7e5de 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -22,7 +22,7 @@
import static com.android.launcher3.LauncherState.HINT_STATE_TWO_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator;
+import static com.android.launcher3.WorkspaceStateTransitionAnimation.getWorkspaceSpringScaleAnimator;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
@@ -172,7 +172,8 @@
} else if (fromState == HINT_STATE && toState == NORMAL) {
config.setInterpolator(ANIM_DEPTH, DEACCEL_3);
if (mHintToNormalDuration == -1) {
- ValueAnimator va = getSpringScaleAnimator(mActivity, mActivity.getWorkspace(),
+ ValueAnimator va = getWorkspaceSpringScaleAnimator(mActivity,
+ mActivity.getWorkspace(),
toState.getWorkspaceScaleAndTranslation(mActivity).scale);
mHintToNormalDuration = (int) va.getDuration();
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 4d79202..f48a262 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -32,7 +32,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
@@ -453,8 +453,8 @@
/**
* @return whether the global actions dialog is showing
*/
- public boolean isGlobalActionsShowing() {
- return (mSystemUiStateFlags & SYSUI_STATE_GLOBAL_ACTIONS_SHOWING) != 0;
+ public boolean isSystemUiDialogShowing() {
+ return (mSystemUiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0;
}
/**
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 0c34ead..9627147 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -701,7 +701,7 @@
// If Bubbles is expanded, use the overlay input consumer, which will close Bubbles
// instead of going all the way home when a swipe up is detected.
- if (mDeviceState.isBubblesExpanded() || mDeviceState.isGlobalActionsShowing()) {
+ if (mDeviceState.isBubblesExpanded() || mDeviceState.isSystemUiDialogShowing()) {
base = new SysUiOverlayInputConsumer(
getBaseContext(), mDeviceState, mInputMonitorCompat);
}
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index 333df10..3b58046 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -15,14 +15,14 @@
*/
package com.android.quickstep.util;
+import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_UNFOLD_ANIMATION;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY_FACTORY;
+import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.Utilities.comp;
import android.annotation.Nullable;
import android.util.FloatProperty;
import android.util.MathUtils;
-import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -30,6 +30,7 @@
import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
+import com.android.launcher3.Workspace;
import com.android.launcher3.util.HorizontalInsettableView;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
@@ -44,8 +45,10 @@
// Percentage of the width of the quick search bar that will be reduced
// from the both sides of the bar when progress is 0
private static final float MAX_WIDTH_INSET_FRACTION = 0.15f;
- private static final FloatProperty<View> UNFOLD_SCALE_PROPERTY =
- SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
+ private static final FloatProperty<Workspace> WORKSPACE_SCALE_PROPERTY =
+ WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
+ private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
+ HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
private final Launcher mLauncher;
@@ -147,8 +150,8 @@
}
private void setScale(float value) {
- UNFOLD_SCALE_PROPERTY.setValue(mLauncher.getWorkspace(), value);
- UNFOLD_SCALE_PROPERTY.setValue(mLauncher.getHotseat(), value);
+ WORKSPACE_SCALE_PROPERTY.setValue(mLauncher.getWorkspace(), value);
+ HOTSEAT_SCALE_PROPERTY.setValue(mLauncher.getHotseat(), value);
}
}
}
diff --git a/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java b/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
index 8659b68..5326d2b 100644
--- a/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
+++ b/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
@@ -15,8 +15,9 @@
*/
package com.android.quickstep.util;
+import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_REVEAL_ANIM;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY_FACTORY;
+import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
@@ -32,6 +33,7 @@
import android.view.View;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
@@ -51,8 +53,11 @@
// Should be used for animations running alongside this WorkspaceRevealAnim.
public static final int DURATION_MS = 350;
- private static final FloatProperty<View> REVEAL_SCALE_PROPERTY =
- SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_REVEAL_ANIM);
+ private static final FloatProperty<Workspace> WORKSPACE_SCALE_PROPERTY =
+ WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_REVEAL_ANIM);
+
+ private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
+ HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_REVEAL_ANIM);
private final float mScaleStart;
private final AnimatorSet mAnimators = new AnimatorSet();
@@ -67,8 +72,8 @@
workspace.setPivotToScaleWithSelf(launcher.getHotseat());
// Add reveal animations.
- addRevealAnimatorsForView(workspace);
- addRevealAnimatorsForView(launcher.getHotseat());
+ addRevealAnimatorsForView(workspace, WORKSPACE_SCALE_PROPERTY);
+ addRevealAnimatorsForView(launcher.getHotseat(), HOTSEAT_SCALE_PROPERTY);
// Add overview scrim animation.
if (animateOverviewScrim) {
@@ -93,8 +98,8 @@
mAnimators.setInterpolator(Interpolators.DECELERATED_EASE);
}
- private void addRevealAnimatorsForView(View v) {
- ObjectAnimator scale = ObjectAnimator.ofFloat(v, REVEAL_SCALE_PROPERTY, mScaleStart, 1f);
+ private <T extends View> void addRevealAnimatorsForView(T v, FloatProperty<T> scaleProperty) {
+ ObjectAnimator scale = ObjectAnimator.ofFloat(v, scaleProperty, mScaleStart, 1f);
scale.setDuration(DURATION_MS);
scale.setInterpolator(Interpolators.DECELERATED_EASE);
mAnimators.play(scale);
@@ -107,7 +112,7 @@
mAnimators.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- REVEAL_SCALE_PROPERTY.set(v, 1f);
+ scaleProperty.set(v, 1f);
v.setAlpha(1f);
}
});
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 307c51f..f2f1c3f 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -48,8 +48,6 @@
private SplitPlaceholderView mSplitPlaceholderView;
private RectF mStartingPosition;
- @Nullable
- private Consumer<RectF> mAdditionalOffsetter;
private final StatefulActivity mActivity;
private final boolean mIsRtl;
private final Rect mOutline = new Rect();
@@ -81,9 +79,8 @@
}
private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
- Drawable icon, RectF positionOut, Consumer<RectF> additionalOffsetter) {
+ Drawable icon, RectF positionOut) {
mStartingPosition = positionOut;
- mAdditionalOffsetter = additionalOffsetter;
updateInitialPositionForView(originalView);
final InsettableFrameLayout.LayoutParams lp =
(InsettableFrameLayout.LayoutParams) getLayoutParams();
@@ -113,15 +110,13 @@
* translation values from originalView will be used
*/
public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
- View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut,
- @Nullable Consumer<RectF> additionalOffsetter) {
+ View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
final BaseDragLayer dragLayer = launcher.getDragLayer();
ViewGroup parent = (ViewGroup) dragLayer.getParent();
final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
.inflate(R.layout.floating_split_select_view, parent, false);
- floatingView.init(launcher, originalView, thumbnail, icon, positionOut,
- additionalOffsetter);
+ floatingView.init(launcher, originalView, thumbnail, icon, positionOut);
parent.addView(floatingView);
return floatingView;
}
@@ -129,14 +124,8 @@
public void updateInitialPositionForView(View originalView) {
Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView, viewBounds,
- true /* ignoreTransform */, null /* recycle */,
+ false /* ignoreTransform */, null /* recycle */,
mStartingPosition);
- if (mAdditionalOffsetter != null) {
- mAdditionalOffsetter.accept(mStartingPosition);
- } else {
- mStartingPosition.offset(originalView.getTranslationX(),
- originalView.getTranslationY());
- }
final InsettableFrameLayout.LayoutParams lp = new InsettableFrameLayout.LayoutParams(
Math.round(mStartingPosition.width()),
Math.round(mStartingPosition.height()));
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index af9f818..04af3c1 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -5,14 +5,17 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import android.content.Context;
+import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.launcher3.util.TransformingTouchDelegate;
@@ -52,7 +55,6 @@
@Nullable private StagedSplitBounds mSplitBoundsConfig;
private final DigitalWellBeingToast mDigitalWellBeingToast2;
-
public GroupedTaskView(Context context) {
this(context, null);
}
@@ -205,6 +207,20 @@
}
@Override
+ protected int getChildTaskIndexAtPosition(PointF position) {
+ if (isCoordInView(mIconView2, position) || isCoordInView(mSnapshotView2, position)) {
+ return 1;
+ }
+ return super.getChildTaskIndexAtPosition(position);
+ }
+
+ private boolean isCoordInView(View v, PointF position) {
+ float[] localPos = new float[]{position.x, position.y};
+ Utilities.mapCoordInSelfToDescendant(v, this, localPos);
+ return Utilities.pointInView(v, localPos[0], localPos[1], 0f /* slop */);
+ }
+
+ @Override
public void onRecycle() {
super.onRecycle();
mSnapshotView2.setThumbnail(mSecondaryTask, null);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a042bff..cb7e08a 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -619,7 +619,7 @@
@Nullable
private TaskView mSplitHiddenTaskView;
@Nullable
- private TaskView mSecondSplitHiddenTaskView;
+ private View mSecondSplitHiddenView;
@Nullable
private StagedSplitBounds mSplitBoundsConfig;
private final Toast mSplitToast = Toast.makeText(getContext(),
@@ -2729,11 +2729,7 @@
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
mSplitHiddenTaskView.getThumbnail(),
mSplitHiddenTaskView.getThumbnail().getThumbnail(),
- mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect,
- floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
- mSplitHiddenTaskView.getTranslationX(),
- mSplitHiddenTaskView.getTranslationY()
- ));
+ mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
mTempRect, true /*fadeWithThumbnail*/);
@@ -2741,7 +2737,7 @@
mSplitSelectSource.view.setVisibility(INVISIBLE);
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
mSplitSelectSource.view, null,
- mSplitSelectSource.drawable, startingTaskRect, null /*additionalOffsetter*/);
+ mSplitSelectSource.drawable, startingTaskRect);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
mTempRect, true /*fadeWithThumbnail*/);
@@ -4004,9 +4000,14 @@
}
}
- public void confirmSplitSelect(TaskView taskView) {
+ /**
+ * Confirms the selection of the next split task. The extra data is passed through because the
+ * user may be selecting a subtask in a group.
+ */
+ public void confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
+ TaskThumbnailView thumbnailView) {
mSplitToast.cancel();
- if (!taskView.getTask().isDockable) {
+ if (!task.isDockable) {
// Task not split screen supported
mSplitUnsupportedToast.show();
return;
@@ -4032,20 +4033,21 @@
false /*fadeWithThumbnail*/);
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
- taskView.getThumbnail(), taskView.getThumbnail().getThumbnail(),
- taskView.getIconView().getDrawable(), secondTaskStartingBounds,
- floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
- taskView.getTranslationX(),
- taskView.getTranslationY()
- ));
+ thumbnailView, thumbnailView.getThumbnail(),
+ iconView.getDrawable(), secondTaskStartingBounds);
mSecondFloatingTaskView.setAlpha(1);
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
- secondTaskEndingBounds, true /*fadeWithThumbnail*/);
+ secondTaskEndingBounds, true /* fadeWithThumbnail */);
pendingAnimation.addEndListener(aBoolean ->
- mSplitSelectStateController.setSecondTaskId(taskView.getTask().key.id,
+ mSplitSelectStateController.setSecondTaskId(task.key.id,
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
- mSecondSplitHiddenTaskView = taskView;
- taskView.setVisibility(INVISIBLE);
+ if (containerTaskView.containsMultipleTasks()) {
+ // If we are launching from a child task, then only hide the thumbnail itself
+ mSecondSplitHiddenView = thumbnailView;
+ } else {
+ mSecondSplitHiddenView = containerTaskView;
+ }
+ mSecondSplitHiddenView.setVisibility(INVISIBLE);
pendingAnimation.buildAnim().start();
}
@@ -4059,8 +4061,8 @@
if (mSecondFloatingTaskView != null) {
mActivity.getRootView().removeView(mSecondFloatingTaskView);
mSecondFloatingTaskView = null;
- mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
- mSecondSplitHiddenTaskView = null;
+ mSecondSplitHiddenView.setVisibility(VISIBLE);
+ mSecondSplitHiddenView = null;
}
mSplitSelectSource = null;
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 488789b..f716965 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -45,6 +45,7 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Outline;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -426,8 +427,11 @@
private final float[] mIconCenterCoords = new float[2];
+ private final PointF mLastTouchDownPosition = new PointF();
+
private boolean mIsClickableAsLiveTile = true;
+
public TaskView(Context context) {
this(context, null);
}
@@ -600,6 +604,14 @@
return mIconView;
}
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mLastTouchDownPosition.set(ev.getX(), ev.getY());
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
private void onClick(View view) {
if (getTask() == null) {
return;
@@ -688,12 +700,22 @@
private boolean confirmSecondSplitSelectApp() {
boolean isSelectingSecondSplitApp = getRecentsView().isSplitSelectionActive();
if (isSelectingSecondSplitApp) {
- getRecentsView().confirmSplitSelect(this);
+ int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
+ TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
+ getRecentsView().confirmSplitSelect(this, container.getTask(), container.getIconView(),
+ container.getThumbnailView());
}
return isSelectingSecondSplitApp;
}
/**
+ * Returns the task under the given position in the local coordinates of this task view.
+ */
+ protected int getChildTaskIndexAtPosition(PointF position) {
+ return 0;
+ }
+
+ /**
* Starts the task associated with this view and animates the startup.
* @return CompletionStage to indicate the animation completion or null if the launch failed.
*/
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 4300392..c43172c 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -67,18 +67,16 @@
};
/**
- * Property to set the scale of workspace and hotseat. The value is based on a combination
+ * Property to set the scale of workspace. The value is based on a combination
* of all the ones set, to have a smooth experience even in the case of overlapping scaling
* animation.
*/
- public static final MultiScalePropertyFactory<View> SCALE_PROPERTY_FACTORY =
- new MultiScalePropertyFactory<View>("scale_property") {
- @Override
- protected void apply(View view, float scale) {
- view.setScaleX(scale);
- view.setScaleY(scale);
- }
- };
+ public static final MultiScalePropertyFactory<Workspace> WORKSPACE_SCALE_PROPERTY_FACTORY =
+ new MultiScalePropertyFactory<Workspace>("workspace_scale_property");
+
+ /** Property to set the scale of hotseat. */
+ public static final MultiScalePropertyFactory<Hotseat> HOTSEAT_SCALE_PROPERTY_FACTORY =
+ new MultiScalePropertyFactory<Hotseat>("hotseat_scale_property");
public static final int SCALE_INDEX_UNFOLD_ANIMATION = 1;
public static final int SCALE_INDEX_UNLOCK_ANIMATION = 2;
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 98e785f..d94e84c 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -18,11 +18,12 @@
import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE;
+import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherState.FLAG_HAS_SYS_UI_SCRIM;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
@@ -64,8 +65,11 @@
*/
public class WorkspaceStateTransitionAnimation {
- private static final FloatProperty<View> WORKSPACE_STATE_SCALE_PROPERTY =
- SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE);
+ private static final FloatProperty<Workspace> WORKSPACE_SCALE_PROPERTY =
+ WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE);
+
+ private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
+ HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE);
private final Launcher mLauncher;
private final Workspace mWorkspace;
@@ -120,9 +124,9 @@
&& fromState == HINT_STATE && state == NORMAL;
if (shouldSpring) {
((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher,
- mWorkspace, mNewScale));
+ mWorkspace, mNewScale, WORKSPACE_SCALE_PROPERTY));
} else {
- propertySetter.setFloat(mWorkspace, WORKSPACE_STATE_SCALE_PROPERTY, mNewScale,
+ propertySetter.setFloat(mWorkspace, WORKSPACE_SCALE_PROPERTY, mNewScale,
scaleInterpolator);
}
@@ -130,11 +134,12 @@
float hotseatScale = hotseatScaleAndTranslation.scale;
if (shouldSpring) {
PendingAnimation pa = (PendingAnimation) propertySetter;
- pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale));
+ pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale,
+ HOTSEAT_SCALE_PROPERTY));
} else {
Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE,
scaleInterpolator);
- propertySetter.setFloat(hotseat, WORKSPACE_STATE_SCALE_PROPERTY, hotseatScale,
+ propertySetter.setFloat(hotseat, HOTSEAT_SCALE_PROPERTY, hotseatScale,
hotseatScaleInterpolator);
}
@@ -198,9 +203,18 @@
}
/**
+ * Returns a spring based animator for the scale property of {@param workspace}.
+ */
+ public static ValueAnimator getWorkspaceSpringScaleAnimator(Launcher launcher,
+ Workspace workspace, float scale) {
+ return getSpringScaleAnimator(launcher, workspace, scale, WORKSPACE_SCALE_PROPERTY);
+ }
+
+ /**
* Returns a spring based animator for the scale property of {@param v}.
*/
- public static ValueAnimator getSpringScaleAnimator(Launcher launcher, View v, float scale) {
+ public static <T extends View> ValueAnimator getSpringScaleAnimator(Launcher launcher, T v,
+ float scale, FloatProperty<T> property) {
ResourceProvider rp = DynamicResource.provider(launcher);
float damping = rp.getFloat(R.dimen.hint_scale_damping_ratio);
float stiffness = rp.getFloat(R.dimen.hint_scale_stiffness);
@@ -211,9 +225,9 @@
.setDampingRatio(damping)
.setMinimumVisibleChange(MIN_VISIBLE_CHANGE_SCALE)
.setEndValue(scale)
- .setStartValue(WORKSPACE_STATE_SCALE_PROPERTY.get(v))
+ .setStartValue(property.get(v))
.setStartVelocity(velocityPxPerS)
- .build(v, WORKSPACE_STATE_SCALE_PROPERTY);
+ .build(v, property);
}
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index 2f3d5d8..fd11b37 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -47,7 +47,6 @@
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.GridSizeMigrationTaskV2;
import com.android.launcher3.model.LoaderTask;
-import com.android.launcher3.model.ModelDelegate;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
@@ -156,9 +155,10 @@
PreviewContext previewContext = new PreviewContext(inflationContext, mIdp);
new LoaderTask(
LauncherAppState.getInstance(previewContext),
- null,
+ /* bgAllAppsList= */ null,
new BgDataModel(),
- new ModelDelegate(), null) {
+ LauncherAppState.getInstance(previewContext).getModel().getModelDelegate(),
+ /* results= */ null) {
@Override
public void run() {
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 3129e2a..308a8f2 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -41,9 +41,9 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import androidx.annotation.NonNull;
+import androidx.core.util.Pair;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles;
@@ -339,6 +339,16 @@
List<IconRequestInfo<T>> iconRequestInfos) {
Map<Pair<UserHandle, Boolean>, List<IconRequestInfo<T>>> iconLoadSubsectionsMap =
iconRequestInfos.stream()
+ .filter(iconRequest -> {
+ if (iconRequest.itemInfo.getTargetComponent() != null) {
+ return true;
+ }
+ Log.i(TAG,
+ "Skipping Item info with null component name: "
+ + iconRequest.itemInfo);
+ iconRequest.itemInfo.bitmap = getDefaultIcon(iconRequest.itemInfo.user);
+ return false;
+ })
.collect(groupingBy(iconRequest ->
Pair.create(iconRequest.itemInfo.user, iconRequest.useLowResIcon)));
diff --git a/src/com/android/launcher3/model/ModelDelegate.java b/src/com/android/launcher3/model/ModelDelegate.java
index 60ca63b..cc42258 100644
--- a/src/com/android/launcher3/model/ModelDelegate.java
+++ b/src/com/android/launcher3/model/ModelDelegate.java
@@ -44,11 +44,7 @@
boolean isPrimaryInstance) {
ModelDelegate delegate = Overrides.getObject(
ModelDelegate.class, context, R.string.model_delegate_class);
- delegate.mApp = app;
- delegate.mAppsList = appsList;
- delegate.mDataModel = dataModel;
- delegate.mIsPrimaryInstance = isPrimaryInstance;
- delegate.mContext = context;
+ delegate.init(context, app, appsList, dataModel, isPrimaryInstance);
return delegate;
}
@@ -61,6 +57,18 @@
public ModelDelegate() { }
/**
+ * Initializes the object with the given params.
+ */
+ private void init(Context context, LauncherAppState app, AllAppsList appsList,
+ BgDataModel dataModel, boolean isPrimaryInstance) {
+ this.mApp = app;
+ this.mAppsList = appsList;
+ this.mDataModel = dataModel;
+ this.mIsPrimaryInstance = isPrimaryInstance;
+ this.mContext = context;
+ }
+
+ /**
* Called periodically to validate and update any data
*/
@WorkerThread
diff --git a/src/com/android/launcher3/util/MultiScalePropertyFactory.java b/src/com/android/launcher3/util/MultiScalePropertyFactory.java
index f27d0f0..a7e6cc8 100644
--- a/src/com/android/launcher3/util/MultiScalePropertyFactory.java
+++ b/src/com/android/launcher3/util/MultiScalePropertyFactory.java
@@ -18,6 +18,8 @@
import android.util.ArrayMap;
import android.util.FloatProperty;
+import android.util.Log;
+import android.view.View;
import com.android.launcher3.Utilities;
@@ -33,8 +35,10 @@
*
* @param <T> Type where to apply the property.
*/
-public abstract class MultiScalePropertyFactory<T> {
+public class MultiScalePropertyFactory<T extends View> {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "MultiScaleProperty";
private final String mName;
private final ArrayMap<Integer, MultiScaleProperty> mProperties =
new ArrayMap<Integer, MultiScaleProperty>();
@@ -56,7 +60,6 @@
(k) -> new MultiScaleProperty(index, mName + "_" + index));
}
-
/**
* Each [setValue] will be aggregated with the other properties values created by the
* corresponding factory.
@@ -91,11 +94,22 @@
mLastAggregatedValue = Utilities.boundToRange(multValue, minValue, maxValue);
mValue = newValue;
apply(obj, mLastAggregatedValue);
+
+ if (DEBUG) {
+ Log.d(TAG, "name=" + mName
+ + " newValue=" + newValue + " mInx=" + mInx
+ + " aggregated=" + mLastAggregatedValue + " others= " + mProperties);
+ }
}
@Override
- public Float get(T t) {
- return mLastAggregatedValue;
+ public Float get(T view) {
+ // The scale of the view should match mLastAggregatedValue. Still, if it has been
+ // changed without using this property, it can differ. As this get method is usually
+ // used to set the starting point on an animation, this would result in some jumps
+ // when the view scale is different than the last aggregated value. To stay on the
+ // safe side, let's return the real view scale.
+ return view.getScaleX();
}
@Override
@@ -104,6 +118,8 @@
}
}
- /** Applies value to object after setValue method is called. */
- protected abstract void apply(T obj, float value);
+ protected void apply(View view, float value) {
+ view.setScaleX(value);
+ view.setScaleY(value);
+ }
}
diff --git a/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt b/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt
index c4a8db6..6099987 100644
--- a/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt
+++ b/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt
@@ -1,5 +1,6 @@
package com.android.launcher3.util
+import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
@@ -14,8 +15,8 @@
private val received = mutableListOf<Float>()
private val factory =
- object : MultiScalePropertyFactory<Int?>("Test") {
- override fun apply(obj: Int?, value: Float) {
+ object : MultiScalePropertyFactory<View?>("Test") {
+ override fun apply(obj: View?, value: Float) {
received.add(value)
}
}