diff options
Diffstat (limited to 'services/java')
5 files changed, 90 insertions, 43 deletions
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 @@ public final class ActiveServices { if (!mRestartingServices.contains(r)) { r.createdFromFg = false; mRestartingServices.add(r); + r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now); } r.cancelNotification(); @@ -1220,6 +1221,9 @@ public final class ActiveServices { 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 @@ public final class ActiveServices { // 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 @@ public final class ActiveServices { } 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 @@ public final class ActiveServices { + 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 @@ public final class ActiveServices { r.tracker = null; } } + if (finishing) { + r.app = null; + } } } @@ -1960,8 +1969,7 @@ public final class ActiveServices { } } - 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 @@ public final class ActiveServices { } } - // 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 @@ public final class ActiveServices { 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 @@ public final class ActiveServices { 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 @@ public final class ActivityManagerService extends ActivityManagerNative boolean dumpDalvik = false; boolean oomOnly = false; boolean isCompact = false; + boolean localOnly = false; int opti = 0; while (opti < args.length) { @@ -11919,12 +11920,15 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ import java.io.PrintWriter; */ 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 @@ public final class ProcessStatsService extends IProcessStats.Stub { 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 @@ public final class ProcessStatsService extends IProcessStats.Stub { } 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 @@ public final class ProcessStatsService extends IProcessStats.Stub { } } 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 @@ public final class ProcessStatsService extends IProcessStats.Stub { } 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 @@ final class ServiceRecord extends Binder { 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 @@ 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, ProcessRecord app) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); |