Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6b70111 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Don't persist description res ids as they are subject to change." into...

Merge "Don't persist description res ids as they are subject to change." into rvc-dev am: 6c725002 am: 53a3dbfd

Change-Id: Ifc0d4a97a0be23e796cf19d1f457a1683190cb3d
parents ad750631 53a3dbfd
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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";
}
+94 −26
Original line number Diff line number Diff line
@@ -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)) {
        @NonNull
        private String getDescriptionToDump(@NonNull Context context) {
            String desc = getDescription(context, descriptionResEntryName, packageName,
                    UserHandle.getUserId(uid));
            if (desc == null) {
                desc = description.toString();
            }
            return desc == null ? "<none>" : desc;
        }

        @Nullable
        private static Resources getPackageResources(@NonNull Context context,
                @NonNull String packageName, int userId) {
            try {
                    final Resources leaseeRes = context.getPackageManager()
                            .getResourcesForApplicationAsUser(
                                    packageName, UserHandle.getUserId(uid));
                    desc = leaseeRes.getString(descriptionResId);
                return context.getPackageManager()
                        .getResourcesForApplicationAsUser(packageName, userId);
            } catch (PackageManager.NameNotFoundException e) {
                    Slog.d(TAG, "Unknown package in user " + UserHandle.getUserId(uid) + ": "
                Slog.d(TAG, "Unknown package in user " + userId + ": "
                        + packageName, e);
                    desc = "<none>";
                }
            } else {
                desc = description.toString();
                return null;
            }
            return desc;
        }

        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);
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -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";
+7 −2
Original line number Diff line number Diff line
@@ -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;
@@ -1187,8 +1188,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