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.task.nonrequiredapps; 18 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertTrue; 23 import static org.mockito.ArgumentMatchers.eq; 24 import static org.mockito.ArgumentMatchers.nullable; 25 import static org.mockito.Matchers.anyInt; 26 import static org.mockito.Mockito.never; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.app.admin.DevicePolicyManager; 31 import android.content.ComponentName; 32 import android.content.Context; 33 import android.content.pm.IPackageManager; 34 35 import androidx.test.filters.SmallTest; 36 37 import com.android.managedprovisioning.common.Utils; 38 import com.android.managedprovisioning.model.ProvisioningParams; 39 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.mockito.Mock; 43 import org.mockito.MockitoAnnotations; 44 45 import java.util.Arrays; 46 import java.util.Collections; 47 import java.util.List; 48 import java.util.Set; 49 import java.util.stream.Collectors; 50 51 /** 52 * Unit tests for {@link NonRequiredAppsLogic}. 53 */ 54 @SmallTest 55 public class NonRequiredAppsLogicTest { 56 private static final String TEST_DPC_PACKAGE_NAME = "dpc.package.name"; 57 private static final ComponentName TEST_MDM_COMPONENT_NAME = new ComponentName( 58 TEST_DPC_PACKAGE_NAME, "pc.package.name.DeviceAdmin"); 59 60 private static final int TEST_USER_ID = 123; 61 private static final List<String> APPS = Arrays.asList("app.a", "app.b", "app.c", "app.d", 62 "app.e", "app.f", "app.g", "app.h"); 63 private static final List<Integer> SNAPSHOT_APPS = Arrays.asList(0, 1, 2, 3); 64 private static final List<Integer> SYSTEM_APPS = Arrays.asList(0, 1, 4, 5); 65 private static final List<Integer> BLACKLIST_APPS = Arrays.asList(0, 2, 4, 6); 66 67 @Mock 68 private DevicePolicyManager mDevicePolicyManager; 69 @Mock 70 private IPackageManager mIPackageManager; 71 @Mock 72 private SystemAppsSnapshot mSnapshot; 73 @Mock 74 private Utils mUtils; 75 @Mock 76 private Context mContext; 77 78 private ProvisioningParams.Builder mParamsBuilder; 79 80 @Before setUp()81 public void setUp() throws Exception { 82 MockitoAnnotations.initMocks(this); 83 mParamsBuilder = createParamsBuilder(); 84 when(mUtils.findDeviceAdmin(nullable(String.class), nullable(ComponentName.class), 85 eq(mContext), eq(TEST_USER_ID))).thenReturn(TEST_MDM_COMPONENT_NAME); 86 } 87 88 @Test testGetSystemAppsToRemove_NewLeave()89 public void testGetSystemAppsToRemove_NewLeave() throws Exception { 90 // GIVEN that a new profile is being created and that system apps should not be deleted 91 mParamsBuilder.setLeaveAllSystemAppsEnabled(true); 92 final NonRequiredAppsLogic logic = createLogic(true); 93 // GIVEN that a combination of apps is present 94 initializeApps(); 95 96 // THEN getSystemAppsToRemove should be empty 97 assertTrue(logic.getSystemAppsToRemove(TEST_USER_ID).isEmpty()); 98 } 99 100 @Test testGetSystemAppsToRemove_newProfile_returnsBlacklistedApps()101 public void testGetSystemAppsToRemove_newProfile_returnsBlacklistedApps() throws Exception { 102 // GIVEN that a new profile is being created and that non desired apps should be deleted 103 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 104 final NonRequiredAppsLogic logic = createLogic(/*newProfile= */true); 105 // GIVEN that a combination of apps is present 106 initializeApps(); 107 108 // THEN getSystemAppsToRemove should return a non-empty list with apps to be removed 109 assertEquals(getAppsSet(Arrays.asList(0, 2, 4, 6)), 110 logic.getSystemAppsToRemove(TEST_USER_ID)); 111 } 112 113 @Test testGetSystemAppsToRemove_deviceAdminComponentIsNotGiven_newProfile_returnsBlacklistedApps()114 public void testGetSystemAppsToRemove_deviceAdminComponentIsNotGiven_newProfile_returnsBlacklistedApps() throws Exception { 115 // GIVEN that only device admin package name is given. 116 mParamsBuilder.setDeviceAdminComponentName(null); 117 mParamsBuilder.setDeviceAdminPackageName(TEST_DPC_PACKAGE_NAME); 118 // GIVEN that a new profile is being created and that non desired apps should be deleted 119 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 120 final NonRequiredAppsLogic logic = createLogic(/*newProfile= */true); 121 // GIVEN that a combination of apps is present 122 initializeApps(); 123 124 // THEN getSystemAppsToRemove should return a non-empty list with apps to be removed 125 assertEquals(getAppsSet(Arrays.asList(0, 2, 4, 6)), 126 logic.getSystemAppsToRemove(TEST_USER_ID)); 127 } 128 129 @Test testGetSystemAppsToRemove_OtaLeave()130 public void testGetSystemAppsToRemove_OtaLeave() throws Exception { 131 // GIVEN that an OTA occurs and that system apps should not be deleted (indicated by the 132 // fact that no snapshot currently exists) 133 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 134 final NonRequiredAppsLogic logic = createLogic(false); 135 // GIVEN that a combination of apps is present 136 initializeApps(); 137 // GIVEN that no snapshot currently exists 138 when(mSnapshot.hasSnapshot(TEST_USER_ID)).thenReturn(false); 139 140 // THEN getSystemAppsToRemove should be empty 141 assertTrue(logic.getSystemAppsToRemove(TEST_USER_ID).isEmpty()); 142 } 143 144 @Test testGetSystemAppsToRemove_OtaDelete()145 public void testGetSystemAppsToRemove_OtaDelete() throws Exception { 146 // GIVEN that an OTA occurs and that system apps should be deleted (indicated by the fact 147 // that a snapshot currently exists) 148 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 149 final NonRequiredAppsLogic logic = createLogic(false); 150 // GIVEN that a combination of apps is present 151 initializeApps(); 152 153 // THEN getSystemAppsToRemove should return a non-empty list with the only app to removed 154 // being the one that is a current system app, non required and not in the last 155 // snapshot. 156 assertEquals(Collections.singleton(APPS.get(4)), logic.getSystemAppsToRemove(TEST_USER_ID)); 157 } 158 159 @Test testMaybeTakeSnapshot_NewLeave()160 public void testMaybeTakeSnapshot_NewLeave() { 161 // GIVEN that a new profile is being created and that system apps should not be deleted 162 mParamsBuilder.setLeaveAllSystemAppsEnabled(true); 163 final NonRequiredAppsLogic logic = createLogic(true); 164 165 // WHEN calling maybeTakeSystemAppsSnapshot 166 logic.maybeTakeSystemAppsSnapshot(TEST_USER_ID); 167 168 // THEN no snapshot should be taken 169 verify(mSnapshot, never()).takeNewSnapshot(anyInt()); 170 } 171 172 @Test testMaybeTakeSnapshot_NewDelete()173 public void testMaybeTakeSnapshot_NewDelete() { 174 // GIVEN that a new profile is being created and that system apps should be deleted 175 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 176 final NonRequiredAppsLogic logic = createLogic(true); 177 178 // WHEN calling maybeTakeSystemAppsSnapshot 179 logic.maybeTakeSystemAppsSnapshot(TEST_USER_ID); 180 181 // THEN a snapshot should be taken 182 verify(mSnapshot).takeNewSnapshot(TEST_USER_ID); 183 } 184 185 @Test testMaybeTakeSnapshot_OtaLeave()186 public void testMaybeTakeSnapshot_OtaLeave() { 187 // GIVEN that an OTA occurs and that system apps should not be deleted (indicated by the 188 // fact that no snapshot currently exists) 189 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 190 final NonRequiredAppsLogic logic = createLogic(false); 191 when(mSnapshot.hasSnapshot(TEST_USER_ID)).thenReturn(false); 192 193 // WHEN calling maybeTakeSystemAppsSnapshot 194 logic.maybeTakeSystemAppsSnapshot(TEST_USER_ID); 195 196 // THEN no snapshot should be taken 197 verify(mSnapshot, never()).takeNewSnapshot(anyInt()); 198 } 199 200 @Test testMaybeTakeSnapshot_OtaDelete()201 public void testMaybeTakeSnapshot_OtaDelete() { 202 // GIVEN that an OTA occurs and that system apps should be deleted (indicated by the fact 203 // that a snapshot currently exists) 204 mParamsBuilder.setLeaveAllSystemAppsEnabled(false); 205 final NonRequiredAppsLogic logic = createLogic(false); 206 when(mSnapshot.hasSnapshot(TEST_USER_ID)).thenReturn(true); 207 208 // WHEN calling maybeTakeSystemAppsSnapshot 209 logic.maybeTakeSystemAppsSnapshot(TEST_USER_ID); 210 211 // THEN a snapshot should be taken 212 verify(mSnapshot).takeNewSnapshot(TEST_USER_ID); 213 } 214 initializeApps()215 private void initializeApps() throws Exception { 216 setCurrentSystemApps(getAppsSet(SYSTEM_APPS)); 217 setLastSnapshot(getAppsSet(SNAPSHOT_APPS)); 218 setNonRequiredApps(getAppsSet(BLACKLIST_APPS)); 219 } 220 setCurrentSystemApps(Set<String> set)221 private void setCurrentSystemApps(Set<String> set) { 222 when(mUtils.getCurrentSystemApps(mIPackageManager, TEST_USER_ID)).thenReturn(set); 223 } 224 setLastSnapshot(Set<String> set)225 private void setLastSnapshot(Set<String> set) { 226 when(mSnapshot.getSnapshot(TEST_USER_ID)).thenReturn(set); 227 when(mSnapshot.hasSnapshot(TEST_USER_ID)).thenReturn(true); 228 } 229 setNonRequiredApps(Set<String> set)230 private void setNonRequiredApps(Set<String> set) { 231 when(mDevicePolicyManager.getDisallowedSystemApps(TEST_MDM_COMPONENT_NAME, TEST_USER_ID, 232 ACTION_PROVISION_MANAGED_DEVICE)).thenReturn(set); 233 } 234 getAppsSet(List<Integer> ids)235 private Set<String> getAppsSet(List<Integer> ids) { 236 return ids.stream().map(APPS::get).collect(Collectors.toSet()); 237 } 238 createLogic(boolean newProfile)239 private NonRequiredAppsLogic createLogic(boolean newProfile) { 240 return new NonRequiredAppsLogic( 241 mContext, 242 mIPackageManager, 243 mDevicePolicyManager, 244 newProfile, 245 mParamsBuilder.build(), 246 mSnapshot, 247 mUtils); 248 } 249 createParamsBuilder()250 private ProvisioningParams.Builder createParamsBuilder() { 251 return new ProvisioningParams.Builder() 252 .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE) 253 .setDeviceAdminComponentName(TEST_MDM_COMPONENT_NAME); 254 } 255 } 256