Loading apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java +44 −13 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.blob; import static android.provider.DeviceConfig.NAMESPACE_BLOBSTORE; import static android.text.format.Formatter.FLAG_IEC_UNITS; import static android.text.format.Formatter.formatFileSize; import static android.util.TimeUtils.formatDuration; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -58,17 +57,23 @@ class BlobStoreConfig { * Job Id for idle maintenance job ({@link BlobStoreIdleJobService}). */ public static final int IDLE_JOB_ID = 0xB70B1D7; // 191934935L public static class DeviceConfigProperties { /** * Max time period (in millis) between each idle maintenance job run. * Denotes the max time period (in millis) between each idle maintenance job run. */ public static final long IDLE_JOB_PERIOD_MILLIS = TimeUnit.DAYS.toMillis(1); public static final String KEY_IDLE_JOB_PERIOD_MS = "idle_job_period_ms"; public static final long DEFAULT_IDLE_JOB_PERIOD_MS = TimeUnit.DAYS.toMillis(1); public static long IDLE_JOB_PERIOD_MS = DEFAULT_IDLE_JOB_PERIOD_MS; /** * Timeout in millis after which sessions with no updates will be deleted. * Denotes the timeout in millis after which sessions with no updates will be deleted. */ public static final long SESSION_EXPIRY_TIMEOUT_MILLIS = TimeUnit.DAYS.toMillis(7); public static final String KEY_SESSION_EXPIRY_TIMEOUT_MS = "session_expiry_timeout_ms"; public static final long DEFAULT_SESSION_EXPIRY_TIMEOUT_MS = TimeUnit.DAYS.toMillis(7); public static long SESSION_EXPIRY_TIMEOUT_MS = DEFAULT_SESSION_EXPIRY_TIMEOUT_MS; public static class DeviceConfigProperties { /** * Denotes how low the limit for the amount of data, that an app will be allowed to acquire * a lease on, can be. Loading Loading @@ -119,6 +124,13 @@ class BlobStoreConfig { } properties.getKeyset().forEach(key -> { switch (key) { case KEY_IDLE_JOB_PERIOD_MS: IDLE_JOB_PERIOD_MS = properties.getLong(key, DEFAULT_IDLE_JOB_PERIOD_MS); break; case KEY_SESSION_EXPIRY_TIMEOUT_MS: SESSION_EXPIRY_TIMEOUT_MS = properties.getLong(key, DEFAULT_SESSION_EXPIRY_TIMEOUT_MS); break; case KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR: TOTAL_BYTES_PER_APP_LIMIT_FLOOR = properties.getLong(key, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR); Loading @@ -143,6 +155,12 @@ class BlobStoreConfig { static void dump(IndentingPrintWriter fout, Context context) { final String dumpFormat = "%s: [cur: %s, def: %s]"; fout.println(String.format(dumpFormat, KEY_IDLE_JOB_PERIOD_MS, TimeUtils.formatDuration(IDLE_JOB_PERIOD_MS), TimeUtils.formatDuration(DEFAULT_IDLE_JOB_PERIOD_MS))); fout.println(String.format(dumpFormat, KEY_SESSION_EXPIRY_TIMEOUT_MS, TimeUtils.formatDuration(SESSION_EXPIRY_TIMEOUT_MS), TimeUtils.formatDuration(DEFAULT_SESSION_EXPIRY_TIMEOUT_MS))); fout.println(String.format(dumpFormat, KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, formatFileSize(context, TOTAL_BYTES_PER_APP_LIMIT_FLOOR, FLAG_IEC_UNITS), formatFileSize(context, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, Loading @@ -166,6 +184,22 @@ class BlobStoreConfig { DeviceConfigProperties.refresh(DeviceConfig.getProperties(NAMESPACE_BLOBSTORE)); } /** * Returns the max time period (in millis) between each idle maintenance job run. */ public static long getIdleJobPeriodMs() { return DeviceConfigProperties.IDLE_JOB_PERIOD_MS; } /** * Returns whether a session is expired or not. A session is considered expired if the session * has not been modified in a while (i.e. SESSION_EXPIRY_TIMEOUT_MS). */ public static boolean hasSessionExpired(long sessionLastModifiedMs) { return sessionLastModifiedMs < System.currentTimeMillis() - DeviceConfigProperties.SESSION_EXPIRY_TIMEOUT_MS; } /** * Returns the maximum amount of data that an app can acquire a lease on. */ Loading Loading @@ -277,9 +311,6 @@ class BlobStoreConfig { fout.println("XML current version: " + XML_VERSION_CURRENT); fout.println("Idle job ID: " + IDLE_JOB_ID); fout.println("Idle job period: " + formatDuration(IDLE_JOB_PERIOD_MILLIS)); fout.println("Session expiry timeout: " + formatDuration(SESSION_EXPIRY_TIMEOUT_MILLIS)); fout.println("Total bytes per app limit: " + formatFileSize(context, getAppDataBytesLimit(), FLAG_IEC_UNITS)); Loading apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java +1 −2 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.blob; import static com.android.server.blob.BlobStoreConfig.IDLE_JOB_ID; import static com.android.server.blob.BlobStoreConfig.IDLE_JOB_PERIOD_MILLIS; import static com.android.server.blob.BlobStoreConfig.LOGV; import static com.android.server.blob.BlobStoreConfig.TAG; Loading Loading @@ -60,7 +59,7 @@ public class BlobStoreIdleJobService extends JobService { new ComponentName(context, BlobStoreIdleJobService.class)) .setRequiresDeviceIdle(true) .setRequiresCharging(true) .setPeriodic(IDLE_JOB_PERIOD_MILLIS) .setPeriodic(BlobStoreConfig.getIdleJobPeriodMs()) .build(); jobScheduler.schedule(job); if (LOGV) { Loading apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -29,10 +29,10 @@ import static android.os.UserHandle.USER_CURRENT; import static android.os.UserHandle.USER_NULL; import static com.android.server.blob.BlobStoreConfig.LOGV; import static com.android.server.blob.BlobStoreConfig.SESSION_EXPIRY_TIMEOUT_MILLIS; 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; Loading Loading @@ -986,9 +986,9 @@ 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 (blobStoreSession.getSessionFile().lastModified() < System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MILLIS) { if (hasSessionExpired(blobStoreSession.getSessionFile().lastModified())) { shouldRemove = true; } Loading services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java +4 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealM import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.server.blob.BlobStoreConfig.SESSION_EXPIRY_TIMEOUT_MILLIS; import static com.android.server.blob.BlobStoreConfig.DeviceConfigProperties.SESSION_EXPIRY_TIMEOUT_MS; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -93,6 +93,7 @@ public class BlobStoreManagerServiceTest { doReturn(true).when(mBlobsDir).exists(); doReturn(new File[0]).when(mBlobsDir).listFiles(); doReturn(true).when(() -> BlobStoreConfig.hasLeaseWaitTimeElapsed(anyLong())); doCallRealMethod().when(() -> BlobStoreConfig.hasSessionExpired(anyLong())); mContext = InstrumentationRegistry.getTargetContext(); mHandler = new TestHandler(Looper.getMainLooper()); Loading Loading @@ -236,7 +237,7 @@ public class BlobStoreManagerServiceTest { public void testHandleIdleMaintenance_deleteStaleSessions() throws Exception { // Setup sessions final File sessionFile1 = mock(File.class); doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MILLIS + 1000) doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MS + 1000) .when(sessionFile1).lastModified(); final long sessionId1 = 342; final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest1".getBytes(), Loading @@ -256,7 +257,7 @@ public class BlobStoreManagerServiceTest { mUserSessions.append(sessionId2, session2); final File sessionFile3 = mock(File.class); doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MILLIS - 2000) doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MS - 2000) .when(sessionFile3).lastModified(); final long sessionId3 = 9484; final BlobHandle blobHandle3 = BlobHandle.createWithSha256("digest3".getBytes(), Loading tests/BlobStoreTestUtils/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ java_library { name: "BlobStoreTestUtils", srcs: ["src/**/*.java"], static_libs: ["truth-prebuilt"], static_libs: [ "truth-prebuilt", "androidx.test.uiautomator_uiautomator", ], sdk_version: "test_current", } No newline at end of file Loading
apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java +44 −13 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.blob; import static android.provider.DeviceConfig.NAMESPACE_BLOBSTORE; import static android.text.format.Formatter.FLAG_IEC_UNITS; import static android.text.format.Formatter.formatFileSize; import static android.util.TimeUtils.formatDuration; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -58,17 +57,23 @@ class BlobStoreConfig { * Job Id for idle maintenance job ({@link BlobStoreIdleJobService}). */ public static final int IDLE_JOB_ID = 0xB70B1D7; // 191934935L public static class DeviceConfigProperties { /** * Max time period (in millis) between each idle maintenance job run. * Denotes the max time period (in millis) between each idle maintenance job run. */ public static final long IDLE_JOB_PERIOD_MILLIS = TimeUnit.DAYS.toMillis(1); public static final String KEY_IDLE_JOB_PERIOD_MS = "idle_job_period_ms"; public static final long DEFAULT_IDLE_JOB_PERIOD_MS = TimeUnit.DAYS.toMillis(1); public static long IDLE_JOB_PERIOD_MS = DEFAULT_IDLE_JOB_PERIOD_MS; /** * Timeout in millis after which sessions with no updates will be deleted. * Denotes the timeout in millis after which sessions with no updates will be deleted. */ public static final long SESSION_EXPIRY_TIMEOUT_MILLIS = TimeUnit.DAYS.toMillis(7); public static final String KEY_SESSION_EXPIRY_TIMEOUT_MS = "session_expiry_timeout_ms"; public static final long DEFAULT_SESSION_EXPIRY_TIMEOUT_MS = TimeUnit.DAYS.toMillis(7); public static long SESSION_EXPIRY_TIMEOUT_MS = DEFAULT_SESSION_EXPIRY_TIMEOUT_MS; public static class DeviceConfigProperties { /** * Denotes how low the limit for the amount of data, that an app will be allowed to acquire * a lease on, can be. Loading Loading @@ -119,6 +124,13 @@ class BlobStoreConfig { } properties.getKeyset().forEach(key -> { switch (key) { case KEY_IDLE_JOB_PERIOD_MS: IDLE_JOB_PERIOD_MS = properties.getLong(key, DEFAULT_IDLE_JOB_PERIOD_MS); break; case KEY_SESSION_EXPIRY_TIMEOUT_MS: SESSION_EXPIRY_TIMEOUT_MS = properties.getLong(key, DEFAULT_SESSION_EXPIRY_TIMEOUT_MS); break; case KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR: TOTAL_BYTES_PER_APP_LIMIT_FLOOR = properties.getLong(key, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR); Loading @@ -143,6 +155,12 @@ class BlobStoreConfig { static void dump(IndentingPrintWriter fout, Context context) { final String dumpFormat = "%s: [cur: %s, def: %s]"; fout.println(String.format(dumpFormat, KEY_IDLE_JOB_PERIOD_MS, TimeUtils.formatDuration(IDLE_JOB_PERIOD_MS), TimeUtils.formatDuration(DEFAULT_IDLE_JOB_PERIOD_MS))); fout.println(String.format(dumpFormat, KEY_SESSION_EXPIRY_TIMEOUT_MS, TimeUtils.formatDuration(SESSION_EXPIRY_TIMEOUT_MS), TimeUtils.formatDuration(DEFAULT_SESSION_EXPIRY_TIMEOUT_MS))); fout.println(String.format(dumpFormat, KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, formatFileSize(context, TOTAL_BYTES_PER_APP_LIMIT_FLOOR, FLAG_IEC_UNITS), formatFileSize(context, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, Loading @@ -166,6 +184,22 @@ class BlobStoreConfig { DeviceConfigProperties.refresh(DeviceConfig.getProperties(NAMESPACE_BLOBSTORE)); } /** * Returns the max time period (in millis) between each idle maintenance job run. */ public static long getIdleJobPeriodMs() { return DeviceConfigProperties.IDLE_JOB_PERIOD_MS; } /** * Returns whether a session is expired or not. A session is considered expired if the session * has not been modified in a while (i.e. SESSION_EXPIRY_TIMEOUT_MS). */ public static boolean hasSessionExpired(long sessionLastModifiedMs) { return sessionLastModifiedMs < System.currentTimeMillis() - DeviceConfigProperties.SESSION_EXPIRY_TIMEOUT_MS; } /** * Returns the maximum amount of data that an app can acquire a lease on. */ Loading Loading @@ -277,9 +311,6 @@ class BlobStoreConfig { fout.println("XML current version: " + XML_VERSION_CURRENT); fout.println("Idle job ID: " + IDLE_JOB_ID); fout.println("Idle job period: " + formatDuration(IDLE_JOB_PERIOD_MILLIS)); fout.println("Session expiry timeout: " + formatDuration(SESSION_EXPIRY_TIMEOUT_MILLIS)); fout.println("Total bytes per app limit: " + formatFileSize(context, getAppDataBytesLimit(), FLAG_IEC_UNITS)); Loading
apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java +1 −2 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.blob; import static com.android.server.blob.BlobStoreConfig.IDLE_JOB_ID; import static com.android.server.blob.BlobStoreConfig.IDLE_JOB_PERIOD_MILLIS; import static com.android.server.blob.BlobStoreConfig.LOGV; import static com.android.server.blob.BlobStoreConfig.TAG; Loading Loading @@ -60,7 +59,7 @@ public class BlobStoreIdleJobService extends JobService { new ComponentName(context, BlobStoreIdleJobService.class)) .setRequiresDeviceIdle(true) .setRequiresCharging(true) .setPeriodic(IDLE_JOB_PERIOD_MILLIS) .setPeriodic(BlobStoreConfig.getIdleJobPeriodMs()) .build(); jobScheduler.schedule(job); if (LOGV) { Loading
apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -29,10 +29,10 @@ import static android.os.UserHandle.USER_CURRENT; import static android.os.UserHandle.USER_NULL; import static com.android.server.blob.BlobStoreConfig.LOGV; import static com.android.server.blob.BlobStoreConfig.SESSION_EXPIRY_TIMEOUT_MILLIS; 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; Loading Loading @@ -986,9 +986,9 @@ 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 (blobStoreSession.getSessionFile().lastModified() < System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MILLIS) { if (hasSessionExpired(blobStoreSession.getSessionFile().lastModified())) { shouldRemove = true; } Loading
services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java +4 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealM import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.server.blob.BlobStoreConfig.SESSION_EXPIRY_TIMEOUT_MILLIS; import static com.android.server.blob.BlobStoreConfig.DeviceConfigProperties.SESSION_EXPIRY_TIMEOUT_MS; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -93,6 +93,7 @@ public class BlobStoreManagerServiceTest { doReturn(true).when(mBlobsDir).exists(); doReturn(new File[0]).when(mBlobsDir).listFiles(); doReturn(true).when(() -> BlobStoreConfig.hasLeaseWaitTimeElapsed(anyLong())); doCallRealMethod().when(() -> BlobStoreConfig.hasSessionExpired(anyLong())); mContext = InstrumentationRegistry.getTargetContext(); mHandler = new TestHandler(Looper.getMainLooper()); Loading Loading @@ -236,7 +237,7 @@ public class BlobStoreManagerServiceTest { public void testHandleIdleMaintenance_deleteStaleSessions() throws Exception { // Setup sessions final File sessionFile1 = mock(File.class); doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MILLIS + 1000) doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MS + 1000) .when(sessionFile1).lastModified(); final long sessionId1 = 342; final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest1".getBytes(), Loading @@ -256,7 +257,7 @@ public class BlobStoreManagerServiceTest { mUserSessions.append(sessionId2, session2); final File sessionFile3 = mock(File.class); doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MILLIS - 2000) doReturn(System.currentTimeMillis() - SESSION_EXPIRY_TIMEOUT_MS - 2000) .when(sessionFile3).lastModified(); final long sessionId3 = 9484; final BlobHandle blobHandle3 = BlobHandle.createWithSha256("digest3".getBytes(), Loading
tests/BlobStoreTestUtils/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ java_library { name: "BlobStoreTestUtils", srcs: ["src/**/*.java"], static_libs: ["truth-prebuilt"], static_libs: [ "truth-prebuilt", "androidx.test.uiautomator_uiautomator", ], sdk_version: "test_current", } No newline at end of file