diff options
| author | 2022-03-21 23:00:19 +0000 | |
|---|---|---|
| committer | 2022-03-21 23:00:19 +0000 | |
| commit | 67266c968206461b378e3f85bbf33ee43b76f5f4 (patch) | |
| tree | 7eebaba854ef89bd58ad72b69aa011efcd2a14d9 | |
| parent | 49fe62daac2785b5b4776a36d09ee00ee8bcc8fe (diff) | |
| parent | f548942f3feadba0d0a7f3b4dd50221dbc35c2d5 (diff) | |
[automerge] Ref count isolated uid use for long partial wakelocks 2p: f548942f3f
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17229945
Bug: 218298973
Change-Id: I1f7c23a58c725917cf27a85a4ec3b02e8a44af19
Merged-In: I86456137e6d6ad47f9974da281defc04d20fb32f
| -rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 25 | ||||
| -rw-r--r-- | core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java | 112 |
2 files changed, 129 insertions, 8 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index c9b652ca1142..ce212e28e884 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -4672,7 +4672,6 @@ public class BatteryStatsImpl extends BatteryStats { public void noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { - uid = mapUid(uid); noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); } @@ -4704,15 +4703,21 @@ public class BatteryStatsImpl extends BatteryStats { private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { + final int mappedUid = mapUid(uid); if (historyName == null) { historyName = name; } - if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, - 0)) { + if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, + mappedUid, 0)) { return; } addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, - historyName, uid); + historyName, mappedUid); + if (mappedUid != uid) { + // Prevent the isolated uid mapping from being removed while the wakelock is + // being held. + incrementIsolatedUidRefCount(uid); + } } public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { @@ -4722,7 +4727,6 @@ public class BatteryStatsImpl extends BatteryStats { public void noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { - uid = mapUid(uid); noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); } @@ -4754,15 +4758,20 @@ public class BatteryStatsImpl extends BatteryStats { private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { + final int mappedUid = mapUid(uid); if (historyName == null) { historyName = name; } - if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, - 0)) { + if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, + mappedUid, 0)) { return; } addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, - historyName, uid); + historyName, mappedUid); + if (mappedUid != uid) { + // Decrement the ref count for the isolated uid and delete the mapping if uneeded. + maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); + } } void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java index 3e2885a74287..a6bc456cbe6d 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -23,6 +23,8 @@ import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU; import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY; +import static com.google.common.truth.Truth.assertThat; + import android.app.ActivityManager; import android.os.BatteryStats; import android.os.BatteryStats.HistoryItem; @@ -206,6 +208,116 @@ public class BatteryStatsNoteTest extends TestCase { assertEquals(120_000, bgTime); } + /** + * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid. + */ + @SmallTest + public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception { + final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); + + + bi.setRecordAllHistoryLocked(true); + bi.forceRecordAllHistory(); + + int pid = 10; + String name = "name"; + String historyName = "historyName"; + + WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); + isolatedWorkChain.addNode(ISOLATED_UID, name); + + // Map ISOLATED_UID to UID. + bi.addIsolatedUidLocked(ISOLATED_UID, UID); + + bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); + bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID); + + clocks.realtime = clocks.uptime = 100; + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + + clocks.realtime = clocks.uptime = 220; + bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID); + + final BatteryStatsHistoryIterator iterator = + bi.createBatteryStatsHistoryIterator(); + + BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + } + + /** + * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid. + */ + @SmallTest + public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception { + final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); + + + bi.setRecordAllHistoryLocked(true); + bi.forceRecordAllHistory(); + + int pid = 10; + String name = "name"; + String historyName = "historyName"; + + WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); + isolatedWorkChain.addNode(ISOLATED_UID, name); + + // Map ISOLATED_UID to UID. + bi.addIsolatedUidLocked(ISOLATED_UID, UID); + + bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); + bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID); + + clocks.realtime = clocks.uptime = 100; + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + + clocks.realtime = clocks.uptime = 150; + bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime); + + clocks.realtime = clocks.uptime = 220; + bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID); + + final BatteryStatsHistoryIterator iterator = + bi.createBatteryStatsHistoryIterator(); + + BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + } /** * Test BatteryStatsImpl.noteUidProcessStateLocked. |