Replacing setAlphaComponent with setAlphaComponentBound for better animation interpolation

setAlphaComponent throws expetion for invalid range, which can cause brashes in overshoot
interpolation

Bug: 118390004
Change-Id: Ic9c5ff3d660eba353b982c4c47ccfaf329b3e296
This commit is contained in:
Sunny Goyal 2018-11-05 11:08:31 -08:00
parent 5bd44153fd
commit 066ace1b88
14 changed files with 80 additions and 47 deletions

View File

@ -18,8 +18,6 @@ import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import com.android.launcher3.icons.R;
import static android.graphics.Paint.DITHER_FLAG;
import static android.graphics.Paint.FILTER_BITMAP_FLAG;
import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
@ -81,6 +79,7 @@ public class BaseIconFactory {
return mNormalizer;
}
@SuppressWarnings("deprecation")
public BitmapInfo createIconBitmap(Intent.ShortcutIconResource iconRes) {
try {
Resources resources = mPm.getResourcesForApplication(iconRes.packageName);
@ -184,8 +183,7 @@ public class BaseIconFactory {
RectF outIconBounds, float[] outScale) {
float scale = 1f;
if (shrinkNonAdaptiveIcons) {
boolean[] outShape = new boolean[1];
if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
if (mWrapperIcon == null) {
mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper)
.mutate();
@ -193,7 +191,7 @@ public class BaseIconFactory {
AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon;
dr.setBounds(0, 0, 1, 1);
scale = getNormalizer().getScale(icon, outIconBounds);
if (ATLEAST_OREO && !(icon instanceof AdaptiveIconDrawable)) {
if (!(icon instanceof AdaptiveIconDrawable)) {
FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground());
fsd.setDrawable(icon);
fsd.setScale(scale);

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons;
import androidx.annotation.ColorInt;
public class GraphicsUtils {
/**
* Set the alpha component of {@code color} to be {@code alpha}. Unlike the support lib version,
* it bounds the alpha in valid range instead of throwing an exception to allow for safer
* interpolation of color animations
*/
@ColorInt
public static int setColorAlphaBound(int color, int alpha) {
if (alpha < 0) {
alpha = 0;
} else if (alpha > 255) {
alpha = 255;
}
return (color & 0x00ffffff) | (alpha << 24);
}
}

View File

@ -16,6 +16,8 @@
package com.android.launcher3.icons;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BlurMaskFilter;
@ -27,8 +29,6 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import androidx.core.graphics.ColorUtils;
/**
* Utility class to add shadows to bitmaps.
*/
@ -142,12 +142,12 @@ public class ShadowGenerator {
// Key shadow
p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
ColorUtils.setAlphaComponent(Color.BLACK, keyShadowAlpha));
setColorAlphaBound(Color.BLACK, keyShadowAlpha));
c.drawRoundRect(bounds, radius, radius, p);
// Ambient shadow
p.setShadowLayer(shadowBlur, 0, 0,
ColorUtils.setAlphaComponent(Color.BLACK, ambientShadowAlpha));
setColorAlphaBound(Color.BLACK, ambientShadowAlpha));
c.drawRoundRect(bounds, radius, radius, p);
if (Color.alpha(color) < 255) {

View File

@ -18,8 +18,7 @@ package com.android.quickstep.views;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static androidx.core.graphics.ColorUtils.setAlphaComponent;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.content.Context;
import android.graphics.Canvas;
@ -141,7 +140,7 @@ public class ShelfScrimView extends ScrimView {
int alpha = Math.round(Utilities.mapToRange(
mProgress, mMidProgress, 1, mMidAlpha, 0, ACCEL));
mShelfColor = setAlphaComponent(mEndScrim, alpha);
mShelfColor = setColorAlphaBound(mEndScrim, alpha);
} else {
mDragHandleOffset += mShiftRange * (mMidProgress - mProgress);
@ -149,12 +148,12 @@ public class ShelfScrimView extends ScrimView {
int alpha = Math.round(
Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha,
(float) mMidAlpha, Interpolators.clampToProgress(ACCEL, 0.5f, 1f)));
mShelfColor = setAlphaComponent(mEndScrim, alpha);
mShelfColor = setColorAlphaBound(mEndScrim, alpha);
int remainingScrimAlpha = Math.round(
Utilities.mapToRange(mProgress, (float) 0, mMidProgress, mMaxScrimAlpha,
(float) 0, LINEAR));
mRemainingScreenColor = setAlphaComponent(mScrimColor, remainingScrimAlpha);
mRemainingScreenColor = setColorAlphaBound(mScrimColor, remainingScrimAlpha);
}
}

View File

@ -16,6 +16,8 @@
package com.android.launcher3;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@ -53,8 +55,6 @@ import com.android.launcher3.model.PackageItemInfo;
import java.text.NumberFormat;
import androidx.core.graphics.ColorUtils;
/**
* TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
* because we want to make the bubble taller than the text and TextView's clip is
@ -473,8 +473,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
// Special case to prevent text shadows in high contrast mode
return Color.TRANSPARENT;
}
return ColorUtils.setAlphaComponent(
mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
return setColorAlphaBound(mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
}
/**

View File

@ -20,6 +20,7 @@ import static com.android.launcher3.BubbleTextView.TEXT_ALPHA_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.folder.FolderShape.getShape;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@ -46,8 +47,6 @@ import com.android.launcher3.util.Themes;
import java.util.List;
import androidx.core.graphics.ColorUtils;
/**
* Manages the opening and closing animations for a {@link Folder}.
*
@ -153,8 +152,8 @@ public class FolderAnimationManager {
// Set up the Folder background.
final int finalColor = Themes.getAttrColor(mContext, android.R.attr.colorPrimary);
final int initialColor =
ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha());
final int initialColor = setColorAlphaBound(
finalColor, mPreviewBackground.getBackgroundAlpha());
mFolderBackground.mutate();
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);

View File

@ -17,6 +17,7 @@
package com.android.launcher3.folder;
import static com.android.launcher3.folder.FolderShape.getShape;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@ -41,8 +42,6 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
import androidx.core.graphics.ColorUtils;
/**
* This object represents a FolderIcon preview background. It stores drawing / measurement
* information, handles drawing, and animation (accept state <--> rest state).
@ -189,7 +188,7 @@ public class PreviewBackground {
public int getBgColor() {
int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
return ColorUtils.setAlphaComponent(mBgColor, alpha);
return setColorAlphaBound(mBgColor, alpha);
}
public int getBadgeColor() {
@ -275,7 +274,7 @@ public class PreviewBackground {
}
public void drawBackgroundStroke(Canvas canvas) {
mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
mPaint.setColor(setColorAlphaBound(mBgColor, mStrokeAlpha));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);

View File

@ -16,6 +16,8 @@
package com.android.launcher3.graphics;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
@ -147,7 +149,7 @@ public class IconPalette {
}
public static int getMutedColor(int color, float whiteScrimAlpha) {
int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * whiteScrimAlpha));
int whiteScrim = setColorAlphaBound(Color.WHITE, (int) (255 * whiteScrimAlpha));
return ColorUtils.compositeColors(whiteScrim, color);
}
}

View File

@ -19,6 +19,8 @@ package com.android.launcher3.graphics;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_USER_PRESENT;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.ObjectAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -174,7 +176,7 @@ public class WorkspaceAndHotseatScrim implements
canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE);
}
canvas.drawColor(ColorUtils.setAlphaComponent(mFullScrimColor, mScrimAlpha));
canvas.drawColor(setColorAlphaBound(mFullScrimColor, mScrimAlpha));
canvas.restore();
}
@ -303,7 +305,7 @@ public class WorkspaceAndHotseatScrim implements
LinearGradient lg = new LinearGradient(0, 0, 0, gradientHeight,
new int[]{
0x00FFFFFF,
ColorUtils.setAlphaComponent(Color.WHITE, (int) (0xFF * 0.95)),
setColorAlphaBound(Color.WHITE, (int) (0xFF * 0.95)),
0xFFFFFFFF},
new float[]{0f, 0.8f, 1f},
Shader.TileMode.CLAMP);

View File

@ -16,6 +16,7 @@
package com.android.launcher3.icons;
import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.content.ComponentName;
import android.content.ContentValues;
@ -56,7 +57,6 @@ import java.util.HashMap;
import java.util.HashSet;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
public class BaseIconCache {
@ -435,7 +435,7 @@ public class BaseIconCache {
Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
if (c.moveToNext()) {
// Set the alpha to be 255, so that we never have a wrong color
entry.color = ColorUtils.setAlphaComponent(c.getInt(0), 255);
entry.color = setColorAlphaBound(c.getInt(0), 255);
entry.title = c.getString(1);
if (entry.title == null) {
entry.title = "";

View File

@ -15,7 +15,7 @@
*/
package com.android.launcher3.settings;
import static androidx.core.graphics.ColorUtils.setAlphaComponent;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@ -57,7 +57,7 @@ public class PreferenceHighlighter extends ItemDecoration implements Runnable {
private static final long HIGHLIGHT_DURATION = 15000L;
private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L;
private static final long HIGHLIGHT_FADE_IN_DURATION = 200L;
private static final int END_COLOR = setAlphaComponent(Color.WHITE, 0);
private static final int END_COLOR = setColorAlphaBound(Color.WHITE, 0);
private final Paint mPaint = new Paint();
private final RecyclerView mRv;
@ -91,7 +91,7 @@ public class PreferenceHighlighter extends ItemDecoration implements Runnable {
if (!mHighLightStarted) {
// Start highlight
int colorTo = setAlphaComponent(Themes.getColorAccent(mRv.getContext()), 66);
int colorTo = setColorAlphaBound(Themes.getColorAccent(mRv.getContext()), 66);
ObjectAnimator anim = ObjectAnimator.ofArgb(this, HIGHLIGHT_COLOR, END_COLOR, colorTo);
anim.setDuration(HIGHLIGHT_FADE_IN_DURATION);
anim.setRepeatMode(ValueAnimator.REVERSE);

View File

@ -16,6 +16,8 @@
package com.android.launcher3.views;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@ -26,8 +28,6 @@ import android.widget.TextView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
import androidx.core.graphics.ColorUtils;
/**
* Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
*/
@ -60,7 +60,7 @@ public class DoubleShadowBubbleTextView extends BubbleTextView {
// We enhance the shadow by drawing the shadow twice
getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
ColorUtils.setAlphaComponent(mShadowInfo.ambientShadowColor, alpha));
setColorAlphaBound(mShadowInfo.ambientShadowColor, alpha));
drawWithoutBadge(canvas);
canvas.save();
@ -69,7 +69,7 @@ public class DoubleShadowBubbleTextView extends BubbleTextView {
getScrollY() + getHeight());
getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
ColorUtils.setAlphaComponent(mShadowInfo.keyShadowColor, alpha));
setColorAlphaBound(mShadowInfo.keyShadowColor, alpha));
drawWithoutBadge(canvas);
canvas.restore();
@ -107,11 +107,11 @@ public class DoubleShadowBubbleTextView extends BubbleTextView {
return true;
} else if (ambientShadowAlpha > 0) {
textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
ColorUtils.setAlphaComponent(ambientShadowColor, textAlpha));
setColorAlphaBound(ambientShadowColor, textAlpha));
return true;
} else if (keyShadowAlpha > 0) {
textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset,
ColorUtils.setAlphaComponent(keyShadowColor, textAlpha));
setColorAlphaBound(keyShadowColor, textAlpha));
return true;
} else {
return false;

View File

@ -22,9 +22,9 @@ import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import static androidx.core.graphics.ColorUtils.compositeColors;
import static androidx.core.graphics.ColorUtils.setAlphaComponent;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@ -182,7 +182,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
@Override
public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
mScrimColor = wallpaperColorInfo.getMainColor();
mEndFlatColor = compositeColors(mEndScrim, setAlphaComponent(
mEndFlatColor = compositeColors(mEndScrim, setColorAlphaBound(
mScrimColor, Math.round(mMaxScrimAlpha * 255)));
mEndFlatColorAlpha = Color.alpha(mEndFlatColor);
updateColors();
@ -201,7 +201,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
public void reInitUi() { }
protected void updateColors() {
mCurrentFlatColor = mProgress >= 1 ? 0 : setAlphaComponent(
mCurrentFlatColor = mProgress >= 1 ? 0 : setColorAlphaBound(
mEndFlatColor, Math.round((1 - mProgress) * mEndFlatColorAlpha));
}

View File

@ -17,6 +17,7 @@ package com.android.launcher3.widget;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import android.content.Context;
@ -42,8 +43,6 @@ import com.android.launcher3.util.Themes;
import com.android.launcher3.views.AbstractSlideInView;
import com.android.launcher3.views.BaseDragLayer;
import androidx.core.graphics.ColorUtils;
/**
* Base class for various widgets popup
*/
@ -162,11 +161,11 @@ abstract class BaseWidgetSheet extends AbstractSlideInView
private static View createColorScrim(Context context) {
View view = new View(context);
view.forceHasOverlappingRendering(false);
if (Utilities.ATLEAST_NOUGAT) view.forceHasOverlappingRendering(false);
WallpaperColorInfo colors = WallpaperColorInfo.getInstance(context);
int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha);
view.setBackgroundColor(ColorUtils.setAlphaComponent(colors.getSecondaryColor(), alpha));
view.setBackgroundColor(setColorAlphaBound(colors.getSecondaryColor(), alpha));
BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(MATCH_PARENT, MATCH_PARENT);
lp.ignoreInsets = true;