Loading core/java/com/android/internal/app/procstats/AssociationState.java +332 −159 File changed.Preview size limit exceeded, changes collapsed. Show changes core/java/com/android/internal/app/procstats/ProcessState.java +84 −3 Original line number Original line Diff line number Diff line Loading @@ -63,6 +63,8 @@ import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import android.util.proto.ProtoUtils; import com.android.internal.app.ProcessMap; import com.android.internal.app.ProcessMap; import com.android.internal.app.procstats.AssociationState.SourceKey; import com.android.internal.app.procstats.AssociationState.SourceState; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; Loading Loading @@ -162,6 +164,11 @@ public final class ProcessState { // Set in computeProcessTimeLocked and used by COMPARATOR to sort. Be careful. // Set in computeProcessTimeLocked and used by COMPARATOR to sort. Be careful. private long mTmpTotalTime; private long mTmpTotalTime; /** * The combined source states which has or had an association with this process. */ ArrayMap<SourceKey, SourceState> mCommonSources; /** /** * Create a new top-level process state, for the initial case where there is only * Create a new top-level process state, for the initial case where there is only * a single package running in a process. The initial state is not running. * a single package running in a process. The initial state is not running. Loading Loading @@ -267,6 +274,21 @@ public final class ProcessState { addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss, addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss, other.mAvgCachedKillPss, other.mMaxCachedKillPss); other.mAvgCachedKillPss, other.mMaxCachedKillPss); } } if (other.mCommonSources != null) { if (mCommonSources == null) { mCommonSources = new ArrayMap<>(); } int size = other.mCommonSources.size(); for (int i = 0; i < size; i++) { final SourceKey key = other.mCommonSources.keyAt(i); SourceState state = mCommonSources.get(key); if (state == null) { state = new SourceState(mStats, null, this, key); mCommonSources.put(key, state); } state.add(other.mCommonSources.valueAt(i)); } } } } public void resetSafely(long now) { public void resetSafely(long now) { Loading @@ -278,6 +300,17 @@ public final class ProcessState { mNumExcessiveCpu = 0; mNumExcessiveCpu = 0; mNumCachedKill = 0; mNumCachedKill = 0; mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; // Reset the combine source state. if (mCommonSources != null) { for (int ip = mCommonSources.size() - 1; ip >= 0; ip--) { final SourceState state = mCommonSources.valueAt(ip); if (state.isInUse()) { state.resetSafely(now); } else { mCommonSources.removeAt(ip); } } } } } public void makeDead() { public void makeDead() { Loading Loading @@ -308,9 +341,18 @@ public final class ProcessState { out.writeLong(mAvgCachedKillPss); out.writeLong(mAvgCachedKillPss); out.writeLong(mMaxCachedKillPss); out.writeLong(mMaxCachedKillPss); } } // The combined source state of all associations. final int numOfSources = mCommonSources != null ? mCommonSources.size() : 0; out.writeInt(numOfSources); for (int i = 0; i < numOfSources; i++) { final SourceKey key = mCommonSources.keyAt(i); final SourceState src = mCommonSources.valueAt(i); key.writeToParcel(mStats, out); src.writeToParcel(out, 0); } } } public boolean readFromParcel(Parcel in, boolean fully) { boolean readFromParcel(Parcel in, int version, boolean fully) { boolean multiPackage = in.readInt() != 0; boolean multiPackage = in.readInt() != 0; if (fully) { if (fully) { mMultiPackage = multiPackage; mMultiPackage = multiPackage; Loading @@ -337,6 +379,19 @@ public final class ProcessState { } else { } else { mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; } } // The combined source state of all associations. final int numOfSources = in.readInt(); if (numOfSources > 0) { mCommonSources = new ArrayMap<>(numOfSources); for (int i = 0; i < numOfSources; i++) { final SourceKey key = new SourceKey(mStats, in, version); final SourceState src = new SourceState(mStats, null, this, key); src.readFromParcel(in); mCommonSources.put(key, src); } } return true; return true; } } Loading Loading @@ -433,6 +488,12 @@ public final class ProcessState { mTotalRunningStartTime = now; mTotalRunningStartTime = now; } } mStartTime = now; mStartTime = now; if (mCommonSources != null) { for (int ip = mCommonSources.size() - 1; ip >= 0; ip--) { final SourceState src = mCommonSources.valueAt(ip); src.commitStateTime(now); } } } } public void incActiveServices(String serviceName) { public void incActiveServices(String serviceName) { Loading Loading @@ -722,6 +783,18 @@ public final class ProcessState { return mPssTable.getValueForId((byte)state, PSS_RSS_MAXIMUM); return mPssTable.getValueForId((byte)state, PSS_RSS_MAXIMUM); } } SourceState getOrCreateSourceState(SourceKey key) { if (mCommonSources == null) { mCommonSources = new ArrayMap<>(); } SourceState state = mCommonSources.get(key); if (state == null) { state = new SourceState(mStats, null, this, key); mCommonSources.put(key, state); } return state; } /** /** * Sums up the PSS data and adds it to 'data'. * Sums up the PSS data and adds it to 'data'. * * Loading Loading @@ -1038,7 +1111,8 @@ public final class ProcessState { } } } } public void dumpInternalLocked(PrintWriter pw, String prefix, boolean dumpAll) { void dumpInternalLocked(PrintWriter pw, String prefix, String reqPackage, long totalTime, long now, boolean dumpAll) { if (dumpAll) { if (dumpAll) { pw.print(prefix); pw.print("myID="); pw.print(prefix); pw.print("myID="); pw.print(Integer.toHexString(System.identityHashCode(this))); pw.print(Integer.toHexString(System.identityHashCode(this))); Loading @@ -1053,6 +1127,13 @@ public final class ProcessState { pw.print("/"); pw.print(mCommonProcess.mUid); pw.print("/"); pw.print(mCommonProcess.mUid); pw.print(" pkg="); pw.println(mCommonProcess.mPackage); pw.print(" pkg="); pw.println(mCommonProcess.mPackage); } } if (mCommonSources != null) { pw.print(prefix); pw.println("Aggregated Association Sources:"); AssociationState.dumpSources( pw, prefix + " ", prefix + " ", prefix + " ", AssociationState.createSortedAssociations(now, totalTime, mCommonSources), now, totalTime, reqPackage, true, dumpAll); } } } if (mActive) { if (mActive) { pw.print(prefix); pw.print("mActive="); pw.println(mActive); pw.print(prefix); pw.print("mActive="); pw.println(mActive); Loading Loading @@ -1559,7 +1640,7 @@ public final class ProcessState { } } mStats.dumpFilteredAssociationStatesProtoForProc(proto, ProcessStatsProto.ASSOCS, mStats.dumpFilteredAssociationStatesProtoForProc(proto, ProcessStatsProto.ASSOCS, now, this, procToPkgMap, uidToPkgMap); now, this, uidToPkgMap); proto.end(token); proto.end(token); } } } } core/java/com/android/internal/app/procstats/ProcessStats.java +51 −85 Original line number Original line Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.service.procstats.ProcessStatsAssociationProto; import android.service.procstats.ProcessStatsAvailablePagesProto; import android.service.procstats.ProcessStatsAvailablePagesProto; import android.service.procstats.ProcessStatsPackageProto; import android.service.procstats.ProcessStatsPackageProto; import android.service.procstats.ProcessStatsSectionProto; import android.service.procstats.ProcessStatsSectionProto; import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateFormat; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.ArraySet; import android.util.ArraySet; Loading Loading @@ -187,7 +186,7 @@ public final class ProcessStats implements Parcelable { {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"}; {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"}; // Current version of the parcel format. // Current version of the parcel format. private static final int PARCEL_VERSION = 38; private static final int PARCEL_VERSION = 39; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; private static final int MAGIC = 0x50535454; Loading Loading @@ -1113,12 +1112,12 @@ public final class ProcessStats implements Parcelable { final long vers = in.readLong(); final long vers = in.readLong(); ProcessState proc = hadData ? mProcesses.get(procName, uid) : null; ProcessState proc = hadData ? mProcesses.get(procName, uid) : null; if (proc != null) { if (proc != null) { if (!proc.readFromParcel(in, false)) { if (!proc.readFromParcel(in, version, false)) { return; return; } } } else { } else { proc = new ProcessState(this, pkgName, uid, vers, procName); proc = new ProcessState(this, pkgName, uid, vers, procName); if (!proc.readFromParcel(in, true)) { if (!proc.readFromParcel(in, version, true)) { return; return; } } } } Loading Loading @@ -1198,13 +1197,13 @@ public final class ProcessStats implements Parcelable { // they will find and use it from the global procs. // they will find and use it from the global procs. ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null; ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null; if (proc != null) { if (proc != null) { if (!proc.readFromParcel(in, false)) { if (!proc.readFromParcel(in, version, false)) { return; return; } } } else { } else { proc = new ProcessState(commonProc, pkgName, uid, vers, procName, proc = new ProcessState(commonProc, pkgName, uid, vers, procName, 0); 0); if (!proc.readFromParcel(in, true)) { if (!proc.readFromParcel(in, version, true)) { return; return; } } } } Loading Loading @@ -1439,16 +1438,15 @@ public final class ProcessStats implements Parcelable { final int NUM = mTrackingAssociations.size(); final int NUM = mTrackingAssociations.size(); for (int i = NUM - 1; i >= 0; i--) { for (int i = NUM - 1; i >= 0; i--) { final AssociationState.SourceState act = mTrackingAssociations.get(i); final AssociationState.SourceState act = mTrackingAssociations.get(i); if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) { if (act.stopActiveIfNecessary(curSeq, now)) { // If this association did not get touched the last time we computed // process states, or its state ended up down in cached, then we no // longer have a reason to track it at all. act.stopActive(now); act.mInTrackingList = false; act.mProcState = ProcessStats.STATE_NOTHING; mTrackingAssociations.remove(i); mTrackingAssociations.remove(i); } else { } else { final ProcessState proc = act.getAssociationState().getProcess(); final AssociationState asc = act.getAssociationState(); if (asc == null) { Slog.wtf(TAG, act.toString() + " shouldn't be in the tracking list."); continue; } final ProcessState proc = asc.getProcess(); if (proc != null) { if (proc != null) { final int procState = proc.getCombinedState() % STATE_COUNT; final int procState = proc.getCombinedState() % STATE_COUNT; if (act.mProcState == procState) { if (act.mProcState == procState) { Loading Loading @@ -1476,7 +1474,7 @@ public final class ProcessStats implements Parcelable { } else { } else { // Don't need rate limiting on it. // Don't need rate limiting on it. Slog.wtf(TAG, "Tracking association without process: " + act Slog.wtf(TAG, "Tracking association without process: " + act + " in " + act.getAssociationState()); + " in " + asc); } } } } } } Loading Loading @@ -1640,7 +1638,8 @@ public final class ProcessStats implements Parcelable { ALL_PROC_STATES, now); ALL_PROC_STATES, now); proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); ALL_PROC_STATES, now); proc.dumpInternalLocked(pw, " ", dumpAll); proc.dumpInternalLocked(pw, " ", reqPackage, totalTime, now, dumpAll); } } } else { } else { ArrayList<ProcessState> procs = new ArrayList<ProcessState>(); ArrayList<ProcessState> procs = new ArrayList<ProcessState>(); Loading Loading @@ -1696,7 +1695,8 @@ public final class ProcessStats implements Parcelable { } } final AssociationDumpContainer cont = final AssociationDumpContainer cont = new AssociationDumpContainer(asc); new AssociationDumpContainer(asc); cont.mSources = asc.createSortedAssociations(now, totalTime); cont.mSources = AssociationState .createSortedAssociations(now, totalTime, asc.mSources); cont.mTotalTime = asc.getTotalDuration(now); cont.mTotalTime = asc.getTotalDuration(now); cont.mActiveTime = asc.getActiveDuration(now); cont.mActiveTime = asc.getActiveDuration(now); associations.add(cont); associations.add(cont); Loading Loading @@ -1777,7 +1777,7 @@ public final class ProcessStats implements Parcelable { proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); ALL_PROC_STATES, now); proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); proc.dumpInternalLocked(pw, " ", dumpAll); proc.dumpInternalLocked(pw, " ", reqPackage, totalTime, now, dumpAll); } } } } pw.print(" Total procs: "); pw.print(numShownProcs); pw.print(" Total procs: "); pw.print(numShownProcs); Loading @@ -1792,6 +1792,10 @@ public final class ProcessStats implements Parcelable { for (int i = 0; i < mTrackingAssociations.size(); i++) { for (int i = 0; i < mTrackingAssociations.size(); i++) { final AssociationState.SourceState src = mTrackingAssociations.get(i); final AssociationState.SourceState src = mTrackingAssociations.get(i); final AssociationState asc = src.getAssociationState(); final AssociationState asc = src.getAssociationState(); if (asc == null) { Slog.wtf(TAG, src.toString() + " shouldn't be in the tracking list."); continue; } pw.print(" #"); pw.print(" #"); pw.print(i); pw.print(i); pw.print(": "); pw.print(": "); Loading Loading @@ -2353,74 +2357,32 @@ public final class ProcessStats implements Parcelable { * @param fieldId The proto output field ID * @param fieldId The proto output field ID * @param now The timestamp when the dump was initiated. * @param now The timestamp when the dump was initiated. * @param procState The target process where its association states should be dumped. * @param procState The target process where its association states should be dumped. * @param proc2Pkg The map between process to packages running within it. * @param uidToPkgMap The map between UID to packages with this UID * @param uidToPkgMap The map between UID to packages with this UID */ */ public void dumpFilteredAssociationStatesProtoForProc(ProtoOutputStream proto, public void dumpFilteredAssociationStatesProtoForProc(ProtoOutputStream proto, long fieldId, long now, ProcessState procState, long fieldId, long now, ProcessState procState, final ProcessMap<ArraySet<PackageState>> proc2Pkg, final SparseArray<ArraySet<String>> uidToPkgMap) { final SparseArray<ArraySet<String>> uidToPkgMap) { if (procState.isMultiPackage() && procState.getCommonProcess() != procState) { if (procState.isMultiPackage() && procState.getCommonProcess() != procState) { // It's a per-package process state, don't bother to write into statsd // It's a per-package process state, don't bother to write into statsd return; return; } } ArrayMap<SourceKey, long[]> assocVals = new ArrayMap<>(); final ArrayMap<SourceKey, SourceState> sources = procState.mCommonSources; final String procName = procState.getName(); if (sources != null && !sources.isEmpty()) { final int procUid = procState.getUid(); final long procVersion = procState.getVersion(); final ArraySet<PackageState> packages = proc2Pkg.get(procName, procUid); if (packages == null || packages.isEmpty()) { // Shouldn't happen return; } for (int i = packages.size() - 1; i >= 0; i--) { final PackageState pkgState = packages.valueAt(i); final ArrayMap<String, AssociationState> associations = pkgState.mAssociations; for (int j = associations.size() - 1; j >= 0; j--) { final AssociationState assoc = associations.valueAt(j); // Make sure this association is really about this process if (!TextUtils.equals(assoc.getProcessName(), procName)) { continue; } final ArrayMap<SourceKey, SourceState> sources = assoc.mSources; for (int k = sources.size() - 1; k >= 0; k--) { final SourceKey key = sources.keyAt(k); final SourceState state = sources.valueAt(k); long[] vals = assocVals.get(key); if (vals == null) { vals = new long[2]; assocVals.put(key, vals); } vals[0] += state.mDuration; vals[1] += state.mCount; if (state.mNesting > 0) { vals[0] += now - state.mStartUptime; } } } } final IProcessStats procStatsService = IProcessStats.Stub.asInterface( final IProcessStats procStatsService = IProcessStats.Stub.asInterface( ServiceManager.getService(SERVICE_NAME)); ServiceManager.getService(SERVICE_NAME)); if (procStatsService != null) { if (procStatsService != null) { try { try { final long minimum = procStatsService.getMinAssociationDumpDuration(); final long minimum = procStatsService.getMinAssociationDumpDuration(); if (minimum > 0) { for (int i = sources.size() - 1; i >= 0; i--) { // Now filter out unnecessary ones. final SourceState src = sources.valueAt(i); for (int i = assocVals.size() - 1; i >= 0; i--) { long duration = src.mDuration; final long[] vals = assocVals.valueAt(i); if (src.mNesting > 0) { if (vals[0] < minimum) { duration += now - src.mStartUptime; assocVals.removeAt(i); } } } } catch (RemoteException e) { // ignore. } } if (duration < minimum) { continue; } } if (!assocVals.isEmpty()) { final SourceKey key = sources.keyAt(i); for (int i = assocVals.size() - 1; i >= 0; i--) { final SourceKey key = assocVals.keyAt(i); final long[] vals = assocVals.valueAt(i); final long token = proto.start(fieldId); final long token = proto.start(fieldId); final int idx = uidToPkgMap.indexOfKey(key.mUid); final int idx = uidToPkgMap.indexOfKey(key.mUid); ProcessState.writeCompressedProcessName(proto, ProcessState.writeCompressedProcessName(proto, Loading @@ -2428,11 +2390,15 @@ public final class ProcessStats implements Parcelable { key.mProcess, key.mPackage, key.mProcess, key.mPackage, idx >= 0 && uidToPkgMap.valueAt(idx).size() > 1); idx >= 0 && uidToPkgMap.valueAt(idx).size() > 1); proto.write(ProcessStatsAssociationProto.ASSOC_UID, key.mUid); proto.write(ProcessStatsAssociationProto.ASSOC_UID, key.mUid); proto.write(ProcessStatsAssociationProto.TOTAL_COUNT, (int) vals[1]); proto.write(ProcessStatsAssociationProto.TOTAL_COUNT, src.mCount); proto.write(ProcessStatsAssociationProto.TOTAL_DURATION_SECS, proto.write(ProcessStatsAssociationProto.TOTAL_DURATION_SECS, (int) (vals[0] / 1000)); (int) (duration / 1000)); proto.end(token); proto.end(token); } } } catch (RemoteException e) { // ignore. } } } } } } Loading Loading
core/java/com/android/internal/app/procstats/AssociationState.java +332 −159 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/java/com/android/internal/app/procstats/ProcessState.java +84 −3 Original line number Original line Diff line number Diff line Loading @@ -63,6 +63,8 @@ import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import android.util.proto.ProtoUtils; import com.android.internal.app.ProcessMap; import com.android.internal.app.ProcessMap; import com.android.internal.app.procstats.AssociationState.SourceKey; import com.android.internal.app.procstats.AssociationState.SourceState; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; Loading Loading @@ -162,6 +164,11 @@ public final class ProcessState { // Set in computeProcessTimeLocked and used by COMPARATOR to sort. Be careful. // Set in computeProcessTimeLocked and used by COMPARATOR to sort. Be careful. private long mTmpTotalTime; private long mTmpTotalTime; /** * The combined source states which has or had an association with this process. */ ArrayMap<SourceKey, SourceState> mCommonSources; /** /** * Create a new top-level process state, for the initial case where there is only * Create a new top-level process state, for the initial case where there is only * a single package running in a process. The initial state is not running. * a single package running in a process. The initial state is not running. Loading Loading @@ -267,6 +274,21 @@ public final class ProcessState { addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss, addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss, other.mAvgCachedKillPss, other.mMaxCachedKillPss); other.mAvgCachedKillPss, other.mMaxCachedKillPss); } } if (other.mCommonSources != null) { if (mCommonSources == null) { mCommonSources = new ArrayMap<>(); } int size = other.mCommonSources.size(); for (int i = 0; i < size; i++) { final SourceKey key = other.mCommonSources.keyAt(i); SourceState state = mCommonSources.get(key); if (state == null) { state = new SourceState(mStats, null, this, key); mCommonSources.put(key, state); } state.add(other.mCommonSources.valueAt(i)); } } } } public void resetSafely(long now) { public void resetSafely(long now) { Loading @@ -278,6 +300,17 @@ public final class ProcessState { mNumExcessiveCpu = 0; mNumExcessiveCpu = 0; mNumCachedKill = 0; mNumCachedKill = 0; mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; // Reset the combine source state. if (mCommonSources != null) { for (int ip = mCommonSources.size() - 1; ip >= 0; ip--) { final SourceState state = mCommonSources.valueAt(ip); if (state.isInUse()) { state.resetSafely(now); } else { mCommonSources.removeAt(ip); } } } } } public void makeDead() { public void makeDead() { Loading Loading @@ -308,9 +341,18 @@ public final class ProcessState { out.writeLong(mAvgCachedKillPss); out.writeLong(mAvgCachedKillPss); out.writeLong(mMaxCachedKillPss); out.writeLong(mMaxCachedKillPss); } } // The combined source state of all associations. final int numOfSources = mCommonSources != null ? mCommonSources.size() : 0; out.writeInt(numOfSources); for (int i = 0; i < numOfSources; i++) { final SourceKey key = mCommonSources.keyAt(i); final SourceState src = mCommonSources.valueAt(i); key.writeToParcel(mStats, out); src.writeToParcel(out, 0); } } } public boolean readFromParcel(Parcel in, boolean fully) { boolean readFromParcel(Parcel in, int version, boolean fully) { boolean multiPackage = in.readInt() != 0; boolean multiPackage = in.readInt() != 0; if (fully) { if (fully) { mMultiPackage = multiPackage; mMultiPackage = multiPackage; Loading @@ -337,6 +379,19 @@ public final class ProcessState { } else { } else { mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0; } } // The combined source state of all associations. final int numOfSources = in.readInt(); if (numOfSources > 0) { mCommonSources = new ArrayMap<>(numOfSources); for (int i = 0; i < numOfSources; i++) { final SourceKey key = new SourceKey(mStats, in, version); final SourceState src = new SourceState(mStats, null, this, key); src.readFromParcel(in); mCommonSources.put(key, src); } } return true; return true; } } Loading Loading @@ -433,6 +488,12 @@ public final class ProcessState { mTotalRunningStartTime = now; mTotalRunningStartTime = now; } } mStartTime = now; mStartTime = now; if (mCommonSources != null) { for (int ip = mCommonSources.size() - 1; ip >= 0; ip--) { final SourceState src = mCommonSources.valueAt(ip); src.commitStateTime(now); } } } } public void incActiveServices(String serviceName) { public void incActiveServices(String serviceName) { Loading Loading @@ -722,6 +783,18 @@ public final class ProcessState { return mPssTable.getValueForId((byte)state, PSS_RSS_MAXIMUM); return mPssTable.getValueForId((byte)state, PSS_RSS_MAXIMUM); } } SourceState getOrCreateSourceState(SourceKey key) { if (mCommonSources == null) { mCommonSources = new ArrayMap<>(); } SourceState state = mCommonSources.get(key); if (state == null) { state = new SourceState(mStats, null, this, key); mCommonSources.put(key, state); } return state; } /** /** * Sums up the PSS data and adds it to 'data'. * Sums up the PSS data and adds it to 'data'. * * Loading Loading @@ -1038,7 +1111,8 @@ public final class ProcessState { } } } } public void dumpInternalLocked(PrintWriter pw, String prefix, boolean dumpAll) { void dumpInternalLocked(PrintWriter pw, String prefix, String reqPackage, long totalTime, long now, boolean dumpAll) { if (dumpAll) { if (dumpAll) { pw.print(prefix); pw.print("myID="); pw.print(prefix); pw.print("myID="); pw.print(Integer.toHexString(System.identityHashCode(this))); pw.print(Integer.toHexString(System.identityHashCode(this))); Loading @@ -1053,6 +1127,13 @@ public final class ProcessState { pw.print("/"); pw.print(mCommonProcess.mUid); pw.print("/"); pw.print(mCommonProcess.mUid); pw.print(" pkg="); pw.println(mCommonProcess.mPackage); pw.print(" pkg="); pw.println(mCommonProcess.mPackage); } } if (mCommonSources != null) { pw.print(prefix); pw.println("Aggregated Association Sources:"); AssociationState.dumpSources( pw, prefix + " ", prefix + " ", prefix + " ", AssociationState.createSortedAssociations(now, totalTime, mCommonSources), now, totalTime, reqPackage, true, dumpAll); } } } if (mActive) { if (mActive) { pw.print(prefix); pw.print("mActive="); pw.println(mActive); pw.print(prefix); pw.print("mActive="); pw.println(mActive); Loading Loading @@ -1559,7 +1640,7 @@ public final class ProcessState { } } mStats.dumpFilteredAssociationStatesProtoForProc(proto, ProcessStatsProto.ASSOCS, mStats.dumpFilteredAssociationStatesProtoForProc(proto, ProcessStatsProto.ASSOCS, now, this, procToPkgMap, uidToPkgMap); now, this, uidToPkgMap); proto.end(token); proto.end(token); } } } }
core/java/com/android/internal/app/procstats/ProcessStats.java +51 −85 Original line number Original line Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.service.procstats.ProcessStatsAssociationProto; import android.service.procstats.ProcessStatsAvailablePagesProto; import android.service.procstats.ProcessStatsAvailablePagesProto; import android.service.procstats.ProcessStatsPackageProto; import android.service.procstats.ProcessStatsPackageProto; import android.service.procstats.ProcessStatsSectionProto; import android.service.procstats.ProcessStatsSectionProto; import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateFormat; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.ArraySet; import android.util.ArraySet; Loading Loading @@ -187,7 +186,7 @@ public final class ProcessStats implements Parcelable { {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"}; {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"}; // Current version of the parcel format. // Current version of the parcel format. private static final int PARCEL_VERSION = 38; private static final int PARCEL_VERSION = 39; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; private static final int MAGIC = 0x50535454; Loading Loading @@ -1113,12 +1112,12 @@ public final class ProcessStats implements Parcelable { final long vers = in.readLong(); final long vers = in.readLong(); ProcessState proc = hadData ? mProcesses.get(procName, uid) : null; ProcessState proc = hadData ? mProcesses.get(procName, uid) : null; if (proc != null) { if (proc != null) { if (!proc.readFromParcel(in, false)) { if (!proc.readFromParcel(in, version, false)) { return; return; } } } else { } else { proc = new ProcessState(this, pkgName, uid, vers, procName); proc = new ProcessState(this, pkgName, uid, vers, procName); if (!proc.readFromParcel(in, true)) { if (!proc.readFromParcel(in, version, true)) { return; return; } } } } Loading Loading @@ -1198,13 +1197,13 @@ public final class ProcessStats implements Parcelable { // they will find and use it from the global procs. // they will find and use it from the global procs. ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null; ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null; if (proc != null) { if (proc != null) { if (!proc.readFromParcel(in, false)) { if (!proc.readFromParcel(in, version, false)) { return; return; } } } else { } else { proc = new ProcessState(commonProc, pkgName, uid, vers, procName, proc = new ProcessState(commonProc, pkgName, uid, vers, procName, 0); 0); if (!proc.readFromParcel(in, true)) { if (!proc.readFromParcel(in, version, true)) { return; return; } } } } Loading Loading @@ -1439,16 +1438,15 @@ public final class ProcessStats implements Parcelable { final int NUM = mTrackingAssociations.size(); final int NUM = mTrackingAssociations.size(); for (int i = NUM - 1; i >= 0; i--) { for (int i = NUM - 1; i >= 0; i--) { final AssociationState.SourceState act = mTrackingAssociations.get(i); final AssociationState.SourceState act = mTrackingAssociations.get(i); if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) { if (act.stopActiveIfNecessary(curSeq, now)) { // If this association did not get touched the last time we computed // process states, or its state ended up down in cached, then we no // longer have a reason to track it at all. act.stopActive(now); act.mInTrackingList = false; act.mProcState = ProcessStats.STATE_NOTHING; mTrackingAssociations.remove(i); mTrackingAssociations.remove(i); } else { } else { final ProcessState proc = act.getAssociationState().getProcess(); final AssociationState asc = act.getAssociationState(); if (asc == null) { Slog.wtf(TAG, act.toString() + " shouldn't be in the tracking list."); continue; } final ProcessState proc = asc.getProcess(); if (proc != null) { if (proc != null) { final int procState = proc.getCombinedState() % STATE_COUNT; final int procState = proc.getCombinedState() % STATE_COUNT; if (act.mProcState == procState) { if (act.mProcState == procState) { Loading Loading @@ -1476,7 +1474,7 @@ public final class ProcessStats implements Parcelable { } else { } else { // Don't need rate limiting on it. // Don't need rate limiting on it. Slog.wtf(TAG, "Tracking association without process: " + act Slog.wtf(TAG, "Tracking association without process: " + act + " in " + act.getAssociationState()); + " in " + asc); } } } } } } Loading Loading @@ -1640,7 +1638,8 @@ public final class ProcessStats implements Parcelable { ALL_PROC_STATES, now); ALL_PROC_STATES, now); proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); ALL_PROC_STATES, now); proc.dumpInternalLocked(pw, " ", dumpAll); proc.dumpInternalLocked(pw, " ", reqPackage, totalTime, now, dumpAll); } } } else { } else { ArrayList<ProcessState> procs = new ArrayList<ProcessState>(); ArrayList<ProcessState> procs = new ArrayList<ProcessState>(); Loading Loading @@ -1696,7 +1695,8 @@ public final class ProcessStats implements Parcelable { } } final AssociationDumpContainer cont = final AssociationDumpContainer cont = new AssociationDumpContainer(asc); new AssociationDumpContainer(asc); cont.mSources = asc.createSortedAssociations(now, totalTime); cont.mSources = AssociationState .createSortedAssociations(now, totalTime, asc.mSources); cont.mTotalTime = asc.getTotalDuration(now); cont.mTotalTime = asc.getTotalDuration(now); cont.mActiveTime = asc.getActiveDuration(now); cont.mActiveTime = asc.getActiveDuration(now); associations.add(cont); associations.add(cont); Loading Loading @@ -1777,7 +1777,7 @@ public final class ProcessStats implements Parcelable { proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); ALL_PROC_STATES, now); proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); proc.dumpInternalLocked(pw, " ", dumpAll); proc.dumpInternalLocked(pw, " ", reqPackage, totalTime, now, dumpAll); } } } } pw.print(" Total procs: "); pw.print(numShownProcs); pw.print(" Total procs: "); pw.print(numShownProcs); Loading @@ -1792,6 +1792,10 @@ public final class ProcessStats implements Parcelable { for (int i = 0; i < mTrackingAssociations.size(); i++) { for (int i = 0; i < mTrackingAssociations.size(); i++) { final AssociationState.SourceState src = mTrackingAssociations.get(i); final AssociationState.SourceState src = mTrackingAssociations.get(i); final AssociationState asc = src.getAssociationState(); final AssociationState asc = src.getAssociationState(); if (asc == null) { Slog.wtf(TAG, src.toString() + " shouldn't be in the tracking list."); continue; } pw.print(" #"); pw.print(" #"); pw.print(i); pw.print(i); pw.print(": "); pw.print(": "); Loading Loading @@ -2353,74 +2357,32 @@ public final class ProcessStats implements Parcelable { * @param fieldId The proto output field ID * @param fieldId The proto output field ID * @param now The timestamp when the dump was initiated. * @param now The timestamp when the dump was initiated. * @param procState The target process where its association states should be dumped. * @param procState The target process where its association states should be dumped. * @param proc2Pkg The map between process to packages running within it. * @param uidToPkgMap The map between UID to packages with this UID * @param uidToPkgMap The map between UID to packages with this UID */ */ public void dumpFilteredAssociationStatesProtoForProc(ProtoOutputStream proto, public void dumpFilteredAssociationStatesProtoForProc(ProtoOutputStream proto, long fieldId, long now, ProcessState procState, long fieldId, long now, ProcessState procState, final ProcessMap<ArraySet<PackageState>> proc2Pkg, final SparseArray<ArraySet<String>> uidToPkgMap) { final SparseArray<ArraySet<String>> uidToPkgMap) { if (procState.isMultiPackage() && procState.getCommonProcess() != procState) { if (procState.isMultiPackage() && procState.getCommonProcess() != procState) { // It's a per-package process state, don't bother to write into statsd // It's a per-package process state, don't bother to write into statsd return; return; } } ArrayMap<SourceKey, long[]> assocVals = new ArrayMap<>(); final ArrayMap<SourceKey, SourceState> sources = procState.mCommonSources; final String procName = procState.getName(); if (sources != null && !sources.isEmpty()) { final int procUid = procState.getUid(); final long procVersion = procState.getVersion(); final ArraySet<PackageState> packages = proc2Pkg.get(procName, procUid); if (packages == null || packages.isEmpty()) { // Shouldn't happen return; } for (int i = packages.size() - 1; i >= 0; i--) { final PackageState pkgState = packages.valueAt(i); final ArrayMap<String, AssociationState> associations = pkgState.mAssociations; for (int j = associations.size() - 1; j >= 0; j--) { final AssociationState assoc = associations.valueAt(j); // Make sure this association is really about this process if (!TextUtils.equals(assoc.getProcessName(), procName)) { continue; } final ArrayMap<SourceKey, SourceState> sources = assoc.mSources; for (int k = sources.size() - 1; k >= 0; k--) { final SourceKey key = sources.keyAt(k); final SourceState state = sources.valueAt(k); long[] vals = assocVals.get(key); if (vals == null) { vals = new long[2]; assocVals.put(key, vals); } vals[0] += state.mDuration; vals[1] += state.mCount; if (state.mNesting > 0) { vals[0] += now - state.mStartUptime; } } } } final IProcessStats procStatsService = IProcessStats.Stub.asInterface( final IProcessStats procStatsService = IProcessStats.Stub.asInterface( ServiceManager.getService(SERVICE_NAME)); ServiceManager.getService(SERVICE_NAME)); if (procStatsService != null) { if (procStatsService != null) { try { try { final long minimum = procStatsService.getMinAssociationDumpDuration(); final long minimum = procStatsService.getMinAssociationDumpDuration(); if (minimum > 0) { for (int i = sources.size() - 1; i >= 0; i--) { // Now filter out unnecessary ones. final SourceState src = sources.valueAt(i); for (int i = assocVals.size() - 1; i >= 0; i--) { long duration = src.mDuration; final long[] vals = assocVals.valueAt(i); if (src.mNesting > 0) { if (vals[0] < minimum) { duration += now - src.mStartUptime; assocVals.removeAt(i); } } } } catch (RemoteException e) { // ignore. } } if (duration < minimum) { continue; } } if (!assocVals.isEmpty()) { final SourceKey key = sources.keyAt(i); for (int i = assocVals.size() - 1; i >= 0; i--) { final SourceKey key = assocVals.keyAt(i); final long[] vals = assocVals.valueAt(i); final long token = proto.start(fieldId); final long token = proto.start(fieldId); final int idx = uidToPkgMap.indexOfKey(key.mUid); final int idx = uidToPkgMap.indexOfKey(key.mUid); ProcessState.writeCompressedProcessName(proto, ProcessState.writeCompressedProcessName(proto, Loading @@ -2428,11 +2390,15 @@ public final class ProcessStats implements Parcelable { key.mProcess, key.mPackage, key.mProcess, key.mPackage, idx >= 0 && uidToPkgMap.valueAt(idx).size() > 1); idx >= 0 && uidToPkgMap.valueAt(idx).size() > 1); proto.write(ProcessStatsAssociationProto.ASSOC_UID, key.mUid); proto.write(ProcessStatsAssociationProto.ASSOC_UID, key.mUid); proto.write(ProcessStatsAssociationProto.TOTAL_COUNT, (int) vals[1]); proto.write(ProcessStatsAssociationProto.TOTAL_COUNT, src.mCount); proto.write(ProcessStatsAssociationProto.TOTAL_DURATION_SECS, proto.write(ProcessStatsAssociationProto.TOTAL_DURATION_SECS, (int) (vals[0] / 1000)); (int) (duration / 1000)); proto.end(token); proto.end(token); } } } catch (RemoteException e) { // ignore. } } } } } } Loading