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