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 android.testing.AndroidTestingRunner
20 import android.view.Display
21 import android.view.WindowManager
22 import androidx.test.filters.SmallTest
23 import com.android.systemui.SysuiTestCase
24 import com.android.systemui.assist.AssistManager
25 import com.android.systemui.log.LogBuffer
26 import com.android.systemui.plugins.statusbar.StatusBarStateController
27 import com.android.systemui.statusbar.CommandQueue
28 import com.android.systemui.statusbar.NotificationShadeWindowController
29 import com.android.systemui.statusbar.notification.row.NotificationGutsManager
30 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
31 import com.android.systemui.statusbar.policy.DeviceProvisionedController
32 import com.android.systemui.statusbar.policy.KeyguardStateController
33 import com.android.systemui.statusbar.window.StatusBarWindowController
34 import com.android.systemui.util.concurrency.FakeExecutor
35 import com.android.systemui.util.mockito.whenever
36 import com.android.systemui.util.time.FakeSystemClock
37 import dagger.Lazy
38 import org.junit.Before
39 import org.junit.Test
40 import org.junit.runner.RunWith
41 import org.mockito.ArgumentMatchers
42 import org.mockito.Mock
43 import org.mockito.Mockito.never
44 import org.mockito.Mockito.verify
45 import org.mockito.MockitoAnnotations
46 
47 @RunWith(AndroidTestingRunner::class)
48 @SmallTest
49 class ShadeControllerImplTest : SysuiTestCase() {
50     @Mock private lateinit var commandQueue: CommandQueue
51     @Mock private lateinit var keyguardStateController: KeyguardStateController
52     @Mock private lateinit var statusBarStateController: StatusBarStateController
53     @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
54     @Mock private lateinit var statusBarWindowController: StatusBarWindowController
55     @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
56     @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
57     @Mock private lateinit var windowManager: WindowManager
58     @Mock private lateinit var assistManager: AssistManager
59     @Mock private lateinit var gutsManager: NotificationGutsManager
60     @Mock private lateinit var shadeViewController: ShadeViewController
61     @Mock private lateinit var nswvc: NotificationShadeWindowViewController
62     @Mock private lateinit var display: Display
63     @Mock private lateinit var touchLog: LogBuffer
64 
65     private lateinit var shadeController: ShadeControllerImpl
66 
67     @Before
68     fun setUp() {
69         MockitoAnnotations.initMocks(this)
70         whenever(windowManager.defaultDisplay).thenReturn(display)
71         whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
72         shadeController =
73             ShadeControllerImpl(
74                 commandQueue,
75                 FakeExecutor(FakeSystemClock()),
76                 touchLog,
77                 keyguardStateController,
78                 statusBarStateController,
79                 statusBarKeyguardViewManager,
80                 statusBarWindowController,
81                 deviceProvisionedController,
82                 notificationShadeWindowController,
83                 windowManager,
84                 Lazy { shadeViewController },
85                 Lazy { assistManager },
86                 Lazy { gutsManager },
87             )
88         shadeController.setNotificationShadeWindowViewController(nswvc)
89     }
90 
91     @Test
92     fun testDisableNotificationShade() {
93         whenever(commandQueue.panelsEnabled()).thenReturn(false)
94 
95         // Trying to open it does nothing.
96         shadeController.animateExpandShade()
97         verify(shadeViewController, never()).expandToNotifications()
98         shadeController.animateExpandQs()
99         verify(shadeViewController, never()).expand(ArgumentMatchers.anyBoolean())
100     }
101 
102     @Test
103     fun testEnableNotificationShade() {
104         whenever(commandQueue.panelsEnabled()).thenReturn(true)
105 
106         // Can now be opened.
107         shadeController.animateExpandShade()
108         verify(shadeViewController).expandToNotifications()
109         shadeController.animateExpandQs()
110         verify(shadeViewController).expandToQs()
111     }
112 
113     @Test
114     fun cancelExpansionAndCollapseShade_callsCancelCurrentTouch() {
115         // GIVEN the shade is tracking a touch
116         whenever(shadeViewController.isTracking).thenReturn(true)
117 
118         // WHEN cancelExpansionAndCollapseShade is called
119         shadeController.cancelExpansionAndCollapseShade()
120 
121         // VERIFY that cancelCurrentTouch is called
122         verify(nswvc).cancelCurrentTouch()
123     }
124 
125     @Test
126     fun cancelExpansionAndCollapseShade_doesNotCallAnimateCollapseShade_whenCollapsed() {
127         // GIVEN the shade is tracking a touch
128         whenever(shadeViewController.isTracking).thenReturn(false)
129 
130         // WHEN cancelExpansionAndCollapseShade is called
131         shadeController.cancelExpansionAndCollapseShade()
132 
133         // VERIFY that cancelCurrentTouch is NOT called
134         verify(nswvc, never()).cancelCurrentTouch()
135     }
136 }
137