diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java index 8cea645f4e71c..821305e182405 100644 --- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java +++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java @@ -142,6 +142,9 @@ public class BlobStoreManager { /** @hide */ public static final int COMMIT_RESULT_ERROR = 1; + /** @hide */ + public static final int INVALID_RES_ID = -1; + private final Context mContext; private final IBlobStoreManager mService; @@ -285,11 +288,65 @@ public class BlobStoreManager { * caller is trying to acquire too many leases. * * @see {@link #acquireLease(BlobHandle, int)} + * @see {@link #acquireLease(BlobHandle, CharSequence)} */ public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId, @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException { try { - mService.acquireLease(blobHandle, descriptionResId, leaseExpiryTimeMillis, + mService.acquireLease(blobHandle, descriptionResId, null, leaseExpiryTimeMillis, + mContext.getOpPackageName()); + } catch (ParcelableException e) { + e.maybeRethrow(IOException.class); + throw new RuntimeException(e); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the + * system that the caller wants the blob to be kept around. + * + *
This is variant of {@link #acquireLease(BlobHandle, int, long)} taking a + * {@link CharSequence} for {@code description}. It is highly recommended that callers only + * use this when a valid resource ID for {@code description} could not be provided. Otherwise, + * apps should prefer using {@link #acquireLease(BlobHandle, int)} which will allow + * {@code description} to be localized. + * + *
Any active leases will be automatically released when the blob's expiry time + * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed. + * + *
This lease information is persisted and calling this more than once will result in + * latest lease overriding any previous lease. + * + * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to + * acquire a lease for. + * @param description a short description string that can be surfaced + * to the user explaining what the blob is used for. + * @param leaseExpiryTimeMillis the time in milliseconds after which the lease can be + * automatically released, in {@link System#currentTimeMillis()} + * timebase. If its value is {@code 0}, then the behavior of this + * API is identical to {@link #acquireLease(BlobHandle, int)} + * where clients have to explicitly call + * {@link #releaseLease(BlobHandle)} when they don't + * need the blob anymore. + * + * @throws IOException when there is an I/O error while acquiring a lease to the blob. + * @throws SecurityException when the blob represented by the {@code blobHandle} does not + * exist or the caller does not have access to it. + * @throws IllegalArgumentException when {@code blobHandle} is invalid or + * if the {@code leaseExpiryTimeMillis} is greater than the + * {@link BlobHandle#getExpiryTimeMillis()}. + * @throws IllegalStateException when a lease could not be acquired, such as when the + * caller is trying to acquire too many leases. + * + * @see {@link #acquireLease(BlobHandle, int, long)} + * @see {@link #acquireLease(BlobHandle, CharSequence)} + */ + public void acquireLease(@NonNull BlobHandle blobHandle, @NonNull CharSequence description, + @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException { + try { + mService.acquireLease(blobHandle, INVALID_RES_ID, description, leaseExpiryTimeMillis, mContext.getOpPackageName()); } catch (ParcelableException e) { e.maybeRethrow(IOException.class); @@ -327,12 +384,54 @@ public class BlobStoreManager { * caller is trying to acquire too many leases. * * @see {@link #acquireLease(BlobHandle, int, long)} + * @see {@link #acquireLease(BlobHandle, CharSequence, long)} */ public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId) throws IOException { acquireLease(blobHandle, descriptionResId, 0); } + /** + * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the + * system that the caller wants the blob to be kept around. + * + *
This is variant of {@link #acquireLease(BlobHandle, int)} taking a {@link CharSequence} + * for {@code description}. It is highly recommended that callers only use this when a valid + * resource ID for {@code description} could not be provided. Otherwise, apps should prefer + * using {@link #acquireLease(BlobHandle, int)} which will allow {@code description} to be + * localized. + * + *
This is similar to {@link #acquireLease(BlobHandle, CharSequence, long)} except clients + * don't have to specify the lease expiry time upfront using this API and need to explicitly + * release the lease using {@link #releaseLease(BlobHandle)} when they no longer like to keep + * a blob around. + * + *
Any active leases will be automatically released when the blob's expiry time + * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed. + * + *
This lease information is persisted and calling this more than once will result in
+ * latest lease overriding any previous lease.
+ *
+ * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+ * acquire a lease for.
+ * @param description a short description string that can be surfaced
+ * to the user explaining what the blob is used for.
+ *
+ * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+ * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+ * exist or the caller does not have access to it.
+ * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+ * @throws IllegalStateException when a lease could not be acquired, such as when the
+ * caller is trying to acquire too many leases.
+ *
+ * @see {@link #acquireLease(BlobHandle, int)}
+ * @see {@link #acquireLease(BlobHandle, CharSequence, long)}
+ */
+ public void acquireLease(@NonNull BlobHandle blobHandle, @NonNull CharSequence description)
+ throws IOException {
+ acquireLease(blobHandle, description, 0);
+ }
+
/**
* Release all active leases to the blob represented by {@code blobHandle} which are
* currently held by the caller.
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index e2128b4217465..a85a25c9c4ad6 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -26,8 +26,8 @@ interface IBlobStoreManager {
ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
void deleteSession(long sessionId, in String packageName);
- void acquireLease(in BlobHandle handle, int descriptionResId, long leaseTimeout,
- 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);
void waitForIdle(in RemoteCallback callback);
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index 803c9a40e5eac..9834d7477838b 100644
--- a/apex/blobstore/framework/java/android/app/blob/XmlTags.java
+++ b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
@@ -52,4 +52,5 @@ public final class XmlTags {
// For leasee
public static final String TAG_LEASEE = "l";
public static final String ATTR_DESCRIPTION_RES_ID = "rid";
+ public static final String ATTR_DESCRIPTION = "d";
}
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 c12e0ec8aec96..c7d803c884108 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -15,6 +15,7 @@
*/
package com.android.server.blob;
+import static android.app.blob.XmlTags.ATTR_DESCRIPTION;
import static android.app.blob.XmlTags.ATTR_DESCRIPTION_RES_ID;
import static android.app.blob.XmlTags.ATTR_EXPIRY_TIME;
import static android.app.blob.XmlTags.ATTR_ID;
@@ -28,12 +29,14 @@ import static android.app.blob.XmlTags.TAG_LEASEE;
import static android.system.OsConstants.O_RDONLY;
import static com.android.server.blob.BlobStoreConfig.TAG;
+import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_STRING_DESC;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.blob.BlobHandle;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.ResourceId;
import android.content.res.Resources;
import android.os.ParcelFileDescriptor;
import android.os.RevocableFileDescriptor;
@@ -141,11 +144,11 @@ class BlobMetadata {
}
}
- void addLeasee(String callingPackage, int callingUid,
- int descriptionResId, long leaseExpiryTimeMillis) {
+ void addLeasee(String callingPackage, int callingUid, int descriptionResId,
+ CharSequence description, long leaseExpiryTimeMillis) {
synchronized (mMetadataLock) {
mLeasees.add(new Leasee(callingPackage, callingUid,
- descriptionResId, leaseExpiryTimeMillis));
+ descriptionResId, description, leaseExpiryTimeMillis));
}
}
@@ -308,7 +311,7 @@ class BlobMetadata {
}
@Nullable
- static BlobMetadata createFromXml(Context context, XmlPullParser in)
+ static BlobMetadata createFromXml(XmlPullParser in, int version, Context context)
throws XmlPullParserException, IOException {
final long blobId = XmlUtils.readLongAttribute(in, ATTR_ID);
final int userId = XmlUtils.readIntAttribute(in, ATTR_USER_ID);
@@ -321,12 +324,12 @@ class BlobMetadata {
if (TAG_BLOB_HANDLE.equals(in.getName())) {
blobHandle = BlobHandle.createFromXml(in);
} else if (TAG_COMMITTER.equals(in.getName())) {
- final Committer committer = Committer.createFromXml(in);
+ final Committer committer = Committer.createFromXml(in, version);
if (committer != null) {
committers.add(committer);
}
} else if (TAG_LEASEE.equals(in.getName())) {
- leasees.add(Leasee.createFromXml(in));
+ leasees.add(Leasee.createFromXml(in, version));
}
}
@@ -366,7 +369,7 @@ class BlobMetadata {
}
@Nullable
- static Committer createFromXml(@NonNull XmlPullParser in)
+ static Committer createFromXml(@NonNull XmlPullParser in, int version)
throws XmlPullParserException, IOException {
final String packageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
final int uid = XmlUtils.readIntAttribute(in, ATTR_UID);
@@ -388,12 +391,15 @@ class BlobMetadata {
static final class Leasee extends Accessor {
public final int descriptionResId;
+ public final CharSequence description;
public final long expiryTimeMillis;
- Leasee(String packageName, int uid, int descriptionResId, long expiryTimeMillis) {
+ Leasee(String packageName, int uid, int descriptionResId, CharSequence description,
+ long expiryTimeMillis) {
super(packageName, uid);
this.descriptionResId = descriptionResId;
this.expiryTimeMillis = expiryTimeMillis;
+ this.description = description;
}
boolean isStillValid() {
@@ -401,35 +407,51 @@ class BlobMetadata {
}
void dump(Context context, IndentingPrintWriter fout) {
- String desc = null;
- try {
- final Resources leaseeRes = context.getPackageManager()
- .getResourcesForApplicationAsUser(packageName, UserHandle.getUserId(uid));
- desc = leaseeRes.getString(descriptionResId);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.d(TAG, "Unknown package in user " + UserHandle.getUserId(uid) + ": "
- + packageName, e);
- desc = "