summaryrefslogtreecommitdiff
path: root/apex/blobstore
diff options
context:
space:
mode:
authorSudheer Shanka <sudheersai@google.com>2021-03-24 14:49:04 -0700
committerSudheer Shanka <sudheersai@google.com>2021-03-26 08:00:10 +0000
commite0237fa50b43c7eb0892d7988bf1b344597fa091 (patch)
tree74aa249f4ad7e7bab1eee73b92a024dc9eaebd24 /apex/blobstore
parent5db986d793f6e8f181c389508a04712f291f19c9 (diff)
Add API to allow apps with location permission to access data blobs.
This is a new access mode that apps can use while committing data blobs to specify that only apps with location permission can the data blobs. Bug: 158705914 CTS-Coverage-Bug: 158705914 Test: atest --test-mapping apex/blobstore Change-Id: If69a2ea317719315f782e71a993cec361fef027f
Diffstat (limited to 'apex/blobstore')
-rw-r--r--apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java71
-rw-r--r--apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl10
-rw-r--r--apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl2
-rw-r--r--apex/blobstore/framework/java/android/app/blob/XmlTags.java4
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java81
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java5
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java35
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java32
8 files changed, 211 insertions, 29 deletions
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 38500aff34ea..22ee501bda8c 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -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);
@@ -897,6 +900,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.
*
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index 39a9fb4bb1f4..db6cb5c972fe 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -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);
} \ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
index 4035b96938d9..e3ccfb8d91c1 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
@@ -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();
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index bfc582623439..6e4b2f79cadb 100644
--- a/apex/blobstore/framework/java/android/app/blob/XmlTags.java
+++ b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
@@ -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";
}
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 4a527adf9abc..ca588c509594 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
@@ -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;
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
index fb02e960f91a..8b12beb57195 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -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;
}
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index f77f6c642f6a..0e7354726123 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -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
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
index fe688828997e..2c3f682a46e0 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -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;
@@ -366,6 +368,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) {
assertCallerIsOwner();
@@ -406,6 +423,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 */);
}