• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.keyguard;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.never;
25 import static org.mockito.Mockito.times;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.content.res.Resources;
30 import android.testing.AndroidTestingRunner;
31 import android.view.View;
32 import android.widget.FrameLayout;
33 import android.widget.RelativeLayout;
34 
35 import androidx.test.filters.SmallTest;
36 
37 import com.android.internal.colorextraction.ColorExtractor;
38 import com.android.keyguard.clock.ClockManager;
39 import com.android.systemui.R;
40 import com.android.systemui.SysuiTestCase;
41 import com.android.systemui.broadcast.BroadcastDispatcher;
42 import com.android.systemui.colorextraction.SysuiColorExtractor;
43 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
44 import com.android.systemui.plugins.ClockPlugin;
45 import com.android.systemui.plugins.statusbar.StatusBarStateController;
46 import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController;
47 import com.android.systemui.statusbar.StatusBarState;
48 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
49 import com.android.systemui.statusbar.phone.KeyguardBypassController;
50 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
51 import com.android.systemui.statusbar.phone.NotificationIconContainer;
52 import com.android.systemui.statusbar.policy.BatteryController;
53 
54 import org.junit.Before;
55 import org.junit.Test;
56 import org.junit.runner.RunWith;
57 import org.mockito.ArgumentCaptor;
58 import org.mockito.Mock;
59 import org.mockito.MockitoAnnotations;
60 import org.mockito.verification.VerificationMode;
61 
62 @SmallTest
63 @RunWith(AndroidTestingRunner.class)
64 public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
65 
66     @Mock
67     private KeyguardClockSwitch mView;
68     @Mock
69     private StatusBarStateController mStatusBarStateController;
70     @Mock
71     private SysuiColorExtractor mColorExtractor;
72     @Mock
73     private ClockManager mClockManager;
74     @Mock
75     KeyguardSliceViewController mKeyguardSliceViewController;
76     @Mock
77     NotificationIconAreaController mNotificationIconAreaController;
78     @Mock
79     BroadcastDispatcher mBroadcastDispatcher;
80     @Mock
81     BatteryController mBatteryController;
82     @Mock
83     KeyguardUpdateMonitor mKeyguardUpdateMonitor;
84     @Mock
85     KeyguardBypassController mBypassController;
86     @Mock
87     LockscreenSmartspaceController mSmartspaceController;
88 
89     @Mock
90     Resources mResources;
91     KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
92     @Mock
93     SmartspaceTransitionController mSmartSpaceTransitionController;
94     @Mock
95     private ClockPlugin mClockPlugin;
96     @Mock
97     ColorExtractor.GradientColors mGradientColors;
98 
99     @Mock
100     private NotificationIconContainer mNotificationIcons;
101     @Mock
102     private AnimatableClockView mClockView;
103     @Mock
104     private AnimatableClockView mLargeClockView;
105     @Mock
106     private FrameLayout mLargeClockFrame;
107 
108     private final View mFakeSmartspaceView = new View(mContext);
109 
110     private KeyguardClockSwitchController mController;
111     private View mStatusArea;
112 
113     @Before
setup()114     public void setup() {
115         MockitoAnnotations.initMocks(this);
116 
117         when(mView.findViewById(R.id.left_aligned_notification_icon_container))
118                 .thenReturn(mNotificationIcons);
119         when(mNotificationIcons.getLayoutParams()).thenReturn(
120                 mock(RelativeLayout.LayoutParams.class));
121         when(mView.getContext()).thenReturn(getContext());
122 
123         when(mView.findViewById(R.id.animatable_clock_view)).thenReturn(mClockView);
124         when(mView.findViewById(R.id.animatable_clock_view_large)).thenReturn(mLargeClockView);
125         when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
126         when(mClockView.getContext()).thenReturn(getContext());
127         when(mLargeClockView.getContext()).thenReturn(getContext());
128 
129         when(mView.isAttachedToWindow()).thenReturn(true);
130         when(mResources.getString(anyInt())).thenReturn("h:mm");
131         when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
132         mController = new KeyguardClockSwitchController(
133                 mView,
134                 mStatusBarStateController,
135                 mColorExtractor,
136                 mClockManager,
137                 mKeyguardSliceViewController,
138                 mNotificationIconAreaController,
139                 mBroadcastDispatcher,
140                 mBatteryController,
141                 mKeyguardUpdateMonitor,
142                 mBypassController,
143                 mSmartspaceController,
144                 mKeyguardUnlockAnimationController,
145                 mSmartSpaceTransitionController
146         );
147 
148         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
149         when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
150 
151         mStatusArea = new View(getContext());
152         when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
153     }
154 
155     @Test
testInit_viewAlreadyAttached()156     public void testInit_viewAlreadyAttached() {
157         mController.init();
158 
159         verifyAttachment(times(1));
160     }
161 
162     @Test
testInit_viewNotYetAttached()163     public void testInit_viewNotYetAttached() {
164         ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
165                 ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
166 
167         when(mView.isAttachedToWindow()).thenReturn(false);
168         mController.init();
169         verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
170 
171         verifyAttachment(never());
172 
173         listenerArgumentCaptor.getValue().onViewAttachedToWindow(mView);
174 
175         verifyAttachment(times(1));
176     }
177 
178     @Test
testInitSubControllers()179     public void testInitSubControllers() {
180         mController.init();
181         verify(mKeyguardSliceViewController).init();
182     }
183 
184     @Test
testInit_viewDetached()185     public void testInit_viewDetached() {
186         ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
187                 ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
188         mController.init();
189         verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
190 
191         verifyAttachment(times(1));
192 
193         listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
194 
195         verify(mColorExtractor).removeOnColorsChangedListener(
196                 any(ColorExtractor.OnColorsChangedListener.class));
197     }
198 
199     @Test
testPluginPassesStatusBarState()200     public void testPluginPassesStatusBarState() {
201         ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
202                 ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class);
203 
204         mController.init();
205         verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture());
206 
207         listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin);
208         verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE);
209     }
210 
211     @Test
testSmartspaceEnabledRemovesKeyguardStatusArea()212     public void testSmartspaceEnabledRemovesKeyguardStatusArea() {
213         when(mSmartspaceController.isEnabled()).thenReturn(true);
214         when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
215         mController.init();
216 
217         assertEquals(View.GONE, mStatusArea.getVisibility());
218     }
219 
220     @Test
testSmartspaceDisabledShowsKeyguardStatusArea()221     public void testSmartspaceDisabledShowsKeyguardStatusArea() {
222         when(mSmartspaceController.isEnabled()).thenReturn(false);
223         mController.init();
224 
225         assertEquals(View.VISIBLE, mStatusArea.getVisibility());
226     }
227 
228     @Test
testDetachRemovesSmartspaceView()229     public void testDetachRemovesSmartspaceView() {
230         when(mSmartspaceController.isEnabled()).thenReturn(true);
231         when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
232         mController.init();
233         verify(mView).addView(eq(mFakeSmartspaceView), anyInt(), any());
234 
235         ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
236                 ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
237         verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
238 
239         listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
240         verify(mView).removeView(mFakeSmartspaceView);
241     }
242 
243     @Test
testRefresh()244     public void testRefresh() {
245         mController.refresh();
246 
247         verify(mSmartspaceController).requestSmartspaceUpdate();
248     }
249 
verifyAttachment(VerificationMode times)250     private void verifyAttachment(VerificationMode times) {
251         verify(mClockManager, times).addOnClockChangedListener(
252                 any(ClockManager.ClockChangedListener.class));
253         verify(mColorExtractor, times).addOnColorsChangedListener(
254                 any(ColorExtractor.OnColorsChangedListener.class));
255         verify(mView, times).updateColors(mGradientColors);
256     }
257 }
258