Merge "Don't persist description res ids as they are subject to change." into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6c725002b7
@@ -145,6 +145,9 @@ public class BlobStoreManager {
|
|||||||
/** @hide */
|
/** @hide */
|
||||||
public static final int INVALID_RES_ID = -1;
|
public static final int INVALID_RES_ID = -1;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public static final String DESC_RES_TYPE_STRING = "string";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final IBlobStoreManager mService;
|
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
|
* <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.
|
* 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
|
* @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
|
||||||
* acquire a lease for.
|
* acquire a lease for.
|
||||||
* @param descriptionResId the resource id for a short description string that can be surfaced
|
* @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
|
* <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.
|
* 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
|
* @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
|
||||||
* acquire a lease for.
|
* acquire a lease for.
|
||||||
* @param descriptionResId the resource id for a short description string that can be surfaced
|
* @param descriptionResId the resource id for a short description string that can be surfaced
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ public final class XmlTags {
|
|||||||
|
|
||||||
// For leasee
|
// For leasee
|
||||||
public static final String TAG_LEASEE = "l";
|
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";
|
public static final String ATTR_DESCRIPTION = "d";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.server.blob;
|
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;
|
||||||
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_EXPIRY_TIME;
|
||||||
import static android.app.blob.XmlTags.ATTR_ID;
|
import static android.app.blob.XmlTags.ATTR_ID;
|
||||||
import static android.app.blob.XmlTags.ATTR_PACKAGE;
|
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.os.Process.INVALID_UID;
|
||||||
import static android.system.OsConstants.O_RDONLY;
|
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.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 static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_STRING_DESC;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -154,7 +157,7 @@ class BlobMetadata {
|
|||||||
synchronized (mMetadataLock) {
|
synchronized (mMetadataLock) {
|
||||||
// We need to override the leasee data, so first remove any existing
|
// We need to override the leasee data, so first remove any existing
|
||||||
// leasee before adding the new one.
|
// leasee before adding the new one.
|
||||||
final Leasee leasee = new Leasee(callingPackage, callingUid,
|
final Leasee leasee = new Leasee(mContext, callingPackage, callingUid,
|
||||||
descriptionResId, description, leaseExpiryTimeMillis);
|
descriptionResId, description, leaseExpiryTimeMillis);
|
||||||
mLeasees.remove(leasee);
|
mLeasees.remove(leasee);
|
||||||
mLeasees.add(leasee);
|
mLeasees.add(leasee);
|
||||||
@@ -459,59 +462,123 @@ class BlobMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final class Leasee extends Accessor {
|
static final class Leasee extends Accessor {
|
||||||
public final int descriptionResId;
|
public final String descriptionResEntryName;
|
||||||
public final CharSequence description;
|
public final CharSequence description;
|
||||||
public final long expiryTimeMillis;
|
public final long expiryTimeMillis;
|
||||||
|
|
||||||
Leasee(String packageName, int uid, int descriptionResId, CharSequence description,
|
Leasee(@NonNull Context context, @NonNull String packageName,
|
||||||
long expiryTimeMillis) {
|
int uid, int descriptionResId,
|
||||||
|
@Nullable CharSequence description, long expiryTimeMillis) {
|
||||||
super(packageName, uid);
|
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.expiryTimeMillis = expiryTimeMillis;
|
||||||
this.description = description;
|
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() {
|
boolean isStillValid() {
|
||||||
return expiryTimeMillis == 0 || expiryTimeMillis <= System.currentTimeMillis();
|
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("desc: " + getDescriptionToDump(context));
|
||||||
fout.println("expiryMs: " + expiryTimeMillis);
|
fout.println("expiryMs: " + expiryTimeMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDescriptionToDump(Context context) {
|
@NonNull
|
||||||
String desc = null;
|
private String getDescriptionToDump(@NonNull Context context) {
|
||||||
if (ResourceId.isValid(descriptionResId)) {
|
String desc = getDescription(context, descriptionResEntryName, packageName,
|
||||||
try {
|
UserHandle.getUserId(uid));
|
||||||
final Resources leaseeRes = context.getPackageManager()
|
if (desc == null) {
|
||||||
.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 {
|
|
||||||
desc = description.toString();
|
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 {
|
void writeToXml(@NonNull XmlSerializer out) throws IOException {
|
||||||
XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, packageName);
|
XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, packageName);
|
||||||
XmlUtils.writeIntAttribute(out, ATTR_UID, uid);
|
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.writeLongAttribute(out, ATTR_EXPIRY_TIME, expiryTimeMillis);
|
||||||
XmlUtils.writeStringAttribute(out, ATTR_DESCRIPTION, description);
|
XmlUtils.writeStringAttribute(out, ATTR_DESCRIPTION, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@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 String packageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
|
||||||
final int uid = XmlUtils.readIntAttribute(in, ATTR_UID);
|
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 long expiryTimeMillis = XmlUtils.readLongAttribute(in, ATTR_EXPIRY_TIME);
|
||||||
final CharSequence description;
|
final CharSequence description;
|
||||||
if (version >= XML_VERSION_ADD_STRING_DESC) {
|
if (version >= XML_VERSION_ADD_STRING_DESC) {
|
||||||
@@ -520,7 +587,8 @@ class BlobMetadata {
|
|||||||
description = null;
|
description = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Leasee(packageName, uid, descriptionResId, description, expiryTimeMillis);
|
return new Leasee(packageName, uid, descriptionResEntryName,
|
||||||
|
description, expiryTimeMillis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ class BlobStoreConfig {
|
|||||||
public static final int XML_VERSION_INIT = 1;
|
public static final int XML_VERSION_INIT = 1;
|
||||||
// Added a string variant of lease description.
|
// Added a string variant of lease description.
|
||||||
public static final int XML_VERSION_ADD_STRING_DESC = 2;
|
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 ROOT_DIR_NAME = "blobstore";
|
||||||
private static final String BLOBS_DIR_NAME = "blobs";
|
private static final String BLOBS_DIR_NAME = "blobs";
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageManagerInternal;
|
import android.content.pm.PackageManagerInternal;
|
||||||
import android.content.pm.PackageStats;
|
import android.content.pm.PackageStats;
|
||||||
import android.content.res.ResourceId;
|
import android.content.res.ResourceId;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
@@ -1187,8 +1188,12 @@ public class BlobStoreManagerService extends SystemService {
|
|||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
|
|
||||||
acquireLeaseInternal(blobHandle, descriptionResId, description, leaseExpiryTimeMillis,
|
try {
|
||||||
callingUid, packageName);
|
acquireLeaseInternal(blobHandle, descriptionResId, description,
|
||||||
|
leaseExpiryTimeMillis, callingUid, packageName);
|
||||||
|
} catch (Resources.NotFoundException e) {
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user