Home | History | Annotate | Download | only in task
      1 /*
      2  * Copyright (C) 2015 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;
     18 
     19 import android.content.pm.ActivityInfo;
     20 import android.content.pm.ApplicationInfo;
     21 import android.content.pm.IPackageDeleteObserver;
     22 import android.content.pm.IPackageManager;
     23 import android.content.pm.PackageInfo;
     24 import android.content.pm.PackageManager;
     25 import android.content.pm.PackageManager.NameNotFoundException;
     26 import android.content.pm.ParceledListSlice;
     27 import android.content.pm.ResolveInfo;
     28 import android.content.pm.ServiceInfo;
     29 import android.content.res.Resources;
     30 import android.content.Context;
     31 import android.content.Intent;
     32 import android.os.RemoteException;
     33 import android.test.AndroidTestCase;
     34 import android.test.mock.MockPackageManager;
     35 import android.test.suitebuilder.annotation.SmallTest;
     36 import android.view.inputmethod.InputMethodInfo;
     37 
     38 import com.android.internal.view.IInputMethodManager;
     39 
     40 import java.io.File;
     41 import java.util.Arrays;
     42 import java.util.ArrayList;
     43 import java.util.Collections;
     44 import java.util.HashSet;
     45 import java.util.List;
     46 import java.util.Set;
     47 
     48 import static org.mockito.Mockito.any;
     49 import static org.mockito.Mockito.anyInt;
     50 import static org.mockito.Mockito.anyString;
     51 import static org.mockito.Mockito.doAnswer;
     52 import static org.mockito.Mockito.eq;
     53 import static org.mockito.Mockito.mock;
     54 import static org.mockito.Mockito.times;
     55 import static org.mockito.Mockito.verify;
     56 import static org.mockito.Mockito.when;
     57 
     58 import org.mockito.invocation.InvocationOnMock;
     59 import org.mockito.stubbing.Answer;
     60 import org.mockito.Mock;
     61 import org.mockito.MockitoAnnotations;
     62 
     63 public class DeleteNonRequiredAppsTaskTest extends AndroidTestCase {
     64 
     65     private @Mock Resources mResources;
     66     private @Mock IPackageManager mIPackageManager;
     67     private @Mock IInputMethodManager mIInputMethodManager;
     68     private @Mock DeleteNonRequiredAppsTask.Callback mCallback;
     69     private @Mock Context mTestContext;
     70 
     71     private FakePackageManager mPackageManager;
     72 
     73     private static final String TEST_MDM_PACKAGE_NAME = "mdm.package.name";
     74     private static final int TEST_USER_ID = 0;
     75     private Set<String> mDeletedApps;
     76     private String[] mSystemAppsWithLauncher;
     77     private Set<String> mInstalledApplications;
     78 
     79     @Override
     80     protected void setUp() throws Exception {
     81         // this is necessary for mockito to work
     82         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
     83 
     84         MockitoAnnotations.initMocks(this);
     85 
     86         mPackageManager = new FakePackageManager();
     87 
     88         when(mTestContext.getResources()).thenReturn(mResources);
     89         when(mTestContext.getPackageManager()).thenReturn(mPackageManager);
     90         when(mTestContext.getFilesDir()).thenReturn(getContext().getFilesDir());
     91 
     92         mDeletedApps = new HashSet<String>();
     93 
     94         setSystemInputMethods();
     95         setRequiredAppsManagedDevice();
     96         setVendorRequiredAppsManagedDevice();
     97         setDisallowedAppsManagedDevice();
     98         setVendorDisallowedAppsManagedDevice();
     99         setRequiredAppsManagedProfile();
    100         setVendorRequiredAppsManagedProfile();
    101         setDisallowedAppsManagedProfile();
    102         setVendorDisallowedAppsManagedProfile();
    103         setRequiredAppsManagedUser();
    104         setVendorRequiredAppsManagedUser();
    105         setDisallowedAppsManagedUser();
    106         setVendorDisallowedAppsManagedUser();
    107     }
    108 
    109     // We run most methods for device owner only, and we'll assume they also work for profile owner.
    110     @SmallTest
    111     public void testOnlyAppsWithLauncherDeletedByDefault() {
    112         setSystemAppsWithLauncher("app.a");
    113         setInstalledSystemApps( "app.a", "app.b");
    114 
    115         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    116 
    117         assertDeletedApps("app.a");
    118         verify(mCallback, times(1)).onSuccess();
    119     }
    120 
    121     @SmallTest
    122     public void testDeviceOwnerRequiredAppsNotDeleted() {
    123         setSystemAppsWithLauncher("app.a", "app.b", "app.c");
    124         setInstalledSystemApps("app.a", "app.b", "app.c");
    125         setRequiredAppsManagedDevice("app.a");
    126         setVendorRequiredAppsManagedDevice("app.b");
    127 
    128         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    129 
    130         assertDeletedApps("app.c");
    131         verify(mCallback, times(1)).onSuccess();
    132     }
    133 
    134     @SmallTest
    135     public void testProfileOwnerRequiredAppsNotDeleted() {
    136         setSystemAppsWithLauncher("app.a", "app.b", "app.c");
    137         setInstalledSystemApps("app.a", "app.b", "app.c");
    138         setRequiredAppsManagedProfile("app.a");
    139         setVendorRequiredAppsManagedProfile("app.b");
    140 
    141         runTask(DeleteNonRequiredAppsTask.PROFILE_OWNER, true, false);
    142 
    143         assertDeletedApps("app.c");
    144         verify(mCallback, times(1)).onSuccess();
    145     }
    146 
    147     @SmallTest
    148     public void testManagedUserRequiredAppsNotDeleted() {
    149         setSystemAppsWithLauncher("app.a", "app.b", "app.c");
    150         setInstalledSystemApps("app.a", "app.b", "app.c");
    151         setRequiredAppsManagedUser("app.a");
    152         setVendorRequiredAppsManagedUser("app.b");
    153 
    154         runTask(DeleteNonRequiredAppsTask.MANAGED_USER, true, false);
    155 
    156         assertDeletedApps("app.c");
    157         verify(mCallback, times(1)).onSuccess();
    158     }
    159 
    160     @SmallTest
    161     public void testMdmNotDeleted() {
    162         setSystemAppsWithLauncher(TEST_MDM_PACKAGE_NAME);
    163         setInstalledSystemApps(TEST_MDM_PACKAGE_NAME);
    164 
    165         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    166 
    167         assertDeletedApps();
    168         verify(mCallback, times(1)).onSuccess();
    169     }
    170 
    171     @SmallTest
    172     public void testDisallowedAppsDeletedEvenIfNoLauncher() {
    173         setSystemAppsWithLauncher();
    174         setInstalledSystemApps("app.a", "app.b", "app.c");
    175         setDisallowedAppsManagedDevice("app.a");
    176         setVendorDisallowedAppsManagedDevice("app.b");
    177 
    178         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    179 
    180         assertDeletedApps("app.a", "app.b");
    181         verify(mCallback, times(1)).onSuccess();
    182     }
    183 
    184     @SmallTest
    185     public void testDeviceOwnerImesNotDeleted() {
    186         setSystemAppsWithLauncher("app.a", "app.b");
    187         setInstalledSystemApps("app.a", "app.b");
    188         setSystemInputMethods("app.a");
    189 
    190         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    191 
    192         assertDeletedApps("app.b");
    193         verify(mCallback, times(1)).onSuccess();
    194     }
    195 
    196     @SmallTest
    197     public void testProfileOwnerImesStillDeleted() {
    198         setSystemAppsWithLauncher("app.a", "app.b");
    199         setInstalledSystemApps("app.a", "app.b");
    200         setSystemInputMethods("app.a");
    201 
    202         runTask(DeleteNonRequiredAppsTask.PROFILE_OWNER, true, false);
    203 
    204         assertDeletedApps("app.a", "app.b");
    205         verify(mCallback, times(1)).onSuccess();
    206     }
    207 
    208     @SmallTest
    209     public void testManagedUserImesNotDeleted() {
    210         setSystemAppsWithLauncher("app.a", "app.b");
    211         setInstalledSystemApps("app.a", "app.b");
    212         setSystemInputMethods("app.a");
    213 
    214         runTask(DeleteNonRequiredAppsTask.MANAGED_USER, true, false);
    215 
    216         assertDeletedApps("app.b");
    217         verify(mCallback, times(1)).onSuccess();
    218     }
    219 
    220     @SmallTest
    221     public void testLeaveAllAppsEnabled() {
    222         setSystemAppsWithLauncher("app.a");
    223         setInstalledSystemApps("app.a");
    224 
    225         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, true);
    226 
    227         assertDeletedApps(); //assert that no app has been deleted.
    228         verify(mCallback, times(1)).onSuccess();
    229     }
    230 
    231     @SmallTest
    232     public void testNewAppsDeletedAfterOta() {
    233         setSystemAppsWithLauncher();
    234         setInstalledSystemApps("app.a");
    235 
    236         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    237 
    238         verify(mCallback, times(1)).onSuccess();
    239         assertDeletedApps(); //assert that no app has been deleted.
    240 
    241         // Now, an OTA happens and installs app.b with a launcher
    242         setSystemAppsWithLauncher("app.b");
    243         setInstalledSystemApps("app.a", "app.b");
    244 
    245         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, false, false);
    246 
    247         assertDeletedApps("app.b");
    248         verify(mCallback, times(2)).onSuccess();
    249     }
    250 
    251     @SmallTest
    252     public void testExistingAppsNotDeletedAgainAfterOta() {
    253         setSystemAppsWithLauncher("app.a");
    254         setInstalledSystemApps("app.a");
    255 
    256         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    257 
    258         verify(mCallback, times(1)).onSuccess();
    259         assertDeletedApps("app.a");
    260         mDeletedApps.clear();
    261 
    262         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, false, false);
    263 
    264         assertDeletedApps();
    265         verify(mCallback, times(2)).onSuccess();
    266     }
    267 
    268     @SmallTest
    269     public void testWhenNoSystemAppsFileFound() {
    270         setSystemAppsWithLauncher("app.a");
    271         setInstalledSystemApps("app.a");
    272 
    273         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    274 
    275         verify(mCallback, times(1)).onSuccess();
    276         assertDeletedApps("app.a");
    277         mDeletedApps.clear();
    278 
    279         setSystemAppsWithLauncher("app.a", "app.b");
    280         setInstalledSystemApps("app.a", "app.b");
    281 
    282         // Now, we set a wrong value to mTestContext.getFilesDir. So it should not find the system apps
    283         // file. So it should not delete any app, but call onError().
    284         when(mTestContext.getFilesDir()).thenReturn(new File(""));
    285         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, false, false);
    286 
    287         assertDeletedApps();
    288         verify(mCallback, times(1)).onError();
    289     }
    290 
    291     @SmallTest
    292     public void testWhenDeletionFails() {
    293         setSystemAppsWithLauncher("app.a");
    294         setInstalledSystemApps("app.a");
    295         mPackageManager.setDeletionSucceeds(false);
    296         runTask(DeleteNonRequiredAppsTask.DEVICE_OWNER, true, false);
    297         verify(mCallback, times(1)).onError();
    298     }
    299 
    300     private void setRequiredAppsManagedDevice(String... apps) {
    301         setStringArray(com.android.managedprovisioning.R.array.required_apps_managed_device,
    302                 apps);
    303     }
    304 
    305     private void setVendorRequiredAppsManagedDevice(String... apps) {
    306         setStringArray(com.android.managedprovisioning.R.array.vendor_required_apps_managed_device,
    307                 apps);
    308     }
    309 
    310     private void setDisallowedAppsManagedDevice(String... apps) {
    311         setStringArray(com.android.managedprovisioning.R.array.disallowed_apps_managed_device,
    312                 apps);
    313     }
    314 
    315     private void setVendorDisallowedAppsManagedDevice(String... apps) {
    316         setStringArray(
    317                 com.android.managedprovisioning.R.array.vendor_disallowed_apps_managed_device,
    318                 apps);
    319     }
    320 
    321     private void setRequiredAppsManagedProfile(String... apps) {
    322         setStringArray(com.android.managedprovisioning.R.array.required_apps_managed_profile,
    323                 apps);
    324     }
    325 
    326     private void setVendorRequiredAppsManagedProfile(String... apps) {
    327         setStringArray(com.android.managedprovisioning.R.array.vendor_required_apps_managed_profile,
    328                 apps);
    329     }
    330 
    331     private void setDisallowedAppsManagedProfile(String... apps) {
    332         setStringArray(com.android.managedprovisioning.R.array.disallowed_apps_managed_profile,
    333                 apps);
    334     }
    335 
    336     private void setVendorDisallowedAppsManagedProfile(String... apps) {
    337         setStringArray(
    338                 com.android.managedprovisioning.R.array.vendor_disallowed_apps_managed_profile,
    339                 apps);
    340     }
    341 
    342     private void setRequiredAppsManagedUser(String... apps) {
    343         setStringArray(com.android.managedprovisioning.R.array.required_apps_managed_user,
    344                 apps);
    345     }
    346 
    347     private void setVendorRequiredAppsManagedUser(String... apps) {
    348         setStringArray(com.android.managedprovisioning.R.array.vendor_required_apps_managed_user,
    349                 apps);
    350     }
    351 
    352     private void setDisallowedAppsManagedUser(String... apps) {
    353         setStringArray(com.android.managedprovisioning.R.array.disallowed_apps_managed_user,
    354                 apps);
    355     }
    356 
    357     private void setVendorDisallowedAppsManagedUser(String... apps) {
    358         setStringArray(
    359                 com.android.managedprovisioning.R.array.vendor_disallowed_apps_managed_user,
    360                 apps);
    361     }
    362 
    363     private void runTask(int type, boolean newProfile, boolean leaveAllSystemAppsEnabled) {
    364         DeleteNonRequiredAppsTask task = new DeleteNonRequiredAppsTask(mTestContext,
    365                 mIPackageManager, mIInputMethodManager, TEST_MDM_PACKAGE_NAME, type, newProfile,
    366                 TEST_USER_ID, leaveAllSystemAppsEnabled, mCallback);
    367         task.run();
    368     }
    369 
    370     private void setStringArray(int resourceId, String[] strs) {
    371         when(mResources.getStringArray(eq(resourceId)))
    372                 .thenReturn(strs);
    373     }
    374 
    375     private void assertDeletedApps(String... appArray) {
    376         assertEquals(setFromArray(appArray), mDeletedApps);
    377     }
    378 
    379     private void setInstalledSystemApps(String... installedApps) {
    380         List<ApplicationInfo> applications = new ArrayList<ApplicationInfo>();
    381         for (String app : installedApps) {
    382             ApplicationInfo aInfo = new ApplicationInfo();
    383             aInfo.flags = ApplicationInfo.FLAG_SYSTEM;
    384             aInfo.packageName = app;
    385             applications.add(aInfo);
    386         }
    387         try {
    388             when(mIPackageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES,
    389                     TEST_USER_ID)).thenReturn(new ParceledListSlice(applications));
    390         } catch (RemoteException e) {
    391             fail(e.toString());
    392         }
    393         mInstalledApplications = setFromArray(installedApps);
    394     }
    395 
    396     private void setSystemInputMethods(String... packageNames) {
    397         List<InputMethodInfo> inputMethods = new ArrayList<InputMethodInfo>();
    398         for (String packageName : packageNames) {
    399             ApplicationInfo aInfo = new ApplicationInfo();
    400             aInfo.flags = ApplicationInfo.FLAG_SYSTEM;
    401             ServiceInfo serviceInfo = new ServiceInfo();
    402             serviceInfo.applicationInfo = aInfo;
    403             serviceInfo.packageName = packageName;
    404             serviceInfo.name = "";
    405             ResolveInfo ri = new ResolveInfo();
    406             ri.serviceInfo = serviceInfo;
    407             InputMethodInfo inputMethodInfo = new InputMethodInfo(ri, false, null, null, 0, false);
    408             inputMethods.add(inputMethodInfo);
    409         }
    410         try {
    411             when(mIInputMethodManager.getInputMethodList()).thenReturn(inputMethods);
    412         } catch (RemoteException e) {
    413             fail(e.toString());
    414         }
    415     }
    416 
    417     private void setSystemAppsWithLauncher(String... apps) {
    418         mSystemAppsWithLauncher = apps;
    419     }
    420 
    421     private <T> Set<T> setFromArray(T[] array) {
    422         return new HashSet<T>(Arrays.asList(array));
    423     }
    424 
    425     class FakePackageManager extends MockPackageManager {
    426         private boolean mDeletionSucceeds = true;
    427 
    428         void setDeletionSucceeds(boolean deletionSucceeds) {
    429             mDeletionSucceeds = deletionSucceeds;
    430         }
    431 
    432         @Override
    433         public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
    434                 int flags, int userId) {
    435             if (mDeletionSucceeds) {
    436                 mDeletedApps.add(packageName);
    437             }
    438             assertTrue((flags & PackageManager.DELETE_SYSTEM_APP) != 0);
    439             assertEquals(TEST_USER_ID, userId);
    440 
    441             int resultCode;
    442             if (mDeletionSucceeds) {
    443                 resultCode = PackageManager.DELETE_SUCCEEDED;
    444             } else {
    445                 resultCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
    446             }
    447 
    448             try {
    449                 observer.packageDeleted(packageName, resultCode);
    450             } catch (RemoteException e) {
    451                 fail(e.toString());
    452             }
    453         }
    454 
    455         @Override
    456         public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
    457             assertTrue("Expected an intent with action ACTION_MAIN and category CATEGORY_LAUNCHER",
    458                     intent.filterEquals(
    459                     new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)));
    460             assertTrue("Expected the flag MATCH_UNINSTALLED_PACKAGES",
    461                     (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0);
    462             assertTrue("Expected the flag MATCH_DISABLED_COMPONENTS",
    463                     (flags & PackageManager.MATCH_DISABLED_COMPONENTS) != 0);
    464             assertTrue("Expected the flag MATCH_ENCRYPTION_AWARE_AND_UNAWARE",
    465                     (flags & PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE) != 0);
    466             assertEquals(userId, TEST_USER_ID);
    467             List<ResolveInfo> result = new ArrayList<ResolveInfo>();
    468             for (String packageName : mSystemAppsWithLauncher) {
    469                 ActivityInfo ai = new ActivityInfo();
    470                 ai.packageName = packageName;
    471                 ResolveInfo ri = new ResolveInfo();
    472                 ri.activityInfo  = ai;
    473                 result.add(ri);
    474             }
    475             return result;
    476         }
    477 
    478         @Override
    479         public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
    480                 throws NameNotFoundException {
    481             if (mInstalledApplications.contains(packageName)) {
    482                 return new PackageInfo();
    483             }
    484             throw new NameNotFoundException();
    485         }
    486     }
    487 }
    488 
    489