summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sudheer Shanka <sudheersai@google.com> 2020-03-04 22:19:21 -0800
committer Sudheer Shanka <sudheersai@google.com> 2020-03-06 11:48:29 -0800
commit1b6b8253cfb4c9847668cf7f75ccac0785b005f7 (patch)
treeef3a4053865b88c5af2a0e582e17c94559ae3d30
parent2e7834d39e7159b903f89ef315db49ffc64e894b (diff)
Don't persist description res ids as they are subject to change.
Instead persist the resource name and update the javadoc to suggest that apps should re-acquire the lease if the description resource changes. Bug: 150829640 Test: atest --test-mapping apex/blobstore Change-Id: Ibeabffe7de046ed74cbbcaed6c69c9d25028799d
-rw-r--r--apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java9
-rw-r--r--apex/blobstore/framework/java/android/app/blob/XmlTags.java2
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java120
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java3
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java9
5 files changed, 113 insertions, 30 deletions
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index f53f1f19aea7..d1e28e99b6d6 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 {
* <p> 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.
*
+ * <p> 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 {
* <p> 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.
*
+ * <p> 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 9834d7477838..e64edc393769 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 4a85a69b82d3..888c3af8bbf7 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 = "<none>";
- }
- } else {
+ @NonNull
+ private String getDescriptionToDump(@NonNull Context context) {
+ String desc = getDescription(context, descriptionResEntryName, packageName,
+ UserHandle.getUserId(uid));
+ if (desc == null) {
desc = description.toString();
}
- return desc;
+ return desc == null ? "<none>" : desc;
+ }
+
+ @Nullable
+ private static Resources getPackageResources(@NonNull Context context,
+ @NonNull String packageName, int userId) {
+ try {
+ return context.getPackageManager()
+ .getResourcesForApplicationAsUser(packageName, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.d(TAG, "Unknown package in user " + userId + ": "
+ + packageName, e);
+ return null;
+ }
}
void writeToXml(@NonNull XmlSerializer out) throws IOException {
XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, packageName);
XmlUtils.writeIntAttribute(out, ATTR_UID, uid);
- XmlUtils.writeIntAttribute(out, ATTR_DESCRIPTION_RES_ID, descriptionResId);
+ XmlUtils.writeStringAttribute(out, ATTR_DESCRIPTION_RES_NAME, descriptionResEntryName);
XmlUtils.writeLongAttribute(out, ATTR_EXPIRY_TIME, expiryTimeMillis);
XmlUtils.writeStringAttribute(out, ATTR_DESCRIPTION, description);
}
@NonNull
- static Leasee createFromXml(@NonNull XmlPullParser in, int version) throws IOException {
+ static Leasee createFromXml(@NonNull XmlPullParser in, int version)
+ throws IOException {
final String packageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
final int uid = XmlUtils.readIntAttribute(in, ATTR_UID);
- final int descriptionResId = XmlUtils.readIntAttribute(in, ATTR_DESCRIPTION_RES_ID);
+ final String descriptionResEntryName;
+ if (version >= XML_VERSION_ADD_DESC_RES_NAME) {
+ descriptionResEntryName = XmlUtils.readStringAttribute(
+ in, ATTR_DESCRIPTION_RES_NAME);
+ } else {
+ descriptionResEntryName = null;
+ }
final long expiryTimeMillis = XmlUtils.readLongAttribute(in, ATTR_EXPIRY_TIME);
final CharSequence description;
if (version >= XML_VERSION_ADD_STRING_DESC) {
@@ -520,7 +587,8 @@ class BlobMetadata {
description = null;
}
- return new Leasee(packageName, uid, descriptionResId, description, expiryTimeMillis);
+ return new Leasee(packageName, uid, descriptionResEntryName,
+ description, expiryTimeMillis);
}
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
index bcc1610435d9..6d31b2c30067 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
@@ -32,8 +32,9 @@ class BlobStoreConfig {
public static final int XML_VERSION_INIT = 1;
// Added a string variant of lease description.
public static final int XML_VERSION_ADD_STRING_DESC = 2;
+ public static final int XML_VERSION_ADD_DESC_RES_NAME = 3;
- public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_STRING_DESC;
+ public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_DESC_RES_NAME;
private static final String ROOT_DIR_NAME = "blobstore";
private static final String BLOBS_DIR_NAME = "blobs";
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 05c661127eab..b202e95ed211 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -54,6 +54,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageStats;
import android.content.res.ResourceId;
+import android.content.res.Resources;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
@@ -1181,8 +1182,12 @@ public class BlobStoreManagerService extends SystemService {
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
- acquireLeaseInternal(blobHandle, descriptionResId, description, leaseExpiryTimeMillis,
- callingUid, packageName);
+ try {
+ acquireLeaseInternal(blobHandle, descriptionResId, description,
+ leaseExpiryTimeMillis, callingUid, packageName);
+ } catch (Resources.NotFoundException e) {
+ throw new IllegalArgumentException(e);
+ }
}
@Override