diff options
6 files changed, 55 insertions, 9 deletions
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 49b3ec1d113b..cea7fcca6e20 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java @@ -212,7 +212,10 @@ class BlobMetadata { } boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid) { - // TODO: verify blob is still valid (expiryTime is not elapsed) + // Don't allow the blob to be accessed after it's expiry time has passed. + if (getBlobHandle().isExpired()) { + return false; + } synchronized (mMetadataLock) { // Check if packageName already holds a lease on the blob. for (int i = 0, size = mLeasees.size(); i < size; ++i) { 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 7a27b2c795fb..a2bce31fc7b2 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -1059,6 +1059,18 @@ public class BlobStoreManagerService extends SystemService { } } + boolean isBlobAvailable(long blobId, int userId) { + synchronized (mBlobsLock) { + final ArrayMap<BlobHandle, BlobMetadata> userBlobs = getUserBlobsLocked(userId); + for (BlobMetadata blobMetadata : userBlobs.values()) { + if (blobMetadata.getBlobId() == blobId) { + return true; + } + } + return false; + } + } + @GuardedBy("mBlobsLock") private void dumpSessionsLocked(IndentingPrintWriter fout, DumpArgs dumpArgs) { for (int i = 0, userCount = mSessions.size(); i < userCount; ++i) { diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java index 72af323e9d5f..a4a2e80c195a 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java @@ -46,6 +46,8 @@ class BlobStoreManagerShellCommand extends ShellCommand { return runDeleteBlob(pw); case "idle-maintenance": return runIdleMaintenance(pw); + case "query-blob-existence": + return runQueryBlobExistence(pw); default: return handleDefaultCommands(cmd); } @@ -91,6 +93,16 @@ class BlobStoreManagerShellCommand extends ShellCommand { return 0; } + private int runQueryBlobExistence(PrintWriter pw) { + final ParsedArgs args = new ParsedArgs(); + if (parseOptions(pw, args) < 0) { + return -1; + } + + pw.println(mService.isBlobAvailable(args.blobId, args.userId) ? 1 : 0); + return 0; + } + @Override public void onHelp() { final PrintWriter pw = getOutPrintWriter(); @@ -121,6 +133,8 @@ class BlobStoreManagerShellCommand extends ShellCommand { pw.println(" --tag: Tag of the blob to delete."); pw.println("idle-maintenance"); pw.println(" Run idle maintenance which takes care of removing stale data."); + pw.println("query-blob-existence [-b BLOB_ID]"); + pw.println(" Prints 1 if blob exists, otherwise 0."); pw.println(); } @@ -147,6 +161,9 @@ class BlobStoreManagerShellCommand extends ShellCommand { case "--tag": args.tag = getNextArgRequired(); break; + case "-b": + args.blobId = Long.parseLong(getNextArgRequired()); + break; default: pw.println("Error: unknown option '" + opt + "'"); return -1; @@ -166,6 +183,7 @@ class BlobStoreManagerShellCommand extends ShellCommand { public long expiryTimeMillis; public CharSequence label; public String tag; + public long blobId; public BlobHandle getBlobHandle() { return BlobHandle.create(algorithm, digest, label, expiryTimeMillis, tag); diff --git a/tests/BlobStoreTestUtils/Android.bp b/tests/BlobStoreTestUtils/Android.bp index 5c7c68b57ba1..53d36389a52a 100644 --- a/tests/BlobStoreTestUtils/Android.bp +++ b/tests/BlobStoreTestUtils/Android.bp @@ -18,6 +18,7 @@ java_library { static_libs: [ "truth-prebuilt", "androidx.test.uiautomator_uiautomator", + "androidx.test.ext.junit", ], sdk_version: "test_current", }
\ No newline at end of file diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java index 371375c0d932..4a0ca664049a 100644 --- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java +++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java @@ -42,6 +42,7 @@ public class DummyBlobData { private final File mFile; private final long mFileSize; private final CharSequence mLabel; + private final long mExpiryDurationMs; byte[] mFileDigest; long mExpiryTimeMs; @@ -51,6 +52,7 @@ public class DummyBlobData { mFile = new File(builder.getContext().getFilesDir(), builder.getFileName()); mFileSize = builder.getFileSize(); mLabel = builder.getLabel(); + mExpiryDurationMs = builder.getExpiryDurationMs(); } public static class Builder { @@ -59,6 +61,7 @@ public class DummyBlobData { private long mFileSize = DEFAULT_SIZE_BYTES; private CharSequence mLabel = "Test label"; private String mFileName = "blob_" + System.nanoTime(); + private long mExpiryDurationMs = TimeUnit.DAYS.toMillis(1); public Builder(Context context) { mContext = context; @@ -104,6 +107,15 @@ public class DummyBlobData { return mFileName; } + public Builder setExpiryDurationMs(long durationMs) { + mExpiryDurationMs = durationMs; + return this; + } + + public long getExpiryDurationMs() { + return mExpiryDurationMs; + } + public DummyBlobData build() { return new DummyBlobData(this); } @@ -114,7 +126,7 @@ public class DummyBlobData { writeRandomData(file, mFileSize); } mFileDigest = FileUtils.digest(mFile, "SHA-256"); - mExpiryTimeMs = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1); + mExpiryTimeMs = System.currentTimeMillis() + mExpiryDurationMs; } public BlobHandle getBlobHandle() throws Exception { diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java index 7cf58e1682bf..b9bd661dfd67 100644 --- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java +++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java @@ -18,7 +18,6 @@ package com.android.utils.blob; import static com.google.common.truth.Truth.assertThat; -import android.app.Instrumentation; import android.app.blob.BlobHandle; import android.app.blob.BlobStoreManager; import android.app.blob.LeaseInfo; @@ -27,6 +26,7 @@ import android.content.res.Resources; import android.os.ParcelFileDescriptor; import android.util.Log; +import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.uiautomator.UiDevice; import java.io.FileInputStream; @@ -149,14 +149,14 @@ public class Utils { assertThat(leaseInfo.getDescription()).isEqualTo(description); } - public static void triggerIdleMaintenance(Instrumentation instrumentation) throws IOException { - runShellCmd(instrumentation, "cmd blob_store idle-maintenance"); + public static void triggerIdleMaintenance() throws IOException { + runShellCmd("cmd blob_store idle-maintenance"); } - private static String runShellCmd(Instrumentation instrumentation, - String cmd) throws IOException { - final UiDevice uiDevice = UiDevice.getInstance(instrumentation); - final String result = uiDevice.executeShellCommand(cmd); + public static String runShellCmd(String cmd) throws IOException { + final UiDevice uiDevice = UiDevice.getInstance( + InstrumentationRegistry.getInstrumentation()); + final String result = uiDevice.executeShellCommand(cmd).trim(); Log.i(TAG, "Output of '" + cmd + "': '" + result + "'"); return result; } |