diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 8b4b99422a4d4..f4211895031b1 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -183,6 +183,7 @@ public final class BatteryStatsImpl extends BatteryStats { public interface ExternalStatsSync { void scheduleSync(String reason); void scheduleWifiSync(String reason); + void scheduleCpuSyncDueToRemovedUid(int uid); } public final MyHandler mHandler; @@ -2522,13 +2523,28 @@ public final class BatteryStatsImpl extends BatteryStats { mIsolatedUids.put(isolatedUid, appUid); } - public void removeIsolatedUidLocked(int isolatedUid, int appUid) { + /** + * Schedules a read of the latest cpu times before removing the isolated UID. + * @see #removeIsolatedUidLocked(int) + */ + public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { int curUid = mIsolatedUids.get(isolatedUid, -1); if (curUid == appUid) { - mIsolatedUids.delete(isolatedUid); + if (mExternalSync != null) { + mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); + } } } + /** + * This should only be called after the cpu times have been read. + * @see #scheduleRemoveIsolatedUidLocked(int, int) + */ + public void removeIsolatedUidLocked(int isolatedUid) { + mIsolatedUids.delete(isolatedUid); + mKernelUidCpuTimeReader.removeUid(isolatedUid); + } + public int mapUid(int uid) { int isolated = mIsolatedUids.get(uid, -1); return isolated > 0 ? isolated : uid; diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 6cc1b115572bf..ab47f763d7f3b 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -41,6 +41,7 @@ import android.os.WorkSource; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; +import android.util.IntArray; import android.util.Slog; import android.util.TimeUtils; @@ -82,6 +83,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub public static final int MSG_SYNC_EXTERNAL_STATS = 1; public static final int MSG_WRITE_TO_DISK = 2; private int mUpdateFlags = 0; + private IntArray mUidsToRemove = new IntArray(); public BatteryStatsHandler(Looper looper) { super(looper); @@ -98,6 +100,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub mUpdateFlags = 0; } updateExternalStats((String)msg.obj, updateFlags); + synchronized (this) { + synchronized (mStats) { + final int numUidsToRemove = mUidsToRemove.size(); + for (int i = 0; i < numUidsToRemove; i++) { + mStats.removeIsolatedUidLocked(mUidsToRemove.get(i)); + } + } + mUidsToRemove.clear(); + } break; case MSG_WRITE_TO_DISK: @@ -111,22 +122,32 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override public void scheduleSync(String reason) { - scheduleSyncImpl(reason, UPDATE_ALL); + synchronized (this) { + scheduleSyncLocked(reason, UPDATE_ALL); + } } @Override public void scheduleWifiSync(String reason) { - scheduleSyncImpl(reason, UPDATE_WIFI); + synchronized (this) { + scheduleSyncLocked(reason, UPDATE_WIFI); + } } - private void scheduleSyncImpl(String reason, int updateFlags) { + @Override + public void scheduleCpuSyncDueToRemovedUid(int uid) { synchronized (this) { - if (mUpdateFlags == 0) { - sendMessage(Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason)); - } - mUpdateFlags |= updateFlags; + scheduleSyncLocked("remove-uid", UPDATE_CPU); + mUidsToRemove.add(uid); } } + + private void scheduleSyncLocked(String reason, int updateFlags) { + if (mUpdateFlags == 0) { + sendMessage(Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason)); + } + mUpdateFlags |= updateFlags; + } } BatteryStatsService(File systemDir, Handler handler) { @@ -220,7 +241,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub void removeIsolatedUid(int isolatedUid, int appUid) { synchronized (mStats) { - mStats.removeIsolatedUidLocked(isolatedUid, appUid); + mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid); } }