From 03cf2586faef0bc4971cbda99bd13d608ed23e0d Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 28 Mar 2017 17:54:05 -0700 Subject: [PATCH 1/4] AOD: prevent clicking shelf when dark Fixes: 35718464 Test: Enable AOD, try clicking on shelf in AOD, make sure it's not clickable. Change-Id: Iede88d1e0ab394f0db2acaac6a1ad8baaeef15f1 --- .../src/com/android/systemui/statusbar/NotificationShelf.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 8da17fa76bd7e..8ba4eb57f079d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -133,6 +133,7 @@ public class NotificationShelf extends ActivatableNotificationView implements mViewInvertHelper.update(dark); } mShelfIcons.setAmbient(dark); + updateInteractiveness(); } @Override @@ -576,7 +577,8 @@ public class NotificationShelf extends ActivatableNotificationView implements } private void updateInteractiveness() { - mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf; + mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf + && !mDark; setClickable(mInteractive); setFocusable(mInteractive); setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES From 7bcf6d378f1bf1294ccd4c9beeb11bfd9b39816d Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 4 Apr 2017 16:44:25 -0700 Subject: [PATCH 2/4] Revert "Revert "NotificationWrappers: Factor out doze treatment"" This reverts commit 934027a4307d5bc4896d662fd92c47c556e11cca. Change-Id: Id4008fc79e474f3820f3587dff40720a57c9ef3a Merged-In: Id4008fc79e474f3820f3587dff40720a57c9ef3a --- .../NotificationCustomViewWrapper.java | 22 ++- .../notification/NotificationDozeHelper.java | 80 +++++++++++ .../NotificationHeaderViewWrapper.java | 126 ++---------------- .../NotificationIconDozeHelper.java | 101 ++++++++++++++ .../NotificationTemplateViewWrapper.java | 35 +++-- .../notification/NotificationViewWrapper.java | 44 ++---- 6 files changed, 233 insertions(+), 175 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java index 3efa29f874506..bca4b43afc0c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java @@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; +import android.content.Context; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.view.View; @@ -38,8 +38,8 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { private boolean mIsLegacy; private int mLegacyColor; - protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) { - super(view, row); + protected NotificationCustomViewWrapper(Context ctx, View view, ExpandableNotificationRow row) { + super(ctx, view, row); mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION); mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color); } @@ -67,13 +67,11 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { } protected void fadeGrayscale(final boolean dark, long delay) { - startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - updateGrayscaleMatrix((float) animation.getAnimatedValue()); - mGreyPaint.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); - mView.setLayerPaint(mGreyPaint); - } + getDozer().startIntensityAnimation(animation -> { + getDozer().updateGrayscaleMatrix((float) animation.getAnimatedValue()); + mGreyPaint.setColorFilter( + new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix())); + mView.setLayerPaint(mGreyPaint); }, dark, delay, new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -86,9 +84,9 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { protected void updateGrayscale(boolean dark) { if (dark) { - updateGrayscaleMatrix(1f); + getDozer().updateGrayscaleMatrix(1f); mGreyPaint.setColorFilter( - new ColorMatrixColorFilter(mGrayscaleColorMatrix)); + new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix())); mView.setLayerPaint(mGreyPaint); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java new file mode 100644 index 0000000000000..09efec61aa4fe --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2017 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.systemui.statusbar.notification; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.widget.ImageView; + +import com.android.systemui.Interpolators; +import com.android.systemui.statusbar.phone.NotificationPanelView; + +public class NotificationDozeHelper { + private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); + + public void fadeGrayscale(final ImageView target, final boolean dark, long delay) { + startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + updateGrayscaleMatrix((float) animation.getAnimatedValue()); + target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); + } + }, dark, delay, new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (!dark) { + target.setColorFilter(null); + } + } + }); + } + + public void updateGrayscale(ImageView target, boolean dark) { + if (dark) { + updateGrayscaleMatrix(1f); + target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); + } else { + target.setColorFilter(null); + } + } + + public void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener, + boolean dark, long delay, Animator.AnimatorListener listener) { + float startIntensity = dark ? 0f : 1f; + float endIntensity = dark ? 1f : 0f; + ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity); + animator.addUpdateListener(updateListener); + animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); + animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); + animator.setStartDelay(delay); + if (listener != null) { + animator.addListener(listener); + } + animator.start(); + } + + public void updateGrayscaleMatrix(float intensity) { + mGrayscaleColorMatrix.setSaturation(1 - intensity); + } + + public ColorMatrix getGrayscaleColorMatrix() { + return mGrayscaleColorMatrix; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java index 38e4ec1a4d7f0..1ffc94480dab1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java @@ -16,17 +16,10 @@ package com.android.systemui.statusbar.notification; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; import android.app.Notification; import android.content.Context; -import android.graphics.Color; import android.graphics.ColorFilter; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; -import android.graphics.drawable.Drawable; import android.util.ArraySet; import android.view.NotificationHeaderView; import android.view.View; @@ -37,7 +30,6 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.systemui.Interpolators; -import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; @@ -55,10 +47,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private static final Interpolator LOW_PRIORITY_HEADER_CLOSE = new PathInterpolator(0.4f, 0f, 0.7f, 1f); - private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( - 0, PorterDuff.Mode.SRC_ATOP); - private final int mIconDarkAlpha; - private final int mIconDarkColor = 0xffffffff; protected final ViewInvertHelper mInvertHelper; protected final ViewTransformationHelper mTransformationHelper; @@ -74,8 +62,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private boolean mTransformLowPriorityTitle; protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) { - super(view, row); - mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); + super(ctx, view, row); mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION); mTransformationHelper = new ViewTransformationHelper(); @@ -108,6 +95,16 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { updateInvertHelper(); } + @Override + protected NotificationDozeHelper createDozer(Context ctx) { + return new NotificationIconDozeHelper(ctx); + } + + @Override + protected NotificationIconDozeHelper getDozer() { + return (NotificationIconDozeHelper) super.getDozer(); + } + protected void resolveHeaderViews() { mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); mHeaderText = (TextView) mView.findViewById(com.android.internal.R.id.header_text); @@ -116,6 +113,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { mColor = resolveColor(mExpandButton); mNotificationHeader = (NotificationHeaderView) mView.findViewById( com.android.internal.R.id.notification_header); + getDozer().setColor(mColor); } private int resolveColor(ImageView icon) { @@ -223,90 +221,8 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { // It also may lead to bugs where the icon isn't correctly greyed out. boolean hadColorFilter = mNotificationHeader.getOriginalIconColor() != NotificationHeaderView.NO_COLOR; - if (fade) { - if (hadColorFilter) { - fadeIconColorFilter(mIcon, dark, delay); - fadeIconAlpha(mIcon, dark, delay); - } else { - fadeGrayscale(mIcon, dark, delay); - } - } else { - if (hadColorFilter) { - updateIconColorFilter(mIcon, dark); - updateIconAlpha(mIcon, dark); - } else { - updateGrayscale(mIcon, dark); - } - } - } - } - private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) { - startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - updateIconColorFilter(target, (Float) animation.getAnimatedValue()); - } - }, dark, delay, null /* listener */); - } - - private void fadeIconAlpha(final ImageView target, boolean dark, long delay) { - startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float t = (float) animation.getAnimatedValue(); - target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t)); - } - }, dark, delay, null /* listener */); - } - - protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) { - startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - updateGrayscaleMatrix((float) animation.getAnimatedValue()); - target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); - } - }, dark, delay, new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (!dark) { - target.setColorFilter(null); - } - } - }); - } - - private void updateIconColorFilter(ImageView target, boolean dark) { - updateIconColorFilter(target, dark ? 1f : 0f); - } - - private void updateIconColorFilter(ImageView target, float intensity) { - int color = interpolateColor(mColor, mIconDarkColor, intensity); - mIconColorFilter.setColor(color); - Drawable iconDrawable = target.getDrawable(); - - // Also, the notification might have been modified during the animation, so background - // might be null here. - if (iconDrawable != null) { - Drawable d = iconDrawable.mutate(); - // DrawableContainer ignores the color filter if it's already set, so clear it first to - // get it set and invalidated properly. - d.setColorFilter(null); - d.setColorFilter(mIconColorFilter); - } - } - - private void updateIconAlpha(ImageView target, boolean dark) { - target.setImageAlpha(dark ? mIconDarkAlpha : 255); - } - - protected void updateGrayscale(ImageView target, boolean dark) { - if (dark) { - updateGrayscaleMatrix(1f); - target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); - } else { - target.setColorFilter(null); + getDozer().setImageDark(mIcon, dark, fade, delay, !hadColorFilter); } } @@ -316,22 +232,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { mNotificationHeader.setOnClickListener(expandable ? onClickListener : null); } - private static int interpolateColor(int source, int target, float t) { - int aSource = Color.alpha(source); - int rSource = Color.red(source); - int gSource = Color.green(source); - int bSource = Color.blue(source); - int aTarget = Color.alpha(target); - int rTarget = Color.red(target); - int gTarget = Color.green(target); - int bTarget = Color.blue(target); - return Color.argb( - (int) (aSource * (1f - t) + aTarget * t), - (int) (rSource * (1f - t) + rTarget * t), - (int) (gSource * (1f - t) + gTarget * t), - (int) (bSource * (1f - t) + bTarget * t)); - } - @Override public NotificationHeaderView getNotificationHeader() { return mNotificationHeader; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java new file mode 100644 index 0000000000000..9f79ef2491d97 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2017 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.systemui.statusbar.notification; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.drawable.Drawable; +import android.widget.ImageView; + +import com.android.systemui.R; + +public class NotificationIconDozeHelper extends NotificationDozeHelper { + + private final int mImageDarkAlpha; + private final int mImageDarkColor = 0xffffffff; + private final PorterDuffColorFilter mImageColorFilter = new PorterDuffColorFilter( + 0, PorterDuff.Mode.SRC_ATOP); + + private int mColor = Color.BLACK; + + public NotificationIconDozeHelper(Context ctx) { + mImageDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); + } + + public void setColor(int color) { + mColor = color; + } + + public void setImageDark(ImageView target, boolean dark, boolean fade, long delay, + boolean useGrayscale) { + if (fade) { + if (!useGrayscale) { + fadeImageColorFilter(target, dark, delay); + fadeImageAlpha(target, dark, delay); + } else { + fadeGrayscale(target, dark, delay); + } + } else { + if (!useGrayscale) { + updateImageColorFilter(target, dark); + updateImageAlpha(target, dark); + } else { + updateGrayscale(target, dark); + } + } + } + + private void fadeImageColorFilter(final ImageView target, boolean dark, long delay) { + startIntensityAnimation(animation -> { + updateImageColorFilter(target, (Float) animation.getAnimatedValue()); + }, dark, delay, null /* listener */); + } + + private void fadeImageAlpha(final ImageView target, boolean dark, long delay) { + startIntensityAnimation(animation -> { + float t = (float) animation.getAnimatedValue(); + target.setImageAlpha((int) (255 * (1f - t) + mImageDarkAlpha * t)); + }, dark, delay, null /* listener */); + } + + private void updateImageColorFilter(ImageView target, boolean dark) { + updateImageColorFilter(target, dark ? 1f : 0f); + } + + private void updateImageColorFilter(ImageView target, float intensity) { + int color = NotificationUtils.interpolateColors(mColor, mImageDarkColor, intensity); + mImageColorFilter.setColor(color); + Drawable imageDrawable = target.getDrawable(); + + // Also, the notification might have been modified during the animation, so background + // might be null here. + if (imageDrawable != null) { + Drawable d = imageDrawable.mutate(); + // DrawableContainer ignores the color filter if it's already set, so clear it first to + // get it set and invalidated properly. + d.setColorFilter(null); + d.setColorFilter(mImageColorFilter); + } + } + + private void updateImageAlpha(ImageView target, boolean dark) { + target.setImageAlpha(dark ? mImageDarkAlpha : 255); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java index 846d03ac74dd1..f0b6b2e89e9f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.notification; -import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; import android.service.notification.StatusBarNotification; @@ -46,7 +45,8 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp private int mContentHeight; private int mMinHeightHint; - protected NotificationTemplateViewWrapper(Context ctx, View view, ExpandableNotificationRow row) { + protected NotificationTemplateViewWrapper(Context ctx, View view, + ExpandableNotificationRow row) { super(ctx, view, row); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @@ -154,16 +154,20 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp // This also clears the existing types super.updateTransformedTypes(); if (mTitle != null) { - mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE, mTitle); + mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE, + mTitle); } if (mText != null) { - mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT, mText); + mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT, + mText); } if (mPicture != null) { - mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE, mPicture); + mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE, + mPicture); } if (mProgressBar != null) { - mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS, mProgressBar); + mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS, + mProgressBar); } } @@ -173,7 +177,7 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp return; } super.setDark(dark, fade, delay); - setPictureGrayscale(dark, fade, delay); + setPictureDark(dark, fade, delay); setProgressBarDark(dark, fade, delay); } @@ -188,12 +192,9 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp } private void fadeProgressDark(final ProgressBar target, final boolean dark, long delay) { - startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float t = (float) animation.getAnimatedValue(); - updateProgressDark(target, t); - } + getDozer().startIntensityAnimation(animation -> { + float t = (float) animation.getAnimatedValue(); + updateProgressDark(target, t); }, dark, delay, null /* listener */); } @@ -207,13 +208,9 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp updateProgressDark(target, dark ? 1f : 0f); } - protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) { + private void setPictureDark(boolean dark, boolean fade, long delay) { if (mPicture != null) { - if (fade) { - fadeGrayscale(mPicture, grayscale, delay); - } else { - updateGrayscale(mPicture, grayscale); - } + getDozer().setImageDark(mPicture, dark, fade, delay, true /* useGrayscale */); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java index c85e8d853b0d9..c86616bc31ed0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java @@ -16,24 +16,17 @@ package com.android.systemui.statusbar.notification; -import android.animation.Animator; -import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; -import android.graphics.ColorMatrix; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.service.notification.StatusBarNotification; import android.support.v4.graphics.ColorUtils; import android.view.NotificationHeaderView; import android.view.View; -import com.android.systemui.Interpolators; -import com.android.systemui.R; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; -import com.android.systemui.statusbar.phone.NotificationPanelView; /** * Wraps the actual notification content view; used to implement behaviors which are different for @@ -41,14 +34,14 @@ import com.android.systemui.statusbar.phone.NotificationPanelView; */ public abstract class NotificationViewWrapper implements TransformableView { - protected final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); protected final View mView; protected final ExpandableNotificationRow mRow; + private final NotificationDozeHelper mDozer; + protected boolean mDark; private int mBackgroundColor = 0; protected boolean mShouldInvertDark; protected boolean mDarkInitialized = false; - private boolean mForcedInvisible; public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) { if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) { @@ -65,13 +58,22 @@ public abstract class NotificationViewWrapper implements TransformableView { } else if (v instanceof NotificationHeaderView) { return new NotificationHeaderViewWrapper(ctx, v, row); } else { - return new NotificationCustomViewWrapper(v, row); + return new NotificationCustomViewWrapper(ctx, v, row); } } - protected NotificationViewWrapper(View view, ExpandableNotificationRow row) { + protected NotificationViewWrapper(Context ctx, View view, ExpandableNotificationRow row) { mView = view; mRow = row; + mDozer = createDozer(ctx); + } + + protected NotificationDozeHelper createDozer(Context ctx) { + return new NotificationIconDozeHelper(mView.getContext()); + } + + protected NotificationDozeHelper getDozer() { + return mDozer; } /** @@ -112,26 +114,6 @@ public abstract class NotificationViewWrapper implements TransformableView { || ColorUtils.calculateLuminance(backgroundColor) > 0.5; } - - protected void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener, - boolean dark, long delay, Animator.AnimatorListener listener) { - float startIntensity = dark ? 0f : 1f; - float endIntensity = dark ? 1f : 0f; - ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity); - animator.addUpdateListener(updateListener); - animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); - animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); - animator.setStartDelay(delay); - if (listener != null) { - animator.addListener(listener); - } - animator.start(); - } - - protected void updateGrayscaleMatrix(float intensity) { - mGrayscaleColorMatrix.setSaturation(1 - intensity); - } - /** * Update the appearance of the expand button. * From 456e005a6dea27a0d29e6a1975c68a9fa71d80a6 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 4 Apr 2017 16:44:29 -0700 Subject: [PATCH 3/4] Revert "Revert "AOD: Use color filter to invert icons for AOD"" This reverts commit 30d9bad7673eaa518cc43444259f71af9b34e5ec. Change-Id: I3a6dd476cb90074d012a05bb291eeaf441fe20d3 Merged-In: I3a6dd476cb90074d012a05bb291eeaf441fe20d3 --- .../systemui/statusbar/NotificationShelf.java | 8 +---- .../systemui/statusbar/StatusBarIconView.java | 31 +++++++++++++++++-- .../notification/NotificationDozeHelper.java | 12 +++++++ .../phone/NotificationIconContainer.java | 18 ++++++++--- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 8ba4eb57f079d..24cf794ddc4a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -23,7 +23,6 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; -import com.android.internal.widget.CachingIconView; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; @@ -127,12 +126,7 @@ public class NotificationShelf extends ActivatableNotificationView implements super.setDark(dark, fade, delay); if (mDark == dark) return; mDark = dark; - if (fade) { - mViewInvertHelper.fade(dark, delay); - } else { - mViewInvertHelper.update(dark); - } - mShelfIcons.setAmbient(dark); + mShelfIcons.setDark(dark, fade, delay); updateInteractiveness(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 1101701942943..ffc4e8d2f0187 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -27,6 +27,7 @@ import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -46,6 +47,7 @@ import android.view.animation.Interpolator; import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.statusbar.notification.NotificationIconDozeHelper; import com.android.systemui.statusbar.notification.NotificationUtils; import java.text.NumberFormat; @@ -99,7 +101,6 @@ public class StatusBarIconView extends AnimatedImageView { private int mDensity; private float mIconScale = 1.0f; private final Paint mDotPaint = new Paint(); - private boolean mDotVisible; private float mDotRadius; private int mStaticDotRadius; private int mVisibleState = STATE_ICON; @@ -110,6 +111,8 @@ public class StatusBarIconView extends AnimatedImageView { private OnVisibilityChangedListener mOnVisibilityChangedListener; private int mDrawableColor; private int mIconColor; + private int mDecorColor; + private float mDarkAmount; private ValueAnimator mColorAnimator; private int mCurrentSetColor = NO_COLOR; private int mAnimationStartColor = NO_COLOR; @@ -119,6 +122,7 @@ public class StatusBarIconView extends AnimatedImageView { animation.getAnimatedFraction()); setColorInternal(newColor); }; + private final NotificationIconDozeHelper mDozer; public StatusBarIconView(Context context, String slot, Notification notification) { this(context, slot, notification, false); @@ -127,6 +131,7 @@ public class StatusBarIconView extends AnimatedImageView { public StatusBarIconView(Context context, String slot, Notification notification, boolean blocked) { super(context); + mDozer = new NotificationIconDozeHelper(context); mBlocked = blocked; mSlot = slot; mNumberPain = new Paint(); @@ -190,6 +195,7 @@ public class StatusBarIconView extends AnimatedImageView { public StatusBarIconView(Context context, AttributeSet attrs) { super(context, attrs); + mDozer = new NotificationIconDozeHelper(context); mBlocked = false; mAlwaysScaleIcon = true; updateIconScale(); @@ -466,7 +472,19 @@ public class StatusBarIconView extends AnimatedImageView { * to the drawable. */ public void setDecorColor(int iconTint) { - mDotPaint.setColor(iconTint); + mDecorColor = iconTint; + updateDecorColor(); + } + + private void updateDecorColor() { + int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDarkAmount); + if (mDotPaint.getColor() != color) { + mDotPaint.setColor(color); + + if (mDotAppearAmount != 0) { + invalidate(); + } + } } /** @@ -477,6 +495,7 @@ public class StatusBarIconView extends AnimatedImageView { mDrawableColor = color; setColorInternal(color); mIconColor = color; + mDozer.setColor(color); } private void setColorInternal(int color) { @@ -649,6 +668,14 @@ public class StatusBarIconView extends AnimatedImageView { mOnVisibilityChangedListener = listener; } + public void setDark(boolean dark, boolean fade, long delay) { + mDozer.setImageDark(this, dark, fade, delay, mIconColor != NO_COLOR); + mDozer.setIntensityDark(f -> { + mDarkAmount = f; + updateDecorColor(); + }, dark, fade, delay); + } + public interface OnVisibilityChangedListener { void onVisibilityChanged(int newVisibility); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java index 09efec61aa4fe..d592c5f5b7f37 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java @@ -26,6 +26,8 @@ import android.widget.ImageView; import com.android.systemui.Interpolators; import com.android.systemui.statusbar.phone.NotificationPanelView; +import java.util.function.Consumer; + public class NotificationDozeHelper { private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); @@ -70,6 +72,16 @@ public class NotificationDozeHelper { animator.start(); } + public void setIntensityDark(Consumer listener, boolean dark, + boolean animate, long delay) { + if (animate) { + startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay, + null /* listener */); + } else { + listener.accept(dark ? 1f : 0f); + } + } + public void updateGrayscaleMatrix(float intensity) { mGrayscaleColorMatrix.setSaturation(1 - intensity); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index 3706dc8242b93..dee15d8163a66 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -95,7 +95,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { private int mActualLayoutWidth = NO_VALUE; private float mActualPaddingEnd = NO_VALUE; private float mActualPaddingStart = NO_VALUE; - private boolean mCentered; + private boolean mDark; private boolean mChangingViewPositions; private int mAddAnimationStartIndex = -1; private int mCannedAnimationStartIndex = -1; @@ -183,6 +183,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { mAddAnimationStartIndex = Math.min(mAddAnimationStartIndex, childIndex); } } + if (mDark && child instanceof StatusBarIconView) { + ((StatusBarIconView) child).setDark(mDark, false, 0); + } } @Override @@ -312,7 +315,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { numDots++; } } - if (mCentered && translationX < getLayoutEnd()) { + boolean center = mDark; + if (center && translationX < getLayoutEnd()) { float delta = (getLayoutEnd() - translationX) / 2; for (int i = 0; i < childCount; i++) { View view = getChildAt(i); @@ -390,9 +394,15 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { mChangingViewPositions = changingViewPositions; } - public void setAmbient(boolean ambient) { - mCentered = ambient; + public void setDark(boolean dark, boolean fade, long delay) { + mDark = dark; mDisallowNextAnimation = true; + for (int i = 0; i < getChildCount(); i++) { + View view = getChildAt(i); + if (view instanceof StatusBarIconView) { + ((StatusBarIconView) view).setDark(dark, fade, delay); + } + } } public IconState getIconState(StatusBarIconView icon) { From 7c68e29171dca0cb2a914a9c701707d5c562cb03 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 4 Apr 2017 17:22:03 -0700 Subject: [PATCH 4/4] NotificationViewWrapper: Fix crash for custom views Bug: 36430936 Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java Change-Id: Ibdf9cf90fcb69a8af8a3b60596143e3be83fe46e Merged-In: Ibdf9cf90fcb69a8af8a3b60596143e3be83fe46e --- .../systemui/statusbar/StatusBarIconView.java | 2 +- .../notification/NotificationViewWrapper.java | 2 +- .../NotificationViewWrapperTest.java | 51 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index ffc4e8d2f0187..8b925a7cdfc53 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -669,7 +669,7 @@ public class StatusBarIconView extends AnimatedImageView { } public void setDark(boolean dark, boolean fade, long delay) { - mDozer.setImageDark(this, dark, fade, delay, mIconColor != NO_COLOR); + mDozer.setImageDark(this, dark, fade, delay, mIconColor == NO_COLOR); mDozer.setIntensityDark(f -> { mDarkAmount = f; updateDecorColor(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java index c86616bc31ed0..f4db9a1977f3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java @@ -69,7 +69,7 @@ public abstract class NotificationViewWrapper implements TransformableView { } protected NotificationDozeHelper createDozer(Context ctx) { - return new NotificationIconDozeHelper(mView.getContext()); + return new NotificationDozeHelper(); } protected NotificationDozeHelper getDozer() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java new file mode 100644 index 0000000000000..a69de7a682913 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 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.systemui.statusbar.notification; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import com.android.systemui.statusbar.ExpandableNotificationRow; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class NotificationViewWrapperTest { + + private Context mContext; + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getTargetContext(); + } + + @Test + public void constructor_doesntUseViewContext() throws Exception { + new TestableNotificationViewWrapper(mContext, new View(null /* context */), null /* row */); + } + + static class TestableNotificationViewWrapper extends NotificationViewWrapper { + protected TestableNotificationViewWrapper(Context ctx, View view, + ExpandableNotificationRow row) { + super(ctx, view, row); + } + } +} \ No newline at end of file