Merge "Fix issue #11223338: Not retaining service started state while restarting" into klp-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index bb04063..7ca3459 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2272,9 +2272,12 @@
public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new FastPrintWriter(fout);
- dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] { "package", packageName });
+ dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] {
+ "-a", "package", packageName });
pw.println();
- dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
+ dumpService(pw, fd, "meminfo", new String[] { "--local", packageName });
+ pw.println();
+ dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { "-a", packageName });
pw.println();
dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
pw.println();
@@ -2296,7 +2299,7 @@
pw.flush();
tp = new TransferPipe();
tp.setBufferPrefix(" ");
- service.dump(tp.getWriteFd().getFileDescriptor(), args);
+ service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
tp.go(fd);
} catch (Throwable e) {
if (tp != null) {
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index 20b8c95..0cad33c 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1758,21 +1758,34 @@
mStartTime, now);
ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
boolean printedHeader = false;
+ boolean sepNeeded = false;
for (int ip=0; ip<pkgMap.size(); ip++) {
- String pkgName = pkgMap.keyAt(ip);
- if (reqPackage != null && !reqPackage.equals(pkgName)) {
- continue;
- }
- SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+ final String pkgName = pkgMap.keyAt(ip);
+ final SparseArray<PackageState> uids = pkgMap.valueAt(ip);
for (int iu=0; iu<uids.size(); iu++) {
- int uid = uids.keyAt(iu);
- PackageState pkgState = uids.valueAt(iu);
+ final int uid = uids.keyAt(iu);
+ final PackageState pkgState = uids.valueAt(iu);
final int NPROCS = pkgState.mProcesses.size();
final int NSRVS = pkgState.mServices.size();
+ final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+ if (!pkgMatch) {
+ boolean procMatch = false;
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (reqPackage.equals(proc.mName)) {
+ procMatch = true;
+ break;
+ }
+ }
+ if (!procMatch) {
+ continue;
+ }
+ }
if (NPROCS > 0 || NSRVS > 0) {
if (!printedHeader) {
pw.println("Per-Package Stats:");
printedHeader = true;
+ sepNeeded = true;
}
pw.print(" * "); pw.print(pkgName); pw.print(" / ");
UserHandle.formatUid(pw, uid); pw.println(":");
@@ -1780,6 +1793,9 @@
if (!dumpSummary || dumpAll) {
for (int iproc=0; iproc<NPROCS; iproc++) {
ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+ continue;
+ }
if (activeOnly && !proc.isInUse()) {
pw.print(" (Not active: ");
pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
@@ -1787,7 +1803,11 @@
}
pw.print(" Process ");
pw.print(pkgState.mProcesses.keyAt(iproc));
- pw.print(" (");
+ if (proc.mCommonProcess.mMultiPackage) {
+ pw.print(" (multi, ");
+ } else {
+ pw.print(" (unique, ");
+ }
pw.print(proc.mDurationsTableSize);
pw.print(" entries)");
pw.println(":");
@@ -1801,6 +1821,9 @@
ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
for (int iproc=0; iproc<NPROCS; iproc++) {
ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+ if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+ continue;
+ }
if (activeOnly && !proc.isInUse()) {
continue;
}
@@ -1811,6 +1834,9 @@
}
for (int isvc=0; isvc<NSRVS; isvc++) {
ServiceState svc = pkgState.mServices.valueAt(isvc);
+ if (!pkgMatch && !reqPackage.equals(svc.mProcessName)) {
+ continue;
+ }
if (activeOnly && !svc.isInUse()) {
pw.print(" (Not active: ");
pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
@@ -1840,64 +1866,73 @@
if (svc.mOwner != null) {
pw.print(" mOwner="); pw.println(svc.mOwner);
}
+ if (svc.mStarted || svc.mRestarting) {
+ pw.print(" mStarted="); pw.print(svc.mStarted);
+ pw.print(" mRestarting="); pw.println(svc.mRestarting);
+ }
}
}
}
}
- if (reqPackage == null) {
- ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
- printedHeader = false;
- int numShownProcs = 0, numTotalProcs = 0;
- for (int ip=0; ip<procMap.size(); ip++) {
- String procName = procMap.keyAt(ip);
- SparseArray<ProcessState> uids = procMap.valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- int uid = uids.keyAt(iu);
- numTotalProcs++;
- ProcessState proc = uids.valueAt(iu);
- if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
- && proc.mPssTableSize == 0) {
- continue;
- }
- numShownProcs++;
- if (!printedHeader) {
- pw.println();
- pw.println("Per-Process Stats:");
- printedHeader = true;
- }
- if (activeOnly && !proc.isInUse()) {
- pw.print(" (Not active: "); pw.print(procName); pw.println(")");
- continue;
- }
- pw.print(" * "); pw.print(procName); pw.print(" / ");
- UserHandle.formatUid(pw, uid);
- pw.print(" ("); pw.print(proc.mDurationsTableSize);
- pw.print(" entries)"); pw.println(":");
- dumpProcessState(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES, now);
- dumpProcessPss(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES);
- if (dumpAll) {
- dumpProcessInternalLocked(pw, " ", proc, dumpAll);
- }
+ ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ printedHeader = false;
+ int numShownProcs = 0, numTotalProcs = 0;
+ for (int ip=0; ip<procMap.size(); ip++) {
+ String procName = procMap.keyAt(ip);
+ SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ int uid = uids.keyAt(iu);
+ numTotalProcs++;
+ ProcessState proc = uids.valueAt(iu);
+ if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
+ && proc.mPssTableSize == 0) {
+ continue;
}
+ if (!proc.mMultiPackage) {
+ continue;
+ }
+ if (reqPackage != null && !reqPackage.equals(procName)
+ && !reqPackage.equals(proc.mPackage)) {
+ continue;
+ }
+ numShownProcs++;
+ if (sepNeeded) {
+ pw.println();
+ }
+ sepNeeded = true;
+ if (!printedHeader) {
+ pw.println("Multi-Package Common Processes:");
+ printedHeader = true;
+ }
+ if (activeOnly && !proc.isInUse()) {
+ pw.print(" (Not active: "); pw.print(procName); pw.println(")");
+ continue;
+ }
+ pw.print(" * "); pw.print(procName); pw.print(" / ");
+ UserHandle.formatUid(pw, uid);
+ pw.print(" ("); pw.print(proc.mDurationsTableSize);
+ pw.print(" entries)"); pw.println(":");
+ dumpProcessState(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+ ALL_PROC_STATES, now);
+ dumpProcessPss(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+ ALL_PROC_STATES);
+ dumpProcessInternalLocked(pw, " ", proc, dumpAll);
}
- if (dumpAll) {
- pw.println();
- pw.print(" Total procs: "); pw.print(numShownProcs);
- pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
- }
+ }
+ if (dumpAll) {
+ pw.println();
+ pw.print(" Total procs: "); pw.print(numShownProcs);
+ pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
+ }
+ if (sepNeeded) {
pw.println();
- if (dumpSummary) {
- pw.println("Summary:");
- dumpSummaryLocked(pw, reqPackage, now, activeOnly);
- } else {
- dumpTotalsLocked(pw, now);
- }
+ }
+ if (dumpSummary) {
+ pw.println("Summary:");
+ dumpSummaryLocked(pw, reqPackage, now, activeOnly);
} else {
- pw.println();
dumpTotalsLocked(pw, now);
}
@@ -2031,17 +2066,20 @@
public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
int[] procStates, int sortProcStates[], long now, String reqPackage,
boolean activeOnly) {
- ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
- ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+ final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
+ final ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
for (int ip=0; ip<pkgMap.size(); ip++) {
- if (reqPackage != null && !reqPackage.equals(pkgMap.keyAt(ip))) {
- continue;
- }
- SparseArray<PackageState> procs = pkgMap.valueAt(ip);
+ final String pkgName = pkgMap.keyAt(ip);
+ final SparseArray<PackageState> procs = pkgMap.valueAt(ip);
for (int iu=0; iu<procs.size(); iu++) {
- PackageState state = procs.valueAt(iu);
- for (int iproc=0; iproc<state.mProcesses.size(); iproc++) {
- ProcessState proc = state.mProcesses.valueAt(iproc);
+ final PackageState state = procs.valueAt(iu);
+ final int NPROCS = state.mProcesses.size();
+ final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+ for (int iproc=0; iproc<NPROCS; iproc++) {
+ final ProcessState proc = state.mProcesses.valueAt(iproc);
+ if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+ continue;
+ }
if (activeOnly && !proc.isInUse()) {
continue;
}
@@ -2601,23 +2639,35 @@
}
}
- void incStartedServices(int memFactor, long now) {
+ void incStartedServices(int memFactor, long now, String serviceName) {
+ if (false) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.d(TAG, "incStartedServices: " + this + " service=" + serviceName
+ + " to " + (mNumStartedServices+1), here);
+ }
if (mCommonProcess != this) {
- mCommonProcess.incStartedServices(memFactor, now);
+ mCommonProcess.incStartedServices(memFactor, now, serviceName);
}
mNumStartedServices++;
if (mNumStartedServices == 1 && mCurState == STATE_NOTHING) {
- setState(STATE_NOTHING, memFactor, now, null);
+ setState(STATE_SERVICE_RESTARTING + (memFactor*STATE_COUNT), now);
}
}
- void decStartedServices(int memFactor, long now) {
+ void decStartedServices(int memFactor, long now, String serviceName) {
+ if (false) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
+ + " to " + (mNumStartedServices-1), here);
+ }
if (mCommonProcess != this) {
- mCommonProcess.decStartedServices(memFactor, now);
+ mCommonProcess.decStartedServices(memFactor, now, serviceName);
}
mNumStartedServices--;
- if (mNumStartedServices == 0 && mCurState == STATE_SERVICE_RESTARTING) {
- setState(STATE_NOTHING, memFactor, now, null);
+ if (mNumStartedServices == 0 && (mCurState%STATE_COUNT) == STATE_SERVICE_RESTARTING) {
+ setState(STATE_NOTHING, now);
} else if (mNumStartedServices < 0) {
Slog.wtfStack(TAG, "Proc started services underrun: pkg="
+ mPackage + " uid=" + mUid + " name=" + mName);
@@ -2873,6 +2923,8 @@
public int mRunState = STATE_NOTHING;
long mRunStartTime;
+ boolean mStarted;
+ boolean mRestarting;
int mStartedCount;
public int mStartedState = STATE_NOTHING;
long mStartedStartTime;
@@ -2902,10 +2954,9 @@
// There was already an old owner, reset this object for its
// new owner.
mOwner = newOwner;
- if (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
- || mExecState != STATE_NOTHING) {
+ if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
long now = SystemClock.uptimeMillis();
- if (mStartedState != STATE_NOTHING) {
+ if (mStarted) {
if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
+ " from " + mOwner + " while started: pkg="
+ mPackage + " service=" + mName + " proc=" + mProc);
@@ -2931,10 +2982,9 @@
public void clearCurrentOwner(Object owner, boolean silently) {
if (mOwner == owner) {
mProc.decActiveServices(mName);
- if (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
- || mExecState != STATE_NOTHING) {
+ if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
long now = SystemClock.uptimeMillis();
- if (mStartedState != STATE_NOTHING) {
+ if (mStarted) {
if (!silently) {
Slog.wtfStack(TAG, "Service owner " + owner
+ " cleared while started: pkg=" + mPackage + " service="
@@ -3042,7 +3092,18 @@
if (mOwner == null) {
Slog.wtf(TAG, "Starting service " + this + " without owner");
}
+ mStarted = started;
+ updateStartedState(memFactor, now);
+ }
+
+ public void setRestarting(boolean restarting, int memFactor, long now) {
+ mRestarting = restarting;
+ updateStartedState(memFactor, now);
+ }
+
+ void updateStartedState(int memFactor, long now) {
final boolean wasStarted = mStartedState != STATE_NOTHING;
+ final boolean started = mStarted || mRestarting;
final int state = started ? memFactor : STATE_NOTHING;
if (mStartedState != state) {
if (mStartedState != STATE_NOTHING) {
@@ -3056,9 +3117,9 @@
mProc = mProc.pullFixedProc(mPackage);
if (wasStarted != started) {
if (started) {
- mProc.incStartedServices(memFactor, now);
+ mProc.incStartedServices(memFactor, now, mName);
} else {
- mProc.decStartedServices(memFactor, now);
+ mProc.decStartedServices(memFactor, now, mName);
}
}
updateRunning(memFactor, now);
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index ea0b978a..5476fde 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -1187,6 +1187,7 @@
if (!mRestartingServices.contains(r)) {
r.createdFromFg = false;
mRestartingServices.add(r);
+ r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
}
r.cancelNotification();
@@ -1220,6 +1221,9 @@
if (removed || callingUid != r.appInfo.uid) {
r.resetRestartCounter();
}
+ if (removed) {
+ r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis());
+ }
mAm.mHandler.removeCallbacks(r.restarter);
return true;
}
@@ -1243,7 +1247,9 @@
// We are now bringing the service up, so no longer in the
// restarting state.
- mRestartingServices.remove(r);
+ if (mRestartingServices.remove(r)) {
+ r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis());
+ }
// Make sure this service is no longer considered delayed, we are starting it now.
if (r.delayed) {
@@ -1581,6 +1587,7 @@
}
r.app.services.remove(r);
if (r.app.thread != null) {
+ updateServiceForegroundLocked(r.app, false);
try {
bumpServiceExecutingLocked(r, false, "destroy");
mDestroyingServices.add(r);
@@ -1591,7 +1598,6 @@
+ r.shortName, e);
serviceProcessGoneLocked(r);
}
- updateServiceForegroundLocked(r.app, false);
} else {
if (DEBUG_SERVICE) Slog.v(
TAG, "Removed service that has no process: " + r);
@@ -1816,6 +1822,9 @@
r.tracker = null;
}
}
+ if (finishing) {
+ r.app = null;
+ }
}
}
@@ -1960,8 +1969,7 @@
}
}
- final void killServicesLocked(ProcessRecord app,
- boolean allowRestart) {
+ final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
// Report disconnected services.
if (false) {
// XXX we are letting the client link to the service for
@@ -1990,16 +1998,8 @@
}
}
- // Clean up any connections this application has to other services.
- for (int i=app.connections.size()-1; i>=0; i--) {
- ConnectionRecord r = app.connections.valueAt(i);
- removeConnectionLocked(r, app, null);
- }
- app.connections.clear();
-
+ // First clear app state from services.
for (int i=app.services.size()-1; i>=0; i--) {
- // Any services running in the application need to be placed
- // back in the pending list.
ServiceRecord sr = app.services.valueAt(i);
synchronized (sr.stats.getBatteryStats()) {
sr.stats.stopLaunchedLocked();
@@ -2020,8 +2020,21 @@
b.binder = null;
b.requested = b.received = b.hasBound = false;
}
+ }
- if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
+ // Clean up any connections this application has to other services.
+ for (int i=app.connections.size()-1; i>=0; i--) {
+ ConnectionRecord r = app.connections.valueAt(i);
+ removeConnectionLocked(r, app, null);
+ }
+ app.connections.clear();
+
+ // Now do remaining service cleanup.
+ for (int i=app.services.size()-1; i>=0; i--) {
+ // Any services running in the application may need to be placed
+ // back in the pending list.
+ ServiceRecord sr = app.services.valueAt(i);
+ if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
&ApplicationInfo.FLAG_PERSISTENT) == 0) {
Slog.w(TAG, "Service crashed " + sr.crashCount
+ " times, stopping: " + sr);
@@ -2054,6 +2067,17 @@
if (!allowRestart) {
app.services.clear();
+
+ // Make sure there are no more restarting services for this process.
+ for (int i=mRestartingServices.size()-1; i>=0; i--) {
+ ServiceRecord r = mRestartingServices.get(i);
+ if (r.processName.equals(app.processName) &&
+ r.serviceInfo.applicationInfo.uid == app.info.uid) {
+ mRestartingServices.remove(i);
+ r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(),
+ SystemClock.uptimeMillis());
+ }
+ }
}
// Make sure we have no more records on the stopping list.
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 164e7b7..fe83e9f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -11901,6 +11901,7 @@
boolean dumpDalvik = false;
boolean oomOnly = false;
boolean isCompact = false;
+ boolean localOnly = false;
int opti = 0;
while (opti < args.length) {
@@ -11919,12 +11920,15 @@
isCompact = true;
} else if ("--oom".equals(opt)) {
oomOnly = true;
+ } else if ("--local".equals(opt)) {
+ localOnly = true;
} else if ("-h".equals(opt)) {
pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
pw.println(" -a: include all available information for each process.");
pw.println(" -d: include dalvik details when dumping process details.");
pw.println(" -c: dump in a compact machine-parseable representation.");
pw.println(" --oom: only show processes organized by oom adj.");
+ pw.println(" --local: only collect details locally, don't call process.");
pw.println("If [process] is specified it can be the name or ");
pw.println("pid of a specific process to dump.");
return;
@@ -12041,14 +12045,22 @@
mi.dalvikPrivateDirty = (int)tmpLong[0];
}
if (dumpDetails) {
- try {
- pw.flush();
- thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
- dumpDalvik, innerArgs);
- } catch (RemoteException e) {
- if (!isCheckinRequest) {
- pw.println("Got RemoteException!");
+ if (localOnly) {
+ ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
+ dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
+ if (isCheckinRequest) {
+ pw.println();
+ }
+ } else {
+ try {
pw.flush();
+ thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
+ dumpDalvik, innerArgs);
+ } catch (RemoteException e) {
+ if (!isCheckinRequest) {
+ pw.println("Got RemoteException!");
+ pw.flush();
+ }
}
}
}
diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/java/com/android/server/am/ConnectionRecord.java
index 576adc2..423e540 100644
--- a/services/java/com/android/server/am/ConnectionRecord.java
+++ b/services/java/com/android/server/am/ConnectionRecord.java
@@ -27,7 +27,7 @@
*/
final class ConnectionRecord {
final AppBindRecord binding; // The application/service binding.
- final ActivityRecord activity; // If non-null, the owning activity.
+ final ActivityRecord activity; // If non-null, the owning activity.
final IServiceConnection conn; // The client connection.
final int flags; // Binding options.
final int clientLabel; // String resource labeling this client.
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index 8d16880..e05fcda 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -750,23 +750,12 @@
return;
} else {
// Not an option, last argument must be a package name.
- try {
- IPackageManager pm = AppGlobals.getPackageManager();
- if (pm.getPackageUid(arg, UserHandle.getCallingUserId()) >= 0) {
- reqPackage = arg;
- // Include all details, since we know we are only going to
- // be dumping a smaller set of data. In fact only the details
- // container per-package data, so that are needed to be able
- // to dump anything at all when filtering by package.
- dumpDetails = true;
- }
- } catch (RemoteException e) {
- }
- if (reqPackage == null) {
- pw.println("Unknown package: " + arg);
- dumpHelp(pw);
- return;
- }
+ reqPackage = arg;
+ // Include all details, since we know we are only going to
+ // be dumping a smaller set of data. In fact only the details
+ // container per-package data, so that are needed to be able
+ // to dump anything at all when filtering by package.
+ dumpDetails = true;
}
}
}
@@ -816,13 +805,14 @@
}
return;
} else if (aggregateHours != 0) {
+ pw.print("AGGREGATED OVER LAST "); pw.print(aggregateHours); pw.println(" HOURS:");
dumpAggregatedStats(pw, aggregateHours, now, reqPackage, isCompact,
dumpDetails, dumpFullDetails, dumpAll, activeOnly);
return;
}
boolean sepNeeded = false;
- if (!currentOnly || isCheckin) {
+ if (dumpAll || isCheckin) {
mWriteLock.lock();
try {
ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
@@ -882,11 +872,11 @@
}
}
if (!isCheckin) {
- if (dumpAll) {
+ if (!currentOnly) {
if (sepNeeded) {
pw.println();
- pw.println("AGGREGATED OVER LAST 24 HOURS:");
}
+ pw.println("AGGREGATED OVER LAST 24 HOURS:");
dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
dumpDetails, dumpFullDetails, dumpAll, activeOnly);
pw.println();
@@ -901,8 +891,8 @@
} else {
if (sepNeeded) {
pw.println();
- pw.println("CURRENT STATS:");
}
+ pw.println("CURRENT STATS:");
if (dumpDetails || dumpFullDetails) {
mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll,
activeOnly);
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index cc1172a..84b1c3a 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -85,6 +85,7 @@
ProcessRecord app; // where this service is running or null.
ProcessRecord isolatedProc; // keep track of isolated process, if requested
ProcessStats.ServiceState tracker; // tracking service execution, may be null
+ ProcessStats.ServiceState restartTracker; // tracking service restart
boolean delayed; // are we waiting to start this service in the background?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
@@ -340,6 +341,26 @@
}
}
+ public void makeRestarting(int memFactor, long now) {
+ if (restartTracker == null) {
+ if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
+ restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
+ serviceInfo.applicationInfo.uid, serviceInfo.processName, serviceInfo.name);
+ }
+ if (restartTracker == null) {
+ return;
+ }
+ }
+ restartTracker.setRestarting(true, memFactor, now);
+ }
+
+ public void clearRestarting(int memFactor, long now) {
+ if (restartTracker != null) {
+ restartTracker.setRestarting(false, memFactor, now);
+ restartTracker = null;
+ }
+ }
+
public AppBindRecord retrieveAppBindingLocked(Intent intent,
ProcessRecord app) {
Intent.FilterComparison filter = new Intent.FilterComparison(intent);