blob: 78e23fce1a3ea5830f3c5dc118d2506059a7281d [file] [log] [blame]
Jorim Jaggi4e857f42014-11-17 19:14:04 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Selim Cinek0ffbda62016-01-01 20:29:12 +010017package com.android.systemui.statusbar.notification;
Jorim Jaggi4e857f42014-11-17 19:14:04 +010018
Jorim Jaggi4e857f42014-11-17 19:14:04 +010019import android.animation.ValueAnimator;
20import android.content.Context;
21import android.graphics.Color;
Selim Cinek4ffd6362015-12-29 15:12:23 +010022import android.service.notification.StatusBarNotification;
Jorim Jaggi4e857f42014-11-17 19:14:04 +010023import android.view.View;
Jorim Jaggi4e857f42014-11-17 19:14:04 +010024import android.widget.ImageView;
Selim Cinek75fe38c2015-11-20 12:47:59 -080025import android.widget.ProgressBar;
Selim Cinek4ffd6362015-12-29 15:12:23 +010026import android.widget.TextView;
27
Winsonc0d70582016-01-29 10:24:39 -080028import com.android.systemui.Interpolators;
Selim Cinekfd3e2622016-01-12 16:02:42 -080029import com.android.systemui.statusbar.CrossFadeHelper;
Selim Cinek0ffbda62016-01-01 20:29:12 +010030import com.android.systemui.statusbar.TransformableView;
Selim Cinekfd3e2622016-01-12 16:02:42 -080031import com.android.systemui.statusbar.ViewTransformationHelper;
Selim Cinek99695592016-01-12 17:51:35 -080032import com.android.systemui.statusbar.stack.StackStateAnimator;
Selim Cinek65b2e7c2015-10-26 14:11:31 -070033
Jorim Jaggi4e857f42014-11-17 19:14:04 +010034/**
35 * Wraps a notification view inflated from a template.
36 */
Selim Cinek9c7712d2015-12-08 19:19:48 -080037public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper {
Jorim Jaggi4e857f42014-11-17 19:14:04 +010038
Selim Cinek9c7712d2015-12-08 19:19:48 -080039 private static final int mDarkProgressTint = 0xffffffff;
Jorim Jaggi4e857f42014-11-17 19:14:04 +010040
Jorim Jaggidacc9242014-12-08 19:21:26 +010041 protected ImageView mPicture;
Selim Cinek75fe38c2015-11-20 12:47:59 -080042 private ProgressBar mProgressBar;
Selim Cinek4ffd6362015-12-29 15:12:23 +010043 private TextView mTitle;
44 private TextView mText;
Jorim Jaggi92df1f22014-12-16 19:44:41 +010045
Jorim Jaggi4e857f42014-11-17 19:14:04 +010046 protected NotificationTemplateViewWrapper(Context ctx, View view) {
Selim Cinek9c7712d2015-12-08 19:19:48 -080047 super(ctx, view);
Selim Cinekfd3e2622016-01-12 16:02:42 -080048 mTransformationHelper.setCustomTransformation(
49 new ViewTransformationHelper.CustomTransformation() {
50 @Override
51 public boolean transformTo(TransformState ownState,
Selim Cinek8f2f6a62016-02-23 19:56:31 -080052 TransformableView notification, final float transformationAmount) {
Selim Cinekfd3e2622016-01-12 16:02:42 -080053 if (!(notification instanceof HybridNotificationView)) {
54 return false;
55 }
56 TransformState otherState = notification.getCurrentState(
57 TRANSFORMING_VIEW_TITLE);
Selim Cinekb66685b2016-02-02 17:16:08 -080058 final View text = ownState.getTransformedView();
Selim Cinek8f2f6a62016-02-23 19:56:31 -080059 CrossFadeHelper.fadeOut(text, transformationAmount);
Selim Cinekfd3e2622016-01-12 16:02:42 -080060 if (otherState != null) {
Selim Cinek8f2f6a62016-02-23 19:56:31 -080061 ownState.transformViewVerticalTo(otherState, this,
62 transformationAmount);
Selim Cinekfd3e2622016-01-12 16:02:42 -080063 otherState.recycle();
64 }
65 return true;
66 }
67
68 @Override
Selim Cinek8f2f6a62016-02-23 19:56:31 -080069 public boolean customTransformTarget(TransformState ownState,
70 TransformState otherState) {
71 float endY = getTransformationY(ownState, otherState);
72 ownState.setTransformationEndY(endY);
73 return true;
74 }
75
76 @Override
Selim Cinekfd3e2622016-01-12 16:02:42 -080077 public boolean transformFrom(TransformState ownState,
Selim Cinek8f2f6a62016-02-23 19:56:31 -080078 TransformableView notification, float transformationAmount) {
Selim Cinekfd3e2622016-01-12 16:02:42 -080079 if (!(notification instanceof HybridNotificationView)) {
80 return false;
81 }
82 TransformState otherState = notification.getCurrentState(
83 TRANSFORMING_VIEW_TITLE);
Selim Cinekb66685b2016-02-02 17:16:08 -080084 final View text = ownState.getTransformedView();
Selim Cinek8f2f6a62016-02-23 19:56:31 -080085 CrossFadeHelper.fadeIn(text, transformationAmount);
Selim Cinekfd3e2622016-01-12 16:02:42 -080086 if (otherState != null) {
Selim Cinek8f2f6a62016-02-23 19:56:31 -080087 ownState.transformViewVerticalFrom(otherState, this,
88 transformationAmount);
Selim Cinekfd3e2622016-01-12 16:02:42 -080089 otherState.recycle();
90 }
91 return true;
92 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -080093
94 @Override
95 public boolean initTransformation(TransformState ownState,
96 TransformState otherState) {
97 float startY = getTransformationY(ownState, otherState);
98 ownState.setTransformationStartY(startY);
99 return true;
100 }
101
102 private float getTransformationY(TransformState ownState,
103 TransformState otherState) {
104 int[] otherStablePosition = otherState.getLaidOutLocationOnScreen();
105 int[] ownStablePosition = ownState.getLaidOutLocationOnScreen();
106 return (otherStablePosition[1]
107 + otherState.getTransformedView().getHeight()
108 - ownStablePosition[1]) * 0.33f;
109 }
110
Selim Cinekfd3e2622016-01-12 16:02:42 -0800111 }, TRANSFORMING_VIEW_TEXT);
Jorim Jaggidacc9242014-12-08 19:21:26 +0100112 }
113
Selim Cinek4ffd6362015-12-29 15:12:23 +0100114 private void resolveTemplateViews(StatusBarNotification notification) {
Selim Cinek65b2e7c2015-10-26 14:11:31 -0700115 mPicture = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon);
Selim Cinek0ffbda62016-01-01 20:29:12 +0100116 mPicture.setTag(ImageTransformState.ICON_TAG,
117 notification.getNotification().getLargeIcon());
Selim Cinek4ffd6362015-12-29 15:12:23 +0100118 mTitle = (TextView) mView.findViewById(com.android.internal.R.id.title);
119 mText = (TextView) mView.findViewById(com.android.internal.R.id.text);
Selim Cinek75fe38c2015-11-20 12:47:59 -0800120 final View progress = mView.findViewById(com.android.internal.R.id.progress);
121 if (progress instanceof ProgressBar) {
122 mProgressBar = (ProgressBar) progress;
123 } else {
124 // It's still a viewstub
125 mProgressBar = null;
126 }
Selim Cinek4ffd6362015-12-29 15:12:23 +0100127 }
128
129 @Override
130 public void notifyContentUpdated(StatusBarNotification notification) {
Selim Cinek646d2052016-01-03 14:42:02 +0800131 // Reinspect the notification. Before the super call, because the super call also updates
132 // the transformation types and we need to have our values set by then.
Selim Cinek4ffd6362015-12-29 15:12:23 +0100133 resolveTemplateViews(notification);
134 super.notifyContentUpdated(notification);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100135 }
136
137 @Override
138 protected void updateInvertHelper() {
139 super.updateInvertHelper();
140 View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column);
Selim Cinek75fe38c2015-11-20 12:47:59 -0800141 if (mainColumn != null) {
Selim Cinek9c7712d2015-12-08 19:19:48 -0800142 mInvertHelper.addTarget(mainColumn);
Selim Cinek75fe38c2015-11-20 12:47:59 -0800143 }
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100144 }
145
146 @Override
Selim Cinek4ffd6362015-12-29 15:12:23 +0100147 protected void updateTransformedTypes() {
148 // This also clears the existing types
149 super.updateTransformedTypes();
150 if (mTitle != null) {
Selim Cinek0ffbda62016-01-01 20:29:12 +0100151 mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE, mTitle);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100152 }
153 if (mText != null) {
Selim Cinek0ffbda62016-01-01 20:29:12 +0100154 mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT, mText);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100155 }
156 if (mPicture != null) {
Selim Cinek0ffbda62016-01-01 20:29:12 +0100157 mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE, mPicture);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100158 }
159 if (mProgressBar != null) {
Selim Cinek0ffbda62016-01-01 20:29:12 +0100160 mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS, mProgressBar);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100161 }
Jorim Jaggidacc9242014-12-08 19:21:26 +0100162 }
163
164 @Override
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100165 public void setDark(boolean dark, boolean fade, long delay) {
Selim Cinekb88b9842016-02-26 09:25:33 -0800166 if (dark == mDark && mDarkInitialized) {
Selim Cinek19ba7052016-01-27 20:04:27 -0800167 return;
168 }
Selim Cinek9c7712d2015-12-08 19:19:48 -0800169 super.setDark(dark, fade, delay);
Jorim Jaggi394a5d62014-11-26 23:07:13 +0100170 setPictureGrayscale(dark, fade, delay);
Selim Cinek75fe38c2015-11-20 12:47:59 -0800171 setProgressBarDark(dark, fade, delay);
172 }
173
174 private void setProgressBarDark(boolean dark, boolean fade, long delay) {
175 if (mProgressBar != null) {
176 if (fade) {
177 fadeProgressDark(mProgressBar, dark, delay);
178 } else {
179 updateProgressDark(mProgressBar, dark);
180 }
181 }
182 }
183
184 private void fadeProgressDark(final ProgressBar target, final boolean dark, long delay) {
185 startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
186 @Override
187 public void onAnimationUpdate(ValueAnimator animation) {
188 float t = (float) animation.getAnimatedValue();
189 updateProgressDark(target, t);
190 }
191 }, dark, delay, null /* listener */);
192 }
193
194 private void updateProgressDark(ProgressBar target, float intensity) {
195 int color = interpolateColor(mColor, mDarkProgressTint, intensity);
196 target.getIndeterminateDrawable().mutate().setTint(color);
197 target.getProgressDrawable().mutate().setTint(color);
198 }
199
200 private void updateProgressDark(ProgressBar target, boolean dark) {
201 updateProgressDark(target, dark ? 1f : 0f);
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100202 }
203
204 protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) {
205 if (mPicture != null) {
206 if (fade) {
207 fadeGrayscale(mPicture, grayscale, delay);
208 } else {
209 updateGrayscale(mPicture, grayscale);
210 }
211 }
212 }
213
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100214 private static int interpolateColor(int source, int target, float t) {
215 int aSource = Color.alpha(source);
216 int rSource = Color.red(source);
217 int gSource = Color.green(source);
218 int bSource = Color.blue(source);
219 int aTarget = Color.alpha(target);
220 int rTarget = Color.red(target);
221 int gTarget = Color.green(target);
222 int bTarget = Color.blue(target);
223 return Color.argb(
224 (int) (aSource * (1f - t) + aTarget * t),
225 (int) (rSource * (1f - t) + rTarget * t),
226 (int) (gSource * (1f - t) + gTarget * t),
227 (int) (bSource * (1f - t) + bTarget * t));
228 }
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100229}