Home | History | Annotate | Download | only in common
      1 /*
      2  * Copyright (C) 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.common;
     18 
     19 import static org.mockito.Mockito.any;
     20 import static org.mockito.Mockito.anyInt;
     21 import static org.mockito.Mockito.eq;
     22 import static org.mockito.Mockito.verify;
     23 import static org.mockito.Mockito.verifyNoMoreInteractions;
     24 import static org.mockito.Mockito.when;
     25 
     26 import android.accounts.AccountManager;
     27 import android.content.ComponentName;
     28 import android.content.Context;
     29 import android.content.Intent;
     30 import android.content.pm.ActivityInfo;
     31 import android.content.pm.ApplicationInfo;
     32 import android.content.pm.IPackageManager;
     33 import android.content.pm.PackageInfo;
     34 import android.content.pm.PackageManager;
     35 import android.content.pm.PackageManager.NameNotFoundException;
     36 import android.content.pm.ParceledListSlice;
     37 import android.content.pm.ResolveInfo;
     38 import android.graphics.Color;
     39 import android.net.ConnectivityManager;
     40 import android.net.NetworkInfo;
     41 import android.os.Build;
     42 import android.test.AndroidTestCase;
     43 import android.test.suitebuilder.annotation.SmallTest;
     44 
     45 import org.mockito.Mock;
     46 import org.mockito.MockitoAnnotations;
     47 
     48 import java.io.FileOutputStream;
     49 import java.util.Arrays;
     50 import java.util.List;
     51 import java.util.Set;
     52 
     53 /**
     54  * Unit-tests for {@link Utils}.
     55  */
     56 @SmallTest
     57 public class UtilsTest extends AndroidTestCase {
     58     private static final String TEST_PACKAGE_NAME_1 = "com.test.packagea";
     59     private static final String TEST_PACKAGE_NAME_2 = "com.test.packageb";
     60     private static final String TEST_DEVICE_ADMIN_NAME = TEST_PACKAGE_NAME_1 + ".DeviceAdmin";
     61     // Another DeviceAdmin in package 1
     62     private static final String TEST_DEVICE_ADMIN_NAME_2 = TEST_PACKAGE_NAME_1 + ".DeviceAdmin2";
     63     private static final ComponentName TEST_COMPONENT_NAME =
     64             new ComponentName(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
     65     private static final ComponentName TEST_COMPONENT_NAME_2 =
     66             new ComponentName(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME_2);
     67     private static final int TEST_USER_ID = 10;
     68     private static final String TEST_FILE_NAME = "testfile";
     69 
     70     @Mock private Context mockContext;
     71     @Mock private AccountManager mockAccountManager;
     72     @Mock private IPackageManager mockIPackageManager;
     73     @Mock private PackageManager mockPackageManager;
     74     @Mock private ConnectivityManager mockConnectivityManager;
     75 
     76     private Utils mUtils;
     77 
     78     @Override
     79     public void setUp() {
     80         // this is necessary for mockito to work
     81         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
     82 
     83         MockitoAnnotations.initMocks(this);
     84 
     85         when(mockContext.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mockAccountManager);
     86         when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
     87         when(mockContext.getSystemService(Context.CONNECTIVITY_SERVICE))
     88                 .thenReturn(mockConnectivityManager);
     89 
     90         mUtils = new Utils();
     91     }
     92 
     93     @Override
     94     public void tearDown() {
     95         mContext.deleteFile(TEST_FILE_NAME);
     96     }
     97 
     98     public void testGetCurrentSystemApps() throws Exception {
     99         // GIVEN two currently installed apps, one of which is system
    100         List<ApplicationInfo> appList = Arrays.asList(
    101                 createApplicationInfo(TEST_PACKAGE_NAME_1, false),
    102                 createApplicationInfo(TEST_PACKAGE_NAME_2, true));
    103         when(mockIPackageManager.getInstalledApplications(
    104                 PackageManager.MATCH_UNINSTALLED_PACKAGES, TEST_USER_ID))
    105                 .thenReturn(new ParceledListSlice<ApplicationInfo>(appList));
    106         // WHEN requesting the current system apps
    107         Set<String> res = mUtils.getCurrentSystemApps(mockIPackageManager, TEST_USER_ID);
    108         // THEN the one system app should be returned
    109         assertEquals(1, res.size());
    110         assertTrue(res.contains(TEST_PACKAGE_NAME_2));
    111     }
    112 
    113     public void testSetComponentEnabledSetting() throws Exception {
    114         // GIVEN a component name and a user id
    115         // WHEN disabling a component
    116         mUtils.setComponentEnabledSetting(mockIPackageManager, TEST_COMPONENT_NAME,
    117                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, TEST_USER_ID);
    118         // THEN the correct method on mockIPackageManager gets invoked
    119         verify(mockIPackageManager).setComponentEnabledSetting(eq(TEST_COMPONENT_NAME),
    120                 eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
    121                 eq(PackageManager.DONT_KILL_APP),
    122                 eq(TEST_USER_ID));
    123         verifyNoMoreInteractions(mockIPackageManager);
    124     }
    125 
    126     public void testPackageRequiresUpdate_notPresent() throws Exception {
    127         // GIVEN that the requested package is not present on the device
    128         // WHEN checking whether an update is required
    129         when(mockPackageManager.getPackageInfo(TEST_PACKAGE_NAME_1, 0))
    130                 .thenThrow(new NameNotFoundException());
    131         // THEN an update is required
    132         assertTrue(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME_1, 0, mockContext));
    133     }
    134 
    135     public void testPackageRequiresUpdate() throws Exception {
    136         // GIVEN a package that is installed on the device
    137         PackageInfo pi = new PackageInfo();
    138         pi.packageName = TEST_PACKAGE_NAME_1;
    139         pi.versionCode = 1;
    140         when(mockPackageManager.getPackageInfo(TEST_PACKAGE_NAME_1, 0)).thenReturn(pi);
    141         // WHEN checking whether an update is required
    142         // THEN verify that update required returns the correct result depending on the minimum
    143         // version code requested.
    144         assertFalse(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME_1, 0, mockContext));
    145         assertFalse(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME_1, 1, mockContext));
    146         assertTrue(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME_1, 2, mockContext));
    147     }
    148 
    149     public void testIsConnectedToNetwork() throws Exception {
    150         // GIVEN the device is currently connected to mobile network
    151         setCurrentNetworkMock(ConnectivityManager.TYPE_MOBILE, true);
    152         // WHEN checking connectivity
    153         // THEN utils should return true
    154         assertTrue(mUtils.isConnectedToNetwork(mockContext));
    155 
    156         // GIVEN the device is currently connected to wifi
    157         setCurrentNetworkMock(ConnectivityManager.TYPE_WIFI, true);
    158         // WHEN checking connectivity
    159         // THEN utils should return true
    160         assertTrue(mUtils.isConnectedToNetwork(mockContext));
    161 
    162         // GIVEN the device is currently disconnected on wifi
    163         setCurrentNetworkMock(ConnectivityManager.TYPE_WIFI, false);
    164         // WHEN checking connectivity
    165         // THEN utils should return false
    166         assertFalse(mUtils.isConnectedToNetwork(mockContext));
    167     }
    168 
    169     public void testIsConnectedToWifi() throws Exception {
    170         // GIVEN the device is currently connected to mobile network
    171         setCurrentNetworkMock(ConnectivityManager.TYPE_MOBILE, true);
    172         // WHEN checking whether connected to wifi
    173         // THEN utils should return false
    174         assertFalse(mUtils.isConnectedToWifi(mockContext));
    175 
    176         // GIVEN the device is currently connected to wifi
    177         setCurrentNetworkMock(ConnectivityManager.TYPE_WIFI, true);
    178         // WHEN checking whether connected to wifi
    179         // THEN utils should return true
    180         assertTrue(mUtils.isConnectedToWifi(mockContext));
    181 
    182         // GIVEN the device is currently disconnected on wifi
    183         setCurrentNetworkMock(ConnectivityManager.TYPE_WIFI, false);
    184         // WHEN checking whether connected to wifi
    185         // THEN utils should return false
    186         assertFalse(mUtils.isConnectedToWifi(mockContext));
    187     }
    188 
    189     public void testGetActiveNetworkInfo() throws Exception {
    190         // GIVEN the device is connected to a network.
    191         final NetworkInfo networkInfo =
    192                 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, null, null);
    193         when(mockConnectivityManager.getActiveNetworkInfo()).thenReturn(networkInfo);
    194         // THEN calling getActiveNetworkInfo should return the correct network info.
    195         assertEquals(mUtils.getActiveNetworkInfo(mockContext), networkInfo);
    196     }
    197 
    198     public void testCurrentLauncherSupportsManagedProfiles_noLauncherSet() throws Exception {
    199         // GIVEN there currently is no default launcher set
    200         when(mockPackageManager.resolveActivity(any(Intent.class), anyInt()))
    201                 .thenReturn(null);
    202         // WHEN checking whether the current launcher support managed profiles
    203         // THEN utils should return false
    204         assertFalse(mUtils.currentLauncherSupportsManagedProfiles(mockContext));
    205     }
    206 
    207     public void testCurrentLauncherSupportsManagedProfiles() throws Exception {
    208         // GIVEN the current default launcher is built against lollipop
    209         setLauncherMock(Build.VERSION_CODES.LOLLIPOP);
    210         // WHEN checking whether the current launcher support managed profiles
    211         // THEN utils should return true
    212         assertTrue(mUtils.currentLauncherSupportsManagedProfiles(mockContext));
    213 
    214         // GIVEN the current default launcher is built against kitkat
    215         setLauncherMock(Build.VERSION_CODES.KITKAT);
    216         // WHEN checking whether the current launcher support managed profiles
    217         // THEN utils should return false
    218         assertFalse(mUtils.currentLauncherSupportsManagedProfiles(mockContext));
    219     }
    220 
    221     public void testFindDeviceAdmin_ComponentName() throws Exception {
    222         // GIVEN a package info with more than one device admin
    223         setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME, TEST_DEVICE_ADMIN_NAME_2);
    224 
    225         // THEN calling findDeviceAdmin returns the correct admin
    226         assertEquals(TEST_COMPONENT_NAME_2,
    227                 mUtils.findDeviceAdmin(null, TEST_COMPONENT_NAME_2, mockContext, TEST_USER_ID));
    228     }
    229 
    230     public void testFindDeviceAdmin_PackageName() throws Exception {
    231         // GIVEN a package info with one device admin
    232         setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
    233 
    234         // THEN calling findDeviceAdmin returns the correct admin
    235         assertEquals(TEST_COMPONENT_NAME,
    236                 mUtils.findDeviceAdmin(
    237                         TEST_PACKAGE_NAME_1, null, mockContext, TEST_USER_ID));
    238     }
    239 
    240     public void testFindDeviceAdmin_NoPackageName() throws Exception {
    241         // GIVEN no package info file
    242         when(mockPackageManager.getPackageInfoAsUser(TEST_PACKAGE_NAME_1,
    243                 PackageManager.GET_RECEIVERS | PackageManager.MATCH_DISABLED_COMPONENTS,
    244                 TEST_USER_ID))
    245                 .thenReturn(null);
    246 
    247         // THEN throw IllegalProvisioningArgumentException
    248         try {
    249             mUtils.findDeviceAdmin(
    250                     TEST_PACKAGE_NAME_1, null, mockContext, TEST_USER_ID);
    251             fail();
    252         } catch (IllegalProvisioningArgumentException e) {
    253             // expected
    254         }
    255     }
    256 
    257     public void testFindDeviceAdmin_AnotherComponentName() throws Exception {
    258         // GIVEN a package info with one device admin
    259         setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
    260 
    261         // THEN looking another device admin throws IllegalProvisioningArgumentException
    262         try {
    263             mUtils.findDeviceAdmin(
    264                     null, TEST_COMPONENT_NAME_2, mockContext, TEST_USER_ID);
    265             fail();
    266         } catch (IllegalProvisioningArgumentException e) {
    267             // expected
    268         }
    269     }
    270 
    271     public void testFindDeviceAdminInPackageInfo_Success() throws Exception {
    272         // GIVEN a package info with one device admin
    273         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
    274 
    275         // THEN calling findDeviceAdminInPackageInfo returns the correct admin
    276         assertEquals(TEST_COMPONENT_NAME,
    277                 mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_1, null, packageInfo));
    278     }
    279 
    280     public void testFindDeviceAdminInPackageInfo_PackageNameMismatch() throws Exception {
    281         // GIVEN a package info with one device admin
    282         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
    283 
    284         // THEN calling findDeviceAdminInPackageInfo with the wrong package name return null
    285         assertNull(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_2, null, packageInfo));
    286     }
    287 
    288     public void testFindDeviceAdminInPackageInfo_NoAdmin() throws Exception {
    289         // GIVEN a package info with no device admin
    290         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1);
    291 
    292         // THEN calling findDeviceAdminInPackageInfo returns null
    293         assertNull(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_1, null, packageInfo));
    294     }
    295 
    296     public void testFindDeviceAdminInPackageInfo_TwoAdmins() throws Exception {
    297         // GIVEN a package info with more than one device admin
    298         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME,
    299                 TEST_DEVICE_ADMIN_NAME_2);
    300 
    301         // THEN calling findDeviceAdminInPackageInfo returns null
    302         assertNull(mUtils.findDeviceAdminInPackageInfo(TEST_PACKAGE_NAME_1, null, packageInfo));
    303     }
    304 
    305     public void testFindDeviceAdminInPackageInfo_TwoAdminsWithComponentName() throws Exception {
    306         // GIVEN a package info with more than one device admin
    307         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME,
    308                 TEST_DEVICE_ADMIN_NAME_2);
    309 
    310         // THEN calling findDeviceAdminInPackageInfo return component 1
    311         assertEquals(TEST_COMPONENT_NAME, mUtils.findDeviceAdminInPackageInfo(
    312                 TEST_PACKAGE_NAME_1, TEST_COMPONENT_NAME, packageInfo));
    313     }
    314 
    315 
    316     public void testFindDeviceAdminInPackageInfo_InvalidComponentName() throws Exception {
    317         // GIVEN a package info with component 1
    318         PackageInfo packageInfo = setUpPackage(TEST_PACKAGE_NAME_1, TEST_DEVICE_ADMIN_NAME);
    319 
    320         // THEN calling findDeviceAdminInPackageInfo with component 2 returns null
    321         assertNull(mUtils.findDeviceAdminInPackageInfo(
    322                 TEST_PACKAGE_NAME_1, TEST_COMPONENT_NAME_2, packageInfo));
    323     }
    324 
    325     public void testComputeHashOfByteArray() {
    326         // GIVEN a byte array
    327         byte[] bytes = "TESTARRAY".getBytes();
    328         // GIVEN its Sha256 hash
    329         byte[] sha256 = new byte[] {100, -45, -118, -68, -104, -15, 63, -60, -84, -44, -13, -63,
    330                 53, -50, 104, -63, 38, 122, 16, -44, -85, -50, 67, 98, 78, 121, 11, 72, 79, 40, 107,
    331                 125};
    332 
    333         // THEN computeHashOfByteArray returns the correct result
    334         assertTrue(Arrays.equals(sha256, mUtils.computeHashOfByteArray(bytes)));
    335     }
    336 
    337     public void testComputeHashOfFile() {
    338         // GIVEN a file with test data
    339         final String fileLocation = getContext().getFilesDir().toString() + "/" + TEST_FILE_NAME;
    340         String string = "Hello world!";
    341         FileOutputStream outputStream;
    342         try {
    343             outputStream = getContext().openFileOutput(TEST_FILE_NAME, Context.MODE_PRIVATE);
    344             outputStream.write(string.getBytes());
    345             outputStream.close();
    346         } catch (Exception e) {
    347             e.printStackTrace();
    348         }
    349         // GIVEN the file's Sha256 hash
    350         byte[] sha256 = new byte[] {-64, 83, 94, 75, -30, -73, -97, -3, -109, 41, 19, 5, 67, 107,
    351                 -8, -119, 49, 78, 74, 63, -82, -64, 94, -49, -4, -69, 125, -13, 26, -39, -27, 26};
    352         // GIVEN the file's Sha1 hash
    353         byte[] sha1 = new byte[] {-45, 72, 106, -23, 19, 110, 120, 86, -68, 66, 33, 35, -123, -22,
    354                 121, 112, -108, 71, 88, 2};
    355 
    356         //THEN the Sha256 hash is correct
    357         assertTrue(
    358                 Arrays.equals(sha256, mUtils.computeHashOfFile(fileLocation, Utils.SHA256_TYPE)));
    359         //THEN the Sha1 hash is correct
    360         assertTrue(Arrays.equals(sha1, mUtils.computeHashOfFile(fileLocation, Utils.SHA1_TYPE)));
    361     }
    362 
    363     public void testComputeHashOfFile_NotPresent() {
    364         // GIVEN no file is present
    365         final String fileLocation = getContext().getFilesDir().toString() + "/" + TEST_FILE_NAME;
    366         getContext().deleteFile(TEST_FILE_NAME);
    367 
    368         // THEN computeHashOfFile should return null
    369         assertNull(mUtils.computeHashOfFile(fileLocation, Utils.SHA256_TYPE));
    370         assertNull(mUtils.computeHashOfFile(fileLocation, Utils.SHA1_TYPE));
    371     }
    372 
    373     public void testBrightColors() {
    374         assertTrue(mUtils.isBrightColor(Color.WHITE));
    375         assertTrue(mUtils.isBrightColor(Color.YELLOW));
    376         assertFalse(mUtils.isBrightColor(Color.BLACK));
    377         assertFalse(mUtils.isBrightColor(Color.BLUE));
    378     }
    379 
    380     public void testCanResolveIntentAsUser() {
    381         // GIVEN intent is null
    382         // THEN intent should not be resolved
    383         assertFalse(mUtils.canResolveIntentAsUser(mockContext, null, TEST_USER_ID));
    384 
    385         // GIVEN a valid intent
    386         Intent intent = new Intent();
    387 
    388         // WHEN resolve activity as user returns null
    389         when(mockPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
    390                 .thenReturn(null);
    391         // THEN intent should not be resolved for user
    392         assertFalse(mUtils.canResolveIntentAsUser(mockContext, intent, TEST_USER_ID));
    393 
    394         // WHEN resolve activity as user returns valid resolve info
    395         when(mockPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
    396                 .thenReturn(new ResolveInfo());
    397         // THEN intent should be resolved
    398         assertTrue(mUtils.canResolveIntentAsUser(mockContext, intent, TEST_USER_ID));
    399     }
    400 
    401     private ApplicationInfo createApplicationInfo(String packageName, boolean system) {
    402         ApplicationInfo ai = new ApplicationInfo();
    403         ai.packageName = packageName;
    404         if (system) {
    405             ai.flags = ApplicationInfo.FLAG_SYSTEM;
    406         }
    407         return ai;
    408     }
    409 
    410     private void setCurrentNetworkMock(int type, boolean connected) {
    411         NetworkInfo networkInfo = new NetworkInfo(type, 0, null, null);
    412         networkInfo.setDetailedState(
    413                 connected ? NetworkInfo.DetailedState.CONNECTED
    414                         : NetworkInfo.DetailedState.DISCONNECTED,
    415                 null, null);
    416         when(mockConnectivityManager.getActiveNetworkInfo()).thenReturn(networkInfo);
    417     }
    418 
    419     private void setLauncherMock(int targetSdkVersion) throws Exception {
    420         ApplicationInfo appInfo = new ApplicationInfo();
    421         appInfo.targetSdkVersion = targetSdkVersion;
    422         ActivityInfo actInfo = new ActivityInfo();
    423         actInfo.packageName = TEST_PACKAGE_NAME_1;
    424         ResolveInfo resInfo = new ResolveInfo();
    425         resInfo.activityInfo = actInfo;
    426 
    427         when(mockPackageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(resInfo);
    428         when(mockPackageManager.getApplicationInfo(TEST_PACKAGE_NAME_1, 0)).thenReturn(appInfo);
    429     }
    430 
    431     private PackageInfo setUpPackage(String packageName, String... adminNames)
    432             throws NameNotFoundException {
    433         PackageInfo packageInfo = new PackageInfo();
    434         packageInfo.packageName = packageName;
    435         packageInfo.receivers = new ActivityInfo[adminNames.length];
    436         for (int i = 0; i < adminNames.length; i++) {
    437             ActivityInfo receiver = new ActivityInfo();
    438             receiver.permission = android.Manifest.permission.BIND_DEVICE_ADMIN;
    439             receiver.name = adminNames[i];
    440             packageInfo.receivers[i] = receiver;
    441         }
    442         when(mockPackageManager.getPackageInfoAsUser(packageName,
    443                 PackageManager.GET_RECEIVERS | PackageManager.MATCH_DISABLED_COMPONENTS,
    444                 TEST_USER_ID))
    445                 .thenReturn(packageInfo);
    446 
    447         return packageInfo;
    448     }
    449 }
    450