diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 36f51fcca1f86..95dee019dfa93 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -2805,28 +2805,63 @@ public final class ActiveServices { /** * Prints a list of ServiceRecords (dumpsys activity services) */ - void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, - int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { - boolean needSep = false; - boolean printedAnything = false; - - ItemMatcher matcher = new ItemMatcher(); - matcher.build(args, opti); - - pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); - try { - if (mLastAnrDump != null) { - pw.println(" Last ANR service:"); - pw.print(mLastAnrDump); - pw.println(); + List collectServicesToDumpLocked(ItemMatcher matcher, String dumpPackage) { + final ArrayList services = new ArrayList<>(); + final int[] users = mAm.mUserController.getUsers(); + for (int user : users) { + ServiceMap smap = getServiceMap(user); + if (smap.mServicesByName.size() > 0) { + for (int si=0; si services = new ArrayList<>(); + + private final long nowReal = SystemClock.elapsedRealtime(); + + private boolean needSep = false; + private boolean printedAnything = false; + private boolean printed = false; + + /** + * Note: do not call directly, use {@link #newServiceDumperLocked} instead (this + * must be called with the lock held). + */ + ServiceDumper(FileDescriptor fd, PrintWriter pw, String[] args, + int opti, boolean dumpAll, String dumpPackage) { + this.fd = fd; + this.pw = pw; + this.args = args; + this.opti = opti; + this.dumpAll = dumpAll; + this.dumpPackage = dumpPackage; + matcher = new ItemMatcher(); + matcher.build(args, opti); + + final int[] users = mAm.mUserController.getUsers(); for (int user : users) { ServiceMap smap = getServiceMap(user); - boolean printed = false; if (smap.mServicesByName.size() > 0) { - long nowReal = SystemClock.elapsedRealtime(); - needSep = false; for (int si=0; si clist = r.connections.valueAt(conni); - for (int i = 0; i < clist.size(); i++) { - ConnectionRecord conn = clist.get(i); - pw.print(" "); - pw.print(conn.binding.intent.intent.getIntent() - .toShortString(false, false, false, false)); - pw.print(" -> "); - ProcessRecord proc = conn.binding.client; - pw.println(proc != null ? proc.toShortString() : "null"); - } - } + needSep |= printed; + } + + dumpUserRemainsLocked(user); + } + } catch (Exception e) { + Slog.w(TAG, "Exception in dumpServicesLocked", e); + } + + dumpRemainsLocked(); + } + + void dumpWithClient() { + synchronized(mAm) { + dumpHeaderLocked(); + } + + try { + int[] users = mAm.mUserController.getUsers(); + for (int user : users) { + // Find the first service for this user. + int serviceIdx = 0; + while (serviceIdx < services.size() && services.get(serviceIdx).userId != user) { + serviceIdx++; + } + printed = false; + if (serviceIdx < services.size()) { + needSep = false; + while (serviceIdx < services.size()) { + ServiceRecord r = services.get(serviceIdx); + serviceIdx++; + if (r.userId != user) { + break; } - } - if (dumpClient && r.app != null && r.app.thread != null) { - pw.println(" Client:"); - pw.flush(); - try { - TransferPipe tp = new TransferPipe(); - try { - r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), - r, args); - tp.setBufferPrefix(" "); - // Short timeout, since blocking here can - // deadlock with the application. - tp.go(fd, 2000); - } finally { - tp.kill(); - } - } catch (IOException e) { - pw.println(" Failure while dumping the service: " + e); - } catch (RemoteException e) { - pw.println(" Got a RemoteException while dumping the service"); + synchronized(mAm) { + dumpServiceLocalLocked(r); } - needSep = true; + dumpServiceClient(r); + } + needSep |= printed; + } + + synchronized(mAm) { + dumpUserRemainsLocked(user); + } + } + } catch (Exception e) { + Slog.w(TAG, "Exception in dumpServicesLocked", e); + } + + synchronized(mAm) { + dumpRemainsLocked(); + } + } + + private void dumpUserHeaderLocked(int user) { + if (!printed) { + if (printedAnything) { + pw.println(); + } + pw.println(" User " + user + " active services:"); + printed = true; + } + printedAnything = true; + if (needSep) { + pw.println(); + } + } + + private void dumpServiceLocalLocked(ServiceRecord r) { + dumpUserHeaderLocked(r.userId); + pw.print(" * "); + pw.println(r); + if (dumpAll) { + r.dump(pw, " "); + needSep = true; + } else { + pw.print(" app="); + pw.println(r.app); + pw.print(" created="); + TimeUtils.formatDuration(r.createTime, nowReal, pw); + pw.print(" started="); + pw.print(r.startRequested); + pw.print(" connections="); + pw.println(r.connections.size()); + if (r.connections.size() > 0) { + pw.println(" Connections:"); + for (int conni=0; conni clist = r.connections.valueAt(conni); + for (int i = 0; i < clist.size(); i++) { + ConnectionRecord conn = clist.get(i); + pw.print(" "); + pw.print(conn.binding.intent.intent.getIntent() + .toShortString(false, false, false, false)); + pw.print(" -> "); + ProcessRecord proc = conn.binding.client; + pw.println(proc != null ? proc.toShortString() : "null"); } } - needSep |= printed; } + } + } + + private void dumpServiceClient(ServiceRecord r) { + final ProcessRecord proc = r.app; + if (proc == null) { + return; + } + final IApplicationThread thread = proc.thread; + if (thread == null) { + return; + } + pw.println(" Client:"); + pw.flush(); + try { + TransferPipe tp = new TransferPipe(); + try { + thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); + tp.setBufferPrefix(" "); + // Short timeout, since blocking here can + // deadlock with the application. + tp.go(fd, 2000); + } finally { + tp.kill(); + } + } catch (IOException e) { + pw.println(" Failure while dumping the service: " + e); + } catch (RemoteException e) { + pw.println(" Got a RemoteException while dumping the service"); + } + needSep = true; + } + + private void dumpUserRemainsLocked(int user) { + ServiceMap smap = getServiceMap(user); + printed = false; + for (int si=0, SN=smap.mDelayedStartList.size(); si 0) { printed = false; - for (int si=0, SN=smap.mDelayedStartList.size(); si 0) { - boolean printed = false; - for (int i=0; i 0) { - boolean printed = false; - for (int i=0; i 0) { - boolean printed = false; - for (int i=0; i< mDestroyingServices.size(); i++) { - ServiceRecord r = mDestroyingServices.get(i); - if (!matcher.match(r, r.name)) { - continue; - } - if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { - continue; - } - printedAnything = true; - if (!printed) { - if (needSep) pw.println(); - needSep = true; - pw.println(" Destroying services:"); - printed = true; - } - pw.print(" * Destroy "); pw.println(r); - r.dump(pw, " "); - } - needSep = true; - } - - if (dumpAll) { - boolean printed = false; - for (int ic=0; ic r = mServiceConnections.valueAt(ic); - for (int i=0; i 0) { + printed = false; + for (int i=0; i 0) { + printed = false; + for (int i=0; i< mDestroyingServices.size(); i++) { + ServiceRecord r = mDestroyingServices.get(i); + if (!matcher.match(r, r.name)) { + continue; + } + if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { + continue; + } + printedAnything = true; + if (!printed) { + if (needSep) pw.println(); + needSep = true; + pw.println(" Destroying services:"); + printed = true; + } + pw.print(" * Destroy "); pw.println(r); + r.dump(pw, " "); + } + needSep = true; + } + + if (dumpAll) { + printed = false; + for (int ic=0; ic r = mServiceConnections.valueAt(ic); + for (int i=0; i 0) { + if (dumpClient) { + ActiveServices.ServiceDumper sdumper; + synchronized (this) { + dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } - dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); + dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, + dumpPackage); } + sdumper.dumpWithClient(); pw.println(); - if (dumpAll) { - pw.println("-------------------------------------------------------------------------------"); + synchronized (this) { + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); + if (mAssociations.size() > 0) { + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); + } + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); + } + + } else { + synchronized (this) { + dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage) + .dumpLocked(); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); + if (mAssociations.size() > 0) { + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); + } + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } + dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); } - dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); } Binder.restoreCallingIdentity(origId); } @@ -16175,8 +16240,8 @@ public final class ActivityManagerService extends ActivityManagerNative catPw.println(); dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); catPw.println(); - mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, - false, false, null); + mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, + false, null).dumpLocked(); catPw.println(); dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); catPw.flush();