Loading services/java/com/android/server/am/ActiveServices.java +18 −12 Original line number Diff line number Diff line Loading @@ -243,8 +243,9 @@ public final class ActiveServices { } r.lastActivity = SystemClock.uptimeMillis(); r.startRequested = true; if (r.tracker != null) { r.tracker.setStarted(true, mAm.mProcessTracker.getMemFactorLocked(), r.lastActivity); ProcessTracker.ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setStarted(true, mAm.mProcessTracker.getMemFactorLocked(), r.lastActivity); } r.callStart = false; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), Loading Loading @@ -505,8 +506,9 @@ public final class ActiveServices { s.lastActivity = SystemClock.uptimeMillis(); if (!s.hasAutoCreateConnections()) { // This is the first binding, let the tracker know. if (s.tracker != null) { s.tracker.setBound(true, mAm.mProcessTracker.getMemFactorLocked(), ProcessTracker.ServiceState stracker = s.getTracker(); if (stracker != null) { stracker.setBound(true, mAm.mProcessTracker.getMemFactorLocked(), s.lastActivity); } } Loading Loading @@ -771,12 +773,7 @@ public final class ActiveServices { sInfo.applicationInfo.uid, sInfo.packageName, sInfo.name); } ProcessTracker.ServiceState tracker = null; if ((sInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { tracker = mAm.mProcessTracker.getServiceStateLocked(sInfo.packageName, sInfo.applicationInfo.uid, sInfo.name); } r = new ServiceRecord(mAm, ss, name, filter, sInfo, res, tracker); r = new ServiceRecord(mAm, ss, name, filter, sInfo, res); res.setService(r); mServiceMap.putServiceByName(name, UserHandle.getUserId(r.appInfo.uid), r); mServiceMap.putServiceByIntent(filter, UserHandle.getUserId(r.appInfo.uid), r); Loading Loading @@ -827,8 +824,9 @@ public final class ActiveServices { + why + " of " + r.shortName); long now = SystemClock.uptimeMillis(); if (r.executeNesting == 0) { if (r.tracker != null) { r.tracker.setExecuting(true, mAm.mProcessTracker.getMemFactorLocked(), now); ProcessTracker.ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setExecuting(true, mAm.mProcessTracker.getMemFactorLocked(), now); } if (r.app != null) { if (r.app.executingServices.size() == 0) { Loading Loading @@ -1340,6 +1338,10 @@ public final class ActiveServices { if (r.tracker != null) { r.tracker.setStarted(false, memFactor, now); r.tracker.setBound(false, memFactor, now); if (r.executeNesting == 0) { r.tracker.makeInactive(); r.tracker = null; } } } Loading Loading @@ -1500,6 +1502,10 @@ public final class ActiveServices { if (r.tracker != null) { r.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactorLocked(), SystemClock.uptimeMillis()); if (inStopping) { r.tracker.makeInactive(); r.tracker = null; } } } } Loading services/java/com/android/server/am/ProcessTracker.java +127 −67 Original line number Diff line number Diff line Loading @@ -547,6 +547,8 @@ public final class ProcessTracker { } public static final class ServiceState { int mActive = 1; final long[] mStartedDurations = new long[ADJ_COUNT]; int mStartedCount; int mStartedState = STATE_NOTHING; Loading @@ -562,11 +564,30 @@ public final class ProcessTracker { int mExecState = STATE_NOTHING; long mExecStartTime; void makeActive() { mActive++; } void makeInactive() { /* RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.i(TAG, "Making " + this + " inactive", here); */ mActive--; } boolean isActive() { return mActive > 0; } void resetSafely(long now) { for (int i=0; i<ADJ_COUNT; i++) { mStartedDurations[i] = mBoundDurations[i] = mExecDurations[i] = 0; } mStartedCount = mBoundCount = mExecCount = 0; mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0; mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0; mExecCount = mExecState != STATE_NOTHING ? 1 : 0; mStartedStartTime = mBoundStartTime = mExecStartTime = now; } Loading Loading @@ -602,6 +623,9 @@ public final class ProcessTracker { } public void setStarted(boolean started, int memFactor, long now) { if (mActive <= 0) { throw new IllegalStateException("Service " + this + " has mActive=" + mActive); } int state = started ? memFactor : STATE_NOTHING; if (mStartedState != state) { if (mStartedState != STATE_NOTHING) { Loading @@ -615,6 +639,9 @@ public final class ProcessTracker { } public void setBound(boolean bound, int memFactor, long now) { if (mActive <= 0) { throw new IllegalStateException("Service " + this + " has mActive=" + mActive); } int state = bound ? memFactor : STATE_NOTHING; if (mBoundState != state) { if (mBoundState != STATE_NOTHING) { Loading @@ -628,6 +655,9 @@ public final class ProcessTracker { } public void setExecuting(boolean executing, int memFactor, long now) { if (mActive <= 0) { throw new IllegalStateException("Service " + this + " has mActive=" + mActive); } int state = executing ? memFactor : STATE_NOTHING; if (mExecState != state) { if (mExecState != STATE_NOTHING) { Loading Loading @@ -687,6 +717,7 @@ public final class ProcessTracker { final Object mPendingWriteLock = new Object(); Parcel mPendingWrite; boolean mPendingWriteCommitted; long mLastWriteTime; State(File baseDir, ProcessTracker tracker) { Loading Loading @@ -718,28 +749,27 @@ public final class ProcessTracker { resetCommon(); long now = SystemClock.uptimeMillis(); ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); final int NPROC = procMap.size(); for (int ip=0; ip<NPROC; ip++) { for (int ip=procMap.size()-1; ip>=0; ip--) { SparseArray<ProcessState> uids = procMap.valueAt(ip); final int NUID = uids.size(); for (int iu=0; iu<NUID; iu++) { for (int iu=uids.size()-1; iu>=0; iu--) { uids.valueAt(iu).resetSafely(now); } } ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap(); final int NPKG = pkgMap.size(); for (int ip=0; ip<NPKG; ip++) { for (int ip=pkgMap.size()-1; ip>=0; ip--) { SparseArray<PackageState> uids = pkgMap.valueAt(ip); final int NUID = uids.size(); for (int iu=0; iu<NUID; iu++) { for (int iu=uids.size()-1; iu>=0; iu--) { PackageState pkgState = uids.valueAt(iu); final int NPROCS = pkgState.mProcesses.size(); for (int iproc=0; iproc<NPROCS; iproc++) { for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) { pkgState.mProcesses.valueAt(iproc).resetSafely(now); } final int NSRVS = pkgState.mServices.size(); for (int isvc=0; isvc<NSRVS; isvc++) { for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) { ServiceState ss = pkgState.mServices.valueAt(isvc); if (ss.isActive()) { pkgState.mServices.valueAt(isvc).resetSafely(now); } else { pkgState.mServices.removeAt(isvc); } } } } Loading @@ -756,9 +786,9 @@ public final class ProcessTracker { mLongs.add(new long[LONGS_SIZE]); mNextLong = 0; Arrays.fill(mMemFactorDurations, 0); mMemFactor = STATE_NOTHING; mStartTime = 0; mReadError = null; mFlags = 0; } private void buildTimePeriodStartClockStr() { Loading Loading @@ -852,30 +882,40 @@ public final class ProcessTracker { private void writeStateLocked(boolean sync, final boolean commit) { synchronized (mPendingWriteLock) { long now = SystemClock.uptimeMillis(); if (mPendingWrite == null || !mPendingWriteCommitted) { mPendingWrite = Parcel.obtain(); mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); if (commit) { mFlags |= State.FLAG_COMPLETE; } writeToParcel(mPendingWrite); mPendingWriteCommitted = commit; } if (commit) { resetSafely(); } else { mLastWriteTime = SystemClock.uptimeMillis(); } Slog.i(TAG, "Prepared write state in " + (SystemClock.uptimeMillis()-now) + "ms"); if (!sync) { BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { performWriteState(commit); performWriteState(); } }); return; } } performWriteState(commit); performWriteState(); } void performWriteState(boolean commit) { if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile() + " commit=" + commit); void performWriteState() { if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile()); Parcel data; synchronized (mPendingWriteLock) { data = mPendingWrite; mPendingWriteCommitted = false; if (data == null) { return; } Loading Loading @@ -903,9 +943,6 @@ public final class ProcessTracker { } } if (commit) { resetSafely(); } } void writeToParcel(Parcel out) { Loading Loading @@ -1438,11 +1475,13 @@ public final class ProcessTracker { } void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now) { long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, mStartTime, now); dumpFilteredSummaryLocked(pw, null, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, new int[] { STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_RECEIVER, STATE_HOME, STATE_LAST_ACTIVITY }, now, reqPackage); STATE_SERVICE, STATE_RECEIVER, STATE_HOME }, now, totalTime, reqPackage); pw.println(); pw.println("Run time Stats:"); dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now); Loading @@ -1461,7 +1500,8 @@ public final class ProcessTracker { } void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, int[] screenStates, int[] memStates, int[] procStates, long now, String reqPackage) { int[] screenStates, int[] memStates, int[] procStates, long now, long totalTime, String reqPackage) { ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates, procStates, now, reqPackage); if (procs.size() > 0) { Loading @@ -1469,7 +1509,8 @@ public final class ProcessTracker { pw.println(); pw.println(header); } dumpProcessSummary(pw, prefix, procs, screenStates, memStates, procStates, now); dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates, procStates, now, totalTime); } } Loading Loading @@ -1659,6 +1700,7 @@ public final class ProcessTracker { final PackageState as = mState.getPackageStateLocked(packageName, uid); ServiceState ss = as.mServices.get(className); if (ss != null) { ss.makeActive(); return ss; } ss = new ServiceState(); Loading @@ -1684,12 +1726,17 @@ public final class ProcessTracker { ArrayMap<String, ServiceState> services = pkg.mServices; for (int k=0; k<services.size(); k++) { ServiceState service = services.valueAt(k); if (service.isActive()) { if (service.mStartedState != STATE_NOTHING) { service.setStarted(true, memFactor, now); } if (service.mBoundState != STATE_NOTHING) { service.setBound(true, memFactor, now); } if (service.mExecState != STATE_NOTHING) { service.setExecuting(true, memFactor, now); } } } } } Loading @@ -1710,7 +1757,6 @@ public final class ProcessTracker { if (now > (mState.mLastWriteTime+WRITE_PERIOD)) { if (SystemClock.elapsedRealtime() > (mState.mTimePeriodStartRealtime+COMMIT_PERIOD)) { mCommitPending = true; mState.mFlags |= State.FLAG_COMPLETE; } return true; } Loading Loading @@ -1845,7 +1891,7 @@ public final class ProcessTracker { } } static void dumpSingleTime(PrintWriter pw, String prefix, long[] durations, static long dumpSingleTime(PrintWriter pw, String prefix, long[] durations, int curState, long curStartTime, long now) { long totalTime = 0; int printedScreen = -1; Loading @@ -1857,9 +1903,12 @@ public final class ProcessTracker { String running = ""; if (curState == state) { time += now - curStartTime; if (pw != null) { running = " (running)"; } } if (time != 0) { if (pw != null) { pw.print(prefix); printScreenLabel(pw, printedScreen != iscreen ? iscreen : STATE_NOTHING); Loading @@ -1867,17 +1916,19 @@ public final class ProcessTracker { printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING); printedMem = imem; TimeUtils.formatDuration(time, pw); pw.println(running); } totalTime += time; } } } if (totalTime != 0) { if (totalTime != 0 && pw != null) { pw.print(prefix); printScreenLabel(pw, STATE_NOTHING); pw.print("TOTAL: "); TimeUtils.formatDuration(totalTime, pw); pw.println(); } return totalTime; } static void dumpAdjTimesCheckin(PrintWriter pw, String sep, long[] durations, Loading Loading @@ -1934,8 +1985,16 @@ public final class ProcessTracker { procStates = _procStates; } void print(PrintWriter pw, boolean full) { TimeUtils.formatDuration(totalTime, pw); void print(PrintWriter pw, long overallTime, boolean full) { double percent = ((double)totalTime/(double)overallTime) * 100; if (percent < 1) { pw.print(String.format("%.2f", percent)); } else if (percent < 10) { pw.print(String.format("%.1f", percent)); } else { pw.print(String.format("%.0f", percent)); } pw.print("%"); if (numPss > 0) { pw.print(" ("); printSizeValue(pw, minPss * 1024); Loading Loading @@ -2230,7 +2289,7 @@ public final class ProcessTracker { static void dumpProcessSummaryDetails(PrintWriter pw, ProcessState proc, String prefix, String label, int[] screenStates, int[] memStates, int[] procStates, long now, boolean full) { long now, long totalTime, boolean full) { ProcessDataCollection totals = new ProcessDataCollection(screenStates, memStates, procStates); computeProcessData(proc, totals, now); Loading @@ -2241,15 +2300,16 @@ public final class ProcessTracker { if (label != null) { pw.print(label); } totals.print(pw, full); totals.print(pw, totalTime, full); if (prefix != null) { pw.println(); } } } static void dumpProcessSummary(PrintWriter pw, String prefix, ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates, long now) { static void dumpProcessSummaryLocked(PrintWriter pw, String prefix, ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates, long now, long totalTime) { for (int i=procs.size()-1; i>=0; i--) { ProcessState proc = procs.get(i); pw.print(prefix); Loading @@ -2259,30 +2319,30 @@ public final class ProcessTracker { UserHandle.formatUid(pw, proc.mUid); pw.println(":"); dumpProcessSummaryDetails(pw, proc, prefix, " TOTAL: ", screenStates, memStates, procStates, now, true); procStates, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Persistent: ", screenStates, memStates, new int[] { STATE_PERSISTENT }, now, true); new int[] { STATE_PERSISTENT }, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Top: ", screenStates, memStates, new int[] {STATE_TOP}, now, true); new int[] {STATE_TOP}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Imp Fg: ", screenStates, memStates, new int[] { STATE_IMPORTANT_FOREGROUND }, now, true); new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Imp Bg: ", screenStates, memStates, new int[] {STATE_IMPORTANT_BACKGROUND}, now, true); new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Backup: ", screenStates, memStates, new int[] {STATE_BACKUP}, now, true); new int[] {STATE_BACKUP}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Heavy Wgt: ", screenStates, memStates, new int[] {STATE_HEAVY_WEIGHT}, now, true); new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Service: ", screenStates, memStates, new int[] {STATE_SERVICE}, now, true); new int[] {STATE_SERVICE}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Receiver: ", screenStates, memStates, new int[] {STATE_RECEIVER}, now, true); new int[] {STATE_RECEIVER}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Home: ", screenStates, memStates, new int[] {STATE_HOME}, now, true); dumpProcessSummaryDetails(pw, proc, prefix, " Last Act: ", screenStates, memStates, new int[] {STATE_LAST_ACTIVITY}, now, true); new int[] {STATE_HOME}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " (Last Act): ", screenStates, memStates, new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " (Cached): ", screenStates, memStates, new int[] {STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY}, now, true); STATE_CACHED_EMPTY}, now, totalTime, true); } } Loading services/java/com/android/server/am/ServiceRecord.java +13 −4 Original line number Diff line number Diff line Loading @@ -73,7 +73,6 @@ final class ServiceRecord extends Binder { final String dataDir; // where activity data should go final boolean exported; // from ServiceInfo.exported final Runnable restarter; // used to schedule retries of starting the service final ProcessTracker.ServiceState tracker; // tracking service execution, may be null final long createTime; // when this service was created final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); Loading @@ -84,6 +83,7 @@ final class ServiceRecord extends Binder { ProcessRecord app; // where this service is running or null. ProcessRecord isolatedProc; // keep track of isolated process, if requested ProcessTracker.ServiceState tracker; // tracking service execution, may be null boolean isForeground; // is service currently in foreground mode? int foregroundId; // Notification ID of last foreground req. Notification foregroundNoti; // Notification record of foreground state. Loading Loading @@ -282,8 +282,7 @@ final class ServiceRecord extends Binder { ServiceRecord(ActivityManagerService ams, BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter, ProcessTracker.ServiceState tracker) { Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter) { this.ams = ams; this.stats = servStats; this.name = name; Loading @@ -299,12 +298,22 @@ final class ServiceRecord extends Binder { dataDir = sInfo.applicationInfo.dataDir; exported = sInfo.exported; this.restarter = restarter; this.tracker = tracker; createTime = SystemClock.elapsedRealtime(); lastActivity = SystemClock.uptimeMillis(); userId = UserHandle.getUserId(appInfo.uid); } public ProcessTracker.ServiceState getTracker() { if (tracker != null) { return tracker; } if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { tracker = ams.mProcessTracker.getServiceStateLocked(serviceInfo.packageName, serviceInfo.applicationInfo.uid, serviceInfo.name); } return tracker; } public AppBindRecord retrieveAppBindingLocked(Intent intent, ProcessRecord app) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); Loading Loading
services/java/com/android/server/am/ActiveServices.java +18 −12 Original line number Diff line number Diff line Loading @@ -243,8 +243,9 @@ public final class ActiveServices { } r.lastActivity = SystemClock.uptimeMillis(); r.startRequested = true; if (r.tracker != null) { r.tracker.setStarted(true, mAm.mProcessTracker.getMemFactorLocked(), r.lastActivity); ProcessTracker.ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setStarted(true, mAm.mProcessTracker.getMemFactorLocked(), r.lastActivity); } r.callStart = false; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), Loading Loading @@ -505,8 +506,9 @@ public final class ActiveServices { s.lastActivity = SystemClock.uptimeMillis(); if (!s.hasAutoCreateConnections()) { // This is the first binding, let the tracker know. if (s.tracker != null) { s.tracker.setBound(true, mAm.mProcessTracker.getMemFactorLocked(), ProcessTracker.ServiceState stracker = s.getTracker(); if (stracker != null) { stracker.setBound(true, mAm.mProcessTracker.getMemFactorLocked(), s.lastActivity); } } Loading Loading @@ -771,12 +773,7 @@ public final class ActiveServices { sInfo.applicationInfo.uid, sInfo.packageName, sInfo.name); } ProcessTracker.ServiceState tracker = null; if ((sInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { tracker = mAm.mProcessTracker.getServiceStateLocked(sInfo.packageName, sInfo.applicationInfo.uid, sInfo.name); } r = new ServiceRecord(mAm, ss, name, filter, sInfo, res, tracker); r = new ServiceRecord(mAm, ss, name, filter, sInfo, res); res.setService(r); mServiceMap.putServiceByName(name, UserHandle.getUserId(r.appInfo.uid), r); mServiceMap.putServiceByIntent(filter, UserHandle.getUserId(r.appInfo.uid), r); Loading Loading @@ -827,8 +824,9 @@ public final class ActiveServices { + why + " of " + r.shortName); long now = SystemClock.uptimeMillis(); if (r.executeNesting == 0) { if (r.tracker != null) { r.tracker.setExecuting(true, mAm.mProcessTracker.getMemFactorLocked(), now); ProcessTracker.ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setExecuting(true, mAm.mProcessTracker.getMemFactorLocked(), now); } if (r.app != null) { if (r.app.executingServices.size() == 0) { Loading Loading @@ -1340,6 +1338,10 @@ public final class ActiveServices { if (r.tracker != null) { r.tracker.setStarted(false, memFactor, now); r.tracker.setBound(false, memFactor, now); if (r.executeNesting == 0) { r.tracker.makeInactive(); r.tracker = null; } } } Loading Loading @@ -1500,6 +1502,10 @@ public final class ActiveServices { if (r.tracker != null) { r.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactorLocked(), SystemClock.uptimeMillis()); if (inStopping) { r.tracker.makeInactive(); r.tracker = null; } } } } Loading
services/java/com/android/server/am/ProcessTracker.java +127 −67 Original line number Diff line number Diff line Loading @@ -547,6 +547,8 @@ public final class ProcessTracker { } public static final class ServiceState { int mActive = 1; final long[] mStartedDurations = new long[ADJ_COUNT]; int mStartedCount; int mStartedState = STATE_NOTHING; Loading @@ -562,11 +564,30 @@ public final class ProcessTracker { int mExecState = STATE_NOTHING; long mExecStartTime; void makeActive() { mActive++; } void makeInactive() { /* RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.i(TAG, "Making " + this + " inactive", here); */ mActive--; } boolean isActive() { return mActive > 0; } void resetSafely(long now) { for (int i=0; i<ADJ_COUNT; i++) { mStartedDurations[i] = mBoundDurations[i] = mExecDurations[i] = 0; } mStartedCount = mBoundCount = mExecCount = 0; mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0; mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0; mExecCount = mExecState != STATE_NOTHING ? 1 : 0; mStartedStartTime = mBoundStartTime = mExecStartTime = now; } Loading Loading @@ -602,6 +623,9 @@ public final class ProcessTracker { } public void setStarted(boolean started, int memFactor, long now) { if (mActive <= 0) { throw new IllegalStateException("Service " + this + " has mActive=" + mActive); } int state = started ? memFactor : STATE_NOTHING; if (mStartedState != state) { if (mStartedState != STATE_NOTHING) { Loading @@ -615,6 +639,9 @@ public final class ProcessTracker { } public void setBound(boolean bound, int memFactor, long now) { if (mActive <= 0) { throw new IllegalStateException("Service " + this + " has mActive=" + mActive); } int state = bound ? memFactor : STATE_NOTHING; if (mBoundState != state) { if (mBoundState != STATE_NOTHING) { Loading @@ -628,6 +655,9 @@ public final class ProcessTracker { } public void setExecuting(boolean executing, int memFactor, long now) { if (mActive <= 0) { throw new IllegalStateException("Service " + this + " has mActive=" + mActive); } int state = executing ? memFactor : STATE_NOTHING; if (mExecState != state) { if (mExecState != STATE_NOTHING) { Loading Loading @@ -687,6 +717,7 @@ public final class ProcessTracker { final Object mPendingWriteLock = new Object(); Parcel mPendingWrite; boolean mPendingWriteCommitted; long mLastWriteTime; State(File baseDir, ProcessTracker tracker) { Loading Loading @@ -718,28 +749,27 @@ public final class ProcessTracker { resetCommon(); long now = SystemClock.uptimeMillis(); ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); final int NPROC = procMap.size(); for (int ip=0; ip<NPROC; ip++) { for (int ip=procMap.size()-1; ip>=0; ip--) { SparseArray<ProcessState> uids = procMap.valueAt(ip); final int NUID = uids.size(); for (int iu=0; iu<NUID; iu++) { for (int iu=uids.size()-1; iu>=0; iu--) { uids.valueAt(iu).resetSafely(now); } } ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap(); final int NPKG = pkgMap.size(); for (int ip=0; ip<NPKG; ip++) { for (int ip=pkgMap.size()-1; ip>=0; ip--) { SparseArray<PackageState> uids = pkgMap.valueAt(ip); final int NUID = uids.size(); for (int iu=0; iu<NUID; iu++) { for (int iu=uids.size()-1; iu>=0; iu--) { PackageState pkgState = uids.valueAt(iu); final int NPROCS = pkgState.mProcesses.size(); for (int iproc=0; iproc<NPROCS; iproc++) { for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) { pkgState.mProcesses.valueAt(iproc).resetSafely(now); } final int NSRVS = pkgState.mServices.size(); for (int isvc=0; isvc<NSRVS; isvc++) { for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) { ServiceState ss = pkgState.mServices.valueAt(isvc); if (ss.isActive()) { pkgState.mServices.valueAt(isvc).resetSafely(now); } else { pkgState.mServices.removeAt(isvc); } } } } Loading @@ -756,9 +786,9 @@ public final class ProcessTracker { mLongs.add(new long[LONGS_SIZE]); mNextLong = 0; Arrays.fill(mMemFactorDurations, 0); mMemFactor = STATE_NOTHING; mStartTime = 0; mReadError = null; mFlags = 0; } private void buildTimePeriodStartClockStr() { Loading Loading @@ -852,30 +882,40 @@ public final class ProcessTracker { private void writeStateLocked(boolean sync, final boolean commit) { synchronized (mPendingWriteLock) { long now = SystemClock.uptimeMillis(); if (mPendingWrite == null || !mPendingWriteCommitted) { mPendingWrite = Parcel.obtain(); mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); if (commit) { mFlags |= State.FLAG_COMPLETE; } writeToParcel(mPendingWrite); mPendingWriteCommitted = commit; } if (commit) { resetSafely(); } else { mLastWriteTime = SystemClock.uptimeMillis(); } Slog.i(TAG, "Prepared write state in " + (SystemClock.uptimeMillis()-now) + "ms"); if (!sync) { BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { performWriteState(commit); performWriteState(); } }); return; } } performWriteState(commit); performWriteState(); } void performWriteState(boolean commit) { if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile() + " commit=" + commit); void performWriteState() { if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile()); Parcel data; synchronized (mPendingWriteLock) { data = mPendingWrite; mPendingWriteCommitted = false; if (data == null) { return; } Loading Loading @@ -903,9 +943,6 @@ public final class ProcessTracker { } } if (commit) { resetSafely(); } } void writeToParcel(Parcel out) { Loading Loading @@ -1438,11 +1475,13 @@ public final class ProcessTracker { } void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now) { long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, mStartTime, now); dumpFilteredSummaryLocked(pw, null, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, new int[] { STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_RECEIVER, STATE_HOME, STATE_LAST_ACTIVITY }, now, reqPackage); STATE_SERVICE, STATE_RECEIVER, STATE_HOME }, now, totalTime, reqPackage); pw.println(); pw.println("Run time Stats:"); dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now); Loading @@ -1461,7 +1500,8 @@ public final class ProcessTracker { } void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, int[] screenStates, int[] memStates, int[] procStates, long now, String reqPackage) { int[] screenStates, int[] memStates, int[] procStates, long now, long totalTime, String reqPackage) { ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates, procStates, now, reqPackage); if (procs.size() > 0) { Loading @@ -1469,7 +1509,8 @@ public final class ProcessTracker { pw.println(); pw.println(header); } dumpProcessSummary(pw, prefix, procs, screenStates, memStates, procStates, now); dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates, procStates, now, totalTime); } } Loading Loading @@ -1659,6 +1700,7 @@ public final class ProcessTracker { final PackageState as = mState.getPackageStateLocked(packageName, uid); ServiceState ss = as.mServices.get(className); if (ss != null) { ss.makeActive(); return ss; } ss = new ServiceState(); Loading @@ -1684,12 +1726,17 @@ public final class ProcessTracker { ArrayMap<String, ServiceState> services = pkg.mServices; for (int k=0; k<services.size(); k++) { ServiceState service = services.valueAt(k); if (service.isActive()) { if (service.mStartedState != STATE_NOTHING) { service.setStarted(true, memFactor, now); } if (service.mBoundState != STATE_NOTHING) { service.setBound(true, memFactor, now); } if (service.mExecState != STATE_NOTHING) { service.setExecuting(true, memFactor, now); } } } } } Loading @@ -1710,7 +1757,6 @@ public final class ProcessTracker { if (now > (mState.mLastWriteTime+WRITE_PERIOD)) { if (SystemClock.elapsedRealtime() > (mState.mTimePeriodStartRealtime+COMMIT_PERIOD)) { mCommitPending = true; mState.mFlags |= State.FLAG_COMPLETE; } return true; } Loading Loading @@ -1845,7 +1891,7 @@ public final class ProcessTracker { } } static void dumpSingleTime(PrintWriter pw, String prefix, long[] durations, static long dumpSingleTime(PrintWriter pw, String prefix, long[] durations, int curState, long curStartTime, long now) { long totalTime = 0; int printedScreen = -1; Loading @@ -1857,9 +1903,12 @@ public final class ProcessTracker { String running = ""; if (curState == state) { time += now - curStartTime; if (pw != null) { running = " (running)"; } } if (time != 0) { if (pw != null) { pw.print(prefix); printScreenLabel(pw, printedScreen != iscreen ? iscreen : STATE_NOTHING); Loading @@ -1867,17 +1916,19 @@ public final class ProcessTracker { printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING); printedMem = imem; TimeUtils.formatDuration(time, pw); pw.println(running); } totalTime += time; } } } if (totalTime != 0) { if (totalTime != 0 && pw != null) { pw.print(prefix); printScreenLabel(pw, STATE_NOTHING); pw.print("TOTAL: "); TimeUtils.formatDuration(totalTime, pw); pw.println(); } return totalTime; } static void dumpAdjTimesCheckin(PrintWriter pw, String sep, long[] durations, Loading Loading @@ -1934,8 +1985,16 @@ public final class ProcessTracker { procStates = _procStates; } void print(PrintWriter pw, boolean full) { TimeUtils.formatDuration(totalTime, pw); void print(PrintWriter pw, long overallTime, boolean full) { double percent = ((double)totalTime/(double)overallTime) * 100; if (percent < 1) { pw.print(String.format("%.2f", percent)); } else if (percent < 10) { pw.print(String.format("%.1f", percent)); } else { pw.print(String.format("%.0f", percent)); } pw.print("%"); if (numPss > 0) { pw.print(" ("); printSizeValue(pw, minPss * 1024); Loading Loading @@ -2230,7 +2289,7 @@ public final class ProcessTracker { static void dumpProcessSummaryDetails(PrintWriter pw, ProcessState proc, String prefix, String label, int[] screenStates, int[] memStates, int[] procStates, long now, boolean full) { long now, long totalTime, boolean full) { ProcessDataCollection totals = new ProcessDataCollection(screenStates, memStates, procStates); computeProcessData(proc, totals, now); Loading @@ -2241,15 +2300,16 @@ public final class ProcessTracker { if (label != null) { pw.print(label); } totals.print(pw, full); totals.print(pw, totalTime, full); if (prefix != null) { pw.println(); } } } static void dumpProcessSummary(PrintWriter pw, String prefix, ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates, long now) { static void dumpProcessSummaryLocked(PrintWriter pw, String prefix, ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates, long now, long totalTime) { for (int i=procs.size()-1; i>=0; i--) { ProcessState proc = procs.get(i); pw.print(prefix); Loading @@ -2259,30 +2319,30 @@ public final class ProcessTracker { UserHandle.formatUid(pw, proc.mUid); pw.println(":"); dumpProcessSummaryDetails(pw, proc, prefix, " TOTAL: ", screenStates, memStates, procStates, now, true); procStates, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Persistent: ", screenStates, memStates, new int[] { STATE_PERSISTENT }, now, true); new int[] { STATE_PERSISTENT }, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Top: ", screenStates, memStates, new int[] {STATE_TOP}, now, true); new int[] {STATE_TOP}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Imp Fg: ", screenStates, memStates, new int[] { STATE_IMPORTANT_FOREGROUND }, now, true); new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Imp Bg: ", screenStates, memStates, new int[] {STATE_IMPORTANT_BACKGROUND}, now, true); new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Backup: ", screenStates, memStates, new int[] {STATE_BACKUP}, now, true); new int[] {STATE_BACKUP}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Heavy Wgt: ", screenStates, memStates, new int[] {STATE_HEAVY_WEIGHT}, now, true); new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Service: ", screenStates, memStates, new int[] {STATE_SERVICE}, now, true); new int[] {STATE_SERVICE}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Receiver: ", screenStates, memStates, new int[] {STATE_RECEIVER}, now, true); new int[] {STATE_RECEIVER}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Home: ", screenStates, memStates, new int[] {STATE_HOME}, now, true); dumpProcessSummaryDetails(pw, proc, prefix, " Last Act: ", screenStates, memStates, new int[] {STATE_LAST_ACTIVITY}, now, true); new int[] {STATE_HOME}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " (Last Act): ", screenStates, memStates, new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " (Cached): ", screenStates, memStates, new int[] {STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY}, now, true); STATE_CACHED_EMPTY}, now, totalTime, true); } } Loading
services/java/com/android/server/am/ServiceRecord.java +13 −4 Original line number Diff line number Diff line Loading @@ -73,7 +73,6 @@ final class ServiceRecord extends Binder { final String dataDir; // where activity data should go final boolean exported; // from ServiceInfo.exported final Runnable restarter; // used to schedule retries of starting the service final ProcessTracker.ServiceState tracker; // tracking service execution, may be null final long createTime; // when this service was created final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); Loading @@ -84,6 +83,7 @@ final class ServiceRecord extends Binder { ProcessRecord app; // where this service is running or null. ProcessRecord isolatedProc; // keep track of isolated process, if requested ProcessTracker.ServiceState tracker; // tracking service execution, may be null boolean isForeground; // is service currently in foreground mode? int foregroundId; // Notification ID of last foreground req. Notification foregroundNoti; // Notification record of foreground state. Loading Loading @@ -282,8 +282,7 @@ final class ServiceRecord extends Binder { ServiceRecord(ActivityManagerService ams, BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter, ProcessTracker.ServiceState tracker) { Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter) { this.ams = ams; this.stats = servStats; this.name = name; Loading @@ -299,12 +298,22 @@ final class ServiceRecord extends Binder { dataDir = sInfo.applicationInfo.dataDir; exported = sInfo.exported; this.restarter = restarter; this.tracker = tracker; createTime = SystemClock.elapsedRealtime(); lastActivity = SystemClock.uptimeMillis(); userId = UserHandle.getUserId(appInfo.uid); } public ProcessTracker.ServiceState getTracker() { if (tracker != null) { return tracker; } if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { tracker = ams.mProcessTracker.getServiceStateLocked(serviceInfo.packageName, serviceInfo.applicationInfo.uid, serviceInfo.name); } return tracker; } public AppBindRecord retrieveAppBindingLocked(Intent intent, ProcessRecord app) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); Loading