diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java index f53f1f19aea71..d1e28e99b6d61 100644 --- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java +++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java @@ -145,6 +145,9 @@ public class BlobStoreManager { /** @hide */ public static final int INVALID_RES_ID = -1; + /** @hide */ + public static final String DESC_RES_TYPE_STRING = "string"; + private final Context mContext; private final IBlobStoreManager mService; @@ -269,6 +272,9 @@ public class BlobStoreManager { *
When an app acquires a lease on a blob, the System will try to keep this * blob around but note that it can still be deleted if it was requested by the user. * + *
In case the resource name for the {@code descriptionResId} is modified as part of + * an app update, apps should re-acquire the lease with the new resource id. + * * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to * acquire a lease for. * @param descriptionResId the resource id for a short description string that can be surfaced @@ -380,6 +386,9 @@ public class BlobStoreManager { *
When an app acquires a lease on a blob, the System will try to keep this * blob around but note that it can still be deleted if it was requested by the user. * + *
In case the resource name for the {@code descriptionResId} is modified as part of
+ * an app update, apps should re-acquire the lease with the new resource id.
+ *
* @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
* acquire a lease for.
* @param descriptionResId the resource id for a short description string that can be surfaced
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index 9834d7477838b..e64edc393769c 100644
--- a/apex/blobstore/framework/java/android/app/blob/XmlTags.java
+++ b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
@@ -51,6 +51,6 @@ 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_RES_NAME = "rn";
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 4a85a69b82d38..888c3af8bbf76 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -15,8 +15,9 @@
*/
package com.android.server.blob;
+import static android.app.blob.BlobStoreManager.DESC_RES_TYPE_STRING;
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_DESCRIPTION_RES_NAME;
import static android.app.blob.XmlTags.ATTR_EXPIRY_TIME;
import static android.app.blob.XmlTags.ATTR_ID;
import static android.app.blob.XmlTags.ATTR_PACKAGE;
@@ -29,7 +30,9 @@ import static android.app.blob.XmlTags.TAG_LEASEE;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.O_RDONLY;
+import static com.android.server.blob.BlobStoreConfig.LOGV;
import static com.android.server.blob.BlobStoreConfig.TAG;
+import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_DESC_RES_NAME;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_STRING_DESC;
import android.annotation.NonNull;
@@ -154,7 +157,7 @@ class BlobMetadata {
synchronized (mMetadataLock) {
// We need to override the leasee data, so first remove any existing
// leasee before adding the new one.
- final Leasee leasee = new Leasee(callingPackage, callingUid,
+ final Leasee leasee = new Leasee(mContext, callingPackage, callingUid,
descriptionResId, description, leaseExpiryTimeMillis);
mLeasees.remove(leasee);
mLeasees.add(leasee);
@@ -459,59 +462,123 @@ class BlobMetadata {
}
static final class Leasee extends Accessor {
- public final int descriptionResId;
+ public final String descriptionResEntryName;
public final CharSequence description;
public final long expiryTimeMillis;
- Leasee(String packageName, int uid, int descriptionResId, CharSequence description,
- long expiryTimeMillis) {
+ Leasee(@NonNull Context context, @NonNull String packageName,
+ int uid, int descriptionResId,
+ @Nullable CharSequence description, long expiryTimeMillis) {
super(packageName, uid);
- this.descriptionResId = descriptionResId;
+ final Resources packageResources = getPackageResources(context, packageName,
+ UserHandle.getUserId(uid));
+ this.descriptionResEntryName = getResourceEntryName(packageResources, descriptionResId);
+ this.expiryTimeMillis = expiryTimeMillis;
+ this.description = description == null
+ ? getDescription(packageResources, descriptionResId)
+ : description;
+ }
+
+ Leasee(String packageName, int uid, @Nullable String descriptionResEntryName,
+ @Nullable CharSequence description, long expiryTimeMillis) {
+ super(packageName, uid);
+ this.descriptionResEntryName = descriptionResEntryName;
this.expiryTimeMillis = expiryTimeMillis;
this.description = description;
}
+ @Nullable
+ private static String getResourceEntryName(@Nullable Resources packageResources,
+ int resId) {
+ if (!ResourceId.isValid(resId) || packageResources == null) {
+ return null;
+ }
+ return packageResources.getResourceEntryName(resId);
+ }
+
+ @Nullable
+ private static String getDescription(@NonNull Context context,
+ @NonNull String descriptionResEntryName, @NonNull String packageName, int userId) {
+ if (descriptionResEntryName == null || descriptionResEntryName.isEmpty()) {
+ return null;
+ }
+ final Resources resources = getPackageResources(context, packageName, userId);
+ if (resources == null) {
+ return null;
+ }
+ try {
+ final int resId = resources.getIdentifier(descriptionResEntryName,
+ DESC_RES_TYPE_STRING, packageName);
+ return resId <= 0 ? null : resources.getString(resId);
+ } catch (Resources.NotFoundException e) {
+ if (LOGV) {
+ Slog.w(TAG, "Description resource not found", e);
+ }
+ return null;
+ }
+ }
+
+ @Nullable
+ private static String getDescription(@Nullable Resources packageResources,
+ int descriptionResId) {
+ if (!ResourceId.isValid(descriptionResId) || packageResources == null) {
+ return null;
+ }
+ return packageResources.getString(descriptionResId);
+ }
+
boolean isStillValid() {
return expiryTimeMillis == 0 || expiryTimeMillis <= System.currentTimeMillis();
}
- void dump(Context context, IndentingPrintWriter fout) {
+ void dump(@NonNull Context context, @NonNull IndentingPrintWriter fout) {
fout.println("desc: " + getDescriptionToDump(context));
fout.println("expiryMs: " + expiryTimeMillis);
}
- private String getDescriptionToDump(Context context) {
- String desc = null;
- if (ResourceId.isValid(descriptionResId)) {
- 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 = "