diff options
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java new file mode 100644 index 0000000..8dc14b0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2014 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.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; + +/** + * Wraps a notification view inflated from a template. + */ +public class NotificationTemplateViewWrapper extends NotificationViewWrapper { + + private final ViewInvertHelper mInvertHelper; + private final ImageView mIcon; + protected final ImageView mPicture; + private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); + private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( + 0, PorterDuff.Mode.SRC_ATOP); + private final int mIconDarkAlpha; + private final int mIconBackgroundColor; + private final int mIconBackgroundDarkColor; + private final Interpolator mLinearOutSlowInInterpolator; + + private boolean mDark; + + protected NotificationTemplateViewWrapper(Context ctx, View view) { + super(view); + mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); + mIconBackgroundDarkColor = + ctx.getResources().getColor(R.color.doze_small_icon_background_color); + mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, + android.R.interpolator.linear_out_slow_in); + View mainColumn = view.findViewById(com.android.internal.R.id.notification_main_column); + mInvertHelper = mainColumn != null + ? new ViewInvertHelper(mainColumn, NotificationPanelView.DOZE_ANIMATION_DURATION) + : null; + ImageView largeIcon = (ImageView) view.findViewById(com.android.internal.R.id.icon); + ImageView rightIcon = (ImageView) view.findViewById(com.android.internal.R.id.right_icon); + mIcon = resolveIcon(largeIcon, rightIcon); + mPicture = resolvePicture(largeIcon); + mIconBackgroundColor = resolveBackgroundColor(mIcon); + } + + private ImageView resolveIcon(ImageView largeIcon, ImageView rightIcon) { + return largeIcon != null && largeIcon.getBackground() != null ? largeIcon + : rightIcon != null && rightIcon.getBackground() != null ? rightIcon + : null; + } + + private ImageView resolvePicture(ImageView largeIcon) { + return largeIcon != null && largeIcon.getBackground() == null + ? largeIcon + : null; + } + + private int resolveBackgroundColor(ImageView icon) { + if (icon != null && icon.getBackground() != null) { + ColorFilter filter = icon.getBackground().getColorFilter(); + if (filter instanceof PorterDuffColorFilter) { + return ((PorterDuffColorFilter) filter).getColor(); + } + } + return 0; + } + + @Override + public void setDark(boolean dark, boolean fade, long delay) { + if (mDark != dark) { + mDark = dark; + if (mInvertHelper != null) { + if (fade) { + mInvertHelper.fade(dark, delay); + } else { + mInvertHelper.update(dark); + } + } + if (mIcon != null) { + if (fade) { + fadeIconColorFilter(mIcon, dark, delay); + fadeIconAlpha(mIcon, dark, delay); + } else { + updateIconColorFilter(mIcon, dark); + updateIconAlpha(mIcon, dark); + } + } + setPictureGrayscale(dark, fade, delay); + } + } + + protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) { + if (mPicture != null) { + if (fade) { + fadeGrayscale(mPicture, grayscale, delay); + } else { + updateGrayscale(mPicture, grayscale); + } + } + } + + 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(mIconBackgroundColor, mIconBackgroundDarkColor, intensity); + mIconColorFilter.setColor(color); + target.getBackground().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); + } + } + + 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)); + } +} |