1 /*
2  * Copyright (C) 2017 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 
17 package com.android.systemui.statusbar.notification;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorListenerAdapter;
21 import android.animation.ValueAnimator;
22 import android.graphics.ColorMatrix;
23 import android.graphics.ColorMatrixColorFilter;
24 import android.view.View;
25 import android.widget.ImageView;
26 
27 import androidx.annotation.Nullable;
28 
29 import com.android.app.animation.Interpolators;
30 import com.android.systemui.res.R;
31 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
32 
33 import java.util.function.Consumer;
34 
35 public class NotificationDozeHelper {
36     private static final int DOZE_ANIMATOR_TAG = R.id.doze_intensity_tag;
37     private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
38 
updateGrayscale(ImageView target, float darkAmount)39     public void updateGrayscale(ImageView target, float darkAmount) {
40         if (darkAmount > 0) {
41             updateGrayscaleMatrix(darkAmount);
42             target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
43         } else {
44             target.setColorFilter(null);
45         }
46     }
47 
48     // TODO: this should be using StatusBarStateController#getDozeAmount
startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener, boolean dark, long delay, Animator.AnimatorListener listener)49     private void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
50             boolean dark, long delay, Animator.AnimatorListener listener) {
51         float startIntensity = dark ? 0f : 1f;
52         float endIntensity = dark ? 1f : 0f;
53         ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
54         animator.addUpdateListener(updateListener);
55         animator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
56         animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
57         animator.setStartDelay(delay);
58         if (listener != null) {
59             animator.addListener(listener);
60         }
61         animator.start();
62     }
63 
setDozing(Consumer<Float> listener, boolean dozing, boolean animate, long delay, View view, @Nullable Runnable endRunnable)64     public void setDozing(Consumer<Float> listener, boolean dozing,
65             boolean animate, long delay, View view, @Nullable Runnable endRunnable) {
66         if (animate) {
67             startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dozing,
68                     delay,
69                     new AnimatorListenerAdapter() {
70 
71                         @Override
72                         public void onAnimationEnd(Animator animation) {
73                             view.setTag(DOZE_ANIMATOR_TAG, null);
74                             if (endRunnable != null) {
75                                 endRunnable.run();
76                             }
77                         }
78 
79                         @Override
80                         public void onAnimationStart(Animator animation) {
81                             view.setTag(DOZE_ANIMATOR_TAG, animation);
82                         }
83                     } /* listener */);
84         } else {
85             Animator animator = (Animator) view.getTag(DOZE_ANIMATOR_TAG);
86             if (animator != null) {
87                 animator.cancel();
88             }
89             listener.accept(dozing ? 1f : 0f);
90             if (endRunnable != null) {
91                 endRunnable.run();
92             }
93         }
94     }
95 
updateGrayscaleMatrix(float intensity)96     private void updateGrayscaleMatrix(float intensity) {
97         mGrayscaleColorMatrix.setSaturation(1 - intensity);
98     }
99 }
100