1 /*
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 
17 package com.android.systemui.statusbar.notification.stack;
18 
19 import android.util.Property;
20 import android.view.View;
21 
22 import androidx.collection.ArraySet;
23 
24 import java.util.ArrayList;
25 
26 /**
27  * Filters the animations for only a certain type of properties.
28  */
29 public class AnimationFilter {
30     public static final int NO_DELAY = -1;
31     boolean animateAlpha;
32     boolean animateX;
33     boolean animateY;
34     ArraySet<View> animateYViews = new ArraySet<>();
35     boolean animateZ;
36     boolean animateHeight;
37     boolean animateTopInset;
38     boolean animateDimmed;
39     boolean animateHideSensitive;
40     boolean hasDelays;
41     boolean hasGoToFullShadeEvent;
42     long customDelay;
43     private ArraySet<Property> mAnimatedProperties = new ArraySet<>();
44 
animateAlpha()45     public AnimationFilter animateAlpha() {
46         animateAlpha = true;
47         return this;
48     }
49 
animateScale()50     public AnimationFilter animateScale() {
51         animate(View.SCALE_X);
52         animate(View.SCALE_Y);
53         return this;
54     }
55 
animateX()56     public AnimationFilter animateX() {
57         animateX = true;
58         return this;
59     }
60 
animateY()61     public AnimationFilter animateY() {
62         animateY = true;
63         return this;
64     }
65 
hasDelays()66     public AnimationFilter hasDelays() {
67         hasDelays = true;
68         return this;
69     }
70 
animateZ()71     public AnimationFilter animateZ() {
72         animateZ = true;
73         return this;
74     }
75 
animateHeight()76     public AnimationFilter animateHeight() {
77         animateHeight = true;
78         return this;
79     }
80 
animateTopInset()81     public AnimationFilter animateTopInset() {
82         animateTopInset = true;
83         return this;
84     }
85 
animateDimmed()86     public AnimationFilter animateDimmed() {
87         animateDimmed = true;
88         return this;
89     }
90 
animateHideSensitive()91     public AnimationFilter animateHideSensitive() {
92         animateHideSensitive = true;
93         return this;
94     }
95 
animateY(View view)96     public AnimationFilter animateY(View view) {
97         animateYViews.add(view);
98         return this;
99     }
100 
shouldAnimateY(View view)101     public boolean shouldAnimateY(View view) {
102         return animateY || animateYViews.contains(view);
103     }
104 
105     /**
106      * Combines multiple filters into {@code this} filter, using or as the operand .
107      *
108      * @param events The animation events from the filters to combine.
109      */
applyCombination(ArrayList<NotificationStackScrollLayout.AnimationEvent> events)110     public void applyCombination(ArrayList<NotificationStackScrollLayout.AnimationEvent> events) {
111         reset();
112         int size = events.size();
113         for (int i = 0; i < size; i++) {
114             NotificationStackScrollLayout.AnimationEvent ev = events.get(i);
115             combineFilter(events.get(i).filter);
116             if (ev.animationType ==
117                     NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
118                 hasGoToFullShadeEvent = true;
119             }
120             if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
121                     .ANIMATION_TYPE_HEADS_UP_DISAPPEAR) {
122                 customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP;
123             } else if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
124                     .ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
125                 // We need both timeouts when clicking, one to delay it and one for the animation
126                 // to look nice
127                 customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP_CLICKED
128                         + StackStateAnimator.ANIMATION_DELAY_HEADS_UP;
129             }
130         }
131     }
132 
combineFilter(AnimationFilter filter)133     public void combineFilter(AnimationFilter filter) {
134         animateAlpha |= filter.animateAlpha;
135         animateX |= filter.animateX;
136         animateY |= filter.animateY;
137         animateYViews.addAll(filter.animateYViews);
138         animateZ |= filter.animateZ;
139         animateHeight |= filter.animateHeight;
140         animateTopInset |= filter.animateTopInset;
141         animateDimmed |= filter.animateDimmed;
142         animateHideSensitive |= filter.animateHideSensitive;
143         hasDelays |= filter.hasDelays;
144         mAnimatedProperties.addAll(filter.mAnimatedProperties);
145     }
146 
reset()147     public void reset() {
148         animateAlpha = false;
149         animateX = false;
150         animateY = false;
151         animateYViews.clear();
152         animateZ = false;
153         animateHeight = false;
154         animateTopInset = false;
155         animateDimmed = false;
156         animateHideSensitive = false;
157         hasDelays = false;
158         hasGoToFullShadeEvent = false;
159         customDelay = NO_DELAY;
160         mAnimatedProperties.clear();
161     }
162 
animate(Property property)163     public AnimationFilter animate(Property property) {
164         mAnimatedProperties.add(property);
165         return this;
166     }
167 
shouldAnimateProperty(Property property)168     public boolean shouldAnimateProperty(Property property) {
169         // TODO: migrate all existing animators to properties
170         return mAnimatedProperties.contains(property);
171     }
172 }
173