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
17package com.android.systemui.statusbar.notification;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertTrue;
23import static org.mockito.Mockito.mock;
24
25import android.animation.AnimatorListenerAdapter;
26import android.animation.ValueAnimator;
27import android.test.suitebuilder.annotation.SmallTest;
28import android.testing.AndroidTestingRunner;
29import android.testing.UiThreadTest;
30import android.util.FloatProperty;
31import android.util.Property;
32import android.view.View;
33import android.view.animation.Interpolator;
34
35import com.android.systemui.Interpolators;
36import com.android.systemui.R;
37import com.android.systemui.SysuiTestCase;
38import com.android.systemui.statusbar.notification.PropertyAnimator;
39import com.android.systemui.statusbar.stack.AnimationFilter;
40import com.android.systemui.statusbar.stack.AnimationProperties;
41import com.android.systemui.statusbar.stack.ViewState;
42
43import org.junit.Before;
44import org.junit.Test;
45import org.junit.runner.RunWith;
46
47@SmallTest
48@RunWith(AndroidTestingRunner.class)
49@UiThreadTest
50public class PropertyAnimatorTest extends SysuiTestCase {
51
52    private View mView;
53    private FloatProperty<View> mEffectiveProperty = new FloatProperty<View>("TEST") {
54        public float mValue = 100;
55
56        @Override
57        public void setValue(View view, float value) {
58            mValue = value;
59        }
60
61        @Override
62        public Float get(View object) {
63            return mValue;
64        }
65    };
66    private PropertyAnimator.AnimatableProperty mProperty
67            = new PropertyAnimator.AnimatableProperty() {
68
69        @Override
70        public int getAnimationStartTag() {
71            return R.id.scale_x_animator_start_value_tag;
72        }
73
74        @Override
75        public int getAnimationEndTag() {
76            return R.id.scale_x_animator_end_value_tag;
77        }
78
79        @Override
80        public int getAnimatorTag() {
81            return R.id.scale_x_animator_tag;
82        }
83
84        @Override
85        public Property getProperty() {
86            return mEffectiveProperty;
87        }
88    };
89    private AnimatorListenerAdapter mFinishListener = mock(AnimatorListenerAdapter.class);
90    private AnimationProperties mAnimationProperties = new AnimationProperties() {
91        @Override
92        public AnimationFilter getAnimationFilter() {
93            return mAnimationFilter;
94        }
95
96        @Override
97        public AnimatorListenerAdapter getAnimationFinishListener() {
98            return mFinishListener;
99        }
100    }.setDuration(200);
101    private AnimationFilter mAnimationFilter = new AnimationFilter();
102    private Interpolator mTestInterpolator = Interpolators.ALPHA_IN;
103
104
105    @Before
106    public void setUp() {
107        mView = new View(getContext());
108    }
109
110    @Test
111    public void testAnimationStarted() {
112        mAnimationFilter.reset();
113        mAnimationFilter.animate(mProperty.getProperty());
114        PropertyAnimator.startAnimation(mView, mProperty, 200, mAnimationProperties);
115        assertTrue(ViewState.isAnimating(mView, mProperty));
116    }
117
118    @Test
119    public void testNoAnimationStarted() {
120        mAnimationFilter.reset();
121        PropertyAnimator.startAnimation(mView, mProperty, 200, mAnimationProperties);
122        assertFalse(ViewState.isAnimating(mView, mProperty));
123    }
124
125    @Test
126    public void testEndValueUpdated() {
127        mAnimationFilter.reset();
128        mAnimationFilter.animate(mProperty.getProperty());
129        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
130        assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationEndTag()),
131                Float.valueOf(200f));
132    }
133
134    @Test
135    public void testStartTagUpdated() {
136        mEffectiveProperty.set(mView, 100f);
137        mAnimationFilter.reset();
138        mAnimationFilter.animate(mProperty.getProperty());
139        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
140        assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationStartTag()),
141                Float.valueOf(100f));
142    }
143
144    @Test
145    public void testValueIsSetUnAnimated() {
146        mAnimationFilter.reset();
147        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
148        assertEquals(Float.valueOf(200f), mEffectiveProperty.get(mView));
149    }
150
151    @Test
152    public void testAnimationToRightValueUpdated() {
153        mAnimationFilter.reset();
154        mAnimationFilter.animate(mProperty.getProperty());
155        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
156        mAnimationFilter.reset();
157        PropertyAnimator.startAnimation(mView, mProperty, 220f, mAnimationProperties);
158        assertTrue(ViewState.isAnimating(mView, mProperty));
159        assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationEndTag()),
160                Float.valueOf(220f));
161    }
162
163    @Test
164    public void testAnimationToRightValueUpdateAnimated() {
165        mAnimationFilter.reset();
166        mAnimationFilter.animate(mProperty.getProperty());
167        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
168        mAnimationFilter.reset();
169        mAnimationFilter.animate(mProperty.getProperty());
170        PropertyAnimator.startAnimation(mView, mProperty, 220f, mAnimationProperties);
171        assertTrue(ViewState.isAnimating(mView, mProperty));
172        assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationEndTag()),
173                Float.valueOf(220f));
174    }
175
176    @Test
177    public void testStartTagShiftedWhenChanging() {
178        mEffectiveProperty.set(mView, 100f);
179        mAnimationFilter.reset();
180        mAnimationFilter.animate(mProperty.getProperty());
181        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
182        mAnimationFilter.reset();
183        PropertyAnimator.startAnimation(mView, mProperty, 220f, mAnimationProperties);
184        assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationStartTag()),
185                Float.valueOf(120f));
186    }
187
188    @Test
189    public void testUsingDuration() {
190        mAnimationFilter.reset();
191        mAnimationFilter.animate(mProperty.getProperty());
192        mAnimationProperties.setDuration(500);
193        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
194        ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
195        assertNotNull(animator);
196        assertEquals(animator.getDuration(), 500);
197    }
198
199    @Test
200    public void testUsingDelay() {
201        mAnimationFilter.reset();
202        mAnimationFilter.animate(mProperty.getProperty());
203        mAnimationProperties.setDelay(200);
204        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
205        ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
206        assertNotNull(animator);
207        assertEquals(animator.getStartDelay(), 200);
208    }
209
210    @Test
211    public void testUsingInterpolator() {
212        mAnimationFilter.reset();
213        mAnimationFilter.animate(mProperty.getProperty());
214        mAnimationProperties.setCustomInterpolator(mEffectiveProperty, mTestInterpolator);
215        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
216        ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
217        assertNotNull(animator);
218        assertEquals(animator.getInterpolator(), mTestInterpolator);
219    }
220
221    @Test
222    public void testUsingListener() {
223        mAnimationFilter.reset();
224        mAnimationFilter.animate(mProperty.getProperty());
225        mAnimationProperties.setCustomInterpolator(mEffectiveProperty, mTestInterpolator);
226        PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
227        ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
228        assertNotNull(animator);
229        assertTrue(animator.getListeners().contains(mFinishListener));
230    }
231}
232