From 560e64d3d95a17123048bebe2fb06ffe4567fb78 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Tue, 9 Jun 2015 19:58:11 -0700 Subject: [PATCH] Switched to round rect clipping while appearing notifications This avoids a few out of memory crashes and in general seems cleaner. Change-Id: Iecb1be76fd561eb8bf2a4b650a866c62ed82ca65 --- .../ActivatableNotificationView.java | 80 +++++++------------ .../statusbar/ExpandableNotificationRow.java | 5 ++ .../statusbar/ExpandableOutlineView.java | 9 ++- .../NotificationOverflowContainer.java | 10 ++- 4 files changed, 50 insertions(+), 54 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index 8bee008a527ef..7cde44c44487c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -21,15 +21,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapShader; import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter; import android.graphics.RectF; -import android.graphics.Shader; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -100,7 +93,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private boolean mDark; private int mBgTint = 0; - private final int mRoundedRectCornerRadius; /** * Flag to indicate that the notification has been touched once and the second touch will @@ -126,10 +118,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private NotificationBackgroundView mBackgroundDimmed; private ObjectAnimator mBackgroundAnimator; private RectF mAppearAnimationRect = new RectF(); - private PorterDuffColorFilter mAppearAnimationFilter; private float mAnimationTranslationY; private boolean mDrawingAppearAnimation; - private Paint mAppearPaint = new Paint(); private ValueAnimator mAppearAnimator; private float mAppearAnimationFraction = -1.0f; private float mAppearAnimationTranslation; @@ -151,9 +141,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mLinearInterpolator = new LinearInterpolator(); setClipChildren(false); setClipToPadding(false); - mAppearAnimationFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); - mRoundedRectCornerRadius = getResources().getDimensionPixelSize( - R.dimen.notification_material_rounded_rect_radius); mLegacyColor = context.getColor(R.color.notification_legacy_background_color); mNormalColor = context.getColor(R.color.notification_material_background_color); mLowPriorityColor = context.getColor( @@ -661,20 +648,26 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } private void updateAppearAnimationAlpha() { - int backgroundColor = getBgColor(); - if (backgroundColor != -1) { - float contentAlphaProgress = mAppearAnimationFraction; - contentAlphaProgress = contentAlphaProgress / (1.0f - ALPHA_ANIMATION_END); - contentAlphaProgress = Math.min(1.0f, contentAlphaProgress); - contentAlphaProgress = mCurrentAlphaInterpolator.getInterpolation(contentAlphaProgress); - int sourceColor = Color.argb((int) (255 * (1.0f - contentAlphaProgress)), - Color.red(backgroundColor), Color.green(backgroundColor), - Color.blue(backgroundColor)); - mAppearAnimationFilter.setColor(sourceColor); - mAppearPaint.setColorFilter(mAppearAnimationFilter); - } + float contentAlphaProgress = mAppearAnimationFraction; + contentAlphaProgress = contentAlphaProgress / (1.0f - ALPHA_ANIMATION_END); + contentAlphaProgress = Math.min(1.0f, contentAlphaProgress); + contentAlphaProgress = mCurrentAlphaInterpolator.getInterpolation(contentAlphaProgress); + setContentAlpha(contentAlphaProgress); } + private void setContentAlpha(float contentAlpha) { + int layerType = contentAlpha == 0.0f || contentAlpha == 1.0f ? LAYER_TYPE_NONE + : LAYER_TYPE_HARDWARE; + View contentView = getContentView(); + int currentLayerType = contentView.getLayerType(); + if (currentLayerType != layerType) { + contentView.setLayerType(layerType, null); + } + contentView.setAlpha(contentAlpha); + } + + protected abstract View getContentView(); + private int getBgColor() { if (mBgTint != 0) { return mBgTint; @@ -708,41 +701,24 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView */ private void enableAppearDrawing(boolean enable) { if (enable != mDrawingAppearAnimation) { - if (enable) { - if (getWidth() == 0 || getActualHeight() == 0) { - // TODO: This should not happen, but it can during expansion. Needs - // investigation - return; - } - Bitmap bitmap = Bitmap.createBitmap(getWidth(), getActualHeight(), - Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - draw(canvas); - mAppearPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, - Shader.TileMode.CLAMP)); - } else { - mAppearPaint.setShader(null); - } mDrawingAppearAnimation = enable; + if (!enable) { + setContentAlpha(1.0f); + } invalidate(); } } @Override protected void dispatchDraw(Canvas canvas) { - if (!mDrawingAppearAnimation) { - super.dispatchDraw(canvas); - } else { - drawAppearRect(canvas); + if (mDrawingAppearAnimation) { + canvas.save(); + canvas.translate(0, mAppearAnimationTranslation); + } + super.dispatchDraw(canvas); + if (mDrawingAppearAnimation) { + canvas.restore(); } - } - - private void drawAppearRect(Canvas canvas) { - canvas.save(); - canvas.translate(0, mAppearAnimationTranslation); - canvas.drawRoundRect(mAppearAnimationRect, mRoundedRectCornerRadius, - mRoundedRectCornerRadius, mAppearPaint); - canvas.restore(); } public void setOnActivatedListener(OnActivatedListener onActivatedListener) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 9ef495de0b468..079265475d7d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -855,6 +855,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { return showingLayout.isContentExpandable(); } + @Override + protected View getContentView() { + return getShowingLayout(); + } + @Override public void setActualHeight(int height, boolean notifyListeners) { super.setActualHeight(height, notifyListeners); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java index a18fff2473978..d77e050dbee7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java @@ -24,16 +24,21 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; +import com.android.systemui.R; + /** * Like {@link ExpandableView}, but setting an outline for the height and clipping. */ public abstract class ExpandableOutlineView extends ExpandableView { private final Rect mOutlineRect = new Rect(); + protected final int mRoundedRectCornerRadius; private boolean mCustomOutline; public ExpandableOutlineView(Context context, AttributeSet attrs) { super(context, attrs); + mRoundedRectCornerRadius = getResources().getDimensionPixelSize( + R.dimen.notification_material_rounded_rect_radius); setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { @@ -43,7 +48,7 @@ public abstract class ExpandableOutlineView extends ExpandableView { getWidth(), Math.max(getActualHeight(), mClipTopAmount)); } else { - outline.setRect(mOutlineRect); + outline.setRoundRect(mOutlineRect, mRoundedRectCornerRadius); } } }); @@ -66,12 +71,14 @@ public abstract class ExpandableOutlineView extends ExpandableView { setOutlineRect(rect.left, rect.top, rect.right, rect.bottom); } else { mCustomOutline = false; + setClipToOutline(false); invalidateOutline(); } } protected void setOutlineRect(float left, float top, float right, float bottom) { mCustomOutline = true; + setClipToOutline(true); mOutlineRect.set((int) left, (int) top, (int) right, (int) bottom); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java index 5fa7070184ce8..9653b6758ce93 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.widget.TextView; import com.android.systemui.R; @@ -32,6 +33,7 @@ public class NotificationOverflowContainer extends ActivatableNotificationView { private NotificationOverflowIconsView mIconsView; private ViewInvertHelper mViewInvertHelper; private boolean mDark; + private View mContent; public NotificationOverflowContainer(Context context, AttributeSet attrs) { super(context, attrs); @@ -43,7 +45,8 @@ public class NotificationOverflowContainer extends ActivatableNotificationView { mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view); mIconsView.setMoreText((TextView) findViewById(R.id.more_text)); mIconsView.setOverflowIndicator(findViewById(R.id.more_icon_overflow)); - mViewInvertHelper = new ViewInvertHelper(findViewById(R.id.content), + mContent = findViewById(R.id.content); + mViewInvertHelper = new ViewInvertHelper(mContent, NotificationPanelView.DOZE_ANIMATION_DURATION); } @@ -59,6 +62,11 @@ public class NotificationOverflowContainer extends ActivatableNotificationView { } } + @Override + protected View getContentView() { + return mContent; + } + public NotificationOverflowIconsView getIconsView() { return mIconsView; }