blob: b9afea155ccf99a215a34fda5bbea646037db378 [file] [log] [blame]
Fabian Kozynski1f32cf02018-10-23 12:23:31 -04001/*
2 * Copyright (C) 2018 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
17package com.android.systemui.appops;
18
19import static org.junit.Assert.assertEquals;
Fabian Kozynski510585d2018-12-19 13:59:17 -050020import static org.mockito.ArgumentMatchers.any;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040021import static org.mockito.ArgumentMatchers.anyBoolean;
22import static org.mockito.ArgumentMatchers.anyInt;
Fabian Kozynski510585d2018-12-19 13:59:17 -050023import static org.mockito.ArgumentMatchers.anyLong;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040024import static org.mockito.ArgumentMatchers.anyString;
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -080025import static org.mockito.ArgumentMatchers.eq;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040026import static org.mockito.Mockito.never;
27import static org.mockito.Mockito.times;
28import static org.mockito.Mockito.verify;
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -080029import static org.mockito.Mockito.when;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040030
31import android.app.AppOpsManager;
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -080032import android.content.pm.PackageManager;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040033import android.os.UserHandle;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040034import android.testing.AndroidTestingRunner;
35import android.testing.TestableLooper;
36
Brett Chabot84151d92019-02-27 15:37:59 -080037import androidx.test.filters.SmallTest;
38
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040039import com.android.systemui.Dependency;
40import com.android.systemui.SysuiTestCase;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040041
42import org.junit.Before;
43import org.junit.Test;
44import org.junit.runner.RunWith;
45import org.mockito.Mock;
46import org.mockito.MockitoAnnotations;
47
48@SmallTest
49@RunWith(AndroidTestingRunner.class)
50@TestableLooper.RunWithLooper
51public class AppOpsControllerTest extends SysuiTestCase {
52 private static final String TEST_PACKAGE_NAME = "test";
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -080053 private static final int TEST_UID = UserHandle.getUid(0, 0);
54 private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0);
55 private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0);
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040056
Fabian Kozynski510585d2018-12-19 13:59:17 -050057 @Mock
58 private AppOpsManager mAppOpsManager;
59 @Mock
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -080060 private PackageManager mPackageManager;
61 @Mock
Fabian Kozynski510585d2018-12-19 13:59:17 -050062 private AppOpsController.Callback mCallback;
63 @Mock
64 private AppOpsControllerImpl.H mMockHandler;
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040065
66 private AppOpsControllerImpl mController;
67
68 @Before
69 public void setUp() {
70 MockitoAnnotations.initMocks(this);
71
72 getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
73
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -080074 // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of
75 // TEST_UID_NON_USER_SENSITIVE are user sensitive.
76 getContext().setMockPackageManager(mPackageManager);
77 when(mPackageManager.getPermissionFlags(anyString(), anyString(),
78 eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn(
79 PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED);
80 when(mPackageManager.getPermissionFlags(anyString(), anyString(),
81 eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn(
82 PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED);
83 when(mPackageManager.getPermissionFlags(anyString(), anyString(),
84 eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0);
85
Fabian Kozynski1f32cf02018-10-23 12:23:31 -040086 mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER));
87 }
88
89 @Test
90 public void testOnlyListenForFewOps() {
91 mController.setListening(true);
92 verify(mAppOpsManager, times(1)).startWatchingActive(AppOpsControllerImpl.OPS, mController);
93 }
94
95 @Test
96 public void testStopListening() {
97 mController.setListening(false);
98 verify(mAppOpsManager, times(1)).stopWatchingActive(mController);
99 }
100
101 @Test
102 public void addCallback_includedCode() {
Fabian Kozynski510585d2018-12-19 13:59:17 -0500103 mController.addCallback(
104 new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_FINE_LOCATION},
105 mCallback);
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400106 mController.onOpActiveChanged(
107 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
Fabian Kozynski0b4592c2018-12-20 12:58:45 -0500108 mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
Fabian Kozynski510585d2018-12-19 13:59:17 -0500109 AppOpsManager.MODE_ALLOWED);
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400110 verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO,
111 TEST_UID, TEST_PACKAGE_NAME, true);
112 }
113
114 @Test
115 public void addCallback_notIncludedCode() {
116 mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
117 mController.onOpActiveChanged(
118 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
119 verify(mCallback, never()).onActiveStateChanged(
120 anyInt(), anyInt(), anyString(), anyBoolean());
121 }
122
123 @Test
124 public void removeCallback_sameCode() {
125 mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
126 mController.removeCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
127 mController.onOpActiveChanged(
128 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
129 verify(mCallback, never()).onActiveStateChanged(
130 anyInt(), anyInt(), anyString(), anyBoolean());
131 }
132
133 @Test
134 public void addCallback_notSameCode() {
135 mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
Fabian Kozynski510585d2018-12-19 13:59:17 -0500136 mController.removeCallback(new int[]{AppOpsManager.OP_CAMERA}, mCallback);
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400137 mController.onOpActiveChanged(
138 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
139 verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO,
140 TEST_UID, TEST_PACKAGE_NAME, true);
141 }
142
143 @Test
144 public void getActiveItems_sameDetails() {
145 mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
146 TEST_UID, TEST_PACKAGE_NAME, true);
147 mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
148 TEST_UID, TEST_PACKAGE_NAME, true);
149 assertEquals(1, mController.getActiveAppOps().size());
150 }
151
152 @Test
153 public void getActiveItems_differentDetails() {
154 mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
155 TEST_UID, TEST_PACKAGE_NAME, true);
156 mController.onOpActiveChanged(AppOpsManager.OP_CAMERA,
157 TEST_UID, TEST_PACKAGE_NAME, true);
Fabian Kozynski0b4592c2018-12-20 12:58:45 -0500158 mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION,
Fabian Kozynski510585d2018-12-19 13:59:17 -0500159 TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
160 assertEquals(3, mController.getActiveAppOps().size());
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400161 }
162
Fabian Kozynski510585d2018-12-19 13:59:17 -0500163 @Test
164 public void getActiveItemsForUser() {
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400165 mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
166 TEST_UID, TEST_PACKAGE_NAME, true);
167 mController.onOpActiveChanged(AppOpsManager.OP_CAMERA,
168 TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
Fabian Kozynski0b4592c2018-12-20 12:58:45 -0500169 mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION,
Fabian Kozynski510585d2018-12-19 13:59:17 -0500170 TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
171 assertEquals(2,
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400172 mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID)).size());
173 assertEquals(1,
Fabian Kozynski510585d2018-12-19 13:59:17 -0500174 mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size());
175 }
176
177 @Test
Philip P. Moltmanne3dbb5a2019-03-07 10:06:11 -0800178 public void nonUserSensitiveOpsAreIgnored() {
179 mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
180 TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true);
181 assertEquals(0, mController.getActiveAppOpsForUser(
182 UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size());
183 }
184
185 @Test
Fabian Kozynski510585d2018-12-19 13:59:17 -0500186 public void opNotedScheduledForRemoval() {
187 mController.setBGHandler(mMockHandler);
Fabian Kozynski0b4592c2018-12-20 12:58:45 -0500188 mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
Fabian Kozynski510585d2018-12-19 13:59:17 -0500189 AppOpsManager.MODE_ALLOWED);
190 verify(mMockHandler).scheduleRemoval(any(AppOpItem.class), anyLong());
Fabian Kozynski1f32cf02018-10-23 12:23:31 -0400191 }
192}