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

Commit 4266a199 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge changes from topics "persist-data", "pkg-uninstall"

* changes:
  Delete sessions belonging to uninstalled packages.
  Persist committed blobs data and any pending sessions.
parents 0111ea77 22f0b166
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -15,13 +15,26 @@
 */
package android.app.blob;

import static android.app.blob.XmlTags.ATTR_ALGO;
import static android.app.blob.XmlTags.ATTR_DIGEST;
import static android.app.blob.XmlTags.ATTR_EXPIRY_TIME;
import static android.app.blob.XmlTags.ATTR_LABEL;
import static android.app.blob.XmlTags.ATTR_TAG;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Base64;

import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

@@ -41,17 +54,20 @@ public final class BlobHandle implements Parcelable {
     * @hide
     */
    @NonNull public final String algorithm;

    /**
     * Hash of the blob this handle is representing using {@link #algorithm}.
     *
     * @hide
     */
    @NonNull public final byte[] digest;

    /**
     * Label of the blob that can be surfaced to the user.
     * @hide
     */
    @NonNull public final CharSequence label;

    /**
     * Time in milliseconds after which the blob should be invalidated and not
     * allowed to be accessed by any other app, in {@link System#currentTimeMillis()} timebase.
@@ -59,6 +75,7 @@ public final class BlobHandle implements Parcelable {
     * @hide
     */
    @CurrentTimeMillisLong public final long expiryTimeMillis;

    /**
     * An opaque {@link String} associated with the blob.
     *
@@ -197,6 +214,15 @@ public final class BlobHandle implements Parcelable {
        return Objects.hash(algorithm, Arrays.hashCode(digest), label, expiryTimeMillis, tag);
    }

    /** @hide */
    public void dump(IndentingPrintWriter fout) {
        fout.println("algo: " + algorithm);
        fout.println("digest: " + Base64.encodeToString(digest, Base64.NO_WRAP));
        fout.println("label: " + label);
        fout.println("expiryMs: " + expiryTimeMillis);
        fout.println("tag: " + tag);
    }

    public static final @NonNull Creator<BlobHandle> CREATOR = new Creator<BlobHandle>() {
        @Override
        public @NonNull BlobHandle createFromParcel(@NonNull Parcel source) {
@@ -208,4 +234,25 @@ public final class BlobHandle implements Parcelable {
            return new BlobHandle[size];
        }
    };

    /** @hide */
    public void writeToXml(@NonNull XmlSerializer out) throws IOException {
        XmlUtils.writeStringAttribute(out, ATTR_ALGO, algorithm);
        XmlUtils.writeByteArrayAttribute(out, ATTR_DIGEST, digest);
        XmlUtils.writeStringAttribute(out, ATTR_LABEL, label);
        XmlUtils.writeLongAttribute(out, ATTR_EXPIRY_TIME, expiryTimeMillis);
        XmlUtils.writeStringAttribute(out, ATTR_TAG, tag);
    }

    /** @hide */
    @NonNull
    public static BlobHandle createFromXml(@NonNull XmlPullParser in) throws IOException {
        final String algo = XmlUtils.readStringAttribute(in, ATTR_ALGO);
        final byte[] digest = XmlUtils.readByteArrayAttribute(in, ATTR_DIGEST);
        final CharSequence label = XmlUtils.readStringAttribute(in, ATTR_LABEL);
        final long expiryTimeMs = XmlUtils.readLongAttribute(in, ATTR_EXPIRY_TIME);
        final String tag = XmlUtils.readStringAttribute(in, ATTR_TAG);

        return BlobHandle.create(algo, digest, label, expiryTimeMs, tag);
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -25,13 +25,17 @@ import android.annotation.SystemService;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
import android.os.RemoteCallback;
import android.os.RemoteException;

import com.android.internal.util.function.pooled.PooledLambda;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;

/**
@@ -352,6 +356,25 @@ public class BlobStoreManager {
        }
    }

    /**
     * Wait until any pending tasks (like persisting data to disk) have finished.
     *
     * @hide
     */
    public void waitForIdle(long timeoutMillis) throws InterruptedException, TimeoutException {
        try {
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            mService.waitForIdle(new RemoteCallback((result) -> countDownLatch.countDown()));
            if (!countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS)) {
                throw new TimeoutException("Timed out waiting for service to become idle");
            }
        } catch (ParcelableException e) {
            throw new RuntimeException(e);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Represents an ongoing session of a blob's contribution to the blob store managed by the
     * system.
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package android.app.blob;

import android.app.blob.BlobHandle;
import android.app.blob.IBlobStoreSession;
import android.os.RemoteCallback;

/** {@hide} */
interface IBlobStoreManager {
@@ -28,4 +29,6 @@ interface IBlobStoreManager {
    void acquireLease(in BlobHandle handle, int descriptionResId, long leaseTimeout,
            in String packageName);
    void releaseLease(in BlobHandle handle, in String packageName);

    void waitForIdle(in RemoteCallback callback);
}
 No newline at end of file
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.app.blob;

/** @hide */
public final class XmlTags {
    public static final String ATTR_VERSION = "v";

    public static final String TAG_SESSIONS = "ss";
    public static final String TAG_BLOBS = "bs";

    // For BlobStoreSession
    public static final String TAG_SESSION = "s";
    public static final String ATTR_ID = "id";
    public static final String ATTR_PACKAGE = "p";
    public static final String ATTR_UID = "u";

    // For BlobMetadata
    public static final String TAG_BLOB = "b";
    public static final String ATTR_USER_ID = "us";

    // For BlobAccessMode
    public static final String TAG_ACCESS_MODE = "am";
    public static final String ATTR_TYPE = "t";
    public static final String TAG_WHITELISTED_PACKAGE = "wl";
    public static final String ATTR_CERTIFICATE = "ct";

    // For BlobHandle
    public static final String TAG_BLOB_HANDLE = "bh";
    public static final String ATTR_ALGO = "al";
    public static final String ATTR_DIGEST = "dg";
    public static final String ATTR_LABEL = "lbl";
    public static final String ATTR_EXPIRY_TIME = "ex";
    public static final String ATTR_TAG = "tg";

    // For committer
    public static final String TAG_COMMITTER = "c";

    // For leasee
    public static final String TAG_LEASEE = "l";
    public static final String ATTR_DESCRIPTION_RES_ID = "rid";
}
+70 −4
Original line number Diff line number Diff line
@@ -15,12 +15,27 @@
 */
package com.android.server.blob;

import static android.app.blob.XmlTags.ATTR_CERTIFICATE;
import static android.app.blob.XmlTags.ATTR_PACKAGE;
import static android.app.blob.XmlTags.ATTR_TYPE;
import static android.app.blob.XmlTags.TAG_WHITELISTED_PACKAGE;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.ArraySet;
import android.util.Base64;
import android.util.DebugUtils;

import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -40,10 +55,10 @@ class BlobAccessMode {
            ACCESS_TYPE_WHITELIST,
    })
    @interface AccessType {}
    static final int ACCESS_TYPE_PRIVATE = 1 << 0;
    static final int ACCESS_TYPE_PUBLIC = 1 << 1;
    static final int ACCESS_TYPE_SAME_SIGNATURE = 1 << 2;
    static final int ACCESS_TYPE_WHITELIST = 1 << 3;
    public static final int ACCESS_TYPE_PRIVATE = 1 << 0;
    public static final int ACCESS_TYPE_PUBLIC = 1 << 1;
    public static final int ACCESS_TYPE_SAME_SIGNATURE = 1 << 2;
    public static final int ACCESS_TYPE_WHITELIST = 1 << 3;

    private int mAccessType = ACCESS_TYPE_PRIVATE;

@@ -112,6 +127,51 @@ class BlobAccessMode {
        return false;
    }

    void dump(IndentingPrintWriter fout) {
        fout.println("accessType: " + DebugUtils.flagsToString(
                BlobAccessMode.class, "ACCESS_TYPE_", mAccessType));
        fout.print("Whitelisted pkgs:");
        if (mWhitelistedPackages.isEmpty()) {
            fout.println(" (Empty)");
        } else {
            fout.increaseIndent();
            for (int i = 0, count = mWhitelistedPackages.size(); i < count; ++i) {
                fout.println(mWhitelistedPackages.valueAt(i).toString());
            }
            fout.decreaseIndent();
        }
    }

    void writeToXml(@NonNull XmlSerializer out) throws IOException {
        XmlUtils.writeIntAttribute(out, ATTR_TYPE, mAccessType);
        for (int i = 0, count = mWhitelistedPackages.size(); i < count; ++i) {
            out.startTag(null, TAG_WHITELISTED_PACKAGE);
            final PackageIdentifier packageIdentifier = mWhitelistedPackages.valueAt(i);
            XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, packageIdentifier.packageName);
            XmlUtils.writeByteArrayAttribute(out, ATTR_CERTIFICATE, packageIdentifier.certificate);
            out.endTag(null, TAG_WHITELISTED_PACKAGE);
        }
    }

    @NonNull
    static BlobAccessMode createFromXml(@NonNull XmlPullParser in)
            throws IOException, XmlPullParserException {
        final BlobAccessMode blobAccessMode = new BlobAccessMode();

        final int accessType = XmlUtils.readIntAttribute(in, ATTR_TYPE);
        blobAccessMode.mAccessType = accessType;

        final int depth = in.getDepth();
        while (XmlUtils.nextElementWithin(in, depth)) {
            if (TAG_WHITELISTED_PACKAGE.equals(in.getName())) {
                final String packageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
                final byte[] certificate = XmlUtils.readByteArrayAttribute(in, ATTR_CERTIFICATE);
                blobAccessMode.allowPackageAccess(packageName, certificate);
            }
        }
        return blobAccessMode;
    }

    private static final class PackageIdentifier {
        public final String packageName;
        public final byte[] certificate;
@@ -143,5 +203,11 @@ class BlobAccessMode {
        public int hashCode() {
            return Objects.hash(packageName, Arrays.hashCode(certificate));
        }

        @Override
        public String toString() {
            return "[" + packageName + ", "
                    + Base64.encodeToString(certificate, Base64.NO_WRAP) + "]";
        }
    }
}
Loading