blob: 0e81d2b169a381a9089609b0a905369c6a09091f [file] [log] [blame]
/*
* Copyright (C) 2018 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.cts.applicationvisibility;
import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.app.UiAutomation;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import androidx.test.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.List;
import java.util.stream.Stream;
@RunWith(JUnit4.class)
public class ApplicationVisibilityCrossUserTest {
private String TINY_PKG = "android.appsecurity.cts.tinyapp";
private Context mContext;
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getContext();
}
/** Tests getting installed packages for the current user */
@Test
public void testPackageVisibility_currentUser() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final List<PackageInfo> packageList =
pm.getInstalledPackagesAsUser(0, mContext.getUserId());
assertFalse(isAppInPackageList(TINY_PKG, packageList));
}
/** Tests getting installed packages for all users, with cross user permission granted */
@Test
public void testPackageVisibility_anyUserCrossUserGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final List<PackageInfo> packageList =
pm.getInstalledPackagesAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
assertTrue(isAppInPackageList(TINY_PKG, packageList));
}
/** Tests getting installed packages for all users, with cross user permission revoked */
@Test
public void testPackageVisibility_anyUserCrossUserNoGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
try {
ungrantAcrossUsersPermission();
final List<PackageInfo> packageList =
pm.getInstalledPackagesAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
fail("Should have received a security exception");
} catch (SecurityException ignore) {}
}
/** Tests getting installed packages for another user, with cross user permission granted */
@Test
public void testPackageVisibility_otherUserGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final List<PackageInfo> packageList =
pm.getInstalledPackagesAsUser(0, getTestUser());
assertTrue(isAppInPackageList(TINY_PKG, packageList));
}
/** Tests getting installed packages for another user, with cross user permission revoked */
@Test
public void testPackageVisibility_otherUserNoGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
try {
ungrantAcrossUsersPermission();
final List<PackageInfo> packageList =
pm.getInstalledPackagesAsUser(0, getTestUser());
fail("Should have received a security exception");
} catch (SecurityException ignore) {}
}
/** Tests getting installed applications for the current user */
@Test
public void testApplicationVisibility_currentUser() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final List<ApplicationInfo> applicationList =
pm.getInstalledApplicationsAsUser(0, mContext.getUserId());
assertFalse(isAppInApplicationList(TINY_PKG, applicationList));
}
/** Tests getting installed applications for all users, with cross user permission granted */
@Test
public void testApplicationVisibility_anyUserCrossUserGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final List<ApplicationInfo> applicationList =
pm.getInstalledApplicationsAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
assertTrue(isAppInApplicationList(TINY_PKG, applicationList));
}
/** Tests getting installed applications for all users, with cross user permission revoked */
@Test
public void testApplicationVisibility_anyUserCrossUserNoGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
try {
ungrantAcrossUsersPermission();
final List<ApplicationInfo> applicationList =
pm.getInstalledApplicationsAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
fail("Should have received a security exception");
} catch (SecurityException ignore) {}
}
/** Tests getting installed applications for another user, with cross user permission granted */
@Test
public void testApplicationVisibility_otherUserGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final List<ApplicationInfo> applicationList =
pm.getInstalledApplicationsAsUser(0, getTestUser());
assertTrue(isAppInApplicationList(TINY_PKG, applicationList));
}
/** Tests getting installed applications for another user, with cross user permission revoked */
@Test
public void testApplicationVisibility_otherUserNoGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
try {
ungrantAcrossUsersPermission();
final List<ApplicationInfo> applicationList =
pm.getInstalledApplicationsAsUser(0, getTestUser());
fail("Should have received a security exception");
} catch (SecurityException ignore) {}
}
/** Tests getting installed packages for the current user */
@Test
public void testGetPackagesForUidVisibility_currentUser() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final int userId = mContext.getUserId();
final int firstAppUid = UserHandle.getUid(userId, Process.FIRST_APPLICATION_UID);
final int lastAppUid = UserHandle.getUid(userId, Process.LAST_APPLICATION_UID);
boolean found = false;
for (int appUid = firstAppUid; appUid < lastAppUid; appUid++) {
found = isAppInPackageNamesArray(TINY_PKG, pm.getPackagesForUid(appUid));
if (found) break;
}
assertFalse(found);
}
/** Tests getting installed packages for primary user, with cross user permission granted */
@Test
public void testGetPackagesForUidVisibility_anotherUserCrossUserGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
boolean found = false;
for (int appUid = Process.FIRST_APPLICATION_UID; appUid < Process.LAST_APPLICATION_UID;
appUid++) {
found = isAppInPackageNamesArray(TINY_PKG, pm.getPackagesForUid(appUid));
if (found) break;
}
assertTrue(found);
}
/** Tests getting installed packages for primary user, with cross user permission revoked */
@Test
public void testGetPackagesForUidVisibility_anotherUserCrossUserNoGrant() throws Exception {
final PackageManager pm = mContext.getPackageManager();
ungrantAcrossUsersPermission();
try {
for (int appUid = Process.FIRST_APPLICATION_UID; appUid < Process.LAST_APPLICATION_UID;
appUid++) {
isAppInPackageNamesArray(TINY_PKG, pm.getPackagesForUid(appUid));
}
fail("Should have received a security exception");
} catch (SecurityException e) {}
}
/**
* Tests getting the uid of the installed packages for the current user.
**/
@Test
public void testGetPackageUidVisibility_currentUser() {
final PackageManager pm = mContext.getPackageManager();
try {
pm.getPackageUid(TINY_PKG, 0 /*flags*/);
fail("Should have received a NameNotFoundException");
} catch (PackageManager.NameNotFoundException e) {
// Expected
}
}
/**
* Tests getting the uid of the installed packages for primary user,
* with cross user permission granted.
**/
@Test
public void testGetPackageUidVisibility_anotherUserCrossUserGrant() {
final PackageManager pm = mContext.createContextAsUser(UserHandle.of(getTestUser()),
0 /*flags*/).getPackageManager();
try {
pm.getPackageUid(TINY_PKG, MATCH_KNOWN_PACKAGES);
} catch (PackageManager.NameNotFoundException e) {
fail("Should not receive a NameNotFoundException");
}
}
/**
* Tests getting the uid of the installed packages for primary user,
* with cross user permission revoked.
**/
@Test
public void testGetPackageUidVisibility_anotherUserCrossUserNoGrant()
throws PackageManager.NameNotFoundException {
final PackageManager pm = mContext.createContextAsUser(UserHandle.of(getTestUser()),
0 /*flags*/).getPackageManager();
ungrantAcrossUsersPermission();
try {
pm.getPackageUid(TINY_PKG, MATCH_KNOWN_PACKAGES);
fail("Should have received a SecurityException");
} catch (SecurityException e) {
// Expected
}
}
/**
* Tests getting the gids of the installed packages for the current user.
**/
@Test
public void testGetPackageGidsVisibility_currentUser() {
final PackageManager pm = mContext.getPackageManager();
try {
pm.getPackageGids(TINY_PKG, 0 /*flags*/);
fail("Should have received a NameNotFoundException");
} catch (PackageManager.NameNotFoundException e) {
// Expected
}
}
/**
* Tests getting the gids of the installed packages for primary user,
* with cross user permission granted.
**/
@Test
public void testGetPackageGidsVisibility_anotherUserCrossUserGrant() {
final PackageManager pm = mContext.createContextAsUser(UserHandle.of(getTestUser()),
0 /*flags*/).getPackageManager();
try {
pm.getPackageUid(TINY_PKG, MATCH_KNOWN_PACKAGES);
} catch (PackageManager.NameNotFoundException e) {
fail("Should not receive a NameNotFoundException");
}
}
/**
* Tests getting the gids of the installed packages for primary user,
* with cross user permission revoked.
**/
@Test
public void testGetPackageGidsVisibility_anotherUserCrossUserNoGrant()
throws PackageManager.NameNotFoundException {
final PackageManager pm = mContext.createContextAsUser(UserHandle.of(getTestUser()),
0 /*flags*/).getPackageManager();
ungrantAcrossUsersPermission();
try {
pm.getPackageUid(TINY_PKG, MATCH_KNOWN_PACKAGES);
fail("Should have received a SecurityException");
} catch (SecurityException e) {
// Expected
}
}
private boolean isAppInPackageList(String packageName,
List<PackageInfo> packageList) {
for (PackageInfo pkgInfo : packageList) {
if (pkgInfo.packageName.equals(packageName)) {
return true;
}
}
return false;
}
private boolean isAppInApplicationList(
String packageName, List<ApplicationInfo> applicationList) {
for (ApplicationInfo appInfo : applicationList) {
if (appInfo.packageName.equals(packageName)) {
return true;
}
}
return false;
}
private boolean isAppInPackageNamesArray(String packageName, String[] packageNames) {
return packageNames != null && Stream.of(packageNames).anyMatch(
name -> name.equals(packageName));
}
private int getTestUser() {
final Bundle testArguments = InstrumentationRegistry.getArguments();
if (testArguments.containsKey("testUser")) {
try {
return Integer.parseInt(testArguments.getString("testUser"));
} catch (NumberFormatException ignore) {}
}
return mContext.getUserId();
}
private static void ungrantAcrossUsersPermission() {
final Context context = InstrumentationRegistry.getContext();
final PackageManager pm = context.getPackageManager();
final UiAutomation uiAutomation =
InstrumentationRegistry.getInstrumentation().getUiAutomation();
try {
uiAutomation.adoptShellPermissionIdentity();
pm.revokeRuntimePermission(context.getPackageName(),
"android.permission.INTERACT_ACROSS_USERS", Process.myUserHandle());
} finally {
uiAutomation.dropShellPermissionIdentity();
}
}
}