1 /*
2  * Copyright (C) 2022 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.statusbar.policy
18 
19 import android.content.Context
20 import android.content.Intent
21 import android.content.IntentFilter
22 import android.content.pm.PackageManager
23 import android.net.Uri
24 import android.os.Handler
25 import android.safetycenter.SafetyCenterManager
26 import android.testing.AndroidTestingRunner
27 import androidx.test.filters.SmallTest
28 import com.android.systemui.SysuiTestCase
29 import com.android.systemui.util.mockito.any
30 import org.junit.Assert.assertEquals
31 import org.junit.Before
32 import org.junit.Test
33 import org.junit.runner.RunWith
34 import org.mockito.ArgumentCaptor
35 import org.mockito.ArgumentMatchers.eq
36 import org.mockito.ArgumentMatchers.same
37 import org.mockito.Mock
38 import org.mockito.MockitoAnnotations
39 import org.mockito.Mockito.never
40 import org.mockito.Mockito.reset
41 import org.mockito.Mockito.times
42 import org.mockito.Mockito.verify
43 import org.mockito.Mockito.`when`
44 
45 @SmallTest
46 @RunWith(AndroidTestingRunner::class)
47 class SafetyControllerTest : SysuiTestCase() {
48 
49     private val TEST_PC_PKG = "testPermissionControllerPackageName"
50     private val OTHER_PKG = "otherPackageName"
51 
52     @Mock
53     private lateinit var context: Context
54     @Mock
55     private lateinit var scm: SafetyCenterManager
56     @Mock
57     private lateinit var pm: PackageManager
58     @Mock
59     private lateinit var handler: Handler
60     @Mock
61     private lateinit var listener: SafetyController.Listener
62 
63     private val packageDataScheme = "package"
64 
65     private lateinit var controller: SafetyController
66 
67     @Before
68     fun setUp() {
69         MockitoAnnotations.initMocks(this)
70         `when`(pm.permissionControllerPackageName).thenReturn(TEST_PC_PKG)
71         `when`(scm.isSafetyCenterEnabled).thenReturn(false)
72         `when`(handler.post(any(Runnable::class.java))).thenAnswer {
73             (it.arguments[0] as Runnable).run()
74             true
75         }
76 
77         controller = SafetyController(context, pm, scm, handler)
78     }
79 
80     @Test
81     fun addingFirstListenerRegistersReceiver() {
82         `when`(scm.isSafetyCenterEnabled).thenReturn(true)
83         controller.addCallback(listener)
84         verify(listener, times(1)).onSafetyCenterEnableChanged(true)
85         val filter = ArgumentCaptor.forClass(IntentFilter::class.java)
86         verify(context, times(1)).registerReceiver(
87             same(controller.mPermControllerChangeReceiver), filter.capture())
88         assertEquals(Intent.ACTION_PACKAGE_CHANGED, filter.value.getAction(0))
89         assertEquals(packageDataScheme, filter.value.getDataScheme(0))
90     }
91 
92     @Test
93     fun removingLastListenerDeregistersReceiver() {
94         controller.addCallback(listener)
95         controller.removeCallback(listener)
96         verify(context, times(1)).unregisterReceiver(
97             eq(controller.mPermControllerChangeReceiver))
98     }
99 
100     @Test
101     fun listenersCalledWhenBroadcastReceivedWithPCPackageAndStateChange() {
102         `when`(scm.isSafetyCenterEnabled).thenReturn(false)
103         controller.addCallback(listener)
104         reset(listener)
105         `when`(scm.isSafetyCenterEnabled).thenReturn(true)
106         val testIntent = Intent(Intent.ACTION_PACKAGE_CHANGED)
107         testIntent.data = Uri.parse("package:$TEST_PC_PKG")
108         controller.mPermControllerChangeReceiver.onReceive(context, testIntent)
109         verify(listener, times(1)).onSafetyCenterEnableChanged(true)
110     }
111 
112     @Test
113     fun listenersNotCalledWhenBroadcastReceivedWithOtherPackage() {
114         `when`(scm.isSafetyCenterEnabled).thenReturn(true)
115         controller.addCallback(listener)
116         reset(listener)
117         val testIntent = Intent(Intent.ACTION_PACKAGE_CHANGED)
118         testIntent.data = Uri.parse("package:$OTHER_PKG")
119         controller.mPermControllerChangeReceiver.onReceive(context, testIntent)
120         verify(listener, never()).onSafetyCenterEnableChanged(true)
121     }
122 
123     @Test
124     fun listenersNotCalledWhenBroadcastReceivedWithNoStateChange() {
125         `when`(scm.isSafetyCenterEnabled).thenReturn(false)
126         controller.addCallback(listener)
127         reset(listener)
128         val testIntent = Intent(Intent.ACTION_PACKAGE_CHANGED)
129         testIntent.data = Uri.parse("package:$TEST_PC_PKG")
130         controller.mPermControllerChangeReceiver.onReceive(context, testIntent)
131         verify(listener, never()).onSafetyCenterEnableChanged(true)
132     }
133 }