• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016, 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.managedprovisioning.ota;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.fail;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.never;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import android.app.admin.DevicePolicyManager;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.content.pm.UserInfo;
31 import android.os.UserHandle;
32 import android.os.UserManager;
33 import android.util.ArraySet;
34 import android.util.Pair;
35 
36 import androidx.test.InstrumentationRegistry;
37 import androidx.test.filters.SmallTest;
38 
39 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
40 import com.android.managedprovisioning.task.AbstractProvisioningTask;
41 import com.android.managedprovisioning.task.CrossProfileIntentFiltersSetter;
42 import com.android.managedprovisioning.task.DeleteNonRequiredAppsTask;
43 import com.android.managedprovisioning.task.DisableInstallShortcutListenersTask;
44 import com.android.managedprovisioning.task.DisallowAddUserTask;
45 import com.android.managedprovisioning.task.InstallExistingPackageTask;
46 import com.android.managedprovisioning.task.MigrateSystemAppsSnapshotTask;
47 import com.android.managedprovisioning.task.UpdateInteractAcrossProfilesAppOpTask;
48 
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 
54 import java.util.ArrayList;
55 import java.util.Collections;
56 import java.util.List;
57 import java.util.function.IntFunction;
58 
59 /**
60  * Unit tests for {@link OtaController}.
61  */
62 @SmallTest
63 public class OtaControllerTest {
64     private static final int DEVICE_OWNER_USER_ID = 12;
65     private static final int MANAGED_PROFILE_USER_ID = 15;
66     private static final int MANAGED_USER_USER_ID = 18;
67 
68     private static final String DUMMY_SYSTEM_IME_PACKAGE_NAME =
69             "com.android.inputmethod.dummysystemime";
70 
71     private static final ComponentName ADMIN_COMPONENT = new ComponentName("com.test.admin",
72             ".AdminReceiver");
73 
74     private static final IntFunction<ArraySet<String>> NO_MISSING_SYSTEM_IME_PROVIDER
75             = userHandle -> new ArraySet<>();
76 
77     @Mock private Context mContext;
78     @Mock private DevicePolicyManager mDevicePolicyManager;
79     @Mock private PackageManager mPackageManager;
80     @Mock private UserManager mUserManager;
81     @Mock private CrossProfileIntentFiltersSetter mCrossProfileIntentFiltersSetter;
82     @Mock private ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker;
83 
84     private TaskExecutor mTaskExecutor;
85 
86     private List<Pair<Integer, AbstractProvisioningTask>> mTasks = new ArrayList<>();
87     private List<UserInfo> mUsers = new ArrayList<>();
88     private List<UserInfo> mProfiles = new ArrayList<>();
89 
90     @Before
setUp()91     public void setUp() {
92         MockitoAnnotations.initMocks(this);
93 
94         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
95                 .thenReturn(mDevicePolicyManager);
96         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
97         when(mContext.getPackageManager()).thenReturn(mPackageManager);
98         when(mContext.getResources())
99                 .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
100 
101         when(mUserManager.getUsers()).thenReturn(mUsers);
102         when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(mProfiles);
103 
104         mTaskExecutor = new FakeTaskExecutor();
105 
106         addSystemUser();
107     }
108 
109     @Test
testDeviceOwnerSystemUser()110     public void testDeviceOwnerSystemUser() {
111         OtaController controller = new OtaController(mContext, mTaskExecutor,
112                 mCrossProfileIntentFiltersSetter, NO_MISSING_SYSTEM_IME_PROVIDER,
113                 mProvisioningAnalyticsTracker);
114 
115         // GIVEN that there is a device owner on the system user
116         setDeviceOwner(UserHandle.USER_SYSTEM, ADMIN_COMPONENT);
117 
118         // WHEN running the OtaController
119         controller.run();
120 
121         // THEN the task list should contain these tasks.
122         assertTaskList(
123                 Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
124                 Pair.create(UserHandle.USER_SYSTEM, DeleteNonRequiredAppsTask.class),
125                 Pair.create(UserHandle.USER_SYSTEM, DisallowAddUserTask.class),
126                 Pair.create(UserHandle.USER_SYSTEM, UpdateInteractAcrossProfilesAppOpTask.class));
127 
128         // THEN cross profile intent filters setter should be invoked for system user
129         verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
130     }
131 
132     @Test
testDeviceOwnerSeparate()133     public void testDeviceOwnerSeparate() {
134         OtaController controller = new OtaController(mContext, mTaskExecutor,
135                 mCrossProfileIntentFiltersSetter, NO_MISSING_SYSTEM_IME_PROVIDER,
136                 mProvisioningAnalyticsTracker);
137 
138         // GIVEN that there is a device owner on a non-system meat user
139         addMeatUser(DEVICE_OWNER_USER_ID);
140         setDeviceOwner(DEVICE_OWNER_USER_ID, ADMIN_COMPONENT);
141 
142         // WHEN running the OtaController
143         controller.run();
144 
145         // THEN the task list should contain DeleteNonRequiredAppsTask and DisallowAddUserTask
146         assertTaskList(
147                 Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
148                 Pair.create(DEVICE_OWNER_USER_ID, DeleteNonRequiredAppsTask.class),
149                 Pair.create(DEVICE_OWNER_USER_ID, DisallowAddUserTask.class),
150                 Pair.create(UserHandle.USER_SYSTEM, UpdateInteractAcrossProfilesAppOpTask.class));
151 
152         // THEN cross profile intent filters setter should be invoked for both users
153         verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
154         verify(mCrossProfileIntentFiltersSetter).resetFilters(DEVICE_OWNER_USER_ID);
155     }
156 
157     @Test
testManagedProfileWithoutMissingSystemIme()158     public void testManagedProfileWithoutMissingSystemIme() {
159         OtaController controller = new OtaController(mContext, mTaskExecutor,
160                 mCrossProfileIntentFiltersSetter, NO_MISSING_SYSTEM_IME_PROVIDER,
161                 mProvisioningAnalyticsTracker);
162 
163         // GIVEN that there is a managed profile
164         addManagedProfile(MANAGED_PROFILE_USER_ID, ADMIN_COMPONENT);
165 
166         // WHEN running the OtaController
167         controller.run();
168 
169         // THEN the task list should contain these tasks.
170         assertTaskList(
171                 Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
172                 Pair.create(MANAGED_PROFILE_USER_ID, InstallExistingPackageTask.class),
173                 Pair.create(MANAGED_PROFILE_USER_ID, DisableInstallShortcutListenersTask.class),
174                 Pair.create(MANAGED_PROFILE_USER_ID, DeleteNonRequiredAppsTask.class),
175                 Pair.create(UserHandle.USER_SYSTEM, UpdateInteractAcrossProfilesAppOpTask.class));
176 
177         // THEN the cross profile intent filters should be reset
178         verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
179         verify(mCrossProfileIntentFiltersSetter, never()).resetFilters(MANAGED_PROFILE_USER_ID);
180 
181         // THEN the DISALLOW_WALLPAPER restriction should be set
182         verify(mUserManager).setUserRestriction(UserManager.DISALLOW_WALLPAPER, true,
183                 UserHandle.of(MANAGED_PROFILE_USER_ID));
184     }
185 
186     @Test
testManagedProfileWithMissingSystemIme()187     public void testManagedProfileWithMissingSystemIme() {
188         IntFunction<ArraySet<String>> missingSystemImeProvider =
189                 (IntFunction<ArraySet<String>>) mock(IntFunction.class);
190 
191         OtaController controller = new OtaController(mContext, mTaskExecutor,
192                 mCrossProfileIntentFiltersSetter, missingSystemImeProvider,
193                 mProvisioningAnalyticsTracker);
194 
195         // GIVEN that there is a managed profile
196         addManagedProfile(MANAGED_PROFILE_USER_ID, ADMIN_COMPONENT);
197 
198         // GIVEN that the managed profile does not have DUMMY_SYSTEM_IME_PACKAGE_NAME.
199         ArraySet<String> missingImes = new ArraySet<>();
200         missingImes.add(DUMMY_SYSTEM_IME_PACKAGE_NAME);
201         when(missingSystemImeProvider.apply(MANAGED_PROFILE_USER_ID)).thenReturn(missingImes);
202 
203         // WHEN running the OtaController
204         controller.run();
205 
206         // THEN the task list should contain these tasks.
207         assertTaskList(
208                 Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
209                 Pair.create(MANAGED_PROFILE_USER_ID, InstallExistingPackageTask.class),
210                 Pair.create(MANAGED_PROFILE_USER_ID, InstallExistingPackageTask.class),
211                 Pair.create(MANAGED_PROFILE_USER_ID, DisableInstallShortcutListenersTask.class),
212                 Pair.create(MANAGED_PROFILE_USER_ID, DeleteNonRequiredAppsTask.class),
213                 Pair.create(UserHandle.USER_SYSTEM, UpdateInteractAcrossProfilesAppOpTask.class));
214 
215         // THEN the cross profile intent filters should be reset
216         verify(mCrossProfileIntentFiltersSetter).resetFilters(UserHandle.USER_SYSTEM);
217         verify(mCrossProfileIntentFiltersSetter, never()).resetFilters(MANAGED_PROFILE_USER_ID);
218 
219         // THEN the DISALLOW_WALLPAPER restriction should be set
220         verify(mUserManager).setUserRestriction(UserManager.DISALLOW_WALLPAPER, true,
221                 UserHandle.of(MANAGED_PROFILE_USER_ID));
222 
223         // THEN the DUMMY_SYSTEM_IME_PACKAGE_NAME should be installed.
224         assertInstallExistingPackageTask(MANAGED_PROFILE_USER_ID, DUMMY_SYSTEM_IME_PACKAGE_NAME);
225     }
226 
227     @Test
testManagedUser()228     public void testManagedUser() {
229         OtaController controller = new OtaController(mContext, mTaskExecutor,
230                 mCrossProfileIntentFiltersSetter, NO_MISSING_SYSTEM_IME_PROVIDER,
231                 mProvisioningAnalyticsTracker);
232 
233         // GIVEN that there is a managed profile
234         addManagedUser(MANAGED_USER_USER_ID, ADMIN_COMPONENT);
235 
236         // WHEN running the OtaController
237         controller.run();
238 
239         // THEN the task list should contain these tasks.
240         assertTaskList(
241                 Pair.create(UserHandle.USER_SYSTEM, MigrateSystemAppsSnapshotTask.class),
242                 Pair.create(MANAGED_USER_USER_ID, DeleteNonRequiredAppsTask.class),
243                 Pair.create(UserHandle.USER_SYSTEM, UpdateInteractAcrossProfilesAppOpTask.class));
244     }
245 
246     private class FakeTaskExecutor extends TaskExecutor {
247 
FakeTaskExecutor()248         public FakeTaskExecutor() {
249             super();
250         }
251 
252         @Override
execute(int userId, AbstractProvisioningTask task)253         public synchronized void execute(int userId, AbstractProvisioningTask task) {
254             mTasks.add(Pair.create(userId, task));
255         }
256     }
257 
addMeatUser(int userId)258     private void addMeatUser(int userId) {
259         UserInfo ui = new UserInfo(userId, null, 0);
260         mUsers.add(ui);
261         when(mUserManager.getProfiles(userId)).thenReturn(Collections.singletonList(ui));
262     }
263 
setDeviceOwner(int userId, ComponentName admin)264     private void setDeviceOwner(int userId, ComponentName admin) {
265         when(mDevicePolicyManager.getDeviceOwnerUserId()).thenReturn(userId);
266         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(admin);
267     }
268 
addManagedProfile(int userId, ComponentName admin)269     private void addManagedProfile(int userId, ComponentName admin) {
270         UserInfo ui = new UserInfo(userId, null, UserInfo.FLAG_MANAGED_PROFILE);
271         mUsers.add(ui);
272         when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
273         when(mUserManager.getProfiles(userId)).thenReturn(Collections.singletonList(ui));
274         mProfiles.add(ui);
275     }
276 
addManagedUser(int userId, ComponentName admin)277     private void addManagedUser(int userId, ComponentName admin) {
278         UserInfo ui = new UserInfo(userId, null, 0);
279         mUsers.add(ui);
280         when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
281     }
282 
addSystemUser()283     private void addSystemUser() {
284         UserInfo ui = new UserInfo(UserHandle.USER_SYSTEM, null, UserInfo.FLAG_PRIMARY);
285         mUsers.add(ui);
286         mProfiles.add(ui);
287     }
288 
assertTaskList(Pair<Integer, Class>.... tasks)289     private void assertTaskList(Pair<Integer, Class>... tasks) {
290         assertEquals(tasks.length, mTasks.size());
291 
292         for (Pair<Integer, Class> task : tasks) {
293             assertTaskListContains(task.first, task.second);
294         }
295     }
296 
assertTaskListContains(Integer userId, Class taskClass)297     private void assertTaskListContains(Integer userId, Class taskClass) {
298         for (Pair<Integer, AbstractProvisioningTask> task : mTasks) {
299             if (userId == task.first && taskClass.isInstance(task.second)) {
300                 return;
301             }
302         }
303         fail("Task for class " + taskClass + " and userId " + userId + " not executed");
304     }
305 
assertInstallExistingPackageTask(int userId, String packageName)306     private void assertInstallExistingPackageTask(int userId, String packageName) {
307         for (Pair<Integer, AbstractProvisioningTask> task : mTasks) {
308             if (userId != task.first || !InstallExistingPackageTask.class.isInstance(task.second)) {
309                 continue;
310             }
311             InstallExistingPackageTask installExistingPackageTask =
312                     (InstallExistingPackageTask) task.second;
313             if (packageName.equals(installExistingPackageTask.getPackageName())) {
314                 return;
315             }
316         }
317         fail("InstallExistingPackageTask for " + packageName + " and userId " + userId
318                 + " not executed");
319     }
320 }
321