Persist blobstore session creation time.
This can be used for checking if a session
should be considered expired and needs to
be deleted.
Bug: 147722548
Test: atest --test-mapping apex/blobstore
Change-Id: I0f500b2baf71f8104a0a6c233071261f9ba9cc14
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index dbfdcba..656749d 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 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 9a711d3..6567266 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 @@
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 a2bce31..8fff0d9 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.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;
@@ -986,9 +985,8 @@
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 62701e5..2b04583 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;
@@ -29,6 +30,8 @@
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;
@@ -89,6 +92,7 @@
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;
@@ -109,16 +113,24 @@
@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;
}
@@ -178,6 +190,12 @@
}
}
+ boolean isExpired() {
+ final long lastModifiedTimeMs = getSessionFile().lastModified();
+ return hasSessionExpired(lastModifiedTimeMs == 0
+ ? mCreationTimeMs : lastModifiedTimeMs);
+ }
+
@Override
@NonNull
public ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
@@ -491,6 +509,7 @@
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();
@@ -511,6 +530,7 @@
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);
@@ -529,6 +549,9 @@
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;
@@ -551,7 +574,7 @@
}
final BlobStoreSession blobStoreSession = new BlobStoreSession(context, sessionId,
- blobHandle, ownerUid, ownerPackageName, stateChangeListener);
+ blobHandle, ownerUid, ownerPackageName, creationTimeMs, stateChangeListener);
blobStoreSession.mBlobAccessMode.allow(blobAccessMode);
return blobStoreSession;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java
index ade01dc..7446289 100644
--- a/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java
@@ -372,6 +372,7 @@
doReturn(sessionId).when(session).getSessionId();
doReturn(sessionFile).when(session).getSessionFile();
doReturn(blobHandle).when(session).getBlobHandle();
+ doCallRealMethod().when(session).isExpired();
return session;
}