diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
index 83ef21e7528b5..b0c295c331d79 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
@@ -24,6 +24,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -32,6 +33,7 @@ import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
+import com.android.server.LocalServices;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -108,7 +110,7 @@ class BlobAccessMode {
}
if ((mAccessType & ACCESS_TYPE_SAME_SIGNATURE) != 0) {
- if (checkSignatures(context, callingUid, committerUid)) {
+ if (checkSignatures(callingUid, committerUid)) {
return true;
}
}
@@ -133,11 +135,11 @@ class BlobAccessMode {
/**
* Compare signatures for two packages of different users.
*/
- private boolean checkSignatures(Context context, int uid1, int uid2) {
+ private boolean checkSignatures(int uid1, int uid2) {
final long token = Binder.clearCallingIdentity();
try {
- return context.getPackageManager().checkSignatures(uid1, uid2)
- == PackageManager.SIGNATURE_MATCH;
+ return LocalServices.getService(PackageManagerInternal.class)
+ .checkUidSignaturesForAllUsers(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index c42d836202e50..7cb7c0bed0ea7 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -28,6 +28,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.PackageManager.SignatureResult;
import android.content.pm.SigningDetails.CertCapabilities;
import android.content.pm.overlay.OverlayPaths;
import android.os.Bundle;
@@ -1283,4 +1284,15 @@ public abstract class PackageManagerInternal {
public abstract void shutdown();
public abstract DynamicCodeLogger getDynamicCodeLogger();
+
+ /**
+ * Compare the signatures of two packages that are installed in different users.
+ *
+ * @param uid1 First UID whose signature will be compared.
+ * @param uid2 Second UID whose signature will be compared.
+ * @return {@link PackageManager#SIGNATURE_MATCH} if signatures are matched.
+ * @throws SecurityException if the caller does not hold the
+ * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
+ */
+ public abstract @SignatureResult int checkUidSignaturesForAllUsers(int uid1, int uid2);
}
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index bb8a74493a16a..2b95b11a09cd4 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -25,6 +25,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.os.Binder;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
@@ -129,7 +130,7 @@ public class IntentFirewall {
mObserver.startWatching();
}
- private PackageManagerInternal getPackageManager() {
+ PackageManagerInternal getPackageManager() {
if (mPackageManager == null) {
mPackageManager = LocalServices.getService(PackageManagerInternal.class);
}
@@ -623,12 +624,13 @@ public class IntentFirewall {
}
boolean signaturesMatch(int uid1, int uid2) {
+ final long token = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
- } catch (RemoteException ex) {
- Slog.e(TAG, "Remote exception while checking signatures", ex);
- return false;
+ // Compare signatures of two packages for different users.
+ return getPackageManager()
+ .checkUidSignaturesForAllUsers(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
diff --git a/services/core/java/com/android/server/firewall/SenderFilter.java b/services/core/java/com/android/server/firewall/SenderFilter.java
index 0074119623298..40684fab5c70a 100644
--- a/services/core/java/com/android/server/firewall/SenderFilter.java
+++ b/services/core/java/com/android/server/firewall/SenderFilter.java
@@ -16,14 +16,11 @@
package com.android.server.firewall;
-import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
+import android.content.pm.PackageManagerInternal;
import android.os.Process;
-import android.os.RemoteException;
-import android.util.Slog;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -37,22 +34,12 @@ class SenderFilter {
private static final String VAL_SYSTEM_OR_SIGNATURE = "system|signature";
private static final String VAL_USER_ID = "userId";
- static boolean isPrivilegedApp(int callerUid, int callerPid) {
+ static boolean isPrivilegedApp(PackageManagerInternal pmi, int callerUid, int callerPid) {
if (callerUid == Process.SYSTEM_UID || callerUid == 0 ||
callerPid == Process.myPid() || callerPid == 0) {
return true;
}
-
- IPackageManager pm = AppGlobals.getPackageManager();
- try {
- return (pm.getPrivateFlagsForUid(callerUid) & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
- != 0;
- } catch (RemoteException ex) {
- Slog.e(IntentFirewall.TAG, "Remote exception while retrieving uid flags",
- ex);
- }
-
- return false;
+ return pmi.isUidPrivileged(callerUid);
}
public static final FilterFactory FACTORY = new FilterFactory("sender") {
@@ -89,7 +76,7 @@ class SenderFilter {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
int callerUid, int callerPid, String resolvedType, int receivingUid) {
- return isPrivilegedApp(callerUid, callerPid);
+ return isPrivilegedApp(ifw.getPackageManager(), callerUid, callerPid);
}
};
@@ -97,8 +84,8 @@ class SenderFilter {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
int callerUid, int callerPid, String resolvedType, int receivingUid) {
- return isPrivilegedApp(callerUid, callerPid) ||
- ifw.signaturesMatch(callerUid, receivingUid);
+ return isPrivilegedApp(ifw.getPackageManager(), callerUid, callerPid)
+ || ifw.signaturesMatch(callerUid, receivingUid);
}
};
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index a978fed724c0d..3042667a2e808 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -228,8 +228,28 @@ public interface Computer extends PackageDataSnapshot {
int userId);
boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid,
int userId);
+ /**
+ * Different form {@link #shouldFilterApplication(PackageStateInternal, int, int)}, the function
+ * returns {@code true} if the target package is not found in the device or uninstalled in the
+ * current user. Unless the caller's function needs to handle the package's uninstalled state
+ * by itself, using this function to keep the consistent behavior between conditions of package
+ * uninstalled and visibility not allowed to avoid the side channel leakage of package
+ * existence.
+ *
+ * Package with {@link PackageManager#SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN} is not
+ * treated as an uninstalled package for the carrier apps customization.
+ */
boolean shouldFilterApplicationIncludingUninstalled(@Nullable PackageStateInternal ps,
int callingUid, int userId);
+ /**
+ * Different from {@link #shouldFilterApplication(SharedUserSetting, int, int)}, the function
+ * returns {@code true} if packages with the same shared user are all uninstalled in the current
+ * user.
+ *
+ * @see #shouldFilterApplicationIncludingUninstalled(PackageStateInternal, int, int)
+ */
+ boolean shouldFilterApplicationIncludingUninstalled(@NonNull SharedUserSetting sus,
+ int callingUid, int userId);
int checkUidPermission(String permName, int uid);
int getPackageUidInternal(String packageName, long flags, int userId, int callingUid);
long updateFlagsForApplication(long flags, int userId);
@@ -378,6 +398,8 @@ public interface Computer extends PackageDataSnapshot {
int checkUidSignatures(int uid1, int uid2);
+ int checkUidSignaturesForAllUsers(int uid1, int uid2);
+
boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
@PackageManager.CertificateInputType int type);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index f91026964f661..c545e7d731dc7 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -2793,6 +2793,26 @@ public class ComputerEngine implements Computer {
ps, callingUid, null, TYPE_UNKNOWN, userId, true /* filterUninstall */);
}
+ /**
+ * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int, boolean)
+ */
+ public final boolean shouldFilterApplicationIncludingUninstalled(
+ @NonNull SharedUserSetting sus, int callingUid, int userId) {
+ if (shouldFilterApplication(sus, callingUid, userId)) {
+ return true;
+ }
+ final ArraySet packageStates =
+ (ArraySet) sus.getPackageStates();
+ for (int index = 0; index < packageStates.size(); index++) {
+ final PackageStateInternal ps = packageStates.valueAt(index);
+ if (ps.getUserStateOrDefault(userId).isInstalled() || ps.isHiddenUntilInstalled()) {
+ return false;
+ }
+ }
+ // Filter it, all packages with the same shared uid are uninstalled.
+ return true;
+ }
+
/**
* Verification statuses are ordered from the worse to the best, except for
* INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
@@ -4253,54 +4273,58 @@ public class ComputerEngine implements Computer {
public int checkUidSignatures(int uid1, int uid2) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- // Map to base uids.
- final int appId1 = UserHandle.getAppId(uid1);
- final int appId2 = UserHandle.getAppId(uid2);
- SigningDetails p1SigningDetails;
- SigningDetails p2SigningDetails;
- Object obj = mSettings.getSettingBase(appId1);
- if (obj != null) {
- if (obj instanceof SharedUserSetting) {
- final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- p1SigningDetails = sus.signatures.mSigningDetails;
- } else if (obj instanceof PackageSetting) {
- final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- p1SigningDetails = ps.getSigningDetails();
- } else {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- } else {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- obj = mSettings.getSettingBase(appId2);
- if (obj != null) {
- if (obj instanceof SharedUserSetting) {
- final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- p2SigningDetails = sus.signatures.mSigningDetails;
- } else if (obj instanceof PackageSetting) {
- final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- p2SigningDetails = ps.getSigningDetails();
- } else {
- return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
- }
- } else {
+ final SigningDetails p1SigningDetails =
+ getSigningDetailsAndFilterAccess(uid1, callingUid, callingUserId);
+ final SigningDetails p2SigningDetails =
+ getSigningDetailsAndFilterAccess(uid2, callingUid, callingUserId);
+ if (p1SigningDetails == null || p2SigningDetails == null) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
}
+ @Override
+ public int checkUidSignaturesForAllUsers(int uid1, int uid2) {
+ final int callingUid = Binder.getCallingUid();
+ final int userId1 = UserHandle.getUserId(uid1);
+ final int userId2 = UserHandle.getUserId(uid2);
+ enforceCrossUserPermission(callingUid, userId1, false /* requireFullPermission */,
+ false /* checkShell */, "checkUidSignaturesForAllUsers");
+ enforceCrossUserPermission(callingUid, userId2, false /* requireFullPermission */,
+ false /* checkShell */, "checkUidSignaturesForAllUsers");
+ final SigningDetails p1SigningDetails =
+ getSigningDetailsAndFilterAccess(uid1, callingUid, userId1);
+ final SigningDetails p2SigningDetails =
+ getSigningDetailsAndFilterAccess(uid2, callingUid, userId2);
+ if (p1SigningDetails == null || p2SigningDetails == null) {
+ return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
+ }
+ return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
+ }
+
+ private SigningDetails getSigningDetailsAndFilterAccess(int uid, int callingUid, int userId) {
+ // Map to base uids.
+ final int appId = UserHandle.getAppId(uid);
+ final Object obj = mSettings.getSettingBase(appId);
+ if (obj == null) {
+ return null;
+ }
+ if (obj instanceof SharedUserSetting) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, userId)) {
+ return null;
+ }
+ return sus.signatures.mSigningDetails;
+ } else if (obj instanceof PackageSetting) {
+ final PackageSetting ps = (PackageSetting) obj;
+ if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId)) {
+ return null;
+ }
+ return ps.getSigningDetails();
+ }
+ return null;
+ }
+
private int checkSignaturesInternal(SigningDetails p1SigningDetails,
SigningDetails p2SigningDetails) {
if (p1SigningDetails == null) {
@@ -4363,27 +4387,9 @@ public class ComputerEngine implements Computer {
@PackageManager.CertificateInputType int type) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- // Map to base uids.
- final int appId = UserHandle.getAppId(uid);
- final SigningDetails signingDetails;
- final Object obj = mSettings.getSettingBase(appId);
- if (obj != null) {
- if (obj instanceof SharedUserSetting) {
- final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
- return false;
- }
- signingDetails = sus.signatures.mSigningDetails;
- } else if (obj instanceof PackageSetting) {
- final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
- return false;
- }
- signingDetails = ps.getSigningDetails();
- } else {
- return false;
- }
- } else {
+ final SigningDetails signingDetails =
+ getSigningDetailsAndFilterAccess(uid, callingUid, callingUserId);
+ if (signingDetails == null) {
return false;
}
switch (type) {
@@ -4446,13 +4452,13 @@ public class ComputerEngine implements Computer {
final Object obj = mSettings.getSettingBase(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, callingUserId)) {
return null;
}
return sus.name + ":" + sus.mAppId;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, callingUserId)) {
return null;
}
return ps.getPackageName();
@@ -4481,14 +4487,14 @@ public class ComputerEngine implements Computer {
final Object obj = mSettings.getSettingBase(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, callingUserId)) {
names[i] = null;
} else {
names[i] = "shared:" + sus.name;
}
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, callingUserId)) {
names[i] = null;
} else {
names[i] = ps.getPackageName();
@@ -4510,7 +4516,7 @@ public class ComputerEngine implements Computer {
return Process.INVALID_UID;
}
final SharedUserSetting suid = mSettings.getSharedUserFromId(sharedUserName);
- if (suid != null && !shouldFilterApplication(suid, callingUid,
+ if (suid != null && !shouldFilterApplicationIncludingUninstalled(suid, callingUid,
UserHandle.getUserId(callingUid))) {
return suid.mAppId;
}
@@ -4531,13 +4537,13 @@ public class ComputerEngine implements Computer {
final Object obj = mSettings.getSettingBase(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, callingUserId)) {
return 0;
}
return sus.getFlags();
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, callingUserId)) {
return 0;
}
return ps.getFlags();
@@ -4559,13 +4565,13 @@ public class ComputerEngine implements Computer {
final Object obj = mSettings.getSettingBase(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplication(sus, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, callingUserId)) {
return 0;
}
return sus.getPrivateFlags();
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, callingUserId)) {
return 0;
}
return ps.getPrivateFlags();
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index 618403f7781d4..b594866fdf442 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -720,6 +720,11 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {
return snapshot().isUidPrivileged(uid);
}
+ @Override
+ public int checkUidSignaturesForAllUsers(int uid1, int uid2) {
+ return snapshot().checkUidSignaturesForAllUsers(uid1, uid2);
+ }
+
@NonNull
@Override
@Deprecated
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java
index a7ba45f0c4c2b..d7b442c8eaf8a 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java
+++ b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java
@@ -27,6 +27,8 @@ import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.KeySet;
+import android.content.pm.PackageManager;
+import android.os.Process;
import android.os.UserHandle;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -56,8 +58,12 @@ public class CrossUserPackageVisibilityTests {
private static final String TEST_DATA_DIR = "/data/local/tmp/appenumerationtests";
private static final String CROSS_USER_TEST_PACKAGE_NAME =
"com.android.appenumeration.crossuserpackagevisibility";
+ private static final String SHARED_USER_TEST_PACKAGE_NAME =
+ "com.android.appenumeration.shareduid";
private static final File CROSS_USER_TEST_APK_FILE =
new File(TEST_DATA_DIR, "AppEnumerationCrossUserPackageVisibilityTestApp.apk");
+ private static final File SHARED_USER_TEST_APK_FILE =
+ new File(TEST_DATA_DIR, "AppEnumerationSharedUserTestApp.apk");
@ClassRule
@Rule
@@ -66,6 +72,7 @@ public class CrossUserPackageVisibilityTests {
private Instrumentation mInstrumentation;
private IPackageManager mIPackageManager;
private Context mContext;
+ private UserReference mCurrentUser;
private UserReference mOtherUser;
@Before
@@ -77,17 +84,21 @@ public class CrossUserPackageVisibilityTests {
// Get another user
final UserReference primaryUser = sDeviceState.primaryUser();
if (primaryUser.id() == UserHandle.myUserId()) {
+ mCurrentUser = primaryUser;
mOtherUser = sDeviceState.secondaryUser();
} else {
+ mCurrentUser = sDeviceState.secondaryUser();
mOtherUser = primaryUser;
}
uninstallPackage(CROSS_USER_TEST_PACKAGE_NAME);
+ uninstallPackage(SHARED_USER_TEST_PACKAGE_NAME);
}
@After
public void tearDown() {
uninstallPackage(CROSS_USER_TEST_PACKAGE_NAME);
+ uninstallPackage(SHARED_USER_TEST_PACKAGE_NAME);
}
@Test
@@ -151,16 +162,61 @@ public class CrossUserPackageVisibilityTests {
assertThat(e1.getMessage()).isEqualTo(e2.getMessage());
}
+ @Test
+ public void testGetFlagsForUid_cannotDetectCrossUserPkg() throws Exception {
+ installPackage(CROSS_USER_TEST_APK_FILE);
+ final int uid = mContext.getPackageManager().getPackageUid(
+ CROSS_USER_TEST_PACKAGE_NAME, PackageManager.PackageInfoFlags.of(0));
+
+ uninstallPackageForUser(CROSS_USER_TEST_PACKAGE_NAME, mCurrentUser);
+
+ assertThat(mIPackageManager.getFlagsForUid(uid)).isEqualTo(0);
+ }
+
+ @Test
+ public void testGetUidForSharedUser_cannotDetectSharedUserPkg() throws Exception {
+ assertThat(mIPackageManager.getUidForSharedUser(SHARED_USER_TEST_PACKAGE_NAME))
+ .isEqualTo(Process.INVALID_UID);
+
+ installPackageForUser(SHARED_USER_TEST_APK_FILE, mOtherUser, true /* forceQueryable */);
+
+ assertThat(mIPackageManager.getUidForSharedUser(SHARED_USER_TEST_PACKAGE_NAME))
+ .isEqualTo(Process.INVALID_UID);
+ }
+
+ private static void installPackage(File apk) {
+ installPackageForUser(apk, null, false /* forceQueryable */);
+ }
+
private static void installPackageForUser(File apk, UserReference user) {
+ installPackageForUser(apk, user, false /* forceQueryable */);
+ }
+
+ private static void installPackageForUser(File apk, UserReference user,
+ boolean forceQueryable) {
assertThat(apk.exists()).isTrue();
- final StringBuilder cmd = new StringBuilder("pm install --user ");
- cmd.append(user.id()).append(" ");
+ final StringBuilder cmd = new StringBuilder("pm install -t ");
+ if (forceQueryable) {
+ cmd.append("--force-queryable ");
+ }
+ if (user != null) {
+ cmd.append("--user ").append(user.id()).append(" ");
+ }
cmd.append(apk.getPath());
final String result = runShellCommand(cmd.toString());
assertThat(result.trim()).contains("Success");
}
private static void uninstallPackage(String packageName) {
- runShellCommand("pm uninstall " + packageName);
+ uninstallPackageForUser(packageName, null /* user */);
+ }
+
+ private static void uninstallPackageForUser(String packageName, UserReference user) {
+ final StringBuilder cmd = new StringBuilder("pm uninstall ");
+ if (user != null) {
+ cmd.append("--user ").append(user.id()).append(" ");
+ }
+ cmd.append(packageName);
+ runShellCommand(cmd.toString());
}
}
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-crossUserPackageVisibility.xml b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-crossUserPackageVisibility.xml
index 874a1fc5ff3e8..9d38ddfab5f10 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-crossUserPackageVisibility.xml
+++ b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-crossUserPackageVisibility.xml
@@ -17,6 +17,6 @@
-
+