Loading core/java/android/app/ActivityManager.java +13 −7 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.WorkSource; import android.text.TextUtils; import android.util.ArrayMap; import android.util.DisplayMetrics; Loading Loading @@ -3911,10 +3912,10 @@ public class ActivityManager { /** * @hide */ public static void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, String tag) { public static void noteWakeupAlarm(PendingIntent ps, WorkSource workSource, int sourceUid, String sourcePkg, String tag) { try { getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null, getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null, workSource, sourceUid, sourcePkg, tag); } catch (RemoteException ex) { } Loading @@ -3923,19 +3924,24 @@ public class ActivityManager { /** * @hide */ public static void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) { public static void noteAlarmStart(PendingIntent ps, WorkSource workSource, int sourceUid, String tag) { try { getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag); getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, workSource, sourceUid, tag); } catch (RemoteException ex) { } } /** * @hide */ public static void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) { public static void noteAlarmFinish(PendingIntent ps, WorkSource workSource, int sourceUid, String tag) { try { getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag); getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, workSource, sourceUid, tag); } catch (RemoteException ex) { } } Loading core/java/android/app/ActivityManagerNative.java +3 −3 Original line number Diff line number Diff line Loading @@ -75,20 +75,20 @@ public abstract class ActivityManagerNative { */ static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, String tag) { ActivityManager.noteWakeupAlarm(ps, sourceUid, sourcePkg, tag); ActivityManager.noteWakeupAlarm(ps, null, sourceUid, sourcePkg, tag); } /** * @deprecated use ActivityManager.noteAlarmStart instead. */ static public void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) { ActivityManager.noteAlarmStart(ps, sourceUid, tag); ActivityManager.noteAlarmStart(ps, null, sourceUid, tag); } /** * @deprecated use ActivityManager.noteAlarmFinish instead. */ static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) { ActivityManager.noteAlarmFinish(ps, sourceUid, tag); ActivityManager.noteAlarmFinish(ps, null, sourceUid, tag); } } core/java/android/app/IActivityManager.aidl +4 −3 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import android.os.IProgressListener; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.StrictMode; import android.os.WorkSource; import android.service.voice.IVoiceInteractionSession; import com.android.internal.app.IVoiceInteractor; import com.android.internal.os.IResultReceiver; Loading Loading @@ -198,7 +199,7 @@ interface IActivityManager { void enterSafeMode(); boolean startNextMatchingActivity(in IBinder callingActivity, in Intent intent, in Bundle options); void noteWakeupAlarm(in IIntentSender sender, int sourceUid, void noteWakeupAlarm(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String sourcePkg, in String tag); void removeContentProvider(in IBinder connection, boolean stable); void setRequestedOrientation(in IBinder token, int requestedOrientation); Loading Loading @@ -468,8 +469,8 @@ interface IActivityManager { void dumpHeapFinished(in String path); void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake); void updateLockTaskPackages(int userId, in String[] packages); void noteAlarmStart(in IIntentSender sender, int sourceUid, in String tag); void noteAlarmFinish(in IIntentSender sender, int sourceUid, in String tag); void noteAlarmStart(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag); void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag); int getPackageProcessState(in String packageName, in String callingPackage); oneway void showLockTaskEscapeMessage(in IBinder token); void updateDeviceOwner(in String packageName); Loading core/java/com/android/internal/os/BatteryStatsImpl.java +70 −15 Original line number Diff line number Diff line Loading @@ -506,8 +506,8 @@ public class BatteryStatsImpl extends BatteryStats { final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); long mHistoryBaseTime; boolean mHaveBatteryLevel = false; boolean mRecordingHistory = false; protected boolean mHaveBatteryLevel = false; protected boolean mRecordingHistory = false; int mNumHistoryItems; final Parcel mHistoryBuffer = Parcel.obtain(); Loading Loading @@ -3975,30 +3975,85 @@ public class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); } public void noteAlarmStartLocked(String name, int uid) { public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); } public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); } private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid) { if (!mRecordAllHistory) { return; } uid = mapUid(uid); final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) { return; if (workSource != null) { for (int i = 0; i < workSource.size(); ++i) { uid = mapUid(workSource.get(i)); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); } addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid); } public void noteAlarmFinishLocked(String name, int uid) { if (!mRecordAllHistory) { return; List<WorkChain> workChains = workSource.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { uid = mapUid(workChains.get(i).getAttributionUid()); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); } } } } else { uid = mapUid(uid); final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) { if (mActiveEvents.updateState(historyItem, name, uid, 0)) { addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); } } } public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag) { if (!isOnBattery()) { return; } addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid); if (workSource != null) { for (int i = 0; i < workSource.size(); ++i) { uid = workSource.get(i); final String workSourceName = workSource.getName(i); BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, workSourceName != null ? workSourceName : packageName); pkg.noteWakeupAlarmLocked(tag); StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, uid, tag); } ArrayList<WorkChain> workChains = workSource.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { final WorkChain wc = workChains.get(i); uid = wc.getAttributionUid(); BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); pkg.noteWakeupAlarmLocked(tag); // TODO(statsd): Log the full attribution chain here once it's available StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, uid, tag); } } } else { BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); pkg.noteWakeupAlarmLocked(tag); StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, uid, tag); } } private void requestWakelockCpuUpdate() { Loading core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +186 −20 Original line number Diff line number Diff line Loading @@ -15,16 +15,19 @@ */ package com.android.internal.os; import static android.os.BatteryStats.STATS_CURRENT; import static android.os.BatteryStats.STATS_SINCE_CHARGED; import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; import android.app.ActivityManager; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.BatteryStats.HistoryItem; import android.os.WorkSource; import android.support.test.filters.SmallTest; import android.view.Display; import com.android.internal.os.BatteryStatsImpl.Uid; import junit.framework.TestCase; import java.util.ArrayList; Loading @@ -45,10 +48,13 @@ import java.util.Map; * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner */ public class BatteryStatsNoteTest extends TestCase { private static final int UID = 10500; private static final WorkSource WS = new WorkSource(UID); /** Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */ /** * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */ @SmallTest public void testNoteBluetoothScanResultLocked() throws Exception { MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks()); Loading @@ -75,7 +81,9 @@ public class BatteryStatsNoteTest extends TestCase{ .getCountLocked(STATS_SINCE_CHARGED)); } /** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */ /** * Test BatteryStatsImpl.Uid.noteStartWakeLocked. */ @SmallTest public void testNoteStartWakeLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms Loading @@ -86,7 +94,8 @@ public class BatteryStatsNoteTest extends TestCase{ bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); bi.getUidStatsLocked(UID).noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); bi.getUidStatsLocked(UID) .noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); clocks.realtime = clocks.uptime = 100; bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); Loading @@ -94,7 +103,8 @@ public class BatteryStatsNoteTest extends TestCase{ clocks.realtime = clocks.uptime = 220; bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID).getAggregatedPartialWakelockTimer(); BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) .getAggregatedPartialWakelockTimer(); long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); assertEquals(220_000, actualTime); Loading @@ -102,7 +112,9 @@ public class BatteryStatsNoteTest extends TestCase{ } /** Test BatteryStatsImpl.noteUidProcessStateLocked. */ /** * Test BatteryStatsImpl.noteUidProcessStateLocked. */ @SmallTest public void testNoteUidProcessStateLocked() throws Exception { final MockClocks clocks = new MockClocks(); Loading Loading @@ -145,7 +157,6 @@ public class BatteryStatsNoteTest extends TestCase{ expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get( Loading @@ -153,19 +164,16 @@ public class BatteryStatsNoteTest extends TestCase{ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP_SLEEPING); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) Loading @@ -174,7 +182,6 @@ public class BatteryStatsNoteTest extends TestCase{ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HOME) Loading @@ -191,7 +198,9 @@ public class BatteryStatsNoteTest extends TestCase{ assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); } /** Test BatteryStatsImpl.updateTimeBasesLocked. */ /** * Test BatteryStatsImpl.updateTimeBasesLocked. */ @SmallTest public void testUpdateTimeBasesLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms Loading @@ -213,7 +222,9 @@ public class BatteryStatsNoteTest extends TestCase{ assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); } /** Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. */ /** * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. */ @SmallTest public void testNoteScreenStateLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms Loading @@ -232,15 +243,13 @@ public class BatteryStatsNoteTest extends TestCase{ assertEquals(bi.getScreenState(), Display.STATE_OFF); } /** Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly. /** * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly. * * Unknown and doze should both be subset of off state * * Timeline 0----100----200----310----400------------1000 * Unknown ------- * On ------- * Off ------- ---------------------- * Doze ---------------- * Timeline 0----100----200----310----400------------1000 Unknown ------- On ------- Off * ------- ---------------------- Doze ---------------- */ @SmallTest public void testNoteScreenStateTimersLocked() throws Exception { Loading Loading @@ -280,4 +289,161 @@ public class BatteryStatsNoteTest extends TestCase{ assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED)); } @SmallTest public void testAlarmStartAndFinishLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); clocks.realtime = clocks.uptime = 100; bi.noteAlarmStartLocked("foo", null, UID); clocks.realtime = clocks.uptime = 5000; bi.noteAlarmFinishLocked("foo", null, UID); HistoryItem item = new HistoryItem(); assertTrue(bi.startIteratingHistoryLocked()); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(UID, item.eventTag.uid); // TODO(narayan): Figure out why this event is written to the history buffer. See // test below where it is being interspersed between multiple START events too. assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_NONE, item.eventCode); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); assertTrue(item.isDeltaData()); assertEquals("foo", item.eventTag.string); assertEquals(UID, item.eventTag.uid); assertFalse(bi.getNextHistoryLocked(item)); } @SmallTest public void testAlarmStartAndFinishLocked_workSource() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); WorkSource ws = new WorkSource(); ws.add(100); ws.createWorkChain().addNode(500, "tag"); bi.noteAlarmStartLocked("foo", ws, UID); clocks.realtime = clocks.uptime = 5000; bi.noteAlarmFinishLocked("foo", ws, UID); HistoryItem item = new HistoryItem(); assertTrue(bi.startIteratingHistoryLocked()); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(100, item.eventTag.uid); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_NONE, item.eventCode); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(500, item.eventTag.uid); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(100, item.eventTag.uid); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(500, item.eventTag.uid); } @SmallTest public void testNoteWakupAlarmLocked() { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.mForceOnBattery = true; bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); bi.noteWakupAlarmLocked("com.foo.bar", UID, null, "tag"); Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_CURRENT)); assertEquals(1, pkg.getWakeupAlarmStats().size()); } @SmallTest public void testNoteWakupAlarmLocked_workSource_uid() { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.mForceOnBattery = true; bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); WorkSource ws = new WorkSource(); ws.add(100); // When a WorkSource is present, "UID" should not be used - only the uids present in the // WorkSource should be reported. bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); assertEquals(0, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); assertEquals(1, pkg.getWakeupAlarmStats().size()); // If the WorkSource contains a "name", it should be interpreted as a package name and // the packageName supplied as an argument must be ignored. ws = new WorkSource(); ws.add(100, "com.foo.baz_alternate"); bi.noteWakupAlarmLocked("com.foo.baz", UID, ws, "tag"); pkg = bi.getPackageStatsLocked(100, "com.foo.baz"); assertEquals(0, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); assertEquals(1, pkg.getWakeupAlarmStats().size()); } @SmallTest public void testNoteWakupAlarmLocked_workSource_workChain() { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.mForceOnBattery = true; bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); WorkSource ws = new WorkSource(); ws.createWorkChain().addNode(100, "com.foo.baz_alternate"); bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); // For WorkChains, again we must only attribute to the uids present in the WorkSource // (and not to "UID"). However, unlike the older "tags" we do not change the packagename // supplied as an argument, given that we're logging the entire attribution chain. Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); assertEquals(0, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); assertEquals(1, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); assertEquals(0, pkg.getWakeupAlarmStats().size()); } } Loading
core/java/android/app/ActivityManager.java +13 −7 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.WorkSource; import android.text.TextUtils; import android.util.ArrayMap; import android.util.DisplayMetrics; Loading Loading @@ -3911,10 +3912,10 @@ public class ActivityManager { /** * @hide */ public static void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, String tag) { public static void noteWakeupAlarm(PendingIntent ps, WorkSource workSource, int sourceUid, String sourcePkg, String tag) { try { getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null, getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null, workSource, sourceUid, sourcePkg, tag); } catch (RemoteException ex) { } Loading @@ -3923,19 +3924,24 @@ public class ActivityManager { /** * @hide */ public static void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) { public static void noteAlarmStart(PendingIntent ps, WorkSource workSource, int sourceUid, String tag) { try { getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag); getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, workSource, sourceUid, tag); } catch (RemoteException ex) { } } /** * @hide */ public static void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) { public static void noteAlarmFinish(PendingIntent ps, WorkSource workSource, int sourceUid, String tag) { try { getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag); getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, workSource, sourceUid, tag); } catch (RemoteException ex) { } } Loading
core/java/android/app/ActivityManagerNative.java +3 −3 Original line number Diff line number Diff line Loading @@ -75,20 +75,20 @@ public abstract class ActivityManagerNative { */ static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, String tag) { ActivityManager.noteWakeupAlarm(ps, sourceUid, sourcePkg, tag); ActivityManager.noteWakeupAlarm(ps, null, sourceUid, sourcePkg, tag); } /** * @deprecated use ActivityManager.noteAlarmStart instead. */ static public void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) { ActivityManager.noteAlarmStart(ps, sourceUid, tag); ActivityManager.noteAlarmStart(ps, null, sourceUid, tag); } /** * @deprecated use ActivityManager.noteAlarmFinish instead. */ static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) { ActivityManager.noteAlarmFinish(ps, sourceUid, tag); ActivityManager.noteAlarmFinish(ps, null, sourceUid, tag); } }
core/java/android/app/IActivityManager.aidl +4 −3 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import android.os.IProgressListener; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.StrictMode; import android.os.WorkSource; import android.service.voice.IVoiceInteractionSession; import com.android.internal.app.IVoiceInteractor; import com.android.internal.os.IResultReceiver; Loading Loading @@ -198,7 +199,7 @@ interface IActivityManager { void enterSafeMode(); boolean startNextMatchingActivity(in IBinder callingActivity, in Intent intent, in Bundle options); void noteWakeupAlarm(in IIntentSender sender, int sourceUid, void noteWakeupAlarm(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String sourcePkg, in String tag); void removeContentProvider(in IBinder connection, boolean stable); void setRequestedOrientation(in IBinder token, int requestedOrientation); Loading Loading @@ -468,8 +469,8 @@ interface IActivityManager { void dumpHeapFinished(in String path); void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake); void updateLockTaskPackages(int userId, in String[] packages); void noteAlarmStart(in IIntentSender sender, int sourceUid, in String tag); void noteAlarmFinish(in IIntentSender sender, int sourceUid, in String tag); void noteAlarmStart(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag); void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag); int getPackageProcessState(in String packageName, in String callingPackage); oneway void showLockTaskEscapeMessage(in IBinder token); void updateDeviceOwner(in String packageName); Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +70 −15 Original line number Diff line number Diff line Loading @@ -506,8 +506,8 @@ public class BatteryStatsImpl extends BatteryStats { final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); long mHistoryBaseTime; boolean mHaveBatteryLevel = false; boolean mRecordingHistory = false; protected boolean mHaveBatteryLevel = false; protected boolean mRecordingHistory = false; int mNumHistoryItems; final Parcel mHistoryBuffer = Parcel.obtain(); Loading Loading @@ -3975,30 +3975,85 @@ public class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); } public void noteAlarmStartLocked(String name, int uid) { public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); } public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); } private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid) { if (!mRecordAllHistory) { return; } uid = mapUid(uid); final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) { return; if (workSource != null) { for (int i = 0; i < workSource.size(); ++i) { uid = mapUid(workSource.get(i)); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); } addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid); } public void noteAlarmFinishLocked(String name, int uid) { if (!mRecordAllHistory) { return; List<WorkChain> workChains = workSource.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { uid = mapUid(workChains.get(i).getAttributionUid()); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); } } } } else { uid = mapUid(uid); final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) { if (mActiveEvents.updateState(historyItem, name, uid, 0)) { addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); } } } public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag) { if (!isOnBattery()) { return; } addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid); if (workSource != null) { for (int i = 0; i < workSource.size(); ++i) { uid = workSource.get(i); final String workSourceName = workSource.getName(i); BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, workSourceName != null ? workSourceName : packageName); pkg.noteWakeupAlarmLocked(tag); StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, uid, tag); } ArrayList<WorkChain> workChains = workSource.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { final WorkChain wc = workChains.get(i); uid = wc.getAttributionUid(); BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); pkg.noteWakeupAlarmLocked(tag); // TODO(statsd): Log the full attribution chain here once it's available StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, uid, tag); } } } else { BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); pkg.noteWakeupAlarmLocked(tag); StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, uid, tag); } } private void requestWakelockCpuUpdate() { Loading
core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +186 −20 Original line number Diff line number Diff line Loading @@ -15,16 +15,19 @@ */ package com.android.internal.os; import static android.os.BatteryStats.STATS_CURRENT; import static android.os.BatteryStats.STATS_SINCE_CHARGED; import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; import android.app.ActivityManager; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.BatteryStats.HistoryItem; import android.os.WorkSource; import android.support.test.filters.SmallTest; import android.view.Display; import com.android.internal.os.BatteryStatsImpl.Uid; import junit.framework.TestCase; import java.util.ArrayList; Loading @@ -45,10 +48,13 @@ import java.util.Map; * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner */ public class BatteryStatsNoteTest extends TestCase { private static final int UID = 10500; private static final WorkSource WS = new WorkSource(UID); /** Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */ /** * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */ @SmallTest public void testNoteBluetoothScanResultLocked() throws Exception { MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks()); Loading @@ -75,7 +81,9 @@ public class BatteryStatsNoteTest extends TestCase{ .getCountLocked(STATS_SINCE_CHARGED)); } /** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */ /** * Test BatteryStatsImpl.Uid.noteStartWakeLocked. */ @SmallTest public void testNoteStartWakeLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms Loading @@ -86,7 +94,8 @@ public class BatteryStatsNoteTest extends TestCase{ bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); bi.getUidStatsLocked(UID).noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); bi.getUidStatsLocked(UID) .noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); clocks.realtime = clocks.uptime = 100; bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); Loading @@ -94,7 +103,8 @@ public class BatteryStatsNoteTest extends TestCase{ clocks.realtime = clocks.uptime = 220; bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID).getAggregatedPartialWakelockTimer(); BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) .getAggregatedPartialWakelockTimer(); long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); assertEquals(220_000, actualTime); Loading @@ -102,7 +112,9 @@ public class BatteryStatsNoteTest extends TestCase{ } /** Test BatteryStatsImpl.noteUidProcessStateLocked. */ /** * Test BatteryStatsImpl.noteUidProcessStateLocked. */ @SmallTest public void testNoteUidProcessStateLocked() throws Exception { final MockClocks clocks = new MockClocks(); Loading Loading @@ -145,7 +157,6 @@ public class BatteryStatsNoteTest extends TestCase{ expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get( Loading @@ -153,19 +164,16 @@ public class BatteryStatsNoteTest extends TestCase{ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP_SLEEPING); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) Loading @@ -174,7 +182,6 @@ public class BatteryStatsNoteTest extends TestCase{ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED, elapsedTimeUs, STATS_SINCE_CHARGED); expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HOME) Loading @@ -191,7 +198,9 @@ public class BatteryStatsNoteTest extends TestCase{ assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); } /** Test BatteryStatsImpl.updateTimeBasesLocked. */ /** * Test BatteryStatsImpl.updateTimeBasesLocked. */ @SmallTest public void testUpdateTimeBasesLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms Loading @@ -213,7 +222,9 @@ public class BatteryStatsNoteTest extends TestCase{ assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); } /** Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. */ /** * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. */ @SmallTest public void testNoteScreenStateLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms Loading @@ -232,15 +243,13 @@ public class BatteryStatsNoteTest extends TestCase{ assertEquals(bi.getScreenState(), Display.STATE_OFF); } /** Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly. /** * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly. * * Unknown and doze should both be subset of off state * * Timeline 0----100----200----310----400------------1000 * Unknown ------- * On ------- * Off ------- ---------------------- * Doze ---------------- * Timeline 0----100----200----310----400------------1000 Unknown ------- On ------- Off * ------- ---------------------- Doze ---------------- */ @SmallTest public void testNoteScreenStateTimersLocked() throws Exception { Loading Loading @@ -280,4 +289,161 @@ public class BatteryStatsNoteTest extends TestCase{ assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED)); } @SmallTest public void testAlarmStartAndFinishLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); clocks.realtime = clocks.uptime = 100; bi.noteAlarmStartLocked("foo", null, UID); clocks.realtime = clocks.uptime = 5000; bi.noteAlarmFinishLocked("foo", null, UID); HistoryItem item = new HistoryItem(); assertTrue(bi.startIteratingHistoryLocked()); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(UID, item.eventTag.uid); // TODO(narayan): Figure out why this event is written to the history buffer. See // test below where it is being interspersed between multiple START events too. assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_NONE, item.eventCode); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); assertTrue(item.isDeltaData()); assertEquals("foo", item.eventTag.string); assertEquals(UID, item.eventTag.uid); assertFalse(bi.getNextHistoryLocked(item)); } @SmallTest public void testAlarmStartAndFinishLocked_workSource() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); WorkSource ws = new WorkSource(); ws.add(100); ws.createWorkChain().addNode(500, "tag"); bi.noteAlarmStartLocked("foo", ws, UID); clocks.realtime = clocks.uptime = 5000; bi.noteAlarmFinishLocked("foo", ws, UID); HistoryItem item = new HistoryItem(); assertTrue(bi.startIteratingHistoryLocked()); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(100, item.eventTag.uid); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_NONE, item.eventCode); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(500, item.eventTag.uid); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(100, item.eventTag.uid); assertTrue(bi.getNextHistoryLocked(item)); assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); assertEquals("foo", item.eventTag.string); assertEquals(500, item.eventTag.uid); } @SmallTest public void testNoteWakupAlarmLocked() { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.mForceOnBattery = true; bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); bi.noteWakupAlarmLocked("com.foo.bar", UID, null, "tag"); Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_CURRENT)); assertEquals(1, pkg.getWakeupAlarmStats().size()); } @SmallTest public void testNoteWakupAlarmLocked_workSource_uid() { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.mForceOnBattery = true; bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); WorkSource ws = new WorkSource(); ws.add(100); // When a WorkSource is present, "UID" should not be used - only the uids present in the // WorkSource should be reported. bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); assertEquals(0, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); assertEquals(1, pkg.getWakeupAlarmStats().size()); // If the WorkSource contains a "name", it should be interpreted as a package name and // the packageName supplied as an argument must be ignored. ws = new WorkSource(); ws.add(100, "com.foo.baz_alternate"); bi.noteWakupAlarmLocked("com.foo.baz", UID, ws, "tag"); pkg = bi.getPackageStatsLocked(100, "com.foo.baz"); assertEquals(0, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); assertEquals(1, pkg.getWakeupAlarmStats().size()); } @SmallTest public void testNoteWakupAlarmLocked_workSource_workChain() { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); bi.setRecordAllHistoryLocked(true); bi.forceRecordAllHistory(); bi.mForceOnBattery = true; bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); WorkSource ws = new WorkSource(); ws.createWorkChain().addNode(100, "com.foo.baz_alternate"); bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); // For WorkChains, again we must only attribute to the uids present in the WorkSource // (and not to "UID"). However, unlike the older "tags" we do not change the packagename // supplied as an argument, given that we're logging the entire attribution chain. Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); assertEquals(0, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); assertEquals(1, pkg.getWakeupAlarmStats().size()); pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); assertEquals(0, pkg.getWakeupAlarmStats().size()); } }