Allow application to inspect query-ability of other package
This CL creates a new API PackageManager#mayPackageQuery for applications that share details about other applications to determine if those details should be withheld from callers that do not otherwise have visibility of them. Bug: 145916881 Test: atest AppEnumerationTests Change-Id: I2dfba1169bce3d9fa88a75c92a22f53e1efe01b5
This commit is contained in:
@@ -12631,6 +12631,7 @@ package android.content.pm {
|
||||
method public boolean isPackageSuspended();
|
||||
method @CheckResult public abstract boolean isPermissionRevokedByPolicy(@NonNull String, @NonNull String);
|
||||
method public abstract boolean isSafeMode();
|
||||
method public boolean mayPackageQuery(@NonNull String, @NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryActivityProperty(@NonNull String);
|
||||
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryApplicationProperty(@NonNull String);
|
||||
method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(@NonNull android.content.Intent, int);
|
||||
|
||||
@@ -3575,4 +3575,19 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
throw e.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPackageQuery(@NonNull String sourcePackageName,
|
||||
@NonNull String targetPackageName) throws NameNotFoundException {
|
||||
Objects.requireNonNull(sourcePackageName);
|
||||
Objects.requireNonNull(targetPackageName);
|
||||
try {
|
||||
return mPM.mayPackageQuery(sourcePackageName, targetPackageName, getUserId());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(PackageManager.NameNotFoundException.class);
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,4 +818,6 @@ interface IPackageManager {
|
||||
ParceledListSlice queryProperty(String propertyName, int componentType);
|
||||
|
||||
void setKeepUninstalledPackages(in List<String> packageList);
|
||||
|
||||
boolean mayPackageQuery(String sourcePackageName, String targetPackageName, int userId);
|
||||
}
|
||||
|
||||
@@ -9329,6 +9329,31 @@ public abstract class PackageManager {
|
||||
"qeuryServiceProperty not implemented in subclass");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the source package is able to query for details about the
|
||||
* target package. Applications that share details about other applications should
|
||||
* use this API to determine if those details should be withheld from callers that
|
||||
* do not otherwise have visibility of them.
|
||||
* <p>
|
||||
* Note: The caller must be able to query for details about the source and target
|
||||
* package. A {@link NameNotFoundException} is thrown if it isn't.
|
||||
*
|
||||
* @param sourcePackageName The source package that would receive details about the
|
||||
* target package.
|
||||
* @param targetPackageName The target package whose details would be shared with the
|
||||
* source package.
|
||||
* @return {@code true} if the source package is able to query for details about the
|
||||
* target package.
|
||||
* @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 package.
|
||||
*/
|
||||
public boolean mayPackageQuery(@NonNull String sourcePackageName,
|
||||
@NonNull String targetPackageName) throws NameNotFoundException {
|
||||
throw new UnsupportedOperationException(
|
||||
"mayPackageQuery not implemented in subclass");
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants implicit visibility of the package that provides an authority to a querying UID.
|
||||
*
|
||||
|
||||
@@ -23388,6 +23388,37 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return new IntentSender(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPackageQuery(String sourcePackageName, String targetPackageName, int userId) {
|
||||
if (!mUserManager.exists(userId)) return false;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "may package query");
|
||||
synchronized (mLock) {
|
||||
final PackageSetting sourceSetting = getPackageSetting(sourcePackageName);
|
||||
final PackageSetting targetSetting = getPackageSetting(targetPackageName);
|
||||
if (sourceSetting == null || targetSetting == null) {
|
||||
throw new ParcelableException(new PackageManager.NameNotFoundException("Package(s) "
|
||||
+ (sourceSetting == null ? sourcePackageName + " " : "")
|
||||
+ (targetSetting == null ? targetPackageName + " " : "")
|
||||
+ "not found."));
|
||||
}
|
||||
final boolean filterSource =
|
||||
shouldFilterApplicationLocked(sourceSetting, callingUid, userId);
|
||||
final boolean filterTarget =
|
||||
shouldFilterApplicationLocked(targetSetting, callingUid, userId);
|
||||
// The caller must have visibility of the both packages
|
||||
if (filterSource || filterTarget) {
|
||||
throw new ParcelableException(new PackageManager.NameNotFoundException("Package(s) "
|
||||
+ (filterSource ? sourcePackageName + " " : "")
|
||||
+ (filterTarget ? targetPackageName + " " : "")
|
||||
+ "not found."));
|
||||
}
|
||||
final int sourcePackageUid = UserHandle.getUid(userId, sourceSetting.appId);
|
||||
return !shouldFilterApplicationLocked(targetSetting, sourcePackageUid, userId);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TempUserState {
|
||||
public final int enabledState;
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user