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