Merge "Add API to allow apps with location permission to access data blobs." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
624f4c5274
@@ -258,7 +258,8 @@ public class BlobStoreManager {
|
||||
public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
|
||||
throws IOException {
|
||||
try {
|
||||
return mService.openBlob(blobHandle, mContext.getOpPackageName());
|
||||
return mService.openBlob(blobHandle, mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
throw new RuntimeException(e);
|
||||
@@ -315,7 +316,7 @@ public class BlobStoreManager {
|
||||
@CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
|
||||
try {
|
||||
mService.acquireLease(blobHandle, descriptionResId, null, leaseExpiryTimeMillis,
|
||||
mContext.getOpPackageName());
|
||||
mContext.getOpPackageName(), mContext.getAttributionTag());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
e.maybeRethrow(LimitExceededException.class);
|
||||
@@ -378,7 +379,7 @@ public class BlobStoreManager {
|
||||
@CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
|
||||
try {
|
||||
mService.acquireLease(blobHandle, INVALID_RES_ID, description, leaseExpiryTimeMillis,
|
||||
mContext.getOpPackageName());
|
||||
mContext.getOpPackageName(), mContext.getAttributionTag());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
e.maybeRethrow(LimitExceededException.class);
|
||||
@@ -497,7 +498,8 @@ public class BlobStoreManager {
|
||||
*/
|
||||
public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
|
||||
try {
|
||||
mService.releaseLease(blobHandle, mContext.getOpPackageName());
|
||||
mService.releaseLease(blobHandle, mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
throw new RuntimeException(e);
|
||||
@@ -602,7 +604,8 @@ public class BlobStoreManager {
|
||||
@Nullable
|
||||
public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle) throws IOException {
|
||||
try {
|
||||
return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName());
|
||||
return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
throw new RuntimeException(e);
|
||||
@@ -896,6 +899,64 @@ public class BlobStoreManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow apps with location permission to access this blob data once it is committed using
|
||||
* a {@link BlobHandle} representing the blob.
|
||||
*
|
||||
* <p> This needs to be called before committing the blob using
|
||||
* {@link #commit(Executor, Consumer)}.
|
||||
*
|
||||
* Note that if a caller allows access to the blob using this API in addition to other APIs
|
||||
* like {@link #allowPackageAccess(String, byte[])}, then apps satisfying any one of these
|
||||
* access conditions will be allowed to access the blob.
|
||||
*
|
||||
* @param permissionName the name of the location permission that needs to be granted
|
||||
* for the app. This can be either one of
|
||||
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
|
||||
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
|
||||
*
|
||||
* @throws IOException when there is an I/O error while changing the access.
|
||||
* @throws SecurityException when the caller is not the owner of the session.
|
||||
* @throws IllegalStateException when the caller tries to change access for a blob which is
|
||||
* already committed.
|
||||
*/
|
||||
public void allowPackagesWithLocationPermission(@NonNull String permissionName)
|
||||
throws IOException {
|
||||
try {
|
||||
mSession.allowPackagesWithLocationPermission(permissionName);
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if access has been allowed for apps with location permission by
|
||||
* using {@link #allowPackagesWithLocationPermission(String)}.
|
||||
*
|
||||
* @param permissionName the name of the location permission that needs to be granted
|
||||
* for the app. This can be either one of
|
||||
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
|
||||
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
|
||||
*
|
||||
* @throws IOException when there is an I/O error while getting the access type.
|
||||
* @throws IllegalStateException when the caller tries to get access type from a session
|
||||
* which is closed or abandoned.
|
||||
*/
|
||||
public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName)
|
||||
throws IOException {
|
||||
try {
|
||||
return mSession.arePackagesWithLocationPermissionAllowed(permissionName);
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(IOException.class);
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the file that was written so far to this session to the blob store maintained by
|
||||
* the system.
|
||||
|
||||
@@ -25,12 +25,13 @@ import android.os.RemoteCallback;
|
||||
interface IBlobStoreManager {
|
||||
long createSession(in BlobHandle handle, in String packageName);
|
||||
IBlobStoreSession openSession(long sessionId, in String packageName);
|
||||
ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
|
||||
ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName,
|
||||
in String attributionTag);
|
||||
void abandonSession(long sessionId, in String packageName);
|
||||
|
||||
void acquireLease(in BlobHandle handle, int descriptionResId, in CharSequence description,
|
||||
long leaseTimeoutMillis, in String packageName);
|
||||
void releaseLease(in BlobHandle handle, in String packageName);
|
||||
long leaseTimeoutMillis, in String packageName, in String attributionTag);
|
||||
void releaseLease(in BlobHandle handle, in String packageName, in String attributionTag);
|
||||
long getRemainingLeaseQuotaBytes(String packageName);
|
||||
|
||||
void waitForIdle(in RemoteCallback callback);
|
||||
@@ -39,5 +40,6 @@ interface IBlobStoreManager {
|
||||
void deleteBlob(long blobId);
|
||||
|
||||
List<BlobHandle> getLeasedBlobs(in String packageName);
|
||||
LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName);
|
||||
LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName,
|
||||
in String attributionTag);
|
||||
}
|
||||
@@ -26,10 +26,12 @@ interface IBlobStoreSession {
|
||||
void allowPackageAccess(in String packageName, in byte[] certificate);
|
||||
void allowSameSignatureAccess();
|
||||
void allowPublicAccess();
|
||||
void allowPackagesWithLocationPermission(in String permissionName);
|
||||
|
||||
boolean isPackageAccessAllowed(in String packageName, in byte[] certificate);
|
||||
boolean isSameSignatureAccessAllowed();
|
||||
boolean isPublicAccessAllowed();
|
||||
boolean arePackagesWithLocationPermissionAllowed(in String permissionName);
|
||||
|
||||
long getSize();
|
||||
void close();
|
||||
|
||||
@@ -38,6 +38,7 @@ public final class XmlTags {
|
||||
public static final String ATTR_TYPE = "t";
|
||||
public static final String TAG_ALLOWED_PACKAGE = "wl";
|
||||
public static final String ATTR_CERTIFICATE = "ct";
|
||||
public static final String TAG_ALLOWED_PERMISSION = "ap";
|
||||
|
||||
// For BlobHandle
|
||||
public static final String TAG_BLOB_HANDLE = "bh";
|
||||
@@ -55,4 +56,7 @@ public final class XmlTags {
|
||||
public static final String TAG_LEASEE = "l";
|
||||
public static final String ATTR_DESCRIPTION_RES_NAME = "rn";
|
||||
public static final String ATTR_DESCRIPTION = "d";
|
||||
|
||||
// Generic
|
||||
public static final String ATTR_VALUE = "val";
|
||||
}
|
||||
|
||||
@@ -15,18 +15,29 @@
|
||||
*/
|
||||
package com.android.server.blob;
|
||||
|
||||
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||
import static android.app.blob.XmlTags.ATTR_CERTIFICATE;
|
||||
import static android.app.blob.XmlTags.ATTR_PACKAGE;
|
||||
import static android.app.blob.XmlTags.ATTR_TYPE;
|
||||
import static android.app.blob.XmlTags.ATTR_VALUE;
|
||||
import static android.app.blob.XmlTags.TAG_ALLOWED_PACKAGE;
|
||||
import static android.app.blob.XmlTags.TAG_ALLOWED_PERMISSION;
|
||||
|
||||
import static com.android.server.blob.BlobStoreConfig.TAG;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.UserHandle;
|
||||
import android.permission.PermissionManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Base64;
|
||||
import android.util.DebugUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
@@ -53,21 +64,27 @@ class BlobAccessMode {
|
||||
ACCESS_TYPE_PUBLIC,
|
||||
ACCESS_TYPE_SAME_SIGNATURE,
|
||||
ACCESS_TYPE_ALLOWLIST,
|
||||
ACCESS_TYPE_LOCATION_PERMISSION,
|
||||
})
|
||||
@interface AccessType {}
|
||||
public static final int ACCESS_TYPE_PRIVATE = 1 << 0;
|
||||
public static final int ACCESS_TYPE_PUBLIC = 1 << 1;
|
||||
public static final int ACCESS_TYPE_SAME_SIGNATURE = 1 << 2;
|
||||
public static final int ACCESS_TYPE_ALLOWLIST = 1 << 3;
|
||||
public static final int ACCESS_TYPE_LOCATION_PERMISSION = 1 << 4;
|
||||
|
||||
private int mAccessType = ACCESS_TYPE_PRIVATE;
|
||||
|
||||
private final ArraySet<PackageIdentifier> mAllowedPackages = new ArraySet<>();
|
||||
private final ArraySet<String> mAllowedPermissions = new ArraySet<>();
|
||||
|
||||
void allow(BlobAccessMode other) {
|
||||
if ((other.mAccessType & ACCESS_TYPE_ALLOWLIST) != 0) {
|
||||
mAllowedPackages.addAll(other.mAllowedPackages);
|
||||
}
|
||||
if ((other.mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
|
||||
mAllowedPermissions.addAll(other.mAllowedPermissions);
|
||||
}
|
||||
mAccessType |= other.mAccessType;
|
||||
}
|
||||
|
||||
@@ -84,6 +101,11 @@ class BlobAccessMode {
|
||||
mAllowedPackages.add(PackageIdentifier.create(packageName, certificate));
|
||||
}
|
||||
|
||||
void allowPackagesWithLocationPermission(@NonNull String permissionName) {
|
||||
mAccessType |= ACCESS_TYPE_LOCATION_PERMISSION;
|
||||
mAllowedPermissions.add(permissionName);
|
||||
}
|
||||
|
||||
boolean isPublicAccessAllowed() {
|
||||
return (mAccessType & ACCESS_TYPE_PUBLIC) != 0;
|
||||
}
|
||||
@@ -99,8 +121,15 @@ class BlobAccessMode {
|
||||
return mAllowedPackages.contains(PackageIdentifier.create(packageName, certificate));
|
||||
}
|
||||
|
||||
boolean isAccessAllowedForCaller(Context context,
|
||||
@NonNull String callingPackage, @NonNull String committerPackage) {
|
||||
boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
|
||||
if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) == 0) {
|
||||
return false;
|
||||
}
|
||||
return mAllowedPermissions.contains(permissionName);
|
||||
}
|
||||
|
||||
boolean isAccessAllowedForCaller(Context context, @NonNull String callingPackage,
|
||||
@NonNull String committerPackage, int callingUid, @Nullable String attributionTag) {
|
||||
if ((mAccessType & ACCESS_TYPE_PUBLIC) != 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -124,9 +153,37 @@ class BlobAccessMode {
|
||||
}
|
||||
}
|
||||
|
||||
if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
|
||||
final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
|
||||
for (int i = 0; i < mAllowedPermissions.size(); ++i) {
|
||||
final String permission = mAllowedPermissions.valueAt(i);
|
||||
if (PermissionManager.checkPackageNamePermission(permission, callingPackage,
|
||||
UserHandle.getUserId(callingUid)) != PackageManager.PERMISSION_GRANTED) {
|
||||
continue;
|
||||
}
|
||||
// TODO: Add appropriate message
|
||||
if (appOpsManager.noteOpNoThrow(getAppOp(permission), callingUid, callingPackage,
|
||||
attributionTag, null /* message */) == AppOpsManager.MODE_ALLOWED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getAppOp(String permission) {
|
||||
switch (permission) {
|
||||
case ACCESS_FINE_LOCATION:
|
||||
return AppOpsManager.OPSTR_FINE_LOCATION;
|
||||
case ACCESS_COARSE_LOCATION:
|
||||
return AppOpsManager.OPSTR_COARSE_LOCATION;
|
||||
default:
|
||||
Slog.w(TAG, "Unknown permission found: " + permission);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
int getAccessType() {
|
||||
return mAccessType;
|
||||
}
|
||||
@@ -148,6 +205,16 @@ class BlobAccessMode {
|
||||
}
|
||||
fout.decreaseIndent();
|
||||
}
|
||||
fout.print("Allowed permissions:");
|
||||
if (mAllowedPermissions.isEmpty()) {
|
||||
fout.println(" (Empty)");
|
||||
} else {
|
||||
fout.increaseIndent();
|
||||
for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
|
||||
fout.println(mAllowedPermissions.valueAt(i).toString());
|
||||
}
|
||||
fout.decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
||||
void writeToXml(@NonNull XmlSerializer out) throws IOException {
|
||||
@@ -159,6 +226,12 @@ class BlobAccessMode {
|
||||
XmlUtils.writeByteArrayAttribute(out, ATTR_CERTIFICATE, packageIdentifier.certificate);
|
||||
out.endTag(null, TAG_ALLOWED_PACKAGE);
|
||||
}
|
||||
for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
|
||||
out.startTag(null, TAG_ALLOWED_PERMISSION);
|
||||
final String permission = mAllowedPermissions.valueAt(i);
|
||||
XmlUtils.writeStringAttribute(out, ATTR_VALUE, permission);
|
||||
out.endTag(null, TAG_ALLOWED_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -176,6 +249,10 @@ class BlobAccessMode {
|
||||
final byte[] certificate = XmlUtils.readByteArrayAttribute(in, ATTR_CERTIFICATE);
|
||||
blobAccessMode.allowPackageAccess(packageName, certificate);
|
||||
}
|
||||
if (TAG_ALLOWED_PERMISSION.equals(in.getName())) {
|
||||
final String permission = XmlUtils.readStringAttribute(in, ATTR_VALUE);
|
||||
blobAccessMode.allowPackagesWithLocationPermission(permission);
|
||||
}
|
||||
}
|
||||
return blobAccessMode;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,8 @@ class BlobMetadata {
|
||||
return getBlobFile().length();
|
||||
}
|
||||
|
||||
boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid) {
|
||||
boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid,
|
||||
@Nullable String attributionTag) {
|
||||
// Don't allow the blob to be accessed after it's expiry time has passed.
|
||||
if (getBlobHandle().isExpired()) {
|
||||
return false;
|
||||
@@ -254,7 +255,7 @@ class BlobMetadata {
|
||||
// Check if the caller is allowed access as per the access mode specified
|
||||
// by the committer.
|
||||
if (committer.blobAccessMode.isAccessAllowedForCaller(mContext,
|
||||
callingPackage, committer.packageName)) {
|
||||
callingPackage, committer.packageName, callingUid, attributionTag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,12 +402,12 @@ public class BlobStoreManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private ParcelFileDescriptor openBlobInternal(BlobHandle blobHandle, int callingUid,
|
||||
String callingPackage) throws IOException {
|
||||
String callingPackage, String attributionTag) throws IOException {
|
||||
synchronized (mBlobsLock) {
|
||||
final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid))
|
||||
.get(blobHandle);
|
||||
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
|
||||
callingPackage, callingUid)) {
|
||||
callingPackage, callingUid, attributionTag)) {
|
||||
if (blobMetadata == null) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BLOB_OPENED, callingUid,
|
||||
INVALID_BLOB_ID, INVALID_BLOB_SIZE,
|
||||
@@ -455,7 +455,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
|
||||
private void acquireLeaseInternal(BlobHandle blobHandle, int descriptionResId,
|
||||
CharSequence description, long leaseExpiryTimeMillis,
|
||||
int callingUid, String callingPackage) {
|
||||
int callingUid, String callingPackage, String attributionTag) {
|
||||
synchronized (mBlobsLock) {
|
||||
final int leasesCount = getLeasedBlobsCountLocked(callingUid, callingPackage);
|
||||
if (leasesCount >= getMaxLeasedBlobs()) {
|
||||
@@ -468,7 +468,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid))
|
||||
.get(blobHandle);
|
||||
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
|
||||
callingPackage, callingUid)) {
|
||||
callingPackage, callingUid, attributionTag)) {
|
||||
if (blobMetadata == null) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
|
||||
INVALID_BLOB_ID, INVALID_BLOB_SIZE,
|
||||
@@ -527,13 +527,13 @@ public class BlobStoreManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid,
|
||||
String callingPackage) {
|
||||
String callingPackage, String attributionTag) {
|
||||
synchronized (mBlobsLock) {
|
||||
final ArrayMap<BlobHandle, BlobMetadata> userBlobs =
|
||||
getUserBlobsLocked(UserHandle.getUserId(callingUid));
|
||||
final BlobMetadata blobMetadata = userBlobs.get(blobHandle);
|
||||
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
|
||||
callingPackage, callingUid)) {
|
||||
callingPackage, callingUid, attributionTag)) {
|
||||
throw new SecurityException("Caller not allowed to access " + blobHandle
|
||||
+ "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
|
||||
}
|
||||
@@ -634,12 +634,12 @@ public class BlobStoreManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private LeaseInfo getLeaseInfoInternal(BlobHandle blobHandle,
|
||||
int callingUid, @NonNull String callingPackage) {
|
||||
int callingUid, @NonNull String callingPackage, String attributionTag) {
|
||||
synchronized (mBlobsLock) {
|
||||
final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid))
|
||||
.get(blobHandle);
|
||||
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
|
||||
callingPackage, callingUid)) {
|
||||
callingPackage, callingUid, attributionTag)) {
|
||||
throw new SecurityException("Caller not allowed to access " + blobHandle
|
||||
+ "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
|
||||
}
|
||||
@@ -1465,7 +1465,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
|
||||
@NonNull String packageName) {
|
||||
@NonNull String packageName, @Nullable String attributionTag) {
|
||||
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
|
||||
blobHandle.assertIsValid();
|
||||
Objects.requireNonNull(packageName, "packageName must not be null");
|
||||
@@ -1480,7 +1480,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
}
|
||||
|
||||
try {
|
||||
return openBlobInternal(blobHandle, callingUid, packageName);
|
||||
return openBlobInternal(blobHandle, callingUid, packageName, attributionTag);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.wrap(e);
|
||||
}
|
||||
@@ -1489,7 +1489,8 @@ public class BlobStoreManagerService extends SystemService {
|
||||
@Override
|
||||
public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
|
||||
@Nullable CharSequence description,
|
||||
@CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName) {
|
||||
@CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName,
|
||||
@Nullable String attributionTag) {
|
||||
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
|
||||
blobHandle.assertIsValid();
|
||||
Preconditions.checkArgument(
|
||||
@@ -1513,7 +1514,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
|
||||
try {
|
||||
acquireLeaseInternal(blobHandle, descriptionResId, description,
|
||||
leaseExpiryTimeMillis, callingUid, packageName);
|
||||
leaseExpiryTimeMillis, callingUid, packageName, attributionTag);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (LimitExceededException e) {
|
||||
@@ -1522,7 +1523,8 @@ public class BlobStoreManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
|
||||
public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName,
|
||||
@Nullable String attributionTag) {
|
||||
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
|
||||
blobHandle.assertIsValid();
|
||||
Objects.requireNonNull(packageName, "packageName must not be null");
|
||||
@@ -1536,7 +1538,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
|
||||
}
|
||||
|
||||
releaseLeaseInternal(blobHandle, callingUid, packageName);
|
||||
releaseLeaseInternal(blobHandle, callingUid, packageName, attributionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1606,7 +1608,8 @@ public class BlobStoreManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
|
||||
public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName,
|
||||
@Nullable String attributionTag) {
|
||||
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
|
||||
blobHandle.assertIsValid();
|
||||
Objects.requireNonNull(packageName, "packageName must not be null");
|
||||
@@ -1620,7 +1623,7 @@ public class BlobStoreManagerService extends SystemService {
|
||||
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
|
||||
}
|
||||
|
||||
return getLeaseInfoInternal(blobHandle, callingUid, packageName);
|
||||
return getLeaseInfoInternal(blobHandle, callingUid, packageName, attributionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.server.blob;
|
||||
|
||||
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||
import static android.app.blob.BlobStoreManager.COMMIT_RESULT_ERROR;
|
||||
import static android.app.blob.XmlTags.ATTR_CREATION_TIME_MS;
|
||||
import static android.app.blob.XmlTags.ATTR_ID;
|
||||
@@ -365,6 +367,21 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allowPackagesWithLocationPermission(@NonNull String permissionName) {
|
||||
assertCallerIsOwner();
|
||||
Preconditions.checkArgument(ACCESS_FINE_LOCATION.equals(permissionName)
|
||||
|| ACCESS_COARSE_LOCATION.equals(permissionName),
|
||||
"permissionName is unknown: " + permissionName);
|
||||
synchronized (mSessionLock) {
|
||||
if (mState != STATE_OPENED) {
|
||||
throw new IllegalStateException("Not allowed to change access type in state: "
|
||||
+ stateToString(mState));
|
||||
}
|
||||
mBlobAccessMode.allowPackagesWithLocationPermission(permissionName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackageAccessAllowed(@NonNull String packageName,
|
||||
@NonNull byte[] certificate) {
|
||||
@@ -405,6 +422,21 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
|
||||
assertCallerIsOwner();
|
||||
Preconditions.checkArgument(ACCESS_FINE_LOCATION.equals(permissionName)
|
||||
|| ACCESS_COARSE_LOCATION.equals(permissionName),
|
||||
"permissionName is unknown: " + permissionName);
|
||||
synchronized (mSessionLock) {
|
||||
if (mState != STATE_OPENED) {
|
||||
throw new IllegalStateException("Not allowed to change access type in state: "
|
||||
+ stateToString(mState));
|
||||
}
|
||||
return mBlobAccessMode.arePackagesWithLocationPermissionAllowed(permissionName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
closeSession(STATE_CLOSED, false /* sendCallback */);
|
||||
|
||||
@@ -7881,8 +7881,10 @@ package android.app.blob {
|
||||
public static class BlobStoreManager.Session implements java.io.Closeable {
|
||||
method public void abandon() throws java.io.IOException;
|
||||
method public void allowPackageAccess(@NonNull String, @NonNull byte[]) throws java.io.IOException;
|
||||
method public void allowPackagesWithLocationPermission(@NonNull String) throws java.io.IOException;
|
||||
method public void allowPublicAccess() throws java.io.IOException;
|
||||
method public void allowSameSignatureAccess() throws java.io.IOException;
|
||||
method public boolean arePackagesWithLocationPermissionAllowed(@NonNull String) throws java.io.IOException;
|
||||
method public void close() throws java.io.IOException;
|
||||
method public void commit(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws java.io.IOException;
|
||||
method public long getSize() throws java.io.IOException;
|
||||
|
||||
Reference in New Issue
Block a user