Merge changes from topic "am-c2841e6a-5061-492f-abbf-dfb8b89ccc04" into ub-launcher3-master
* changes:
[automerger] Fix some state issues with user-controlled animations am: 31fbd4c08b
Fix some state issues with user-controlled animations
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 85ccf29..94aaf15 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -335,10 +335,14 @@
launcherAnimator.play(dragLayerAlpha);
launcherAnimator.play(dragLayerTransY);
mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ // Pause page indicator animations as they lead to layer trashing.
+ mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
endListener = () -> {
mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null);
mDragLayer.setAlpha(1);
mDragLayer.setTranslationY(0);
+ mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
};
}
return new Pair<>(launcherAnimator, endListener);
@@ -694,6 +698,13 @@
workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
workspaceAnimator.setDuration(333);
workspaceAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ currentPage.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ workspaceAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ currentPage.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
// Animate the shelf in two parts: slide in, and overeshoot.
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
@@ -715,7 +726,6 @@
allAppsOvershoot.setDuration(153);
allAppsOvershoot.setInterpolator(Interpolators.OVERSHOOT_0);
-
anim.play(workspaceAnimator);
anim.playSequentially(allAppsSlideIn, allAppsOvershoot);
anim.addListener(mReapplyStateListener);
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index ab73074..168bd08 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -780,7 +780,7 @@
}
private static final class IconDB extends SQLiteCacheHelper {
- private final static int RELEASE_VERSION = 21;
+ private final static int RELEASE_VERSION = 22;
private final static String TABLE_NAME = "icons";
private final static String COLUMN_ROWID = "rowid";
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2c08169..af4faa8 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -318,7 +318,7 @@
if (!internalStateHandled) {
// If we are not binding synchronously, show a fade in animation when
// the first page bind completes.
- mDragLayer.setAlpha(0);
+ mLauncherView.setAlpha(0);
}
} else {
// Pages bound synchronously.
@@ -2131,8 +2131,8 @@
@Override
public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
- if (mDragLayer.getAlpha() < 1) {
- mDragLayer.animate().alpha(1).withEndAction(
+ if (mLauncherView.getAlpha() < 1) {
+ mLauncherView.animate().alpha(1).withEndAction(
executor == null ? null : executor::onLoadAnimationCompleted).start();
} else if (executor != null) {
executor.onLoadAnimationCompleted();
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 37405db..211d98f 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -45,6 +45,7 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.AllAppsScrim;
import com.android.launcher3.keyboard.FocusedItemDecorator;
@@ -122,6 +123,13 @@
}
@Override
+ protected void setDampedScrollShift(float shift) {
+ // Bound the shift amount to avoid content from drawing on top (Y-val) of the QSB.
+ float maxShift = getSearchView().getHeight() / 2f;
+ super.setDampedScrollShift(Utilities.boundToRange(shift, -maxShift, maxShift));
+ }
+
+ @Override
public void onDeviceProfileChanged(DeviceProfile dp) {
for (AdapterHolder holder : mAH) {
if (holder.recyclerView != null) {
diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java
index 81f3f90..a2a0801 100644
--- a/src/com/android/launcher3/graphics/IconNormalizer.java
+++ b/src/com/android/launcher3/graphics/IconNormalizer.java
@@ -24,6 +24,7 @@
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -66,12 +67,10 @@
private final int mMaxSize;
private final Bitmap mBitmap;
- private final Bitmap mBitmapARGB;
private final Canvas mCanvas;
private final Paint mPaintMaskShape;
private final Paint mPaintMaskShapeOutline;
private final byte[] mPixels;
- private final int[] mPixelsARGB;
private final Rect mAdaptiveIconBounds;
private float mAdaptiveIconScale;
@@ -83,9 +82,6 @@
private final Path mShapePath;
private final Matrix mMatrix;
- private final Paint mPaintIcon;
- private final Canvas mCanvasARGB;
-
/** package private **/
IconNormalizer(Context context) {
// Use twice the icon size as maximum size to avoid scaling down twice.
@@ -93,19 +89,11 @@
mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8);
mCanvas = new Canvas(mBitmap);
mPixels = new byte[mMaxSize * mMaxSize];
- mPixelsARGB = new int[mMaxSize * mMaxSize];
mLeftBorder = new float[mMaxSize];
mRightBorder = new float[mMaxSize];
mBounds = new Rect();
mAdaptiveIconBounds = new Rect();
- // Needed for isShape() method
- mBitmapARGB = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ARGB_8888);
- mCanvasARGB = new Canvas(mBitmapARGB);
-
- mPaintIcon = new Paint();
- mPaintIcon.setColor(Color.WHITE);
-
mPaintMaskShape = new Paint();
mPaintMaskShape.setColor(Color.RED);
mPaintMaskShape.setStyle(Paint.Style.FILL);
@@ -115,7 +103,7 @@
mPaintMaskShapeOutline.setStrokeWidth(2 * context.getResources().getDisplayMetrics().density);
mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE);
mPaintMaskShapeOutline.setColor(Color.BLACK);
- mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+ mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mShapePath = new Path();
mMatrix = new Matrix();
@@ -141,8 +129,6 @@
// Condition 2:
// Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation
// should generate transparent image, if the actual icon is equivalent to the shape.
- mBitmapARGB.eraseColor(Color.TRANSPARENT);
- mCanvasARGB.drawBitmap(mBitmap, 0, 0, mPaintIcon);
// Fit the shape within the icon's bounding box
mMatrix.reset();
@@ -151,31 +137,41 @@
maskPath.transform(mMatrix, mShapePath);
// XOR operation
- mCanvasARGB.drawPath(mShapePath, mPaintMaskShape);
+ mCanvas.drawPath(mShapePath, mPaintMaskShape);
// DST_OUT operation around the mask path outline
- mCanvasARGB.drawPath(mShapePath, mPaintMaskShapeOutline);
+ mCanvas.drawPath(mShapePath, mPaintMaskShapeOutline);
// Check if the result is almost transparent
- return isTransparentBitmap(mBitmapARGB);
+ return isTransparentBitmap();
}
/**
* Used to determine if certain the bitmap is transparent.
*/
- private boolean isTransparentBitmap(Bitmap bitmap) {
- int w = mBounds.width();
- int h = mBounds.height();
- bitmap.getPixels(mPixelsARGB, 0 /* the first index to write into the array */,
- w /* stride */,
- mBounds.left, mBounds.top,
- w, h);
+ private boolean isTransparentBitmap() {
+ ByteBuffer buffer = ByteBuffer.wrap(mPixels);
+ buffer.rewind();
+ mBitmap.copyPixelsToBuffer(buffer);
+
+ int y = mBounds.top;
+ // buffer position
+ int index = y * mMaxSize;
+ // buffer shift after every row, width of buffer = mMaxSize
+ int rowSizeDiff = mMaxSize - mBounds.right;
+
int sum = 0;
- for (int i = w * h - 1; i >= 0; i--) {
- if(Color.alpha(mPixelsARGB[i]) > MIN_VISIBLE_ALPHA) {
+ for (; y < mBounds.bottom; y++) {
+ index += mBounds.left;
+ for (int x = mBounds.left; x < mBounds.right; x++) {
+ if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) {
sum++;
+ }
+ index++;
}
+ index += rowSizeDiff;
}
+
float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height());
return percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD;
}
@@ -306,7 +302,7 @@
mBounds.bottom = bottomY;
if (outBounds != null) {
- outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top),
+ outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top) / height,
1 - ((float) mBounds.right) / width,
1 - ((float) mBounds.bottom) / height);
}
diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
index 3c16cde..1383f53 100644
--- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
@@ -41,8 +41,9 @@
private static final int LINE_ALPHA_ANIMATOR_INDEX = 0;
private static final int NUM_PAGES_ANIMATOR_INDEX = 1;
private static final int TOTAL_SCROLL_ANIMATOR_INDEX = 2;
+ private static final int ANIMATOR_COUNT = 3;
- private ValueAnimator[] mAnimators = new ValueAnimator[3];
+ private ValueAnimator[] mAnimators = new ValueAnimator[ANIMATOR_COUNT];
private final Handler mDelayedLineFadeHandler = new Handler(Looper.getMainLooper());
private final Launcher mLauncher;
@@ -232,6 +233,28 @@
mAnimators[animatorIndex].start();
}
+ /**
+ * Pauses all currently running animations.
+ */
+ public void pauseAnimations() {
+ for (int i = 0; i < ANIMATOR_COUNT; i++) {
+ if (mAnimators[i] != null) {
+ mAnimators[i].pause();
+ }
+ }
+ }
+
+ /**
+ * Force-ends all currently running or paused animations.
+ */
+ public void skipAnimationsToEnd() {
+ for (int i = 0; i < ANIMATOR_COUNT; i++) {
+ if (mAnimators[i] != null) {
+ mAnimators[i].end();
+ }
+ }
+ }
+
@Override
public void setInsets(Rect insets) {
DeviceProfile grid = mLauncher.getDeviceProfile();
diff --git a/src/com/android/launcher3/views/SpringRelativeLayout.java b/src/com/android/launcher3/views/SpringRelativeLayout.java
index a508191..598738b 100644
--- a/src/com/android/launcher3/views/SpringRelativeLayout.java
+++ b/src/com/android/launcher3/views/SpringRelativeLayout.java
@@ -97,7 +97,7 @@
mActiveEdge = edge;
}
- private void setDampedScrollShift(float shift) {
+ protected void setDampedScrollShift(float shift) {
if (shift != mDampedScrollShift) {
mDampedScrollShift = shift;
invalidate();