diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index d16f3318a3c31..e9ebd729ef9fe 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -3716,15 +3716,7 @@ public class ApplicationPackageManager extends PackageManager { throws NameNotFoundException { Objects.requireNonNull(packageName); Objects.requireNonNull(propertyName); - try { - final Property property = mPM.getProperty(propertyName, packageName, null); - if (property == null) { - throw new NameNotFoundException(); - } - return property; - } catch (RemoteException e) { - throw e.rethrowAsRuntimeException(); - } + return getPropertyAsUser(propertyName, packageName, null /* className */, getUserId()); } @Override @@ -3732,9 +3724,18 @@ public class ApplicationPackageManager extends PackageManager { throws NameNotFoundException { Objects.requireNonNull(component); Objects.requireNonNull(propertyName); + return getPropertyAsUser(propertyName, + component.getPackageName(), component.getClassName(), getUserId()); + } + + @Override + public Property getPropertyAsUser(@NonNull String propertyName, @NonNull String packageName, + @Nullable String className, int userId) throws NameNotFoundException { + Objects.requireNonNull(packageName); + Objects.requireNonNull(propertyName); try { - final Property property = mPM.getProperty( - propertyName, component.getPackageName(), component.getClassName()); + final Property property = mPM.getPropertyAsUser(propertyName, + packageName, className, userId); if (property == null) { throw new NameNotFoundException(); } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index f49ab5711bbf1..cb188fbc703e9 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -795,7 +795,8 @@ interface IPackageManager { void holdLock(in IBinder token, in int durationMs); - PackageManager.Property getProperty(String propertyName, String packageName, String className); + PackageManager.Property getPropertyAsUser(String propertyName, String packageName, + String className, int userId); ParceledListSlice queryProperty(String propertyName, int componentType); void setKeepUninstalledPackages(in List packageList); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index df3578f36fe18..53c23f3fffa76 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -10224,6 +10224,21 @@ public abstract class PackageManager { "getProperty not implemented in subclass"); } + /** + * If the provided className is {@code null}, returns the property defined on the application. + * Otherwise, returns the property defined on the component. + * + * @throws NameNotFoundException if the given package is not installed on the calling user or + * component does not exist or if the given property is not defined within the manifest. + * @hide + */ + @NonNull + public Property getPropertyAsUser(@NonNull String propertyName, @NonNull String packageName, + @Nullable String className, int userId) throws NameNotFoundException { + throw new UnsupportedOperationException( + "getPropertyAsUser not implemented in subclass"); + } + /** * Returns the property definition for all <application> tags. *

If the property is not defined with any <application> tag, diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java index bd1ac2dcffda4..5dacdb40713bc 100644 --- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java +++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java @@ -189,8 +189,9 @@ public class BackupEligibilityRules { boolean isDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; if (UserHandle.isCore(app.uid) || isPrivileged) { try { - return mPackageManager.getProperty(PackageManager.PROPERTY_ALLOW_ADB_BACKUP, - packageName).getBoolean(); + return mPackageManager.getPropertyAsUser( + PackageManager.PROPERTY_ALLOW_ADB_BACKUP, packageName, + null /* className */, mUserId).getBoolean(); } catch (PackageManager.NameNotFoundException e) { Slog.w(TAG, "Failed to read allowAdbBackup property for + " + packageName); diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java index 42c7687f0f28b..622396ccfa368 100644 --- a/services/companion/java/com/android/server/companion/PackageUtils.java +++ b/services/companion/java/com/android/server/companion/PackageUtils.java @@ -110,7 +110,7 @@ final class PackageUtils { final ComponentName componentName = service.getComponentName(); - if (isPrimaryCompanionDeviceService(pm, componentName)) { + if (isPrimaryCompanionDeviceService(pm, componentName, userId)) { // "Primary" service should be at the head of the list. services.add(0, componentName); } else { @@ -122,9 +122,10 @@ final class PackageUtils { } private static boolean isPrimaryCompanionDeviceService(@NonNull PackageManager pm, - @NonNull ComponentName componentName) { + @NonNull ComponentName componentName, @UserIdInt int userId) { try { - return pm.getProperty(PROPERTY_PRIMARY_TAG, componentName).getBoolean(); + return pm.getPropertyAsUser(PROPERTY_PRIMARY_TAG, componentName.getPackageName(), + componentName.getClassName(), userId).getBoolean(); } catch (PackageManager.NameNotFoundException e) { return false; } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 8edd75e61478b..77b582e968999 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3728,7 +3728,8 @@ class StorageManagerService extends IStorageManager.Stub try { final PackageManager.Property noAppStorageProp = mContext.getPackageManager() - .getProperty(PackageManager.PROPERTY_NO_APP_DATA_STORAGE, callingPkg); + .getPropertyAsUser(PackageManager.PROPERTY_NO_APP_DATA_STORAGE, callingPkg, + null /* className */, userId); if (noAppStorageProp != null && noAppStorageProp.getBoolean()) { throw new SecurityException(callingPkg + " should not have " + appPath); } diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java index 759b6a3d4acab..c69bc50948aac 100644 --- a/services/core/java/com/android/server/pm/IPackageManagerBase.java +++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java @@ -711,12 +711,17 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub { @Override @Deprecated - public final PackageManager.Property getProperty(String propertyName, String packageName, - String className) { + public final PackageManager.Property getPropertyAsUser(String propertyName, String packageName, + String className, int userId) { Objects.requireNonNull(propertyName); Objects.requireNonNull(packageName); - PackageStateInternal packageState = snapshot().getPackageStateForInstalledAndFiltered( - packageName, Binder.getCallingUid(), UserHandle.getCallingUserId()); + final int callingUid = Binder.getCallingUid(); + final Computer snapshot = snapshot(); + snapshot.enforceCrossUserOrProfilePermission(callingUid, userId, + /* requireFullPermission */ false, + /* checkShell */ false, "getPropertyAsUser"); + PackageStateInternal packageState = snapshot.getPackageStateForInstalledAndFiltered( + packageName, callingUid, userId); if (packageState == null) { return null; } diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java index 7aea65e78616e..310c8f4b5d698 100644 --- a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java @@ -19,6 +19,7 @@ package com.android.server.backup.utils; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; @@ -250,9 +251,9 @@ public class BackupEligibilityRulesTest { /* flags */ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( OperationType.ADB_BACKUP); - when(mPackageManager.getProperty(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP), - eq(TEST_PACKAGE_NAME))).thenReturn(getAdbBackupProperty( - /* allowAdbBackup */ false)); + when(mPackageManager.getPropertyAsUser(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP), + eq(TEST_PACKAGE_NAME), isNull(), eq(mUserId))) + .thenReturn(getAdbBackupProperty(/* allowAdbBackup */ false)); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo); @@ -267,9 +268,9 @@ public class BackupEligibilityRulesTest { /* flags */ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( OperationType.ADB_BACKUP); - when(mPackageManager.getProperty(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP), - eq(TEST_PACKAGE_NAME))).thenReturn(getAdbBackupProperty( - /* allowAdbBackup */ true)); + when(mPackageManager.getPropertyAsUser(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP), + eq(TEST_PACKAGE_NAME), isNull(), eq(mUserId))) + .thenReturn(getAdbBackupProperty(/* allowAdbBackup */ true)); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);