diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java index 38500aff34ea..f6ae56f01758 100644 --- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java +++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java @@ -506,6 +506,22 @@ public class BlobStoreManager { } } + /** + * Release all the leases which are currently held by the caller. + * + * @hide + */ + public void releaseAllLeases() throws Exception { + try { + mService.releaseAllLeases(mContext.getOpPackageName()); + } catch (ParcelableException e) { + e.maybeRethrow(IOException.class); + throw new RuntimeException(e); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Return the remaining quota size for acquiring a lease (in bytes) which indicates the * remaining amount of data that an app can acquire a lease on before the System starts diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl index 39a9fb4bb1f4..1566fa8b00d0 100644 --- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl +++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl @@ -31,6 +31,7 @@ interface IBlobStoreManager { void acquireLease(in BlobHandle handle, int descriptionResId, in CharSequence description, long leaseTimeoutMillis, in String packageName); void releaseLease(in BlobHandle handle, in String packageName); + void releaseAllLeases(in String packageName); long getRemainingLeaseQuotaBytes(String packageName); void waitForIdle(in RemoteCallback callback); 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 c83ca8c2e31d..9ac3e412b1e4 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -554,6 +554,21 @@ public class BlobStoreManagerService extends SystemService { } } + private void releaseAllLeasesInternal(int callingUid, String callingPackage) { + synchronized (mBlobsLock) { + // Remove the package from the leasee list + mBlobsMap.forEach((blobHandle, blobMetadata) -> { + blobMetadata.removeLeasee(callingPackage, callingUid); + }); + writeBlobsInfoAsync(); + + if (LOGV) { + Slog.v(TAG, "Release all leases associated with pkg=" + + callingPackage + ", uid=" + callingUid); + } + } + } + private long getRemainingLeaseQuotaBytesInternal(int callingUid, String callingPackage) { synchronized (mBlobsLock) { final long remainingQuota = BlobStoreConfig.getAppDataBytesLimit() @@ -1376,7 +1391,7 @@ public class BlobStoreManagerService extends SystemService { } } - private boolean isAllowedBlobAccess(int uid, String packageName) { + private boolean isAllowedBlobStoreAccess(int uid, String packageName) { return (!Process.isSdkSandboxUid(uid) && !Process.isIsolated(uid) && !mPackageManagerInternal.isInstantApp(packageName, UserHandle.getUserId(uid))); } @@ -1442,7 +1457,7 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); - if (!isAllowedBlobAccess(callingUid, packageName)) { + if (!isAllowedBlobStoreAccess(callingUid, packageName)) { throw new SecurityException("Caller not allowed to create session; " + "callingUid=" + callingUid + ", callingPackage=" + packageName); } @@ -1491,7 +1506,7 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); - if (!isAllowedBlobAccess(callingUid, packageName)) { + if (!isAllowedBlobStoreAccess(callingUid, packageName)) { throw new SecurityException("Caller not allowed to open blob; " + "callingUid=" + callingUid + ", callingPackage=" + packageName); } @@ -1522,7 +1537,7 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); - if (!isAllowedBlobAccess(callingUid, packageName)) { + if (!isAllowedBlobStoreAccess(callingUid, packageName)) { throw new SecurityException("Caller not allowed to open blob; " + "callingUid=" + callingUid + ", callingPackage=" + packageName); } @@ -1546,7 +1561,7 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); - if (!isAllowedBlobAccess(callingUid, packageName)) { + if (!isAllowedBlobStoreAccess(callingUid, packageName)) { throw new SecurityException("Caller not allowed to open blob; " + "callingUid=" + callingUid + ", callingPackage=" + packageName); } @@ -1554,6 +1569,21 @@ public class BlobStoreManagerService extends SystemService { releaseLeaseInternal(blobHandle, callingUid, packageName); } + @Override + public void releaseAllLeases(@NonNull String packageName) { + Objects.requireNonNull(packageName, "packageName must not be null"); + + final int callingUid = Binder.getCallingUid(); + verifyCallingPackage(callingUid, packageName); + + if (!isAllowedBlobStoreAccess(callingUid, packageName)) { + throw new SecurityException("Caller not allowed to open blob; " + + "callingUid=" + callingUid + ", callingPackage=" + packageName); + } + + releaseAllLeasesInternal(callingUid, packageName); + } + @Override public long getRemainingLeaseQuotaBytes(@NonNull String packageName) { final int callingUid = Binder.getCallingUid(); @@ -1629,7 +1659,7 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); - if (!isAllowedBlobAccess(callingUid, packageName)) { + if (!isAllowedBlobStoreAccess(callingUid, packageName)) { throw new SecurityException("Caller not allowed to open blob; " + "callingUid=" + callingUid + ", callingPackage=" + packageName); }