Home | History | Annotate | Download | only in applicationvisibility
      1 /*
      2  * Copyright (C) 2018 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 package com.android.cts.applicationvisibility;
     17 
     18 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
     19 
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertTrue;
     22 import static org.junit.Assert.fail;
     23 
     24 import android.app.UiAutomation;
     25 import android.content.Context;
     26 import android.content.pm.ApplicationInfo;
     27 import android.content.pm.PackageInfo;
     28 import android.content.pm.PackageManager;
     29 import android.os.Bundle;
     30 import android.os.Process;
     31 
     32 import androidx.test.InstrumentationRegistry;
     33 
     34 import org.junit.Before;
     35 import org.junit.Test;
     36 import org.junit.runner.RunWith;
     37 import org.junit.runners.JUnit4;
     38 
     39 import java.util.List;
     40 
     41 @RunWith(JUnit4.class)
     42 public class ApplicationVisibilityCrossUserTest {
     43     private String TINY_PKG = "android.appsecurity.cts.tinyapp";
     44     private Context mContext;
     45 
     46     @Before
     47     public void setUp() throws Exception {
     48         mContext = InstrumentationRegistry.getContext();
     49     }
     50 
     51     /** Tests getting installed packages for the current user */
     52     @Test
     53     public void testPackageVisibility_currentUser() throws Exception {
     54         final PackageManager pm = mContext.getPackageManager();
     55         final List<PackageInfo> packageList =
     56                 pm.getInstalledPackagesAsUser(0, mContext.getUserId());
     57         assertFalse(isAppInPackageList(TINY_PKG, packageList));
     58     }
     59 
     60     /** Tests getting installed packages for all users, with cross user permission granted */
     61     @Test
     62     public void testPackageVisibility_anyUserCrossUserGrant() throws Exception {
     63         final PackageManager pm = mContext.getPackageManager();
     64         final List<PackageInfo> packageList =
     65                 pm.getInstalledPackagesAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
     66         assertTrue(isAppInPackageList(TINY_PKG, packageList));
     67     }
     68 
     69     /** Tests getting installed packages for all users, with cross user permission revoked */
     70     @Test
     71     public void testPackageVisibility_anyUserCrossUserNoGrant() throws Exception {
     72         final PackageManager pm = mContext.getPackageManager();
     73         try {
     74             ungrantAcrossUsersPermission();
     75             final List<PackageInfo> packageList =
     76                     pm.getInstalledPackagesAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
     77             fail("Should have received a security exception");
     78         } catch (SecurityException ignore) {}
     79     }
     80 
     81     /** Tests getting installed packages for another user, with cross user permission granted */
     82     @Test
     83     public void testPackageVisibility_otherUserGrant() throws Exception {
     84         final PackageManager pm = mContext.getPackageManager();
     85         final List<PackageInfo> packageList =
     86                 pm.getInstalledPackagesAsUser(0, getTestUser());
     87         assertTrue(isAppInPackageList(TINY_PKG, packageList));
     88     }
     89 
     90     /** Tests getting installed packages for another user, with cross user permission revoked */
     91     @Test
     92     public void testPackageVisibility_otherUserNoGrant() throws Exception {
     93         final PackageManager pm = mContext.getPackageManager();
     94         try {
     95             ungrantAcrossUsersPermission();
     96             final List<PackageInfo> packageList =
     97                     pm.getInstalledPackagesAsUser(0, getTestUser());
     98             fail("Should have received a security exception");
     99         } catch (SecurityException ignore) {}
    100     }
    101 
    102     /** Tests getting installed applications for the current user */
    103     @Test
    104     public void testApplicationVisibility_currentUser() throws Exception {
    105         final PackageManager pm = mContext.getPackageManager();
    106         final List<ApplicationInfo> applicationList =
    107                 pm.getInstalledApplicationsAsUser(0, mContext.getUserId());
    108         assertFalse(isAppInApplicationList(TINY_PKG, applicationList));
    109     }
    110 
    111     /** Tests getting installed applications for all users, with cross user permission granted */
    112     @Test
    113     public void testApplicationVisibility_anyUserCrossUserGrant() throws Exception {
    114         final PackageManager pm = mContext.getPackageManager();
    115         final List<ApplicationInfo> applicationList =
    116                 pm.getInstalledApplicationsAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
    117         assertTrue(isAppInApplicationList(TINY_PKG, applicationList));
    118     }
    119 
    120     /** Tests getting installed applications for all users, with cross user permission revoked */
    121     @Test
    122     public void testApplicationVisibility_anyUserCrossUserNoGrant() throws Exception {
    123         final PackageManager pm = mContext.getPackageManager();
    124         try {
    125             ungrantAcrossUsersPermission();
    126             final List<ApplicationInfo> applicationList =
    127                     pm.getInstalledApplicationsAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
    128             fail("Should have received a security exception");
    129         } catch (SecurityException ignore) {}
    130     }
    131 
    132     /** Tests getting installed applications for another user, with cross user permission granted */
    133     @Test
    134     public void testApplicationVisibility_otherUserGrant() throws Exception {
    135         final PackageManager pm = mContext.getPackageManager();
    136         final List<ApplicationInfo> applicationList =
    137                 pm.getInstalledApplicationsAsUser(0, getTestUser());
    138         assertTrue(isAppInApplicationList(TINY_PKG, applicationList));
    139     }
    140 
    141     /** Tests getting installed applications for another user, with cross user permission revoked */
    142     @Test
    143     public void testApplicationVisibility_otherUserNoGrant() throws Exception {
    144         final PackageManager pm = mContext.getPackageManager();
    145         try {
    146             ungrantAcrossUsersPermission();
    147             final List<ApplicationInfo> applicationList =
    148                     pm.getInstalledApplicationsAsUser(0, getTestUser());
    149             fail("Should have received a security exception");
    150         } catch (SecurityException ignore) {}
    151     }
    152 
    153     private boolean isAppInPackageList(String packageName,
    154             List<PackageInfo> packageList) {
    155         for (PackageInfo pkgInfo : packageList) {
    156             if (pkgInfo.packageName.equals(packageName)) {
    157                 return true;
    158             }
    159         }
    160         return false;
    161     }
    162 
    163     private boolean isAppInApplicationList(
    164             String packageName, List<ApplicationInfo> applicationList) {
    165         for (ApplicationInfo appInfo : applicationList) {
    166             if (appInfo.packageName.equals(packageName)) {
    167                 return true;
    168             }
    169         }
    170         return false;
    171     }
    172 
    173     private int getTestUser() {
    174         final Bundle testArguments = InstrumentationRegistry.getArguments();
    175         if (testArguments.containsKey("testUser")) {
    176             try {
    177                 return Integer.parseInt(testArguments.getString("testUser"));
    178             } catch (NumberFormatException ignore) {}
    179         }
    180         return mContext.getUserId();
    181     }
    182 
    183     private static void ungrantAcrossUsersPermission() {
    184         final Context context = InstrumentationRegistry.getContext();
    185         final PackageManager pm = context.getPackageManager();
    186         final UiAutomation uiAutomation =
    187                 InstrumentationRegistry.getInstrumentation().getUiAutomation();
    188         try {
    189             uiAutomation.adoptShellPermissionIdentity();
    190             pm.revokeRuntimePermission(context.getPackageName(),
    191                     "android.permission.INTERACT_ACROSS_USERS", Process.myUserHandle());
    192         } finally {
    193             uiAutomation.dropShellPermissionIdentity();
    194         }
    195     }
    196 }
    197