blob: de7664c769e696e05f3facd2a38b7d29bf6814f0 [file] [log] [blame]
Kunhung Li29007e62018-07-30 19:30:25 +08001/*
2 * Copyright (C) 2018 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.keyguard;
18
19import static android.view.View.GONE;
20import static android.view.View.VISIBLE;
21
22import static com.google.common.truth.Truth.assertThat;
23
24import static org.mockito.Mockito.doReturn;
25import static org.mockito.Mockito.mock;
Robert Snoeberger33ce6d92018-10-26 10:52:38 -040026import static org.mockito.Mockito.never;
Kunhung Li29007e62018-07-30 19:30:25 +080027import static org.mockito.Mockito.verify;
Kunhung Li29007e62018-07-30 19:30:25 +080028import static org.mockito.Mockito.when;
29
30import android.graphics.Color;
31import android.graphics.Paint.Style;
32import android.test.suitebuilder.annotation.SmallTest;
33import android.testing.AndroidTestingRunner;
34import android.testing.TestableLooper.RunWithLooper;
35import android.text.TextPaint;
36import android.view.LayoutInflater;
Robert Snoeberger60854082019-01-04 13:13:17 -050037import android.view.View;
Robert Snoebergere3b3e782018-12-17 13:32:15 -050038import android.widget.FrameLayout;
Kunhung Li29007e62018-07-30 19:30:25 +080039import android.widget.TextClock;
40
Robert Snoeberger15b4af12019-01-18 15:37:27 -050041import com.android.keyguard.clock.ClockManager;
Sunny Goyal87fccf02019-08-13 17:39:10 -070042import com.android.systemui.R;
Robert Snoebergerbe35b762019-03-15 14:33:02 -040043import com.android.systemui.SystemUIFactory;
Kunhung Li29007e62018-07-30 19:30:25 +080044import com.android.systemui.SysuiTestCase;
45import com.android.systemui.plugins.ClockPlugin;
Beverly8fdb5332019-02-04 14:29:49 -050046import com.android.systemui.plugins.statusbar.StatusBarStateController;
Robert Snoeberger60854082019-01-04 13:13:17 -050047import com.android.systemui.statusbar.StatusBarState;
Robert Snoebergerbe35b762019-03-15 14:33:02 -040048import com.android.systemui.util.InjectionInflationController;
Kunhung Li29007e62018-07-30 19:30:25 +080049
50import org.junit.Before;
51import org.junit.Test;
52import org.junit.runner.RunWith;
Kunhung Li29007e62018-07-30 19:30:25 +080053import org.mockito.InjectMocks;
54import org.mockito.Mock;
55import org.mockito.MockitoAnnotations;
56
57@SmallTest
Kunhung Li29007e62018-07-30 19:30:25 +080058@RunWith(AndroidTestingRunner.class)
Robert Snoebergere3b3e782018-12-17 13:32:15 -050059// Need to run on the main thread because KeyguardSliceView$Row init checks for
60// the main thread before acquiring a wake lock. This class is constructed when
61// the keyguard_clcok_switch layout is inflated.
62@RunWithLooper(setAsMainLooper = true)
Kunhung Li29007e62018-07-30 19:30:25 +080063public class KeyguardClockSwitchTest extends SysuiTestCase {
Robert Snoebergere3b3e782018-12-17 13:32:15 -050064 private FrameLayout mClockContainer;
Robert Snoebergera1df7fb2019-02-11 14:00:14 -050065 private FrameLayout mBigClockContainer;
66 private TextClock mBigClock;
Robert Snoeberger60854082019-01-04 13:13:17 -050067 private StatusBarStateController.StateListener mStateListener;
Kunhung Li29007e62018-07-30 19:30:25 +080068
69 @Mock
70 TextClock mClockView;
71 @InjectMocks
72 KeyguardClockSwitch mKeyguardClockSwitch;
73
74 @Before
75 public void setUp() {
Robert Snoebergerbe35b762019-03-15 14:33:02 -040076 InjectionInflationController inflationController = new InjectionInflationController(
77 SystemUIFactory.getInstance().getRootComponent());
78 LayoutInflater layoutInflater = inflationController
79 .injectable(LayoutInflater.from(getContext()));
Kunhung Li29007e62018-07-30 19:30:25 +080080 mKeyguardClockSwitch =
81 (KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
Robert Snoebergere3b3e782018-12-17 13:32:15 -050082 mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
Robert Snoebergera1df7fb2019-02-11 14:00:14 -050083 mBigClockContainer = new FrameLayout(getContext());
84 mBigClock = new TextClock(getContext());
Kunhung Li29007e62018-07-30 19:30:25 +080085 MockitoAnnotations.initMocks(this);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -040086 when(mClockView.getPaint()).thenReturn(mock(TextPaint.class));
Robert Snoeberger60854082019-01-04 13:13:17 -050087 mStateListener = mKeyguardClockSwitch.getStateListener();
Kunhung Li29007e62018-07-30 19:30:25 +080088 }
89
90 @Test
Kunhung Li29007e62018-07-30 19:30:25 +080091 public void onPluginConnected_showPluginClock() {
92 ClockPlugin plugin = mock(ClockPlugin.class);
93 TextClock pluginView = new TextClock(getContext());
94 when(plugin.getView()).thenReturn(pluginView);
Kunhung Li29007e62018-07-30 19:30:25 +080095
Robert Snoeberger15b4af12019-01-18 15:37:27 -050096 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Kunhung Li29007e62018-07-30 19:30:25 +080097
98 verify(mClockView).setVisibility(GONE);
Robert Snoebergere3b3e782018-12-17 13:32:15 -050099 assertThat(plugin.getView().getParent()).isEqualTo(mClockContainer);
Kunhung Li29007e62018-07-30 19:30:25 +0800100 }
101
102 @Test
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500103 public void onPluginConnected_showPluginBigClock() {
104 // GIVEN that the container for the big clock has visibility GONE
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500105 mBigClockContainer.setVisibility(GONE);
106 mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500107 // AND the plugin returns a view for the big clock
108 ClockPlugin plugin = mock(ClockPlugin.class);
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500109 when(plugin.getBigClockView()).thenReturn(mBigClock);
Robert Snoeberger98312392019-03-15 16:53:51 -0400110 // AND in the keyguard state
111 mStateListener.onStateChanged(StatusBarState.KEYGUARD);
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500112 // WHEN the plugin is connected
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500113 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500114 // THEN the big clock container is visible and it is the parent of the
115 // big clock view.
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500116 assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
117 assertThat(mBigClock.getParent()).isEqualTo(mBigClockContainer);
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500118 }
119
120 @Test
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400121 public void onPluginConnected_nullView() {
122 ClockPlugin plugin = mock(ClockPlugin.class);
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500123 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400124 verify(mClockView, never()).setVisibility(GONE);
125 }
126
127 @Test
128 public void onPluginConnected_showSecondPluginClock() {
129 // GIVEN a plugin has already connected
130 ClockPlugin plugin1 = mock(ClockPlugin.class);
131 when(plugin1.getView()).thenReturn(new TextClock(getContext()));
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500132 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin1);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400133 // WHEN a second plugin is connected
134 ClockPlugin plugin2 = mock(ClockPlugin.class);
135 when(plugin2.getView()).thenReturn(new TextClock(getContext()));
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500136 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin2);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400137 // THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
Robert Snoebergere3b3e782018-12-17 13:32:15 -0500138 assertThat(plugin2.getView().getParent()).isEqualTo(mClockContainer);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400139 assertThat(plugin1.getView().getParent()).isNull();
140 }
141
142 @Test
Robert Snoeberger58f23152019-01-10 15:51:32 -0500143 public void onPluginConnected_darkAmountInitialized() {
144 // GIVEN that the dark amount has already been set
145 mKeyguardClockSwitch.setDarkAmount(0.5f);
146 // WHEN a plugin is connected
147 ClockPlugin plugin = mock(ClockPlugin.class);
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500148 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Robert Snoeberger58f23152019-01-10 15:51:32 -0500149 // THEN dark amount should be initalized on the plugin.
150 verify(plugin).setDarkAmount(0.5f);
151 }
152
153 @Test
Kunhung Li29007e62018-07-30 19:30:25 +0800154 public void onPluginDisconnected_showDefaultClock() {
155 ClockPlugin plugin = mock(ClockPlugin.class);
156 TextClock pluginView = new TextClock(getContext());
157 when(plugin.getView()).thenReturn(pluginView);
158 mClockView.setVisibility(GONE);
Kunhung Li29007e62018-07-30 19:30:25 +0800159
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500160 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
161 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
Kunhung Li29007e62018-07-30 19:30:25 +0800162
163 verify(mClockView).setVisibility(VISIBLE);
164 assertThat(plugin.getView().getParent()).isNull();
165 }
166
167 @Test
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500168 public void onPluginDisconnected_hidePluginBigClock() {
169 // GIVEN that the big clock container is visible
170 FrameLayout bigClockContainer = new FrameLayout(getContext());
171 bigClockContainer.setVisibility(VISIBLE);
172 mKeyguardClockSwitch.setBigClockContainer(bigClockContainer);
173 // AND the plugin returns a view for the big clock
174 ClockPlugin plugin = mock(ClockPlugin.class);
175 TextClock pluginView = new TextClock(getContext());
176 when(plugin.getBigClockView()).thenReturn(pluginView);
Robert Snoeberger98312392019-03-15 16:53:51 -0400177 // AND in the keyguard state
178 mStateListener.onStateChanged(StatusBarState.KEYGUARD);
Robert Snoeberger8bf1a3c2019-01-10 10:30:09 -0500179 // WHEN the plugin is connected and then disconnected
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500180 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
181 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
Robert Snoeberger6a0140a2018-12-20 12:46:17 -0500182 // THEN the big lock container is GONE and the big clock view doesn't have
183 // a parent.
184 assertThat(bigClockContainer.getVisibility()).isEqualTo(GONE);
185 assertThat(pluginView.getParent()).isNull();
186 }
187
188 @Test
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400189 public void onPluginDisconnected_nullView() {
190 ClockPlugin plugin = mock(ClockPlugin.class);
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500191 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
192 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400193 verify(mClockView, never()).setVisibility(GONE);
194 }
195
196 @Test
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400197 public void onPluginDisconnected_secondOfTwoDisconnected() {
198 // GIVEN two plugins are connected
199 ClockPlugin plugin1 = mock(ClockPlugin.class);
200 when(plugin1.getView()).thenReturn(new TextClock(getContext()));
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500201 ClockManager.ClockChangedListener listener = mKeyguardClockSwitch.getClockChangedListener();
202 listener.onClockChanged(plugin1);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400203 ClockPlugin plugin2 = mock(ClockPlugin.class);
204 when(plugin2.getView()).thenReturn(new TextClock(getContext()));
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500205 listener.onClockChanged(plugin2);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400206 // WHEN the second plugin is disconnected
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500207 listener.onClockChanged(null);
Robert Snoeberger33ce6d92018-10-26 10:52:38 -0400208 // THEN the default clock should be shown.
209 verify(mClockView).setVisibility(VISIBLE);
210 assertThat(plugin1.getView().getParent()).isNull();
211 assertThat(plugin2.getView().getParent()).isNull();
212 }
213
214 @Test
Robert Snoeberger3358cfb2019-04-03 13:09:55 -0400215 public void onPluginDisconnected_onDestroyView() {
216 // GIVEN a plugin is connected
217 ClockPlugin clockPlugin = mock(ClockPlugin.class);
218 when(clockPlugin.getView()).thenReturn(new TextClock(getContext()));
219 ClockManager.ClockChangedListener listener = mKeyguardClockSwitch.getClockChangedListener();
220 listener.onClockChanged(clockPlugin);
221 // WHEN the plugin is disconnected
222 listener.onClockChanged(null);
223 // THEN onDestroyView is called on the plugin
224 verify(clockPlugin).onDestroyView();
225 }
226
227 @Test
Kunhung Li29007e62018-07-30 19:30:25 +0800228 public void setTextColor_defaultClockSetTextColor() {
229 mKeyguardClockSwitch.setTextColor(Color.YELLOW);
230
231 verify(mClockView).setTextColor(Color.YELLOW);
232 }
233
234 @Test
235 public void setTextColor_pluginClockSetTextColor() {
236 ClockPlugin plugin = mock(ClockPlugin.class);
237 TextClock pluginView = new TextClock(getContext());
238 when(plugin.getView()).thenReturn(pluginView);
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500239 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Kunhung Li29007e62018-07-30 19:30:25 +0800240
241 mKeyguardClockSwitch.setTextColor(Color.WHITE);
242
243 verify(plugin).setTextColor(Color.WHITE);
244 }
245
246 @Test
247 public void setStyle_defaultClockSetStyle() {
248 TextPaint paint = mock(TextPaint.class);
249 Style style = mock(Style.class);
250 doReturn(paint).when(mClockView).getPaint();
251
252 mKeyguardClockSwitch.setStyle(style);
253
254 verify(paint).setStyle(style);
255 }
256
257 @Test
258 public void setStyle_pluginClockSetStyle() {
259 ClockPlugin plugin = mock(ClockPlugin.class);
260 TextClock pluginView = new TextClock(getContext());
261 when(plugin.getView()).thenReturn(pluginView);
Kunhung Li29007e62018-07-30 19:30:25 +0800262 Style style = mock(Style.class);
Robert Snoeberger15b4af12019-01-18 15:37:27 -0500263 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Kunhung Li29007e62018-07-30 19:30:25 +0800264
265 mKeyguardClockSwitch.setStyle(style);
266
267 verify(plugin).setStyle(style);
268 }
Robert Snoeberger60854082019-01-04 13:13:17 -0500269
270 @Test
Robert Snoeberger98312392019-03-15 16:53:51 -0400271 public void onStateChanged_GoneInShade() {
Robert Snoeberger60854082019-01-04 13:13:17 -0500272 // GIVEN that the big clock container is visible
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500273 mBigClockContainer.setVisibility(View.VISIBLE);
274 mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
Robert Snoeberger60854082019-01-04 13:13:17 -0500275 // WHEN transitioned to SHADE state
276 mStateListener.onStateChanged(StatusBarState.SHADE);
Robert Snoeberger98312392019-03-15 16:53:51 -0400277 // THEN the container is gone.
278 assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
Robert Snoeberger60854082019-01-04 13:13:17 -0500279 }
280
281 @Test
282 public void onStateChanged_VisibleInKeyguard() {
Robert Snoeberger98312392019-03-15 16:53:51 -0400283 // GIVEN that the big clock container is gone
284 mBigClockContainer.setVisibility(View.GONE);
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500285 mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
Robert Snoeberger98312392019-03-15 16:53:51 -0400286 // AND GIVEN that a plugin is active.
287 ClockPlugin plugin = mock(ClockPlugin.class);
288 when(plugin.getBigClockView()).thenReturn(mBigClock);
289 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Robert Snoeberger60854082019-01-04 13:13:17 -0500290 // WHEN transitioned to KEYGUARD state
291 mStateListener.onStateChanged(StatusBarState.KEYGUARD);
292 // THEN the container is visible.
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500293 assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
294 }
295
296 @Test
297 public void setBigClockContainer_visible() {
298 // GIVEN that the big clock container is visible
299 mBigClockContainer.setVisibility(View.VISIBLE);
300 // AND GIVEN that a plugin is active.
301 ClockPlugin plugin = mock(ClockPlugin.class);
302 when(plugin.getBigClockView()).thenReturn(mBigClock);
303 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Robert Snoeberger98312392019-03-15 16:53:51 -0400304 // AND in the keyguard state
305 mStateListener.onStateChanged(StatusBarState.KEYGUARD);
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500306 // WHEN the container is associated with the clock switch
307 mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
308 // THEN the container remains visible.
309 assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
310 }
311
312 @Test
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500313 public void setBigClockContainer_gone() {
314 // GIVEN that the big clock container is gone
315 mBigClockContainer.setVisibility(View.GONE);
316 // AND GIVEN that a plugin is active.
317 ClockPlugin plugin = mock(ClockPlugin.class);
318 when(plugin.getBigClockView()).thenReturn(mBigClock);
319 mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
Robert Snoeberger98312392019-03-15 16:53:51 -0400320 // AND in the keyguard state
321 mStateListener.onStateChanged(StatusBarState.KEYGUARD);
Robert Snoebergera1df7fb2019-02-11 14:00:14 -0500322 // WHEN the container is associated with the clock switch
323 mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
324 // THEN the container is made visible.
325 assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
Robert Snoeberger60854082019-01-04 13:13:17 -0500326 }
Kunhung Li29007e62018-07-30 19:30:25 +0800327}