1 /*
2  * Copyright (C) 2023 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 android.view.View.INVISIBLE;
20 
21 import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
22 import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
23 
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.Mockito.atLeast;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.res.Resources;
31 import android.view.View;
32 import android.view.ViewGroup;
33 import android.widget.FrameLayout;
34 import android.widget.LinearLayout;
35 import android.widget.RelativeLayout;
36 
37 import com.android.systemui.R;
38 import com.android.systemui.SysuiTestCase;
39 import com.android.systemui.dump.DumpManager;
40 import com.android.systemui.flags.FakeFeatureFlags;
41 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
42 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
43 import com.android.systemui.log.LogBuffer;
44 import com.android.systemui.plugins.ClockAnimations;
45 import com.android.systemui.plugins.ClockController;
46 import com.android.systemui.plugins.ClockEvents;
47 import com.android.systemui.plugins.ClockFaceConfig;
48 import com.android.systemui.plugins.ClockFaceController;
49 import com.android.systemui.plugins.ClockFaceEvents;
50 import com.android.systemui.plugins.ClockTickRate;
51 import com.android.systemui.plugins.statusbar.StatusBarStateController;
52 import com.android.systemui.shared.clocks.AnimatableClockView;
53 import com.android.systemui.shared.clocks.ClockRegistry;
54 import com.android.systemui.statusbar.StatusBarState;
55 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
56 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
57 import com.android.systemui.statusbar.phone.NotificationIconContainer;
58 import com.android.systemui.util.concurrency.FakeExecutor;
59 import com.android.systemui.util.settings.SecureSettings;
60 import com.android.systemui.util.time.FakeSystemClock;
61 
62 import org.junit.Before;
63 import org.mockito.ArgumentCaptor;
64 import org.mockito.Captor;
65 import org.mockito.Mock;
66 import org.mockito.MockitoAnnotations;
67 
68 public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
69 
70     @Mock
71     protected KeyguardClockSwitch mView;
72     @Mock
73     protected StatusBarStateController mStatusBarStateController;
74     @Mock
75     protected ClockRegistry mClockRegistry;
76     @Mock
77     KeyguardSliceViewController mKeyguardSliceViewController;
78     @Mock
79     NotificationIconAreaController mNotificationIconAreaController;
80     @Mock
81     LockscreenSmartspaceController mSmartspaceController;
82 
83     @Mock
84     Resources mResources;
85     @Mock
86     KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
87     @Mock
88     protected ClockController mClockController;
89     @Mock
90     protected ClockFaceController mLargeClockController;
91     @Mock
92     protected ClockFaceController mSmallClockController;
93     @Mock
94     protected ClockAnimations mClockAnimations;
95     @Mock
96     protected ClockEvents mClockEvents;
97     @Mock
98     protected ClockFaceEvents mClockFaceEvents;
99     @Mock
100     DumpManager mDumpManager;
101     @Mock
102     ClockEventController mClockEventController;
103 
104     @Mock
105     protected NotificationIconContainer mNotificationIcons;
106     @Mock
107     protected AnimatableClockView mSmallClockView;
108     @Mock
109     protected AnimatableClockView mLargeClockView;
110     @Mock
111     protected FrameLayout mSmallClockFrame;
112     @Mock
113     protected FrameLayout mLargeClockFrame;
114     @Mock
115     protected SecureSettings mSecureSettings;
116     @Mock
117     protected LogBuffer mLogBuffer;
118 
119     protected final View mFakeDateView = (View) (new ViewGroup(mContext) {
120         @Override
121         protected void onLayout(boolean changed, int l, int t, int r, int b) {}
122     });
123     protected final View mFakeWeatherView = new View(mContext);
124     protected final View mFakeSmartspaceView = new View(mContext);
125 
126     protected KeyguardClockSwitchController mController;
127     protected View mSliceView;
128     protected LinearLayout mStatusArea;
129     protected FakeExecutor mExecutor;
130     protected FakeFeatureFlags mFakeFeatureFlags;
131     @Captor protected ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor =
132             ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
133 
134     @Before
setup()135     public void setup() {
136         MockitoAnnotations.initMocks(this);
137 
138         mFakeDateView.setTag(R.id.tag_smartspace_view, new Object());
139         mFakeWeatherView.setTag(R.id.tag_smartspace_view, new Object());
140         mFakeSmartspaceView.setTag(R.id.tag_smartspace_view, new Object());
141 
142         when(mView.findViewById(R.id.left_aligned_notification_icon_container))
143                 .thenReturn(mNotificationIcons);
144         when(mNotificationIcons.getLayoutParams()).thenReturn(
145                 mock(RelativeLayout.LayoutParams.class));
146         when(mView.getContext()).thenReturn(getContext());
147         when(mView.getResources()).thenReturn(mResources);
148         when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin))
149                 .thenReturn(100);
150         when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
151                 .thenReturn(-200);
152         when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
153                 .thenReturn(INVISIBLE);
154 
155         when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
156         when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
157         when(mSmallClockView.getContext()).thenReturn(getContext());
158         when(mLargeClockView.getContext()).thenReturn(getContext());
159 
160         when(mView.isAttachedToWindow()).thenReturn(true);
161         when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
162         when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
163         when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
164         mExecutor = new FakeExecutor(new FakeSystemClock());
165         mFakeFeatureFlags = new FakeFeatureFlags();
166         mFakeFeatureFlags.set(FACE_AUTH_REFACTOR, false);
167         mFakeFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
168         mController = new KeyguardClockSwitchController(
169                 mView,
170                 mStatusBarStateController,
171                 mClockRegistry,
172                 mKeyguardSliceViewController,
173                 mNotificationIconAreaController,
174                 mSmartspaceController,
175                 mKeyguardUnlockAnimationController,
176                 mSecureSettings,
177                 mExecutor,
178                 mDumpManager,
179                 mClockEventController,
180                 mLogBuffer,
181                 KeyguardInteractorFactory.create(mFakeFeatureFlags).getKeyguardInteractor(),
182                 mFakeFeatureFlags
183         );
184 
185         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
186         when(mLargeClockController.getView()).thenReturn(mLargeClockView);
187         when(mSmallClockController.getView()).thenReturn(mSmallClockView);
188         when(mClockController.getLargeClock()).thenReturn(mLargeClockController);
189         when(mClockController.getSmallClock()).thenReturn(mSmallClockController);
190         when(mClockController.getEvents()).thenReturn(mClockEvents);
191         when(mSmallClockController.getEvents()).thenReturn(mClockFaceEvents);
192         when(mLargeClockController.getEvents()).thenReturn(mClockFaceEvents);
193         when(mLargeClockController.getAnimations()).thenReturn(mClockAnimations);
194         when(mSmallClockController.getAnimations()).thenReturn(mClockAnimations);
195         when(mClockRegistry.createCurrentClock()).thenReturn(mClockController);
196         when(mClockEventController.getClock()).thenReturn(mClockController);
197         when(mSmallClockController.getConfig())
198                 .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
199         when(mLargeClockController.getConfig())
200                 .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
201 
202         mSliceView = new View(getContext());
203         when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
204         mStatusArea = new LinearLayout(getContext());
205         when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
206     }
207 
removeView(View v)208     private void removeView(View v) {
209         ViewGroup group = ((ViewGroup) v.getParent());
210         if (group != null) {
211             group.removeView(v);
212         }
213     }
214 
init()215     protected void init() {
216         mController.init();
217 
218         verify(mView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture());
219         mAttachCaptor.getValue().onViewAttachedToWindow(mView);
220     }
221 }
222