Merge "Fix lock contention while swiping up" into ub-launcher3-edmonton
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 9416a29..ad4af62 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -203,7 +203,12 @@
}
private boolean shouldIgnoreSwipeUpEnabledSettings() {
- String sdkInt = getSystemProperty("ro.product.first_api_level", "0");
+ int deviceApiLevel = Build.VERSION.SDK_INT;
+
+ // Note: on factory ROM devices, this first_api_level property is intentionally not set.
+ // deviceApiLevel is used in these case.
+ String sdkInt = getSystemProperty("ro.product.first_api_level",
+ Integer.toString(deviceApiLevel));
try {
return Integer.parseInt(sdkInt) >= Build.VERSION_CODES.P;
} catch (Exception e) {
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 7676a70..9c2c8b3 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep;
+import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
@@ -190,7 +192,7 @@
@Override
public void onTaskStackChangedBackground() {
int userId = UserHandle.myUserId();
- if (!mPreloadTasksInBackground || !checkCurrentUserId(userId, false /* debug */)) {
+ if (!mPreloadTasksInBackground || !checkCurrentOrManagedUserId(userId, mContext)) {
// TODO: Only register this for the current user
return;
}
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index f9628d7..d7fad43 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -47,6 +47,8 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import java.util.List;
+
/**
* Contains helpful methods for retrieving data from {@link Task}s.
*/
@@ -207,4 +209,17 @@
}
return false;
}
+
+ public static boolean checkCurrentOrManagedUserId(int currentUserId, Context context) {
+ if (currentUserId == UserHandle.myUserId()) {
+ return true;
+ }
+ List<UserHandle> allUsers = UserManagerCompat.getInstance(context).getUserProfiles();
+ for (int i = allUsers.size() - 1; i >= 0; i--) {
+ if (currentUserId == allUsers.get(i).getIdentifier()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
index 34f580b..48b07a7 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
@@ -15,7 +15,9 @@
*/
package com.android.quickstep.util;
-import android.animation.TimeInterpolator;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
@@ -30,7 +32,7 @@
public class TaskViewDrawable extends Drawable {
- public static FloatProperty<TaskViewDrawable> PROGRESS =
+ public static final FloatProperty<TaskViewDrawable> PROGRESS =
new FloatProperty<TaskViewDrawable>("progress") {
@Override
public void setValue(TaskViewDrawable taskViewDrawable, float v) {
@@ -43,8 +45,10 @@
}
};
- private static final TimeInterpolator ICON_SIZE_INTERPOLATOR =
- (t) -> (Math.max(t, 0.3f) - 0.3f) / 0.7f;
+ /**
+ * The progress at which we play the atomic icon scale animation.
+ */
+ private static final float ICON_SCALE_THRESHOLD = 0.95f;
private final RecentsView mParent;
private final View mIconView;
@@ -55,11 +59,15 @@
private final ClipAnimationHelper mClipAnimationHelper;
private float mProgress = 1;
+ private boolean mPassedIconScaleThreshold;
+ private ValueAnimator mIconScaleAnimator;
+ private float mIconScale;
public TaskViewDrawable(TaskView tv, RecentsView parent) {
mParent = parent;
mIconView = tv.getIconView();
mIconPos = new int[2];
+ mIconScale = mIconView.getScaleX();
Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true);
mThumbnailView = tv.getThumbnail();
@@ -70,6 +78,37 @@
public void setProgress(float progress) {
mProgress = progress;
mParent.invalidate();
+ boolean passedIconScaleThreshold = progress <= ICON_SCALE_THRESHOLD;
+ if (mPassedIconScaleThreshold != passedIconScaleThreshold) {
+ mPassedIconScaleThreshold = passedIconScaleThreshold;
+ animateIconScale(mPassedIconScaleThreshold ? 0 : 1);
+ }
+ }
+
+ private void animateIconScale(float toScale) {
+ if (mIconScaleAnimator != null) {
+ mIconScaleAnimator.cancel();
+ }
+ mIconScaleAnimator = ValueAnimator.ofFloat(mIconScale, toScale);
+ mIconScaleAnimator.addUpdateListener(valueAnimator -> {
+ mIconScale = (float) valueAnimator.getAnimatedValue();
+ if (mProgress > ICON_SCALE_THRESHOLD) {
+ // Speed up the icon scale to ensure it is 1 when progress is 1.
+ float iconProgress = (mProgress - ICON_SCALE_THRESHOLD) / (1 - ICON_SCALE_THRESHOLD);
+ if (iconProgress > mIconScale) {
+ mIconScale = iconProgress;
+ }
+ }
+ invalidateSelf();
+ });
+ mIconScaleAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mIconScaleAnimator = null;
+ }
+ });
+ mIconScaleAnimator.setDuration(TaskView.SCALE_ICON_DURATION);
+ mIconScaleAnimator.start();
}
@Override
@@ -81,8 +120,7 @@
canvas.save();
canvas.translate(mIconPos[0], mIconPos[1]);
- float scale = ICON_SIZE_INTERPOLATOR.getInterpolation(mProgress);
- canvas.scale(scale, scale, mIconView.getWidth() / 2, mIconView.getHeight() / 2);
+ canvas.scale(mIconScale, mIconScale, mIconView.getWidth() / 2, mIconView.getHeight() / 2);
mIconView.draw(canvas);
canvas.restore();
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8c3e1a2..5035721 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -21,7 +21,9 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
@@ -122,13 +124,19 @@
private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
@Override
public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
updateThumbnail(taskId, snapshot);
}
@Override
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
// Check this is for the right user
- if (!checkCurrentUserId(userId, false /* debug */)) {
+ if (!checkCurrentOrManagedUserId(userId, getContext())) {
return;
}
@@ -141,20 +149,24 @@
@Override
public void onActivityUnpinned() {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
// TODO: Re-enable layout transitions for addition of the unpinned task
reloadIfNeeded();
}
@Override
public void onTaskRemoved(int taskId) {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
TaskView taskView = getTaskView(taskId);
if (taskView != null) {
dismissTask(taskView, true /* animate */, false /* removeTask */);
}
}
- };
- private TaskStackChangeListener mTaskStackClearFlagListener = new TaskStackChangeListener() {
@Override
public void onPinnedStackAnimationStarted() {
// Needed for activities that auto-enter PiP, which will not trigger a remote
@@ -173,7 +185,7 @@
private boolean mRunningTaskIconScaledDown = false;
private boolean mOverviewStateEnabled;
- private boolean mTaskStackListenerRegistered;
+ private boolean mHandleTaskStackChanges;
private Runnable mNextPageSwitchRunnable;
private boolean mSwipeDownShouldLaunchApp;
@@ -260,7 +272,7 @@
super.onAttachedToWindow();
updateTaskStackListenerState();
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
- ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackClearFlagListener);
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
}
@Override
@@ -268,8 +280,7 @@
super.onDetachedFromWindow();
updateTaskStackListenerState();
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
- ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
- mTaskStackClearFlagListener);
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
}
@Override
@@ -433,18 +444,13 @@
}
private void updateTaskStackListenerState() {
- boolean registerStackListener = mOverviewStateEnabled && isAttachedToWindow()
+ boolean handleTaskStackChanges = mOverviewStateEnabled && isAttachedToWindow()
&& getWindowVisibility() == VISIBLE;
- if (registerStackListener != mTaskStackListenerRegistered) {
- if (registerStackListener) {
- ActivityManagerWrapper.getInstance()
- .registerTaskStackListener(mTaskStackListener);
+ if (handleTaskStackChanges != mHandleTaskStackChanges) {
+ mHandleTaskStackChanges = handleTaskStackChanges;
+ if (handleTaskStackChanges) {
reloadIfNeeded();
- } else {
- ActivityManagerWrapper.getInstance()
- .unregisterTaskStackListener(mTaskStackListener);
}
- mTaskStackListenerRegistered = registerStackListener;
}
}
@@ -960,15 +966,13 @@
if (currTask == null) {
return;
}
- currTask.setScaleX(mAdjacentScale);
- currTask.setScaleY(mAdjacentScale);
+ currTask.setZoomScale(mAdjacentScale);
if (mCurrentPage - 1 >= 0) {
TaskView adjacentTask = getPageAt(mCurrentPage - 1);
float[] scaleAndTranslation = getAdjacentScaleAndTranslation(currTask, adjacentTask,
mAdjacentScale, 0);
- adjacentTask.setScaleX(scaleAndTranslation[0]);
- adjacentTask.setScaleY(scaleAndTranslation[0]);
+ adjacentTask.setZoomScale(scaleAndTranslation[0]);
adjacentTask.setTranslationX(-scaleAndTranslation[1]);
adjacentTask.setTranslationY(scaleAndTranslation[2]);
}
@@ -976,8 +980,7 @@
TaskView adjacentTask = getPageAt(mCurrentPage + 1);
float[] scaleAndTranslation = getAdjacentScaleAndTranslation(currTask, adjacentTask,
mAdjacentScale, 0);
- adjacentTask.setScaleX(scaleAndTranslation[0]);
- adjacentTask.setScaleY(scaleAndTranslation[0]);
+ adjacentTask.setZoomScale(scaleAndTranslation[0]);
adjacentTask.setTranslationX(scaleAndTranslation[1]);
adjacentTask.setTranslationY(scaleAndTranslation[2]);
}
@@ -986,7 +989,7 @@
private float[] getAdjacentScaleAndTranslation(TaskView currTask, TaskView adjacentTask,
float currTaskToScale, float currTaskToTranslationY) {
float displacement = currTask.getWidth() * (currTaskToScale - currTask.getCurveScale());
- sTempFloatArray[0] = currTaskToScale * adjacentTask.getCurveScale();
+ sTempFloatArray[0] = currTaskToScale;
sTempFloatArray[1] = mIsRtl ? -displacement : displacement;
sTempFloatArray[2] = currTaskToTranslationY;
return sTempFloatArray;
@@ -1127,13 +1130,15 @@
return anim;
}
- private ObjectAnimator createAnimForChild(View child, float[] toScaleAndTranslation) {
- return ObjectAnimator.ofPropertyValuesHolder(child,
+ private Animator createAnimForChild(TaskView child, float[] toScaleAndTranslation) {
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(ObjectAnimator.ofFloat(child, TaskView.ZOOM_SCALE, toScaleAndTranslation[0]));
+ anim.play(ObjectAnimator.ofPropertyValuesHolder(child,
new PropertyListBuilder()
- .scale(child.getScaleX() * toScaleAndTranslation[0])
.translationX(toScaleAndTranslation[1])
.translationY(toScaleAndTranslation[2])
- .build());
+ .build()));
+ return anim;
}
public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index b8b9196..4f447b1 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -30,14 +30,15 @@
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.util.Log;
+import android.util.Property;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
-import android.widget.ImageView;
-
import android.widget.Toast;
+
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
@@ -76,12 +77,26 @@
*/
private static final float EDGE_SCALE_DOWN_FACTOR = 0.03f;
- private static final long SCALE_ICON_DURATION = 120;
+ public static final long SCALE_ICON_DURATION = 120;
+
+ public static final Property<TaskView, Float> ZOOM_SCALE =
+ new FloatProperty<TaskView>("zoomScale") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setZoomScale(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mZoomScale;
+ }
+ };
private Task mTask;
private TaskThumbnailView mSnapshotView;
private IconView mIconView;
private float mCurveScale;
+ private float mZoomScale;
private float mCurveDimAlpha;
private Animator mDimAlphaAnim;
@@ -207,8 +222,7 @@
}
public void resetVisualProperties() {
- setScaleX(1f);
- setScaleY(1f);
+ setZoomScale(1);
setTranslationX(0f);
setTranslationY(0f);
setTranslationZ(0);
@@ -226,9 +240,7 @@
mSnapshotView.setDimAlpha(mCurveDimAlpha);
}
- mCurveScale = getCurveScaleForCurveInterpolation(curveInterpolation);
- setScaleX(mCurveScale);
- setScaleY(mCurveScale);
+ setCurveScale(getCurveScaleForCurveInterpolation(curveInterpolation));
}
@Override
@@ -247,10 +259,26 @@
return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
}
+ private void setCurveScale(float curveScale) {
+ mCurveScale = curveScale;
+ onScaleChanged();
+ }
+
public float getCurveScale() {
return mCurveScale;
}
+ public void setZoomScale(float adjacentScale) {
+ mZoomScale = adjacentScale;
+ onScaleChanged();
+ }
+
+ private void onScaleChanged() {
+ float scale = mCurveScale * mZoomScale;
+ setScaleX(scale);
+ setScaleY(scale);
+ }
+
@Override
public boolean hasOverlappingRendering() {
// TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
diff --git a/res/animator-v23/discovery_bounce.xml b/res/animator-v23/discovery_bounce.xml
index 8d0e8fd..f554853 100644
--- a/res/animator-v23/discovery_bounce.xml
+++ b/res/animator-v23/discovery_bounce.xml
@@ -26,14 +26,14 @@
android:fraction="0"
android:value="1f" />
<keyframe
- android:fraction="0.346"
+ android:fraction="0.246"
android:value="1f" />
<keyframe
android:fraction=".423"
android:interpolator="@interpolator/disco_bounce"
- android:value="0.9438f" />
+ android:value="0.9738f" />
<keyframe
- android:fraction="0.654"
+ android:fraction="0.754"
android:interpolator="@interpolator/disco_bounce"
android:value="1f" />
<keyframe
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5dc7844..65fffd3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -310,7 +310,7 @@
<!-- Accessibility action to show quick actions menu for an icon. [CHAR_LIMIT=30] -->
<string name="action_deep_shortcut">Shortcuts</string>
- <!-- Accessibility description when the shortcuts menu has notifications as well as shortcuts. [CHAR_LIMIT=50] -->
+ <!-- Accessibility description when the context menu of a launcher icon that has notifications as well as shortcuts (providing quick access to app's actions). The "shortcuts" translation should be consistent with the one for action_deep_shortcut. [CHAR_LIMIT=50] -->
<string name="shortcuts_menu_with_notifications_description">Shortcuts and notifications
</string>
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index d04401e..cf0c7fc 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -387,6 +387,7 @@
}
public void setCurrentUserControlledAnimation(AnimatorPlaybackController controller) {
+ clearCurrentAnimation();
setCurrentAnimation(controller.getTarget());
mConfig.userControlled = true;
mConfig.playbackController = controller;
@@ -405,15 +406,10 @@
}
if (mConfig.playbackController != null
&& mConfig.playbackController.getTarget() == childAnim) {
- if (mConfig.mCurrentAnimation != null) {
- mConfig.mCurrentAnimation.removeListener(mConfig);
- mConfig.mCurrentAnimation = null;
- }
- mConfig.playbackController = null;
+ clearCurrentAnimation();
break;
} else if (mConfig.mCurrentAnimation == childAnim) {
- mConfig.mCurrentAnimation.removeListener(mConfig);
- mConfig.mCurrentAnimation = null;
+ clearCurrentAnimation();
break;
}
}
@@ -425,6 +421,14 @@
mConfig.setAnimation(anim, null);
}
+ private void clearCurrentAnimation() {
+ if (mConfig.mCurrentAnimation != null) {
+ mConfig.mCurrentAnimation.removeListener(mConfig);
+ mConfig.mCurrentAnimation = null;
+ }
+ mConfig.playbackController = null;
+ }
+
private class StartAnimRunnable implements Runnable {
private final AnimatorSet mAnim;
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index 8f1c8df..e8c5f15 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -156,14 +156,14 @@
float verticalProgress = OVERVIEW.getVerticalProgress(launcher);
TimeInterpolator pathInterpolator = new PathInterpolator(0.35f, 0, 0.5f, 1);
- Keyframe keyframe3 = Keyframe.ofFloat(0.423f, verticalProgress - (1 - 0.9438f));
+ Keyframe keyframe3 = Keyframe.ofFloat(0.423f, verticalProgress - (1 - 0.9738f));
keyframe3.setInterpolator(pathInterpolator);
- Keyframe keyframe4 = Keyframe.ofFloat(0.654f, verticalProgress);
+ Keyframe keyframe4 = Keyframe.ofFloat(0.754f, verticalProgress);
keyframe4.setInterpolator(pathInterpolator);
PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe("progress",
Keyframe.ofFloat(0, verticalProgress),
- Keyframe.ofFloat(0.346f, verticalProgress), keyframe3, keyframe4,
+ Keyframe.ofFloat(0.246f, verticalProgress), keyframe3, keyframe4,
Keyframe.ofFloat(1f, verticalProgress));
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(null,
new PropertyValuesHolder[]{propertyValuesHolder});
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index e1e1f83..1e5f854 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -288,7 +288,7 @@
if (mScaledMaskPath != null) {
mBgSpringDrawable.setColorFilter(mBaseFilter);
- mBgSpringDrawable.setColorFilter(mBaseFilter);
+ mFgSpringDrawable.setColorFilter(mBaseFilter);
mBadge.setColorFilter(mBaseFilter);
}
} else {