Loading packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java +24 −8 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; Loading @@ -35,13 +36,19 @@ public class ViewInvertHelper { private final Paint mDarkPaint = new Paint(); private final Interpolator mLinearOutSlowInInterpolator; private final ArrayList<View> mTargets; private final ColorMatrix mMatrix = new ColorMatrix(); private final ColorMatrix mGrayscaleMatrix = new ColorMatrix(); private final long mFadeDuration; private final ArrayList<View> mTargets = new ArrayList<>(); public ViewInvertHelper(View target, long fadeDuration) { this(constructArray(target), fadeDuration); public ViewInvertHelper(View v, long fadeDuration) { this(v.getContext(), fadeDuration); addTarget(v); } public ViewInvertHelper(Context context, long fadeDuration) { mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); mFadeDuration = fadeDuration; } private static ArrayList<View> constructArray(View target) { Loading @@ -50,11 +57,12 @@ public class ViewInvertHelper { return views; } public ViewInvertHelper(ArrayList<View> targets, long fadeDuration) { mTargets = targets; mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTargets.get(0).getContext(), android.R.interpolator.linear_out_slow_in); mFadeDuration = fadeDuration; public void clearTargets() { mTargets.clear(); } public void addTarget(View target) { mTargets.add(target); } public void fade(final boolean invert, long delay) { Loading Loading @@ -112,4 +120,12 @@ public class ViewInvertHelper { mMatrix.preConcat(mGrayscaleMatrix); mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix)); } public void setInverted(boolean invert, boolean fade, long delay) { if (fade) { fade(invert, delay); } else { update(invert); } } } No newline at end of file packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private boolean mIsHeadsUp; private boolean mLastChronometerRunning = true; private NotificationHeaderView mNotificationHeader; private NotificationViewWrapper mNotificationHeaderWrapper; private ViewStub mChildrenContainerStub; private NotificationGroupManager mGroupManager; private boolean mChildrenExpanded; Loading Loading @@ -570,6 +571,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { if (showing != null) { showing.setDark(dark, fade, delay); } if (mIsSummaryWithChildren) { mChildrenContainer.setDark(dark, fade, delay); mNotificationHeaderWrapper.setDark(dark, fade, delay); } } public boolean isExpandable() { Loading Loading @@ -967,9 +972,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { com.android.internal.R.id.expand_button); expandButton.setVisibility(VISIBLE); mNotificationHeader.setOnClickListener(mExpandClickListener); mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(), mNotificationHeader); addView(mNotificationHeader); } else { header.reapply(getContext(), mNotificationHeader); mNotificationHeaderWrapper.notifyContentUpdated(); } updateHeaderExpandButton(); updateChildrenHeaderAppearance(); Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +3 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,9 @@ public class NotificationContentView extends FrameLayout { if (mDark == dark || mContractedChild == null) return; mDark = dark; mContractedWrapper.setDark(dark && !mShowingLegacyBackground, fade, delay); if (mSingleLineView != null) { mSingleLineView.setDark(dark, fade, delay); } } public void setHeadsUp(boolean headsUp) { Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderViewWrapper.java 0 → 100644 +239 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.view.NotificationHeaderView; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; import java.util.ArrayList; /** * Wraps a notification header view. */ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( 0, PorterDuff.Mode.SRC_ATOP); private final int mIconDarkAlpha; private final int mIconDarkColor = 0xffffffff; protected final Interpolator mLinearOutSlowInInterpolator; protected final ViewInvertHelper mInvertHelper; protected int mColor; private ImageView mIcon; private ImageView mExpandButton; private NotificationHeaderView mNotificationHeader; protected NotificationHeaderViewWrapper(Context ctx, View view) { super(view); mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in); mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION); resolveHeaderViews(); } protected void resolveHeaderViews() { mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button); mColor = resolveColor(mExpandButton); mNotificationHeader = (NotificationHeaderView) mView.findViewById( com.android.internal.R.id.notification_header); for (int i = 0; i < mNotificationHeader.getChildCount(); i++) { View child = mNotificationHeader.getChildAt(i); if (child != mIcon) { mInvertHelper.addTarget(child); } } } private int resolveColor(ImageView icon) { if (icon != null && icon.getDrawable() != null) { ColorFilter filter = icon.getDrawable().getColorFilter(); if (filter instanceof PorterDuffColorFilter) { return ((PorterDuffColorFilter) filter).getColor(); } } return 0; } @Override public void notifyContentUpdated() { mInvertHelper.clearTargets(); // Reinspect the notification. resolveHeaderViews(); } @Override public void setDark(boolean dark, boolean fade, long delay) { if (fade) { mInvertHelper.fade(dark, delay); } else { mInvertHelper.update(dark); } if (mIcon != null) { 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); } } } } 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(mLinearOutSlowInInterpolator); animator.setStartDelay(delay); if (listener != null) { animator.addListener(listener); } animator.start(); } 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) { iconDrawable.mutate().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); } } @Override public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) { mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE); mNotificationHeader.setOnClickListener(expandable ? onClickListener : null); } private void updateGrayscaleMatrix(float intensity) { mGrayscaleColorMatrix.setSaturation(1 - intensity); } 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; } } packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java +8 −192 Original line number Diff line number Diff line Loading @@ -16,74 +16,31 @@ package com.android.systemui.statusbar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.MotionEvent; import android.view.NotificationHeaderView; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; import java.util.ArrayList; /** * Wraps a notification view inflated from a template. */ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper { private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( 0, PorterDuff.Mode.SRC_ATOP); private final int mIconDarkAlpha; private final int mIconDarkColor = 0xffffffff; private final int mDarkProgressTint = 0xffffffff; private final Interpolator mLinearOutSlowInInterpolator; private static final int mDarkProgressTint = 0xffffffff; private int mColor; private ViewInvertHelper mInvertHelper; private ImageView mIcon; protected ImageView mPicture; private ImageView mExpandButton; private NotificationHeaderView mNotificationHeader; private ProgressBar mProgressBar; protected NotificationTemplateViewWrapper(Context ctx, View view) { super(view); mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in); resolveViews(); super(ctx, view); resolveTemplateViews(); } private void resolveViews() { private void resolveTemplateViews() { View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column); mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); mPicture = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon); mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button); mColor = resolveColor(mExpandButton); final View progress = mView.findViewById(com.android.internal.R.id.progress); if (progress instanceof ProgressBar) { mProgressBar = (ProgressBar) progress; Loading @@ -91,68 +48,22 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { // It's still a viewstub mProgressBar = null; } mNotificationHeader = (NotificationHeaderView) mView.findViewById( com.android.internal.R.id.notification_header); ArrayList<View> viewsToInvert = new ArrayList<>(); if (mainColumn != null) { viewsToInvert.add(mainColumn); } for (int i = 0; i < mNotificationHeader.getChildCount(); i++) { View child = mNotificationHeader.getChildAt(i); if (child != mIcon) { viewsToInvert.add(child); } } mInvertHelper = new ViewInvertHelper(viewsToInvert, NotificationPanelView.DOZE_ANIMATION_DURATION); } private int resolveColor(ImageView icon) { if (icon != null && icon.getDrawable() != null) { ColorFilter filter = icon.getDrawable().getColorFilter(); if (filter instanceof PorterDuffColorFilter) { return ((PorterDuffColorFilter) filter).getColor(); mInvertHelper.addTarget(mainColumn); } } return 0; } @Override public void notifyContentUpdated() { super.notifyContentUpdated(); // Reinspect the notification. resolveViews(); resolveTemplateViews(); } @Override public void setDark(boolean dark, boolean fade, long delay) { if (mInvertHelper != null) { if (fade) { mInvertHelper.fade(dark, delay); } else { mInvertHelper.update(dark); } } if (mIcon != null) { 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); } } } super.setDark(dark, fade, delay); setPictureGrayscale(dark, fade, delay); setProgressBarDark(dark, fade, delay); } Loading Loading @@ -197,96 +108,6 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { } } private 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(mLinearOutSlowInInterpolator); animator.setStartDelay(delay); if (listener != null) { animator.addListener(listener); } animator.start(); } 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) { iconDrawable.mutate().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); } } @Override public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) { mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE); mNotificationHeader.setOnClickListener(expandable ? onClickListener : null); } private void updateGrayscaleMatrix(float intensity) { mGrayscaleColorMatrix.setSaturation(1 - intensity); } private static int interpolateColor(int source, int target, float t) { int aSource = Color.alpha(source); int rSource = Color.red(source); Loading @@ -302,9 +123,4 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { (int) (gSource * (1f - t) + gTarget * t), (int) (bSource * (1f - t) + bTarget * t)); } @Override public NotificationHeaderView getNotificationHeader() { return mNotificationHeader; } } Loading
packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java +24 −8 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; Loading @@ -35,13 +36,19 @@ public class ViewInvertHelper { private final Paint mDarkPaint = new Paint(); private final Interpolator mLinearOutSlowInInterpolator; private final ArrayList<View> mTargets; private final ColorMatrix mMatrix = new ColorMatrix(); private final ColorMatrix mGrayscaleMatrix = new ColorMatrix(); private final long mFadeDuration; private final ArrayList<View> mTargets = new ArrayList<>(); public ViewInvertHelper(View target, long fadeDuration) { this(constructArray(target), fadeDuration); public ViewInvertHelper(View v, long fadeDuration) { this(v.getContext(), fadeDuration); addTarget(v); } public ViewInvertHelper(Context context, long fadeDuration) { mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); mFadeDuration = fadeDuration; } private static ArrayList<View> constructArray(View target) { Loading @@ -50,11 +57,12 @@ public class ViewInvertHelper { return views; } public ViewInvertHelper(ArrayList<View> targets, long fadeDuration) { mTargets = targets; mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTargets.get(0).getContext(), android.R.interpolator.linear_out_slow_in); mFadeDuration = fadeDuration; public void clearTargets() { mTargets.clear(); } public void addTarget(View target) { mTargets.add(target); } public void fade(final boolean invert, long delay) { Loading Loading @@ -112,4 +120,12 @@ public class ViewInvertHelper { mMatrix.preConcat(mGrayscaleMatrix); mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix)); } public void setInverted(boolean invert, boolean fade, long delay) { if (fade) { fade(invert, delay); } else { update(invert); } } } No newline at end of file
packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private boolean mIsHeadsUp; private boolean mLastChronometerRunning = true; private NotificationHeaderView mNotificationHeader; private NotificationViewWrapper mNotificationHeaderWrapper; private ViewStub mChildrenContainerStub; private NotificationGroupManager mGroupManager; private boolean mChildrenExpanded; Loading Loading @@ -570,6 +571,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { if (showing != null) { showing.setDark(dark, fade, delay); } if (mIsSummaryWithChildren) { mChildrenContainer.setDark(dark, fade, delay); mNotificationHeaderWrapper.setDark(dark, fade, delay); } } public boolean isExpandable() { Loading Loading @@ -967,9 +972,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { com.android.internal.R.id.expand_button); expandButton.setVisibility(VISIBLE); mNotificationHeader.setOnClickListener(mExpandClickListener); mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(), mNotificationHeader); addView(mNotificationHeader); } else { header.reapply(getContext(), mNotificationHeader); mNotificationHeaderWrapper.notifyContentUpdated(); } updateHeaderExpandButton(); updateChildrenHeaderAppearance(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +3 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,9 @@ public class NotificationContentView extends FrameLayout { if (mDark == dark || mContractedChild == null) return; mDark = dark; mContractedWrapper.setDark(dark && !mShowingLegacyBackground, fade, delay); if (mSingleLineView != null) { mSingleLineView.setDark(dark, fade, delay); } } public void setHeadsUp(boolean headsUp) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderViewWrapper.java 0 → 100644 +239 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.view.NotificationHeaderView; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; import java.util.ArrayList; /** * Wraps a notification header view. */ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( 0, PorterDuff.Mode.SRC_ATOP); private final int mIconDarkAlpha; private final int mIconDarkColor = 0xffffffff; protected final Interpolator mLinearOutSlowInInterpolator; protected final ViewInvertHelper mInvertHelper; protected int mColor; private ImageView mIcon; private ImageView mExpandButton; private NotificationHeaderView mNotificationHeader; protected NotificationHeaderViewWrapper(Context ctx, View view) { super(view); mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in); mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION); resolveHeaderViews(); } protected void resolveHeaderViews() { mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button); mColor = resolveColor(mExpandButton); mNotificationHeader = (NotificationHeaderView) mView.findViewById( com.android.internal.R.id.notification_header); for (int i = 0; i < mNotificationHeader.getChildCount(); i++) { View child = mNotificationHeader.getChildAt(i); if (child != mIcon) { mInvertHelper.addTarget(child); } } } private int resolveColor(ImageView icon) { if (icon != null && icon.getDrawable() != null) { ColorFilter filter = icon.getDrawable().getColorFilter(); if (filter instanceof PorterDuffColorFilter) { return ((PorterDuffColorFilter) filter).getColor(); } } return 0; } @Override public void notifyContentUpdated() { mInvertHelper.clearTargets(); // Reinspect the notification. resolveHeaderViews(); } @Override public void setDark(boolean dark, boolean fade, long delay) { if (fade) { mInvertHelper.fade(dark, delay); } else { mInvertHelper.update(dark); } if (mIcon != null) { 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); } } } } 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(mLinearOutSlowInInterpolator); animator.setStartDelay(delay); if (listener != null) { animator.addListener(listener); } animator.start(); } 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) { iconDrawable.mutate().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); } } @Override public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) { mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE); mNotificationHeader.setOnClickListener(expandable ? onClickListener : null); } private void updateGrayscaleMatrix(float intensity) { mGrayscaleColorMatrix.setSaturation(1 - intensity); } 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; } }
packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java +8 −192 Original line number Diff line number Diff line Loading @@ -16,74 +16,31 @@ package com.android.systemui.statusbar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.MotionEvent; import android.view.NotificationHeaderView; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; import java.util.ArrayList; /** * Wraps a notification view inflated from a template. */ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper { private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( 0, PorterDuff.Mode.SRC_ATOP); private final int mIconDarkAlpha; private final int mIconDarkColor = 0xffffffff; private final int mDarkProgressTint = 0xffffffff; private final Interpolator mLinearOutSlowInInterpolator; private static final int mDarkProgressTint = 0xffffffff; private int mColor; private ViewInvertHelper mInvertHelper; private ImageView mIcon; protected ImageView mPicture; private ImageView mExpandButton; private NotificationHeaderView mNotificationHeader; private ProgressBar mProgressBar; protected NotificationTemplateViewWrapper(Context ctx, View view) { super(view); mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in); resolveViews(); super(ctx, view); resolveTemplateViews(); } private void resolveViews() { private void resolveTemplateViews() { View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column); mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); mPicture = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon); mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button); mColor = resolveColor(mExpandButton); final View progress = mView.findViewById(com.android.internal.R.id.progress); if (progress instanceof ProgressBar) { mProgressBar = (ProgressBar) progress; Loading @@ -91,68 +48,22 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { // It's still a viewstub mProgressBar = null; } mNotificationHeader = (NotificationHeaderView) mView.findViewById( com.android.internal.R.id.notification_header); ArrayList<View> viewsToInvert = new ArrayList<>(); if (mainColumn != null) { viewsToInvert.add(mainColumn); } for (int i = 0; i < mNotificationHeader.getChildCount(); i++) { View child = mNotificationHeader.getChildAt(i); if (child != mIcon) { viewsToInvert.add(child); } } mInvertHelper = new ViewInvertHelper(viewsToInvert, NotificationPanelView.DOZE_ANIMATION_DURATION); } private int resolveColor(ImageView icon) { if (icon != null && icon.getDrawable() != null) { ColorFilter filter = icon.getDrawable().getColorFilter(); if (filter instanceof PorterDuffColorFilter) { return ((PorterDuffColorFilter) filter).getColor(); mInvertHelper.addTarget(mainColumn); } } return 0; } @Override public void notifyContentUpdated() { super.notifyContentUpdated(); // Reinspect the notification. resolveViews(); resolveTemplateViews(); } @Override public void setDark(boolean dark, boolean fade, long delay) { if (mInvertHelper != null) { if (fade) { mInvertHelper.fade(dark, delay); } else { mInvertHelper.update(dark); } } if (mIcon != null) { 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); } } } super.setDark(dark, fade, delay); setPictureGrayscale(dark, fade, delay); setProgressBarDark(dark, fade, delay); } Loading Loading @@ -197,96 +108,6 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { } } private 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(mLinearOutSlowInInterpolator); animator.setStartDelay(delay); if (listener != null) { animator.addListener(listener); } animator.start(); } 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) { iconDrawable.mutate().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); } } @Override public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) { mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE); mNotificationHeader.setOnClickListener(expandable ? onClickListener : null); } private void updateGrayscaleMatrix(float intensity) { mGrayscaleColorMatrix.setSaturation(1 - intensity); } private static int interpolateColor(int source, int target, float t) { int aSource = Color.alpha(source); int rSource = Color.red(source); Loading @@ -302,9 +123,4 @@ public class NotificationTemplateViewWrapper extends NotificationViewWrapper { (int) (gSource * (1f - t) + gTarget * t), (int) (bSource * (1f - t) + bTarget * t)); } @Override public NotificationHeaderView getNotificationHeader() { return mNotificationHeader; } }