diff options
author | 2024-05-24 19:56:36 +0000 | |
---|---|---|
committer | 2024-05-24 19:56:36 +0000 | |
commit | d6004db98e21ed55f260369cb7d554c43033012f (patch) | |
tree | 79d5b528cfb57f7d378403b230c6bc1e223e2170 | |
parent | 27f27604b7348dcb2c7568313643aa3d052a36f7 (diff) | |
parent | 4b99fe8aec29fe67ccb753cad382218f95fe75f5 (diff) |
Merge "Handle failed AppStartInfo record write" into main
-rw-r--r-- | services/core/java/com/android/server/am/AppStartInfoTracker.java | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java index 79a85182ac09..a8227fa8e38b 100644 --- a/services/core/java/com/android/server/am/AppStartInfoTracker.java +++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java @@ -83,6 +83,7 @@ public final class AppStartInfoTracker { private static final int FOREACH_ACTION_NONE = 0; private static final int FOREACH_ACTION_REMOVE_ITEM = 1; private static final int FOREACH_ACTION_STOP_ITERATION = 2; + private static final int FOREACH_ACTION_REMOVE_AND_STOP_ITERATION = 3; private static final String MONITORING_MODE_EMPTY_TEXT = "No records"; @@ -659,8 +660,13 @@ public final class AppStartInfoTracker { } } + /** + * Run provided callback for each packake in start info dataset. + * + * @return whether the for each completed naturally, false if it was stopped manually. + */ @GuardedBy("mLock") - private void forEachPackageLocked( + private boolean forEachPackageLocked( BiFunction<String, SparseArray<AppStartInfoContainer>, Integer> callback) { if (callback != null) { ArrayMap<String, SparseArray<AppStartInfoContainer>> map = mData.getMap(); @@ -670,14 +676,17 @@ public final class AppStartInfoTracker { map.removeAt(i); break; case FOREACH_ACTION_STOP_ITERATION: - i = 0; - break; + return false; + case FOREACH_ACTION_REMOVE_AND_STOP_ITERATION: + map.removeAt(i); + return false; case FOREACH_ACTION_NONE: default: break; } } } + return true; } @GuardedBy("mLock") @@ -870,13 +879,14 @@ public final class AppStartInfoTracker { } AtomicFile af = new AtomicFile(mProcStartInfoFile); FileOutputStream out = null; + boolean succeeded; long now = System.currentTimeMillis(); try { out = af.startWrite(); ProtoOutputStream proto = new ProtoOutputStream(out); proto.write(AppsStartInfoProto.LAST_UPDATE_TIMESTAMP, now); synchronized (mLock) { - forEachPackageLocked( + succeeded = forEachPackageLocked( (packageName, records) -> { long token = proto.start(AppsStartInfoProto.PACKAGES); proto.write(AppsStartInfoProto.Package.PACKAGE_NAME, packageName); @@ -884,19 +894,30 @@ public final class AppStartInfoTracker { for (int j = 0; j < uidArraySize; j++) { try { records.valueAt(j) - .writeToProto(proto, AppsStartInfoProto.Package.USERS); + .writeToProto(proto, AppsStartInfoProto.Package.USERS); } catch (IOException e) { Slog.w(TAG, "Unable to write app start info into persistent" + "storage: " + e); + // There was likely an issue with this record that won't resolve + // next time we try to persist so remove it. Also stop iteration + // as we failed the write and need to start again from scratch. + return AppStartInfoTracker + .FOREACH_ACTION_REMOVE_AND_STOP_ITERATION; } } proto.end(token); return AppStartInfoTracker.FOREACH_ACTION_NONE; }); - mLastAppStartInfoPersistTimestamp = now; + if (succeeded) { + mLastAppStartInfoPersistTimestamp = now; + } + } + if (succeeded) { + proto.flush(); + af.finishWrite(out); + } else { + af.failWrite(out); } - proto.flush(); - af.finishWrite(out); } catch (IOException e) { Slog.w(TAG, "Unable to write historical app start info into persistent storage: " + e); af.failWrite(out); |