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.systemui.shade; 18 19 import static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.anyInt; 21 import static org.mockito.Mockito.doAnswer; 22 import static org.mockito.Mockito.mock; 23 import static org.mockito.Mockito.when; 24 25 import android.content.res.Resources; 26 import android.os.Handler; 27 import android.os.Looper; 28 import android.view.ViewGroup; 29 import android.view.ViewParent; 30 import android.view.accessibility.AccessibilityManager; 31 32 import com.android.internal.jank.InteractionJankMonitor; 33 import com.android.internal.logging.MetricsLogger; 34 import com.android.internal.logging.UiEventLogger; 35 import com.android.keyguard.KeyguardStatusView; 36 import com.android.keyguard.KeyguardUpdateMonitor; 37 import com.android.keyguard.TestScopeProvider; 38 import com.android.systemui.R; 39 import com.android.systemui.SysuiTestCase; 40 import com.android.systemui.classifier.FalsingCollector; 41 import com.android.systemui.dump.DumpManager; 42 import com.android.systemui.flags.FeatureFlags; 43 import com.android.systemui.fragments.FragmentHostManager; 44 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; 45 import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor; 46 import com.android.systemui.media.controls.pipeline.MediaDataManager; 47 import com.android.systemui.media.controls.ui.MediaHierarchyManager; 48 import com.android.systemui.plugins.FalsingManager; 49 import com.android.systemui.plugins.qs.QS; 50 import com.android.systemui.qs.QSFragment; 51 import com.android.systemui.screenrecord.RecordingController; 52 import com.android.systemui.shade.data.repository.ShadeRepository; 53 import com.android.systemui.shade.domain.interactor.ShadeInteractor; 54 import com.android.systemui.shade.transition.ShadeTransitionController; 55 import com.android.systemui.statusbar.LockscreenShadeTransitionController; 56 import com.android.systemui.statusbar.NotificationRemoteInputManager; 57 import com.android.systemui.statusbar.NotificationShadeDepthController; 58 import com.android.systemui.statusbar.PulseExpansionHandler; 59 import com.android.systemui.statusbar.QsFrameTranslateController; 60 import com.android.systemui.statusbar.StatusBarStateControllerImpl; 61 import com.android.systemui.statusbar.SysuiStatusBarStateController; 62 import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository; 63 import com.android.systemui.statusbar.notification.stack.AmbientState; 64 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; 65 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; 66 import com.android.systemui.statusbar.phone.KeyguardBypassController; 67 import com.android.systemui.statusbar.phone.KeyguardStatusBarView; 68 import com.android.systemui.statusbar.phone.LightBarController; 69 import com.android.systemui.statusbar.phone.LockscreenGestureLogger; 70 import com.android.systemui.statusbar.phone.ScrimController; 71 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; 72 import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; 73 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository; 74 import com.android.systemui.statusbar.policy.CastController; 75 import com.android.systemui.statusbar.policy.DeviceProvisionedController; 76 import com.android.systemui.statusbar.policy.KeyguardStateController; 77 import com.android.systemui.user.domain.interactor.UserInteractor; 78 import com.android.systemui.util.kotlin.JavaAdapter; 79 80 import dagger.Lazy; 81 82 import org.junit.After; 83 import org.junit.Before; 84 import org.mockito.Mock; 85 import org.mockito.MockitoAnnotations; 86 87 import kotlinx.coroutines.test.TestScope; 88 89 public class QuickSettingsControllerBaseTest extends SysuiTestCase { 90 protected static final float QS_FRAME_START_X = 0f; 91 protected static final int QS_FRAME_WIDTH = 1000; 92 protected static final int QS_FRAME_TOP = 0; 93 protected static final int QS_FRAME_BOTTOM = 1000; 94 protected static final int DEFAULT_HEIGHT = 1000; 95 // In split shade min = max 96 protected static final int DEFAULT_MIN_HEIGHT_SPLIT_SHADE = DEFAULT_HEIGHT; 97 protected static final int DEFAULT_MIN_HEIGHT = 300; 98 99 protected QuickSettingsController mQsController; 100 101 protected TestScope mTestScope = TestScopeProvider.getTestScope(); 102 103 @Mock 104 protected Resources mResources; 105 @Mock protected KeyguardBottomAreaView mQsFrame; 106 @Mock protected KeyguardStatusBarView mKeyguardStatusBar; 107 @Mock protected QS mQs; 108 @Mock protected QSFragment mQSFragment; 109 @Mock protected Lazy<NotificationPanelViewController> mPanelViewControllerLazy; 110 @Mock protected NotificationPanelViewController mNotificationPanelViewController; 111 @Mock protected NotificationPanelView mPanelView; 112 @Mock protected ViewGroup mQsHeader; 113 @Mock protected ViewParent mPanelViewParent; 114 @Mock protected QsFrameTranslateController mQsFrameTranslateController; 115 @Mock protected ShadeTransitionController mShadeTransitionController; 116 @Mock protected PulseExpansionHandler mPulseExpansionHandler; 117 @Mock protected NotificationRemoteInputManager mNotificationRemoteInputManager; 118 @Mock protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; 119 @Mock protected LightBarController mLightBarController; 120 @Mock protected NotificationStackScrollLayoutController 121 mNotificationStackScrollLayoutController; 122 @Mock protected LockscreenShadeTransitionController mLockscreenShadeTransitionController; 123 @Mock protected NotificationShadeDepthController mNotificationShadeDepthController; 124 @Mock protected ShadeHeaderController mShadeHeaderController; 125 @Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager; 126 @Mock protected KeyguardStateController mKeyguardStateController; 127 @Mock protected KeyguardBypassController mKeyguardBypassController; 128 @Mock protected KeyguardUpdateMonitor mKeyguardUpdateMonitor; 129 @Mock protected ScrimController mScrimController; 130 @Mock protected MediaDataManager mMediaDataManager; 131 @Mock protected MediaHierarchyManager mMediaHierarchyManager; 132 @Mock protected AmbientState mAmbientState; 133 @Mock protected RecordingController mRecordingController; 134 @Mock protected FalsingManager mFalsingManager; 135 @Mock protected FalsingCollector mFalsingCollector; 136 @Mock protected AccessibilityManager mAccessibilityManager; 137 @Mock protected LockscreenGestureLogger mLockscreenGestureLogger; 138 @Mock protected MetricsLogger mMetricsLogger; 139 @Mock protected FeatureFlags mFeatureFlags; 140 @Mock protected InteractionJankMonitor mInteractionJankMonitor; 141 @Mock protected ShadeLogger mShadeLogger; 142 @Mock protected DumpManager mDumpManager; 143 @Mock protected UiEventLogger mUiEventLogger; 144 @Mock protected CastController mCastController; 145 @Mock protected DeviceProvisionedController mDeviceProvisionedController; 146 @Mock protected UserInteractor mUserInteractor; 147 protected FakeDisableFlagsRepository mDisableFlagsRepository = 148 new FakeDisableFlagsRepository(); 149 protected FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository(); 150 151 protected SysuiStatusBarStateController mStatusBarStateController; 152 protected ShadeInteractor mShadeInteractor; 153 154 protected Handler mMainHandler; 155 protected LockscreenShadeTransitionController.Callback mLockscreenShadeTransitionCallback; 156 157 protected final ShadeExpansionStateManager mShadeExpansionStateManager = 158 new ShadeExpansionStateManager(); 159 160 protected FragmentHostManager.FragmentListener mFragmentListener; 161 162 @Before setup()163 public void setup() { 164 MockitoAnnotations.initMocks(this); 165 when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController); 166 mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager, 167 mInteractionJankMonitor, mShadeExpansionStateManager); 168 169 when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true); 170 mShadeInteractor = 171 new ShadeInteractor( 172 mTestScope.getBackgroundScope(), 173 mDisableFlagsRepository, 174 mKeyguardRepository, 175 new FakeUserSetupRepository(), 176 mDeviceProvisionedController, 177 mUserInteractor 178 ); 179 180 KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext); 181 keyguardStatusView.setId(R.id.keyguard_status_view); 182 183 when(mResources.getDimensionPixelSize( 184 R.dimen.lockscreen_shade_qs_transition_distance)).thenReturn(DEFAULT_HEIGHT); 185 when(mPanelView.getResources()).thenReturn(mResources); 186 when(mPanelView.getContext()).thenReturn(getContext()); 187 when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar); 188 when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000); 189 when(mPanelView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame); 190 when(mQsFrame.getX()).thenReturn(QS_FRAME_START_X); 191 when(mQsFrame.getWidth()).thenReturn(QS_FRAME_WIDTH); 192 when(mQsHeader.getTop()).thenReturn(QS_FRAME_TOP); 193 when(mQsHeader.getBottom()).thenReturn(QS_FRAME_BOTTOM); 194 when(mPanelView.getY()).thenReturn((float) QS_FRAME_TOP); 195 when(mPanelView.getHeight()).thenReturn(QS_FRAME_BOTTOM); 196 when(mPanelView.findViewById(R.id.keyguard_status_view)) 197 .thenReturn(mock(KeyguardStatusView.class)); 198 when(mQs.getView()).thenReturn(mPanelView); 199 when(mQSFragment.getView()).thenReturn(mPanelView); 200 201 when(mNotificationRemoteInputManager.isRemoteInputActive()) 202 .thenReturn(false); 203 when(mInteractionJankMonitor.begin(any(), anyInt())) 204 .thenReturn(true); 205 when(mInteractionJankMonitor.end(anyInt())) 206 .thenReturn(true); 207 208 when(mPanelView.getParent()).thenReturn(mPanelViewParent); 209 when(mQs.getHeader()).thenReturn(mQsHeader); 210 211 doAnswer(invocation -> { 212 mLockscreenShadeTransitionCallback = invocation.getArgument(0); 213 return null; 214 }).when(mLockscreenShadeTransitionController).addCallback(any()); 215 216 217 mMainHandler = new Handler(Looper.getMainLooper()); 218 219 mQsController = new QuickSettingsController( 220 mPanelViewControllerLazy, 221 mPanelView, 222 mQsFrameTranslateController, 223 mShadeTransitionController, 224 mPulseExpansionHandler, 225 mNotificationRemoteInputManager, 226 mShadeExpansionStateManager, 227 mStatusBarKeyguardViewManager, 228 mLightBarController, 229 mNotificationStackScrollLayoutController, 230 mLockscreenShadeTransitionController, 231 mNotificationShadeDepthController, 232 mShadeHeaderController, 233 mStatusBarTouchableRegionManager, 234 mKeyguardStateController, 235 mKeyguardBypassController, 236 mKeyguardUpdateMonitor, 237 mScrimController, 238 mMediaDataManager, 239 mMediaHierarchyManager, 240 mAmbientState, 241 mRecordingController, 242 mFalsingManager, 243 mFalsingCollector, 244 mAccessibilityManager, 245 mLockscreenGestureLogger, 246 mMetricsLogger, 247 mFeatureFlags, 248 mInteractionJankMonitor, 249 mShadeLogger, 250 mDumpManager, 251 mock(KeyguardFaceAuthInteractor.class), 252 mock(ShadeRepository.class), 253 mShadeInteractor, 254 new JavaAdapter(mTestScope.getBackgroundScope()), 255 mCastController 256 ); 257 mQsController.init(); 258 259 mFragmentListener = mQsController.getQsFragmentListener(); 260 } 261 262 @After tearDown()263 public void tearDown() { 264 mMainHandler.removeCallbacksAndMessages(null); 265 } 266 } 267