Merge changes Ibdf9cf90,I3a6dd476,Id4008fc7,Iede88d1e into oc-dev

* changes:
  NotificationViewWrapper: Fix crash for custom views
  Revert "Revert "AOD: Use color filter to invert icons for AOD""
  Revert "Revert "NotificationWrappers: Factor out doze treatment""
  AOD: prevent clicking shelf when dark
This commit is contained in:
TreeHugger Robot
2017-04-05 20:30:15 +00:00
committed by Android (Google) Code Review
10 changed files with 343 additions and 189 deletions

View File

@@ -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,8 @@ 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();
}
@Override
@@ -576,7 +571,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

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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;
import java.util.function.Consumer;
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 setIntensityDark(Consumer<Float> 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);
}
public ColorMatrix getGrayscaleColorMatrix() {
return mGrayscaleColorMatrix;
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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 */);
}
}

View File

@@ -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 NotificationDozeHelper();
}
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.
*

View File

@@ -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) {

View File

@@ -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);
}
}
}