Add delayed writing for RoleUserState.
This change adds delayed writing for RoleUserState.
Bug: 110557011
Test: manual
Change-Id: If537e9523b96d9e4c6157e9b6e95b956e5d3c08f
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index 3e3e156..ce05974 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -60,6 +60,9 @@
private static final String ROLES_FILE_NAME = "roles.xml";
+ private static final long WRITE_DELAY_MILLIS = 200;
+ private static final long MAX_WRITE_DELAY_MILLIS = 2000;
+
private static final String TAG_ROLES = "roles";
private static final String TAG_ROLE = "role";
private static final String TAG_HOLDER = "holder";
@@ -85,6 +88,9 @@
private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>();
@GuardedBy("RoleManagerService.mLock")
+ private long mWritePendingSinceMillis;
+
+ @GuardedBy("RoleManagerService.mLock")
private boolean mDestroyed;
@NonNull
@@ -282,14 +288,31 @@
for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
String roleName = mRoles.keyAt(i);
ArraySet<String> roleHolders = mRoles.valueAt(i);
+
roleHolders = new ArraySet<>(roleHolders);
roles.put(roleName, roleHolders);
}
- mWriteHandler.removeCallbacksAndMessages(null);
- // TODO: Throttle writes.
- mWriteHandler.sendMessage(PooledLambda.obtainMessage(RoleUserState::writeSync, this,
- mVersion, mLastGrantPackagesHash, roles));
+ long currentTimeMillis = System.currentTimeMillis();
+ long writeDelayMillis;
+ if (!mWriteHandler.hasMessagesOrCallbacks()) {
+ mWritePendingSinceMillis = currentTimeMillis;
+ writeDelayMillis = WRITE_DELAY_MILLIS;
+ } else {
+ mWriteHandler.removeCallbacksAndMessages(null);
+ long writePendingDurationMillis = currentTimeMillis - mWritePendingSinceMillis;
+ if (writePendingDurationMillis >= MAX_WRITE_DELAY_MILLIS) {
+ writeDelayMillis = 0;
+ } else {
+ long maxWriteDelayMillis = Math.max(MAX_WRITE_DELAY_MILLIS
+ - writePendingDurationMillis, 0);
+ writeDelayMillis = Math.min(WRITE_DELAY_MILLIS, maxWriteDelayMillis);
+ }
+ }
+
+ mWriteHandler.sendMessageDelayed(PooledLambda.obtainMessage(RoleUserState::writeSync, this,
+ mVersion, mLastGrantPackagesHash, roles), writeDelayMillis);
+ Slog.i(LOG_TAG, "Scheduled writing roles.xml");
}
@WorkerThread
@@ -310,6 +333,7 @@
serializer.endDocument();
atomicFile.finishWrite(out);
+ Slog.i(LOG_TAG, "Wrote roles.xml successfully");
} catch (IllegalArgumentException | IllegalStateException | IOException e) {
Slog.wtf(LOG_TAG, "Failed to write roles.xml, restoring backup", e);
if (out != null) {
@@ -367,6 +391,7 @@
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
parseXmlLocked(parser);
+ Slog.i(LOG_TAG, "Read roles.xml successfully");
} catch (FileNotFoundException e) {
Slog.i(LOG_TAG, "roles.xml not found");
} catch (XmlPullParserException | IOException e) {