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