1 package com.android.systemui.qs.tiles
2 
3 import android.app.AlarmManager
4 import android.app.PendingIntent
5 import android.os.Handler
6 import android.provider.AlarmClock
7 import android.service.quicksettings.Tile
8 import android.testing.AndroidTestingRunner
9 import android.testing.TestableLooper
10 import androidx.test.filters.SmallTest
11 import com.android.internal.logging.MetricsLogger
12 import com.android.systemui.SysuiTestCase
13 import com.android.systemui.classifier.FalsingManagerFake
14 import com.android.systemui.plugins.ActivityStarter
15 import com.android.systemui.plugins.statusbar.StatusBarStateController
16 import com.android.systemui.qs.QSHost
17 import com.android.systemui.qs.QsEventLogger
18 import com.android.systemui.qs.logging.QSLogger
19 import com.android.systemui.settings.UserTracker
20 import com.android.systemui.statusbar.policy.NextAlarmController
21 import com.android.systemui.util.mockito.capture
22 import com.android.systemui.util.mockito.eq
23 import com.google.common.truth.Truth.assertThat
24 import org.junit.After
25 import org.junit.Before
26 import org.junit.Test
27 import org.junit.runner.RunWith
28 import org.mockito.ArgumentCaptor
29 import org.mockito.Captor
30 import org.mockito.Mock
31 import org.mockito.Mockito.verify
32 import org.mockito.Mockito.`when`
33 import org.mockito.MockitoAnnotations
34 
35 @SmallTest
36 @RunWith(AndroidTestingRunner::class)
37 @TestableLooper.RunWithLooper(setAsMainLooper = true)
38 class AlarmTileTest : SysuiTestCase() {
39 
40     @Mock
41     private lateinit var qsHost: QSHost
42     @Mock
43     private lateinit var metricsLogger: MetricsLogger
44     @Mock
45     private lateinit var statusBarStateController: StatusBarStateController
46     @Mock
47     private lateinit var activityStarter: ActivityStarter
48     @Mock
49     private lateinit var qsLogger: QSLogger
50     @Mock
51     private lateinit var userTracker: UserTracker
52     @Mock
53     private lateinit var nextAlarmController: NextAlarmController
54     @Mock
55     private lateinit var uiEventLogger: QsEventLogger
56     @Mock
57     private lateinit var pendingIntent: PendingIntent
58     @Captor
59     private lateinit var callbackCaptor: ArgumentCaptor<NextAlarmController.NextAlarmChangeCallback>
60 
61     private lateinit var testableLooper: TestableLooper
62     private lateinit var tile: AlarmTile
63 
64     @Before
65     fun setUp() {
66         MockitoAnnotations.initMocks(this)
67         testableLooper = TestableLooper.get(this)
68 
69         `when`(qsHost.context).thenReturn(mContext)
70 
71         tile = AlarmTile(
72             qsHost,
73             uiEventLogger,
74             testableLooper.looper,
75             Handler(testableLooper.looper),
76             FalsingManagerFake(),
77             metricsLogger,
78             statusBarStateController,
79             activityStarter,
80             qsLogger,
81             userTracker,
82             nextAlarmController
83         )
84 
85         tile.initialize()
86 
87         verify(nextAlarmController).observe(eq(tile), capture(callbackCaptor))
88         tile.refreshState()
89         testableLooper.processAllMessages()
90     }
91 
92     @After
93     fun tearDown() {
94         tile.destroy()
95         testableLooper.processAllMessages()
96     }
97 
98     @Test
99     fun testAvailable() {
100         assertThat(tile.isAvailable).isTrue()
101     }
102 
103     @Test
104     fun testDoesntHandleLongClick() {
105         assertThat(tile.state.handlesLongClick).isFalse()
106     }
107 
108     @Test
109     fun testDefaultIntentShowAlarms() {
110         assertThat(tile.defaultIntent.action).isEqualTo(AlarmClock.ACTION_SHOW_ALARMS)
111     }
112 
113     @Test
114     fun testInactiveByDefault() {
115         assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
116     }
117 
118     @Test
119     fun testInactiveAfterNullNextAlarm() {
120         callbackCaptor.value.onNextAlarmChanged(null)
121 
122         testableLooper.processAllMessages()
123         assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
124     }
125 
126     @Test
127     fun testActivityStartedWhenNullNextAlarm() {
128         callbackCaptor.value.onNextAlarmChanged(null)
129         tile.click(null /* view */)
130 
131         testableLooper.processAllMessages()
132         verify(activityStarter).postStartActivityDismissingKeyguard(tile.defaultIntent, 0,
133                 null /* animationController */)
134     }
135 
136     @Test
137     fun testActiveAfterNextAlarm() {
138         val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
139         callbackCaptor.value.onNextAlarmChanged(alarmInfo)
140 
141         testableLooper.processAllMessages()
142         assertThat(tile.state.state).isEqualTo(Tile.STATE_ACTIVE)
143     }
144 
145     @Test
146     fun testActivityStartedWhenNextAlarm() {
147         val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
148         callbackCaptor.value.onNextAlarmChanged(alarmInfo)
149         tile.click(null /* view */)
150 
151         testableLooper.processAllMessages()
152         verify(activityStarter).postStartActivityDismissingKeyguard(pendingIntent,
153                 null /* animationController */)
154     }
155 }