Merge "Add an api to query the visibility list of target packages"

This commit is contained in:
Rhed Jao
2022-12-15 03:17:08 +00:00
committed by Android (Google) Code Review
7 changed files with 72 additions and 22 deletions

View File

@@ -3609,6 +3609,7 @@ package android.content.pm {
public abstract class PackageManager {
method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
method public abstract boolean arePermissionsIndividuallyControlled();
method @NonNull public boolean[] canPackageQuery(@NonNull String, @NonNull String[]) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(@NonNull String);
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, @NonNull android.content.pm.PackageManager.ApplicationInfoFlags, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;

View File

@@ -3816,8 +3816,17 @@ public class ApplicationPackageManager extends PackageManager {
@NonNull String targetPackageName) throws NameNotFoundException {
Objects.requireNonNull(sourcePackageName);
Objects.requireNonNull(targetPackageName);
return canPackageQuery(sourcePackageName, new String[]{targetPackageName})[0];
}
@Override
@NonNull
public boolean[] canPackageQuery(@NonNull String sourcePackageName,
@NonNull String[] targetPackageNames) throws NameNotFoundException {
Objects.requireNonNull(sourcePackageName);
Objects.requireNonNull(targetPackageNames);
try {
return mPM.canPackageQuery(sourcePackageName, targetPackageName, getUserId());
return mPM.canPackageQuery(sourcePackageName, targetPackageNames, getUserId());
} catch (ParcelableException e) {
e.maybeRethrow(PackageManager.NameNotFoundException.class);
throw new RuntimeException(e);

View File

@@ -797,5 +797,5 @@ interface IPackageManager {
void setKeepUninstalledPackages(in List<String> packageList);
boolean canPackageQuery(String sourcePackageName, String targetPackageName, int userId);
boolean[] canPackageQuery(String sourcePackageName, in String[] targetPackageNames, int userId);
}

View File

@@ -10387,6 +10387,30 @@ public abstract class PackageManager {
"canPackageQuery not implemented in subclass");
}
/**
* Same as {@link #canPackageQuery(String, String)} but accepts an array of target packages to
* be queried.
*
* @param sourcePackageName The source package that would receive details about the
* target package.
* @param targetPackageNames An array of target packages whose details would be shared with the
* source package.
* @return An array of booleans where each member specifies whether the source package is able
* to query for details about the target package given by the corresponding value at the same
* index in the array of target packages.
* @throws NameNotFoundException if either a given package can not be found on the
* system, or if the caller is not able to query for details about the source or
* target packages.
* @hide
*/
@SystemApi
@NonNull
public boolean[] canPackageQuery(@NonNull String sourcePackageName,
@NonNull String[] targetPackageNames) throws NameNotFoundException {
throw new UnsupportedOperationException(
"canPackageQuery not implemented in subclass");
}
/**
* Makes a package that provides an authority {@code visibleAuthority} become visible to the
* application {@code recipientUid}.

View File

@@ -570,8 +570,9 @@ public interface Computer extends PackageDataSnapshot {
@PackageManager.InstallReason
int getInstallReason(@NonNull String packageName, @UserIdInt int userId);
boolean canPackageQuery(@NonNull String sourcePackageName, @NonNull String targetPackageName,
@UserIdInt int userId);
@NonNull
boolean[] canPackageQuery(@NonNull String sourcePackageName,
@NonNull String[] targetPackageNames, @UserIdInt int userId);
boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
@UserIdInt int sourceUserId, @UserIdInt int targetUserId);

View File

@@ -159,6 +159,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -5337,29 +5338,42 @@ public class ComputerEngine implements Computer {
}
@Override
public boolean canPackageQuery(@NonNull String sourcePackageName,
@NonNull String targetPackageName, @UserIdInt int userId) {
if (!mUserManager.exists(userId)) return false;
@NonNull
public boolean[] canPackageQuery(@NonNull String sourcePackageName,
@NonNull String[] targetPackageNames, @UserIdInt int userId) {
final int targetSize = targetPackageNames.length;
final boolean[] results = new boolean[targetSize];
if (!mUserManager.exists(userId)) {
return results;
}
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
false /*checkShell*/, "may package query");
false /*checkShell*/, "can package query");
final PackageStateInternal sourceSetting = getPackageStateInternal(sourcePackageName);
final PackageStateInternal targetSetting = getPackageStateInternal(targetPackageName);
boolean throwException = sourceSetting == null || targetSetting == null;
if (!throwException) {
final boolean filterSource =
shouldFilterApplicationIncludingUninstalled(sourceSetting, callingUid, userId);
final boolean filterTarget =
shouldFilterApplicationIncludingUninstalled(targetSetting, callingUid, userId);
// The caller must have visibility of the both packages
throwException = filterSource || filterTarget;
final PackageStateInternal[] targetSettings = new PackageStateInternal[targetSize];
// Throw exception if the caller without the visibility of source package
boolean throwException =
(sourceSetting == null || shouldFilterApplicationIncludingUninstalled(
sourceSetting, callingUid, userId));
for (int i = 0; !throwException && i < targetSize; i++) {
targetSettings[i] = getPackageStateInternal(targetPackageNames[i]);
// Throw exception if the caller without the visibility of target package
throwException =
(targetSettings[i] == null || shouldFilterApplicationIncludingUninstalled(
targetSettings[i], callingUid, userId));
}
if (throwException) {
throw new ParcelableException(new PackageManager.NameNotFoundException("Package(s) "
+ sourcePackageName + " and/or " + targetPackageName + " not found."));
+ sourcePackageName + " and/or " + Arrays.toString(targetPackageNames)
+ " not found."));
}
final int sourcePackageUid = UserHandle.getUid(userId, sourceSetting.getAppId());
return !shouldFilterApplication(targetSetting, sourcePackageUid, userId);
for (int i = 0; i < targetSize; i++) {
results[i] = !shouldFilterApplication(targetSettings[i], sourcePackageUid, userId);
}
return results;
}
/*

View File

@@ -1153,9 +1153,10 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub {
@Override
@Deprecated
public final boolean canPackageQuery(@NonNull String sourcePackageName,
@NonNull String targetPackageName, @UserIdInt int userId) {
return snapshot().canPackageQuery(sourcePackageName, targetPackageName, userId);
@NonNull
public final boolean[] canPackageQuery(@NonNull String sourcePackageName,
@NonNull String[] targetPackageNames, @UserIdInt int userId) {
return snapshot().canPackageQuery(sourcePackageName, targetPackageNames, userId);
}
@Override