summaryrefslogtreecommitdiff
path: root/apex/blobstore
diff options
context:
space:
mode:
Diffstat (limited to 'apex/blobstore')
-rw-r--r--apex/blobstore/framework/java/android/app/blob/BlobHandle.java11
-rw-r--r--apex/blobstore/framework/java/android/app/blob/BlobInfo.java20
-rw-r--r--apex/blobstore/framework/java/android/app/blob/XmlTags.java1
-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.java12
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java37
6 files changed, 65 insertions, 19 deletions
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobHandle.java b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
index bcef8ceaa941..ecc78ce7cf34 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
@@ -219,7 +219,7 @@ public final class BlobHandle implements Parcelable {
public void dump(IndentingPrintWriter fout, boolean dumpFull) {
if (dumpFull) {
fout.println("algo: " + algorithm);
- fout.println("digest: " + (dumpFull ? encodeDigest() : safeDigest()));
+ fout.println("digest: " + (dumpFull ? encodeDigest(digest) : safeDigest(digest)));
fout.println("label: " + label);
fout.println("expiryMs: " + expiryTimeMillis);
fout.println("tag: " + tag);
@@ -243,19 +243,20 @@ public final class BlobHandle implements Parcelable {
public String toString() {
return "BlobHandle {"
+ "algo:" + algorithm + ","
- + "digest:" + safeDigest() + ","
+ + "digest:" + safeDigest(digest) + ","
+ "label:" + label + ","
+ "expiryMs:" + expiryTimeMillis + ","
+ "tag:" + tag
+ "}";
}
- private String safeDigest() {
- final String digestStr = encodeDigest();
+ /** @hide */
+ public static String safeDigest(@NonNull byte[] digest) {
+ final String digestStr = encodeDigest(digest);
return digestStr.substring(0, 2) + ".." + digestStr.substring(digestStr.length() - 2);
}
- private String encodeDigest() {
+ private static String encodeDigest(@NonNull byte[] digest) {
return Base64.encodeToString(digest, Base64.NO_WRAP);
}
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobInfo.java b/apex/blobstore/framework/java/android/app/blob/BlobInfo.java
index 80062d5d245f..ba92d95b483e 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobInfo.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobInfo.java
@@ -16,9 +16,13 @@
package android.app.blob;
+import static android.text.format.Formatter.FLAG_IEC_UNITS;
+
import android.annotation.NonNull;
+import android.app.AppGlobals;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.format.Formatter;
import java.util.Collections;
import java.util.List;
@@ -32,13 +36,15 @@ public final class BlobInfo implements Parcelable {
private final long mId;
private final long mExpiryTimeMs;
private final CharSequence mLabel;
+ private final long mSizeBytes;
private final List<LeaseInfo> mLeaseInfos;
- public BlobInfo(long id, long expiryTimeMs, CharSequence label,
+ public BlobInfo(long id, long expiryTimeMs, CharSequence label, long sizeBytes,
List<LeaseInfo> leaseInfos) {
mId = id;
mExpiryTimeMs = expiryTimeMs;
mLabel = label;
+ mSizeBytes = sizeBytes;
mLeaseInfos = leaseInfos;
}
@@ -46,6 +52,7 @@ public final class BlobInfo implements Parcelable {
mId = in.readLong();
mExpiryTimeMs = in.readLong();
mLabel = in.readCharSequence();
+ mSizeBytes = in.readLong();
mLeaseInfos = in.readArrayList(null /* classloader */);
}
@@ -61,6 +68,10 @@ public final class BlobInfo implements Parcelable {
return mLabel;
}
+ public long getSizeBytes() {
+ return mSizeBytes;
+ }
+
public List<LeaseInfo> getLeases() {
return Collections.unmodifiableList(mLeaseInfos);
}
@@ -70,6 +81,7 @@ public final class BlobInfo implements Parcelable {
dest.writeLong(mId);
dest.writeLong(mExpiryTimeMs);
dest.writeCharSequence(mLabel);
+ dest.writeLong(mSizeBytes);
dest.writeList(mLeaseInfos);
}
@@ -83,10 +95,16 @@ public final class BlobInfo implements Parcelable {
+ "id: " + mId + ","
+ "expiryMs: " + mExpiryTimeMs + ","
+ "label: " + mLabel + ","
+ + "size: " + formatBlobSize(mSizeBytes) + ","
+ "leases: " + LeaseInfo.toShortString(mLeaseInfos) + ","
+ "}";
}
+ private static String formatBlobSize(long sizeBytes) {
+ return Formatter.formatFileSize(AppGlobals.getInitialApplication(),
+ sizeBytes, FLAG_IEC_UNITS);
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index dbfdcba05a73..656749d1a8c4 100644
--- a/apex/blobstore/framework/java/android/app/blob/XmlTags.java
+++ b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
@@ -27,6 +27,7 @@ public final class XmlTags {
public static final String ATTR_ID = "id";
public static final String ATTR_PACKAGE = "p";
public static final String ATTR_UID = "u";
+ public static final String ATTR_CREATION_TIME_MS = "crt";
// For BlobMetadata
public static final String TAG_BLOB = "b";
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 9a711d31b6a9..656726622cfd 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
@@ -45,8 +45,9 @@ class BlobStoreConfig {
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_ADD_COMMIT_TIME = 4;
+ public static final int XML_VERSION_ADD_SESSION_CREATION_TIME = 5;
- public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_COMMIT_TIME;
+ public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_SESSION_CREATION_TIME;
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 a2bce31fc7b2..68c4bb675907 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -32,7 +32,6 @@ 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_CURRENT;
import static com.android.server.blob.BlobStoreConfig.getAdjustedCommitTimeMs;
-import static com.android.server.blob.BlobStoreConfig.hasSessionExpired;
import static com.android.server.blob.BlobStoreSession.STATE_ABANDONED;
import static com.android.server.blob.BlobStoreSession.STATE_COMMITTED;
import static com.android.server.blob.BlobStoreSession.STATE_VERIFIED_INVALID;
@@ -479,11 +478,14 @@ public class BlobStoreManagerService extends SystemService {
? Resources.ID_NULL
: getDescriptionResourceId(resourcesGetter.apply(leasee.packageName),
leasee.descriptionResEntryName, leasee.packageName);
- leaseInfos.add(new LeaseInfo(leasee.packageName, leasee.expiryTimeMillis,
+ final long expiryTimeMs = leasee.expiryTimeMillis == 0
+ ? blobHandle.getExpiryTimeMillis() : leasee.expiryTimeMillis;
+ leaseInfos.add(new LeaseInfo(leasee.packageName, expiryTimeMs,
descriptionResId, leasee.description));
});
blobInfos.add(new BlobInfo(blobMetadata.getBlobId(),
- blobHandle.getExpiryTimeMillis(), blobHandle.getLabel(), leaseInfos));
+ blobHandle.getExpiryTimeMillis(), blobHandle.getLabel(),
+ blobMetadata.getSize(), leaseInfos));
});
}
return blobInfos;
@@ -592,6 +594,7 @@ public class BlobStoreManagerService extends SystemService {
} else {
blob.addOrReplaceCommitter(existingCommitter);
}
+ Slog.d(TAG, "Error committing the blob", e);
session.sendCommitCallbackResult(COMMIT_RESULT_ERROR);
}
getUserSessionsLocked(UserHandle.getUserId(session.getOwnerUid()))
@@ -986,9 +989,8 @@ public class BlobStoreManagerService extends SystemService {
userSessions.removeIf((sessionId, blobStoreSession) -> {
boolean shouldRemove = false;
- // TODO: handle the case where no content has been written to session yet.
// Cleanup sessions which haven't been modified in a while.
- if (hasSessionExpired(blobStoreSession.getSessionFile().lastModified())) {
+ if (blobStoreSession.isExpired()) {
shouldRemove = true;
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
index 7dc1bd089afb..a10b0b324f83 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -16,6 +16,7 @@
package com.android.server.blob;
import static android.app.blob.BlobStoreManager.COMMIT_RESULT_ERROR;
+import static android.app.blob.XmlTags.ATTR_CREATION_TIME_MS;
import static android.app.blob.XmlTags.ATTR_ID;
import static android.app.blob.XmlTags.ATTR_PACKAGE;
import static android.app.blob.XmlTags.ATTR_UID;
@@ -27,8 +28,9 @@ import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_RDWR;
import static android.system.OsConstants.SEEK_SET;
-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_SESSION_CREATION_TIME;
+import static com.android.server.blob.BlobStoreConfig.hasSessionExpired;
import android.annotation.BytesLong;
import android.annotation.NonNull;
@@ -91,6 +93,7 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
private final long mSessionId;
private final int mOwnerUid;
private final String mOwnerPackageName;
+ private final long mCreationTimeMs;
// Do not access this directly, instead use getSessionFile().
private File mSessionFile;
@@ -111,16 +114,24 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
@GuardedBy("mSessionLock")
private IBlobCommitCallback mBlobCommitCallback;
- BlobStoreSession(Context context, long sessionId, BlobHandle blobHandle,
- int ownerUid, String ownerPackageName, SessionStateChangeListener listener) {
+ private BlobStoreSession(Context context, long sessionId, BlobHandle blobHandle,
+ int ownerUid, String ownerPackageName, long creationTimeMs,
+ SessionStateChangeListener listener) {
this.mContext = context;
this.mBlobHandle = blobHandle;
this.mSessionId = sessionId;
this.mOwnerUid = ownerUid;
this.mOwnerPackageName = ownerPackageName;
+ this.mCreationTimeMs = creationTimeMs;
this.mListener = listener;
}
+ BlobStoreSession(Context context, long sessionId, BlobHandle blobHandle,
+ int ownerUid, String ownerPackageName, SessionStateChangeListener listener) {
+ this(context, sessionId, blobHandle, ownerUid, ownerPackageName,
+ System.currentTimeMillis(), listener);
+ }
+
public BlobHandle getBlobHandle() {
return mBlobHandle;
}
@@ -180,6 +191,12 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
}
}
+ boolean isExpired() {
+ final long lastModifiedTimeMs = getSessionFile().lastModified();
+ return hasSessionExpired(lastModifiedTimeMs == 0
+ ? mCreationTimeMs : lastModifiedTimeMs);
+ }
+
@Override
@NonNull
public ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
@@ -428,9 +445,10 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
mState = STATE_VERIFIED_VALID;
// Commit callback will be sent once the data is persisted.
} else {
- if (LOGV) {
- Slog.v(TAG, "Digest of the data didn't match the given BlobHandle.digest");
- }
+ Slog.d(TAG, "Digest of the data ("
+ + (mDataDigest == null ? "null" : BlobHandle.safeDigest(mDataDigest))
+ + ") didn't match the given BlobHandle.digest ("
+ + BlobHandle.safeDigest(mBlobHandle.digest) + ")");
mState = STATE_VERIFIED_INVALID;
sendCommitCallbackResult(COMMIT_RESULT_ERROR);
}
@@ -510,6 +528,7 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
fout.println("state: " + stateToString(mState));
fout.println("ownerUid: " + mOwnerUid);
fout.println("ownerPkg: " + mOwnerPackageName);
+ fout.println("creation time: " + BlobStoreUtils.formatTime(mCreationTimeMs));
fout.println("blobHandle:");
fout.increaseIndent();
@@ -530,6 +549,7 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
XmlUtils.writeLongAttribute(out, ATTR_ID, mSessionId);
XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, mOwnerPackageName);
XmlUtils.writeIntAttribute(out, ATTR_UID, mOwnerUid);
+ XmlUtils.writeLongAttribute(out, ATTR_CREATION_TIME_MS, mCreationTimeMs);
out.startTag(null, TAG_BLOB_HANDLE);
mBlobHandle.writeToXml(out);
@@ -548,6 +568,9 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
final long sessionId = XmlUtils.readLongAttribute(in, ATTR_ID);
final String ownerPackageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
final int ownerUid = XmlUtils.readIntAttribute(in, ATTR_UID);
+ final long creationTimeMs = version >= XML_VERSION_ADD_SESSION_CREATION_TIME
+ ? XmlUtils.readLongAttribute(in, ATTR_CREATION_TIME_MS)
+ : System.currentTimeMillis();
final int depth = in.getDepth();
BlobHandle blobHandle = null;
@@ -570,7 +593,7 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
}
final BlobStoreSession blobStoreSession = new BlobStoreSession(context, sessionId,
- blobHandle, ownerUid, ownerPackageName, stateChangeListener);
+ blobHandle, ownerUid, ownerPackageName, creationTimeMs, stateChangeListener);
blobStoreSession.mBlobAccessMode.allow(blobAccessMode);
return blobStoreSession;
}