アクティビティのスタックのダンプ(dump activity stack)
>adb shell dumpsys activity > activity.log
# ダンプログ出力元クラスは下記
# com.android.server.am.ActivityManagerService.dumpHistoryList
# (FileDescriptor, PrintWriter, List, String, String, boolean, boolean, boolean, String)
>adb shell dumpsys activity -h Activity manager dump options: [-a] [-c] [-h] [cmd] ... cmd may be one of: a[ctivities]: activity stack state b[roadcasts] [PACKAGE_NAME]: broadcast state i[ntents] [PACKAGE_NAME]: pending intent state p[rocesses] [PACKAGE_NAME]: process state o[om]: out of memory management prov[iders] [COMP_SPEC ...]: content provider state provider [COMP_SPEC]: provider client-side state s[ervices] [COMP_SPEC ...]: service state service [COMP_SPEC]: service client-side state package [PACKAGE_NAME]: all state related to given package all: dump all activities top: dump the top activity cmd may also be a COMP_SPEC to dump activities. COMP_SPEC may be a component name (com.foo/.myApp), a partial substring in a component name, a hex object identifier. -a: include all available server state. -c: include client state.
8565 @Override 8566 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8567 if (checkCallingPermission(android.Manifest.permission.DUMP) 8568 != PackageManager.PERMISSION_GRANTED) { 8569 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8570 + Binder.getCallingPid() 8571 + ", uid=" + Binder.getCallingUid() 8572 + " without permission " 8573 + android.Manifest.permission.DUMP); 8574 return; 8575 } 8576 8577 boolean dumpAll = false; 8578 boolean dumpClient = false; 8579 String dumpPackage = null; 8580 8581 int opti = 0; 8582 while (opti < args.length) { 8583 String opt = args[opti]; 8584 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8585 break; 8586 } 8587 opti++; 8588 if ("-a".equals(opt)) { 8589 dumpAll = true; 8590 } else if ("-c".equals(opt)) { 8591 dumpClient = true; 8592 } else if ("-h".equals(opt)) { 8593 pw.println("Activity manager dump options:"); 8594 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8595 pw.println(" cmd may be one of:"); 8596 pw.println(" a[ctivities]: activity stack state"); 8597 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8598 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8599 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8600 pw.println(" o[om]: out of memory management"); 8601 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8602 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8603 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8604 pw.println(" service [COMP_SPEC]: service client-side state"); 8605 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8606 pw.println(" all: dump all activities"); 8607 pw.println(" top: dump the top activity"); 8608 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8609 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8610 pw.println(" a partial substring in a component name, a"); 8611 pw.println(" hex object identifier."); 8612 pw.println(" -a: include all available server state."); 8613 pw.println(" -c: include client state."); 8614 return; 8615 } else { 8616 pw.println("Unknown argument: " + opt + "; use -h for help"); 8617 } 8618 } 8619 8620 long origId = Binder.clearCallingIdentity(); 8621 boolean more = false; 8622 // Is the caller requesting to dump a particular piece of data? 8623 if (opti < args.length) { 8624 String cmd = args[opti]; 8625 opti++; 8626 if ("activities".equals(cmd) || "a".equals(cmd)) { 8627 synchronized (this) { 8628 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); <====== ここ 8629 } 8630 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
ActivityManagerServiceのmMainStackにアクセスできるのかな?
160 public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 279 public ActivityStack mMainStack;
8794 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8795 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8796 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8797 pw.println(" Main stack:"); 8798 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8799 dumpPackage); 8800 pw.println(" "); 8801 pw.println(" Running activities (most recent first):"); 8802 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8803 dumpPackage); 8804 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8805 pw.println(" "); 8806 pw.println(" Activities waiting for another to become visible:"); 8807 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8808 !dumpAll, false, dumpPackage); 8809 } 8810 if (mMainStack.mStoppingActivities.size() > 0) { 8811 pw.println(" "); 8812 pw.println(" Activities waiting to stop:"); 8813 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8814 !dumpAll, false, dumpPackage); 8815 } 8816 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8817 pw.println(" "); 8818 pw.println(" Activities waiting to sleep:"); 8819 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8820 !dumpAll, false, dumpPackage); 8821 } 8822 if (mMainStack.mFinishingActivities.size() > 0) { 8823 pw.println(" "); 8824 pw.println(" Activities waiting to finish:"); 8825 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8826 !dumpAll, false, dumpPackage); 8827 } 8828 8829 pw.println(" "); 8830 if (mMainStack.mPausingActivity != null) { 8831 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8832 } 8833 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8834 pw.println(" mFocusedActivity: " + mFocusedActivity); 8835 if (dumpAll) { 8836 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8837 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8838 pw.println(" mDismissKeyguardOnNextActivity: " 8839 + mMainStack.mDismissKeyguardOnNextActivity); 8840 } 8841 8842 if (mRecentTasks.size() > 0) { 8843 pw.println(); 8844 pw.println(" Recent tasks:"); 8845 8846 final int N = mRecentTasks.size(); 8847 for (int i=0; i<N; i++) { 8848 TaskRecord tr = mRecentTasks.get(i); 8849 if (dumpPackage != null) { 8850 if (tr.realActivity == null || 8851 !dumpPackage.equals(tr.realActivity)) { 8852 continue; 8853 } 8854 } 8855 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8856 pw.println(tr); 8857 if (dumpAll) { 8858 mRecentTasks.get(i).dump(pw, " "); 8859 } 8860 } 8861 } 8862 8863 if (dumpAll) { 8864 pw.println(" "); 8865 pw.println(" mCurTask: " + mCurTask); 8866 } 8867 8868 return true; 8869 }
9879 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9880 String prefix, String label, boolean complete, boolean brief, boolean client, 9881 String dumpPackage) { 9882 TaskRecord lastTask = null; 9883 boolean needNL = false; 9884 final String innerPrefix = prefix + " "; 9885 final String[] args = new String[0]; 9886 for (int i=list.size()-1; i>=0; i--) { 9887 final ActivityRecord r = (ActivityRecord)list.get(i); 9888 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9889 continue; 9890 } 9891 final boolean full = !brief && (complete || !r.isInHistory()); 9892 if (needNL) { 9893 pw.println(" "); 9894 needNL = false; 9895 } 9896 if (lastTask != r.task) { 9897 lastTask = r.task; 9898 pw.print(prefix); 9899 pw.print(full ? "* " : " "); 9900 pw.println(lastTask); 9901 if (full) { 9902 lastTask.dump(pw, prefix + " "); 9903 } else if (complete) { 9904 // Complete + brief == give a summary. Isn't that obvious?!? 9905 if (lastTask.intent != null) { 9906 pw.print(prefix); pw.print(" "); 9907 pw.println(lastTask.intent.toInsecureStringWithClip()); 9908 } 9909 } 9910 } 9911 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9912 pw.print(" #"); pw.print(i); pw.print(": "); 9913 pw.println(r); 9914 if (full) { 9915 r.dump(pw, innerPrefix); 9916 } else if (complete) { 9917 // Complete + brief == give a summary. Isn't that obvious?!? 9918 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9919 if (r.app != null) { 9920 pw.print(innerPrefix); pw.println(r.app); 9921 } 9922 } 9923 if (client && r.app != null && r.app.thread != null) { 9924 // flush anything that is already in the PrintWriter since the thread is going 9925 // to write to the file descriptor directly 9926 pw.flush(); 9927 try { 9928 TransferPipe tp = new TransferPipe(); 9929 try { 9930 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9931 r.appToken, innerPrefix, args); 9932 // Short timeout, since blocking here can 9933 // deadlock with the application. 9934 tp.go(fd, 2000); 9935 } finally { 9936 tp.kill(); 9937 } 9938 } catch (IOException e) { 9939 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9940 } catch (RemoteException e) { 9941 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9942 } 9943 needNL = true; 9944 } 9945 } 9946 }
821 public void dumpActivity(FileDescriptor fd, IBinder activitytoken, 822 String prefix, String[] args) { 823 DumpComponentInfo data = new DumpComponentInfo(); 824 try { 825 data.fd = ParcelFileDescriptor.dup(fd); 826 data.token = activitytoken; 827 data.prefix = prefix; 828 data.args = args; 829 queueOrSendMessage(H.DUMP_ACTIVITY, data); 830 } catch (IOException e) { 831 Slog.w(TAG, "dumpActivity failed", e); 832 } 833 }
1186 public void handleMessage(Message msg) { 1187 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1188 switch (msg.what) { 1365 case DUMP_ACTIVITY: 1366 handleDumpActivity((DumpComponentInfo)msg.obj); 1367 break;
2451 private void handleDumpActivity(DumpComponentInfo info) { 2452 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2453 try { 2454 ActivityClientRecord r = mActivities.get(info.token); 2455 if (r != null && r.activity != null) { 2456 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor())); 2457 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 2458 pw.flush(); 2459 } 2460 } finally { 2461 IoUtils.closeQuietly(info.fd); 2462 StrictMode.setThreadPolicy(oldPolicy); 2463 } 2464 }
4709 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 4710 writer.print(prefix); writer.print("Local Activity "); 4711 writer.print(Integer.toHexString(System.identityHashCode(this))); 4712 writer.println(" State:"); 4713 String innerPrefix = prefix + " "; 4714 writer.print(innerPrefix); writer.print("mResumed="); 4715 writer.print(mResumed); writer.print(" mStopped="); 4716 writer.print(mStopped); writer.print(" mFinished="); 4717 writer.println(mFinished); 4718 writer.print(innerPrefix); writer.print("mLoadersStarted="); 4719 writer.println(mLoadersStarted); 4720 writer.print(innerPrefix); writer.print("mChangingConfigurations="); 4721 writer.println(mChangingConfigurations); 4722 writer.print(innerPrefix); writer.print("mCurrentConfig="); 4723 writer.println(mCurrentConfig); 4724 if (mLoaderManager != null) { 4725 writer.print(prefix); writer.print("Loader Manager "); 4726 writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager))); 4727 writer.println(":"); 4728 mLoaderManager.dump(prefix + " ", fd, writer, args); 4729 } 4730 mFragments.dump(prefix, fd, writer, args); 4731 }