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