/* * Copyright 2016, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.managedprovisioning.task.nonrequiredapps; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.os.RemoteException; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.test.mock.MockPackageManager; import android.view.inputmethod.InputMethodInfo; import com.android.internal.view.IInputMethodManager; import com.android.managedprovisioning.model.ProvisioningParams; import com.android.managedprovisioning.R; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest public class OverlayPackagesProviderTest { private static final String TEST_DPC_PACKAGE_NAME = "dpc.package.name"; private static final int TEST_USER_ID = 123; private @Mock Resources mResources; private @Mock IInputMethodManager mIInputMethodManager; private @Mock Context mTestContext; private Resources mRealResources; private FakePackageManager mPackageManager; private String[] mSystemAppsWithLauncher; private OverlayPackagesProvider mHelper; @Before public void setUp() { MockitoAnnotations.initMocks(this); mPackageManager = new FakePackageManager(); when(mTestContext.getResources()).thenReturn(mResources); when(mTestContext.getPackageManager()).thenReturn(mPackageManager); when(mTestContext.getFilesDir()).thenReturn( InstrumentationRegistry.getTargetContext().getCacheDir()); setSystemInputMethods(); setRequiredAppsManagedDevice(); setVendorRequiredAppsManagedDevice(); setDisallowedAppsManagedDevice(); setVendorDisallowedAppsManagedDevice(); setRequiredAppsManagedProfile(); setVendorRequiredAppsManagedProfile(); setDisallowedAppsManagedProfile(); setVendorDisallowedAppsManagedProfile(); setRequiredAppsManagedUser(); setVendorRequiredAppsManagedUser(); setDisallowedAppsManagedUser(); setVendorDisallowedAppsManagedUser(); mRealResources = InstrumentationRegistry.getTargetContext().getResources(); } @Test public void testAppsWithLauncherAreNonRequiredByDefault() { setSystemAppsWithLauncher("app.a", "app.b"); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired("app.a", "app.b"); } @Test public void testDeviceOwnerRequiredApps() { setSystemAppsWithLauncher("app.a", "app.b", "app.c"); setRequiredAppsManagedDevice("app.a"); setVendorRequiredAppsManagedDevice("app.b"); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired("app.c"); } @Test public void testProfileOwnerRequiredApps() { setSystemAppsWithLauncher("app.a", "app.b", "app.c"); setRequiredAppsManagedProfile("app.a"); setVendorRequiredAppsManagedProfile("app.b"); buildHelper(ACTION_PROVISION_MANAGED_PROFILE, false); verifyAppsAreNonRequired("app.c"); } @Test public void testManagedUserRequiredApps() { setSystemAppsWithLauncher("app.a", "app.b", "app.c"); setRequiredAppsManagedUser("app.a"); setVendorRequiredAppsManagedUser("app.b"); buildHelper(ACTION_PROVISION_MANAGED_USER, false); verifyAppsAreNonRequired("app.c"); } @Test public void testDpcIsRequired() { setSystemAppsWithLauncher("app.a", TEST_DPC_PACKAGE_NAME); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired("app.a"); } @Test public void testDisallowedAppsAreNonRequiredEvenIfNoLauncher() { setSystemAppsWithLauncher(); setDisallowedAppsManagedDevice("app.a"); setVendorDisallowedAppsManagedDevice("app.b"); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired("app.a", "app.b"); } @Test public void testDeviceOwnerImesAreRequired() { setSystemAppsWithLauncher("app.a", "app.b"); setSystemInputMethods("app.a"); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired("app.b"); } @Test public void testProfileOwnerImesAreNonRequired() { setSystemAppsWithLauncher("app.a", "app.b"); setSystemInputMethods("app.a"); buildHelper(ACTION_PROVISION_MANAGED_PROFILE, false); verifyAppsAreNonRequired("app.a", "app.b"); } @Test public void testManagedUserImesAreRequired() { setSystemAppsWithLauncher("app.a", "app.b"); setSystemInputMethods("app.a"); buildHelper(ACTION_PROVISION_MANAGED_USER, false); verifyAppsAreNonRequired("app.b"); } @Test public void testDisallowedAppsAreNonInstalled() { setSystemAppsWithLauncher("app.a"); setDisallowedAppsManagedDevice("app.c"); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired("app.a", "app.c"); } @Test public void testLeaveAllSystemAppsEnabled() { setSystemAppsWithLauncher("app.a", "app.b"); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, true); verifyAppsAreNonRequired(); } /** * If an app is listed as both required and disallowed, it should be only in the disallowed * list. Therefore, it should be present in the non-required list. */ @Test public void testAllowedAndDisallowedAtTheSameTimeManagedDevice() { setDisallowedAppsManagedDevice(TEST_DPC_PACKAGE_NAME); setRequiredAppsManagedDevice(TEST_DPC_PACKAGE_NAME); buildHelper(ACTION_PROVISION_MANAGED_DEVICE, false); verifyAppsAreNonRequired(TEST_DPC_PACKAGE_NAME); } /** * @see {@link #testAllowedAndDisallowedAtTheSameTimeManagedDevice} */ @Test public void testAllowedAndDisallowedAtTheSameTimeManagedUser() { setDisallowedAppsManagedUser(TEST_DPC_PACKAGE_NAME); setRequiredAppsManagedUser(TEST_DPC_PACKAGE_NAME); buildHelper(ACTION_PROVISION_MANAGED_USER, false); verifyAppsAreNonRequired(TEST_DPC_PACKAGE_NAME); } /** * @see {@link #testAllowedAndDisallowedAtTheSameTimeManagedDevice} */ @Test public void testAllowedAndDisallowedAtTheSameTimeManagedProfile() { setDisallowedAppsManagedProfile(TEST_DPC_PACKAGE_NAME); setRequiredAppsManagedProfile(TEST_DPC_PACKAGE_NAME); buildHelper(ACTION_PROVISION_MANAGED_PROFILE, false); verifyAppsAreNonRequired(TEST_DPC_PACKAGE_NAME); } @Test public void testNotRequiredAndDisallowedInResManagedDevice() { verifyEmptyIntersection(R.array.required_apps_managed_device, R.array.disallowed_apps_managed_device); } @Test public void testNotRequiredAndDisallowedInResManagedUser() { verifyEmptyIntersection(R.array.required_apps_managed_user, R.array.disallowed_apps_managed_user); } @Test public void testNotRequiredAndDisallowedInResManagedProfile() { verifyEmptyIntersection(R.array.required_apps_managed_profile, R.array.disallowed_apps_managed_profile); } @Test public void testNotRequiredAndDisallowedInResManagedDeviceVendor() { verifyEmptyIntersection(R.array.vendor_required_apps_managed_device, R.array.vendor_disallowed_apps_managed_device); } @Test public void testNotRequiredAndDisallowedInResManagedUserVendor() { verifyEmptyIntersection(R.array.vendor_required_apps_managed_user, R.array.vendor_disallowed_apps_managed_user); } @Test public void testNotRequiredAndDisallowedInResManagedProfileVendor() { verifyEmptyIntersection(R.array.vendor_required_apps_managed_profile, R.array.vendor_disallowed_apps_managed_profile); } private ArrayList getStringArrayInRealResources(int id) { return new ArrayList<>(Arrays.asList(mRealResources.getStringArray(id))); } private void verifyEmptyIntersection(int requiredId, int disallowedId) { ArrayList required = getStringArrayInRealResources(requiredId); ArrayList disallowed = getStringArrayInRealResources(disallowedId); required.retainAll(disallowed); assertTrue(required.isEmpty()); } private void verifyAppsAreNonRequired(String... appArray) { assertEquals(setFromArray(appArray), mHelper.getNonRequiredApps(TEST_USER_ID)); } private void buildHelper(String action, boolean leaveAllSystemAppsEnabled) { ProvisioningParams params = new ProvisioningParams.Builder() .setProvisioningAction(action) .setDeviceAdminPackageName(TEST_DPC_PACKAGE_NAME) .setLeaveAllSystemAppsEnabled(leaveAllSystemAppsEnabled) .build(); mHelper = new OverlayPackagesProvider(mTestContext, params, mIInputMethodManager); } private void setRequiredAppsManagedDevice(String... apps) { setStringArray(R.array.required_apps_managed_device, apps); } private void setVendorRequiredAppsManagedDevice(String... apps) { setStringArray(R.array.vendor_required_apps_managed_device, apps); } private void setDisallowedAppsManagedDevice(String... apps) { setStringArray(R.array.disallowed_apps_managed_device, apps); } private void setVendorDisallowedAppsManagedDevice(String... apps) { setStringArray(R.array.vendor_disallowed_apps_managed_device, apps); } private void setRequiredAppsManagedProfile(String... apps) { setStringArray(R.array.required_apps_managed_profile, apps); } private void setVendorRequiredAppsManagedProfile(String... apps) { setStringArray(R.array.vendor_required_apps_managed_profile, apps); } private void setDisallowedAppsManagedProfile(String... apps) { setStringArray(R.array.disallowed_apps_managed_profile, apps); } private void setVendorDisallowedAppsManagedProfile(String... apps) { setStringArray(R.array.vendor_disallowed_apps_managed_profile, apps); } private void setRequiredAppsManagedUser(String... apps) { setStringArray(R.array.required_apps_managed_user, apps); } private void setVendorRequiredAppsManagedUser(String... apps) { setStringArray(R.array.vendor_required_apps_managed_user, apps); } private void setDisallowedAppsManagedUser(String... apps) { setStringArray(R.array.disallowed_apps_managed_user, apps); } private void setVendorDisallowedAppsManagedUser(String... apps) { setStringArray(R.array.vendor_disallowed_apps_managed_user, apps); } private void setStringArray(int resourceId, String[] strs) { when(mResources.getStringArray(eq(resourceId))) .thenReturn(strs); } private void setSystemInputMethods(String... packageNames) { List inputMethods = new ArrayList(); for (String packageName : packageNames) { ApplicationInfo aInfo = new ApplicationInfo(); aInfo.flags = ApplicationInfo.FLAG_SYSTEM; ServiceInfo serviceInfo = new ServiceInfo(); serviceInfo.applicationInfo = aInfo; serviceInfo.packageName = packageName; serviceInfo.name = ""; ResolveInfo ri = new ResolveInfo(); ri.serviceInfo = serviceInfo; InputMethodInfo inputMethodInfo = new InputMethodInfo(ri, false, null, null, 0, false); inputMethods.add(inputMethodInfo); } try { when(mIInputMethodManager.getInputMethodList()).thenReturn(inputMethods); } catch (RemoteException e) { fail(e.toString()); } } private void setSystemAppsWithLauncher(String... apps) { mSystemAppsWithLauncher = apps; } private Set setFromArray(T... array) { if (array == null) { return null; } return new HashSet(Arrays.asList(array)); } class FakePackageManager extends MockPackageManager { @Override public List queryIntentActivitiesAsUser(Intent intent, int flags, int userId) { assertTrue("Expected an intent with action ACTION_MAIN", Intent.ACTION_MAIN.equals(intent.getAction())); assertEquals("Expected an intent with category CATEGORY_LAUNCHER", setFromArray(Intent.CATEGORY_LAUNCHER), intent.getCategories()); assertTrue("Expected the flag MATCH_UNINSTALLED_PACKAGES", (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0); assertTrue("Expected the flag MATCH_DISABLED_COMPONENTS", (flags & PackageManager.MATCH_DISABLED_COMPONENTS) != 0); assertTrue("Expected the flag MATCH_DIRECT_BOOT_AWARE", (flags & PackageManager.MATCH_DIRECT_BOOT_AWARE) != 0); assertTrue("Expected the flag MATCH_DIRECT_BOOT_UNAWARE", (flags & PackageManager.MATCH_DIRECT_BOOT_UNAWARE) != 0); assertEquals(userId, TEST_USER_ID); List result = new ArrayList<>(); if (mSystemAppsWithLauncher == null) { return result; } for (String packageName : mSystemAppsWithLauncher) { ActivityInfo ai = new ActivityInfo(); ai.packageName = packageName; ResolveInfo ri = new ResolveInfo(); ri.activityInfo = ai; result.add(ri); } return result; } } }