diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index baaa55d348418..d1f514327731f 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -377,6 +377,12 @@ public class ActivityManager { /** @hide Process is being cached for later use and is empty. */ public static final int PROCESS_STATE_CACHED_EMPTY = 16; + /** @hide The lowest process state number */ + public static final int MIN_PROCESS_STATE = PROCESS_STATE_NONEXISTENT; + + /** @hide The highest process state number */ + public static final int MAX_PROCESS_STATE = PROCESS_STATE_CACHED_EMPTY; + /** @hide Should this process state be considered a background state? */ public static final boolean isProcStateBackground(int procState) { return procState >= PROCESS_STATE_BACKUP; diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index f99caba59b403..d741c49482806 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -940,7 +940,7 @@ public final class ActiveServices { } } - mAm.startAssociationLocked(callerApp.uid, callerApp.processName, + mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState, s.appInfo.uid, s.name, s.processName); AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4bb3a541a23fe..261e14fc6c37b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -892,6 +892,12 @@ public final class ActivityManagerService extends ActivityManagerNative int mNesting; long mStartTime; + // states of the source process when the bind occurred. + int mLastState = ActivityManager.MAX_PROCESS_STATE + 1; + long mLastStateUptime; + long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE + - ActivityManager.MIN_PROCESS_STATE+1]; + Association(int sourceUid, String sourceProcess, int targetUid, ComponentName targetComponent, String targetProcess) { mSourceUid = sourceUid; @@ -6057,8 +6063,7 @@ public final class ActivityManagerService extends ActivityManagerNative "No more processes in " + old.uidRecord); enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); mActiveUids.remove(uid); - mBatteryStatsService.noteUidProcessState(uid, - ActivityManager.PROCESS_STATE_NONEXISTENT); + noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT); } old.uidRecord = null; } @@ -6083,7 +6088,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "Creating new process uid: " + uidRec); mActiveUids.put(proc.uid, uidRec); - mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState); + noteUidProcessState(uidRec.uid, uidRec.curProcState); enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE); } proc.uidRecord = uidRec; @@ -10191,7 +10196,8 @@ public final class ActivityManagerService extends ActivityManagerNative } cpr.connections.add(conn); r.conProviders.add(conn); - startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); + startAssociationLocked(r.uid, r.processName, r.curProcState, + cpr.uid, cpr.name, cpr.info.processName); return conn; } cpr.addExternalProcessHandleLocked(externalProcessToken); @@ -13798,10 +13804,27 @@ public final class ActivityManagerService extends ActivityManagerNative TimeUtils.formatDuration(dur, pw); pw.print(" ("); pw.print(ass.mCount); - pw.println(" times)"); + pw.print(" times)"); + pw.print(" "); + for (int i=0; i 0) { - pw.print(" "); - pw.print(" Currently active: "); + pw.print(" Currently active: "); TimeUtils.formatDuration(now - ass.mStartTime, pw); pw.println(); } @@ -18239,8 +18262,8 @@ public final class ActivityManagerService extends ActivityManagerNative return null; } - Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, - ComponentName targetComponent, String targetProcess) { + Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, + int targetUid, ComponentName targetComponent, String targetProcess) { if (!mTrackingAssociations) { return null; } @@ -18269,7 +18292,8 @@ public final class ActivityManagerService extends ActivityManagerNative ass.mCount++; ass.mNesting++; if (ass.mNesting == 1) { - ass.mStartTime = SystemClock.uptimeMillis(); + ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis(); + ass.mLastState = sourceState; } return ass; } @@ -18298,7 +18322,39 @@ public final class ActivityManagerService extends ActivityManagerNative } ass.mNesting--; if (ass.mNesting == 0) { - ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; + long uptime = SystemClock.uptimeMillis(); + ass.mTime += uptime - ass.mStartTime; + ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] + += uptime - ass.mLastStateUptime; + ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2; + } + } + + private void noteUidProcessState(final int uid, final int state) { + mBatteryStatsService.noteUidProcessState(uid, state); + if (mTrackingAssociations) { + for (int i1=0, N1=mAssociations.size(); i1>> targetComponents + = mAssociations.valueAt(i1); + for (int i2=0, N2=targetComponents.size(); i2> sourceUids + = targetComponents.valueAt(i2); + ArrayMap sourceProcesses = sourceUids.get(uid); + if (sourceProcesses != null) { + for (int i4=0, N4=sourceProcesses.size(); i4= 1) { + // currently associated + long uptime = SystemClock.uptimeMillis(); + ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] + += uptime - ass.mLastStateUptime; + ass.mLastState = state; + ass.mLastStateUptime = uptime; + } + } + } + } + } } } @@ -20177,7 +20233,7 @@ public final class ActivityManagerService extends ActivityManagerNative } uidRec.setProcState = uidRec.curProcState; enqueueUidChangeLocked(uidRec, -1, uidChange); - mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState); + noteUidProcessState(uidRec.uid, uidRec.curProcState); } }