/** * Entry point for the Stetho dumpapp script. * * {@link #initialize} must have been called in the app before running dumpapp. */ @Override public void dump(DumperContext dumpContext) throws DumpException { ensureInitialized(); List<String> args = dumpContext.getArgsAsList(); PrintStream writer = dumpContext.getStdout(); String cmd = args.isEmpty() ? null : args.get(0); List<String> rest = args.isEmpty() ? new ArrayList<String>() : args.subList(1, args.size()); if (cmd != null && cmd.equals("memcache")) { memcache(writer, rest); } else if (cmd != null && cmd.equals("diskcache")) { diskcache(mMainFileCache, "Main", writer, rest); diskcache(mSmallFileCache, "Small", writer, rest); } else { usage(writer); if (TextUtils.isEmpty(cmd)) { throw new DumpUsageException("Missing command"); } else { throw new DumpUsageException("Unknown command: " + cmd); } } }
private void diskcache(FileCache cache, String title, PrintStream writer, List<String> args) throws DumpException { DiskStorage.DiskDumpInfo intDiskDumpInfo; try { intDiskDumpInfo = cache.getDumpInfo(); } catch (IOException e) { throw new DumpException(e.getMessage()); } if (!args.isEmpty() && args.get(0).equals("-s")) { writeDiskDumpInfoScriptReadable(writer, intDiskDumpInfo); } else { writer.println(); writer.println(title + " disk cache contents:"); writeDiskDumpInfo(writer, intDiskDumpInfo); } }
@Override public void dump(DumperContext dumpContext) throws DumpException { Iterator<String> argsIter = dumpContext.getArgsAsList().iterator(); String command = ArgsHelper.nextOptionalArg(argsIter, null); if ("throw".equals(command)) { doUncaughtException(argsIter); } else if ("kill".equals(command)) { doKill(dumpContext, argsIter); } else if ("exit".equals(command)) { doSystemExit(argsIter); } else { doUsage(dumpContext.getStdout()); if (command != null) { throw new DumpUsageException("Unsupported command: " + command); } } }
private void doKill(DumperContext dumpContext, Iterator<String> argsIter) throws DumpException { String signal = ArgsHelper.nextOptionalArg(argsIter, OPTION_KILL_DEFAULT); try { Process kill = new ProcessBuilder() .command("/system/bin/kill", "-" + signal, String.valueOf(android.os.Process.myPid())) .redirectErrorStream(true) .start(); // Handle kill command output gracefully in the event that the signal delivered didn't // actually take out our process... try { InputStream in = kill.getInputStream(); Util.copy(in, dumpContext.getStdout(), new byte[1024]); } finally { kill.destroy(); } } catch (IOException e) { throw new DumpException("Failed to invoke kill: " + e); } }
@Override public void dump(DumperContext dumpContext) throws DumpException { final PrintStream output = dumpContext.getStdout(); Iterator<String> argsIter = dumpContext.getArgsAsList().iterator(); String outputPath = argsIter.hasNext() ? argsIter.next() : null; if (outputPath == null) { usage(output); } else { if ("-".equals(outputPath)) { handlePipeOutput(output); } else { File outputFile = new File(outputPath); if (!outputFile.isAbsolute()) { outputFile = mContext.getFileStreamPath(outputPath); } writeHprof(outputFile); output.println("Wrote to " + outputFile); } } }
private void handlePipeOutput(OutputStream output) throws DumpException { File hprofFile = mContext.getFileStreamPath("hprof-dump.hprof"); try { writeHprof(hprofFile); try { InputStream input = new FileInputStream(hprofFile); try { Util.copy(input, output, new byte[2048]); } finally { input.close(); } } catch (IOException e) { throw new DumpException("Failure copying " + hprofFile + " to dumper output"); } } finally { if (hprofFile.exists()) { hprofFile.delete(); } } }
@Override public void dump(DumperContext dumpContext) throws DumpException { Iterator<String> args = dumpContext.getArgsAsList().iterator(); String command = ArgsHelper.nextOptionalArg(args, ""); if ("ls".equals(command)) { doLs(dumpContext.getStdout()); } else if ("tree".equals(command)) { doTree(dumpContext.getStdout()); } else if ("download".equals(command)) { doDownload(dumpContext.getStdout(), args); } else { doUsage(dumpContext.getStdout()); if (!"".equals(command)) { throw new DumpUsageException("Unknown command: " + command); } } }
@Override public void dump(DumperContext dumpContext) throws DumpException { PrintStream writer = dumpContext.getStdout(); Iterator<String> argsIter = dumpContext.getArgsAsList().iterator(); String command = ArgsHelper.nextOptionalArg(argsIter, null); if (CMD_LIST.equalsIgnoreCase(command)) { doList(writer); } else if (CMD_DELETE.equalsIgnoreCase(command)) { doRemove(writer, argsIter); } else if (CMD_CLEAR.equalsIgnoreCase(command)) { doClear(writer); } else if (CMD_REFRESH.equalsIgnoreCase(command)) { doRefresh(writer); } else { usage(writer); if (command != null) { throw new DumpUsageException("Unknown command: " + command); } } }
private void dumpTypeMap(DumperContext dumperContext, InfoDumper dumper) throws DumpException { PrintStream writer = dumperContext.getStdout(); if (mIsAll) { writer.println("[" + dumper.getTitle() + "]"); } LinkedHashMap<String, String> dumps = dumper.getDumpMap(mContext); if (dumps == null) { writer.println(dumper.getErrorMessage()); if (mIsAll) { writer.println(""); } return; } for (Map.Entry<String, String> e : dumps.entrySet()) { writer.println(e.getKey() + ": " + e.getValue()); } if (mIsAll) { writer.println(""); } }
private void dumpTypeList(DumperContext dumperContext, InfoDumper dumper) throws DumpException { PrintStream writer = dumperContext.getStdout(); if (mIsAll) { writer.println("[" + dumper.getTitle() + "]"); } List<String> dumps = dumper.getDumpList(mContext); if (dumps == null) { writer.println(dumper.getErrorMessage()); if (mIsAll) { writer.println(""); } return; } for (String dump : dumps) { writer.println(dump); } if (mIsAll) { writer.println(""); } }
@Override public LinkedHashMap<String, String> getDumpMap(Context context) throws DumpException { LinkedHashMap<String, String> dumps = new LinkedHashMap<>(); dumps.put(Settings.Secure.ANDROID_ID, getAndroidId(context)); dumps.put("UUID", getUUID()); String adIdKey = "AdvertisingId"; String adOptoutKey = "isAdOptout"; AdvertisingIdClient.Info adInfo = getAdInfo(context); if (adInfo == null) { dumps.put(adIdKey, "Getting AdvertisingId need a android.permission.INTERNET"); dumps.put(adOptoutKey, "Getting AdvertisingId need a android.permission.INTERNET"); } else { dumps.put(adIdKey, adInfo.getId()); dumps.put(adOptoutKey, Boolean.toString(adInfo.isLimitAdTrackingEnabled())); } return dumps; }
@Override public LinkedHashMap<String, String> getDumpMap(Context context) throws DumpException { ActivityManager activityManager = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)); List<ActivityManager.ProcessErrorStateInfo> errorStateInfo = activityManager.getProcessesInErrorState(); if (errorStateInfo == null) return null; LinkedHashMap<String, String> dumps = new LinkedHashMap<>(); for (ActivityManager.ProcessErrorStateInfo error : errorStateInfo) { dumps.put("Error.condition", Integer.toString(error.condition)); // CRASHED,NOT_RESPONDING,NO_ERROR dumps.put("Error.longMsg", error.longMsg); dumps.put("Error.shortMsg", error.shortMsg); dumps.put("Error.pid", Integer.toString(error.pid)); dumps.put("Error.processName", error.processName); dumps.put("Error.stackTrace", error.stackTrace); dumps.put("Error.tag", error.tag); dumps.put("Error.uid", Integer.toString(error.uid)); } return dumps; }
@Override public LinkedHashMap<String, String> getDumpMap(Context context) throws DumpException { int permissionInfo = context.getPackageManager().checkPermission(Manifest.permission.READ_PHONE_STATE, context.getPackageName()); if (permissionInfo == PackageManager.PERMISSION_DENIED) { return null; } TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); LinkedHashMap<String, String> dumps = new LinkedHashMap<>(); dumps.put("Line1Number", telephonyManager.getLine1Number()); dumps.put("DeviceId", telephonyManager.getDeviceId()); dumps.put("SimCountryIso", telephonyManager.getSimCountryIso()); dumps.put("SimOperator", telephonyManager.getSimOperator()); dumps.put("SimOperatorName", telephonyManager.getSimOperatorName()); dumps.put("SimSerialNumber", telephonyManager.getSimSerialNumber()); dumps.put("SimState", Integer.toString(telephonyManager.getSimState())); dumps.put("VoiceMailNumber", telephonyManager.getVoiceMailNumber()); return dumps; }
@Override public List<String> getDumpList(Context context) throws DumpException { PackageManager packageManager = context.getPackageManager(); try { PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS); if (packageInfo == null || packageInfo.requestedPermissions == null) { return null; } List<String> dumps = new ArrayList<>(); for (String permission : packageInfo.requestedPermissions) { dumps.add(permission); } return dumps; } catch (PackageManager.NameNotFoundException e) { throw new DumpException(e.getMessage()); } }
private void getFiles( PrintStream writer, CountingMemoryCacheInspector.DumpInfo<CacheKey, CloseableImage> dumpInfo) throws DumpException, IOException { writer.println("\nStoring all images in the memory cache into /sdcard/imagedumperfiles/ ..."); File dir = new File(Environment.getExternalStorageDirectory().getPath() + "/imagedumperfiles/"); if (dir.exists() && dir.isDirectory()) { File[] files = dir.listFiles(); if (files != null) { for (File file : files) { file.delete(); } } if (!dir.delete()) { throw new DumpException("Failed to clear existing /sdcard/imagedumperfiles directory"); } } if (!dir.mkdirs()) { throw new DumpException("Failed to create /sdcard/imagedumperfiles directory"); } if (!dumpInfo.lruEntries.isEmpty()) { writer.println("LRU Entries:"); storeEntries(dumpInfo.lruEntries, 1, writer, dir); } if (!dumpInfo.sharedEntries.isEmpty()) { writer.println("Shared Entries:"); storeEntries(dumpInfo.sharedEntries, dumpInfo.lruEntries.size()+1, writer, dir); } writer.println("Done!"); }
@Override public void dump(DumperContext dumpContext) throws DumpException { Iterator<String> args = dumpContext.getArgsAsList().iterator(); String command = ArgsHelper.nextOptionalArg(args, ""); if ("download".equals(command)) { doDownload(dumpContext.getStdout(), args); } else { doUsage(dumpContext.getStdout()); if (!"".equals(command)) { throw new DumpUsageException("Unknown command: " + command); } } }
@Override public void dump(DumperContext dumpContext) throws DumpException { final PrintStream writer = dumpContext.getStdout(); List<String> args = dumpContext.getArgsAsList(); String commandName = args.isEmpty() ? "" : args.remove(0); switch (commandName) { case "alarms": displayAlarms(writer); break; case "appInfo": displayAppInfo(writer); break; case "bootReceiver": displayBootReceiverState(writer); break; case "currentSession": displayCurrentSessionData(writer); break; case "endpoint": changeEndpoint(writer, args); break; case "notif": displayNotificationReminder(); break; default: doUsage(writer); break; } }
private void writeHprof(File outputPath) throws DumpException { try { // Test that we can write here. dumpHprofData appears to hang if it cannot write // to the target location on ART. truncateAndDeleteFile(outputPath); Debug.dumpHprofData(outputPath.getAbsolutePath()); } catch (IOException e) { throw new DumpException("Failure writing to " + outputPath + ": " + e.getMessage()); } }
@Override public void dump(DumperContext dumpContext) throws DumpException { PrintStream writer = dumpContext.getStdout(); Iterator<String> args = dumpContext.getArgsAsList().iterator(); String helloToWhom = ArgsHelper.nextOptionalArg(args, null); if (helloToWhom != null) { doHello(dumpContext.getStdin(), writer, helloToWhom); } else { doUsage(writer); } }
private void doHello(InputStream in, PrintStream writer, String name) throws DumpException { if (TextUtils.isEmpty(name)) { // This will print an error to the dumpapp user and cause a non-zero exit of the // script. throw new DumpUsageException("Name is empty"); } else if ("-".equals(name)) { try { name = new BufferedReader(new InputStreamReader(in)).readLine(); } catch (IOException e) { throw new DumpException(e.toString()); } } writer.println("Hello " + name + "!"); }
@Override public LinkedHashMap<String, String> getDumpMap(Context context) throws DumpException { int permissionInfo = context.getPackageManager().checkPermission(Manifest.permission.ACCESS_NETWORK_STATE, context.getPackageName()); if (permissionInfo == PackageManager.PERMISSION_DENIED) { return null; } ConnectivityManager connectivity = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo network = connectivity.getActiveNetworkInfo(); LinkedHashMap<String, String> dumps = new LinkedHashMap<>(); if (network == null) { dumps.put("NetworkInfo", "NetworkInfo is null."); } else if (!network.isAvailable()) { dumps.put("NetworkInfo", "connection not available."); } else if (!network.isConnectedOrConnecting()) { dumps.put("NetworkInfo", "not connect."); } else { dumps.put("NetworkInfo", network.getTypeName()); } return dumps; }
@Override public List<String> getDumpList(Context context) throws DumpException { try { PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); List<String> dumps = new ArrayList<>(); dumps.add(new Date(packageInfo.lastUpdateTime).toString()); return dumps; } catch (PackageManager.NameNotFoundException e) { throw new DumpException(e.getMessage()); } }
@Override public LinkedHashMap<String, String> getDumpMap(Context context) throws DumpException { ActivityManager activityManager = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); LinkedHashMap<String, String> dumps = new LinkedHashMap<>(); dumps.put("MemoryInfo availMem", Long.toString(memoryInfo.availMem)); dumps.put("MemoryInfo lowMemory", Boolean.toString(memoryInfo.lowMemory)); dumps.put("MemoryInfo threshold", Long.toString(memoryInfo.threshold)); return dumps; }
@Override public LinkedHashMap<String, String> getDumpMap(Context context) throws DumpException { DisplayMetrics metrics = getDisplayMetrics(context); int dpi = getDpi(metrics); String dpiType = getDpiType(dpi); LinkedHashMap<String, String> dumps = new LinkedHashMap<>(); dumps.put("dpi", Integer.toString(dpi)); dumps.put("Generalized density", dpiType); dumps.put("widthPixels", Integer.toString(metrics.widthPixels)); dumps.put("heightPixels", Integer.toString(metrics.heightPixels)); return dumps; }
@Override public void dump(DumperContext dumperContext) throws DumpException { Iterator<String> argsIterator = dumperContext.getArgsAsList().iterator(); String command = ArgsHelper.nextOptionalArg(argsIterator, null); mIsAll = false; if (CMD_BUILD_CONFIG.equalsIgnoreCase(command)) { dumpBuildConfig(dumperContext); } else if (CMD_PERMISSION.equalsIgnoreCase(command)) { dumpPermission(dumperContext); } else if (CMD_LAST_UPDATE.equalsIgnoreCase(command)) { dumpLastUpdate(dumperContext); } else if (CMD_APPLICATION_INFO.equalsIgnoreCase(command)) { dumpApplicationInfo(dumperContext); } else if (CMD_ID.equalsIgnoreCase(command)) { dumpIds(dumperContext); } else if (CMD_OS_BUILD.equalsIgnoreCase(command)) { dumpOsBuild(dumperContext); } else if (CMD_DPI.equalsIgnoreCase(command)) { dumpDpi(dumperContext); } else if (CMD_MEMORY.equalsIgnoreCase(command)) { dumpMemory(dumperContext); } else if (CMD_ERROR.equalsIgnoreCase(command)) { dumpError(dumperContext); } else if (CMD_NETWORK.equalsIgnoreCase(command)) { dumpNetwork(dumperContext); } else if (CMD_TEL.equalsIgnoreCase(command)) { dumpTel(dumperContext); } else if (CMD_ALL.equalsIgnoreCase(command)) { mIsAll = true; dumpBuildConfig(dumperContext); dumpPermission(dumperContext); dumpLastUpdate(dumperContext); dumpApplicationInfo(dumperContext); dumpIds(dumperContext); dumpOsBuild(dumperContext); dumpDpi(dumperContext); dumpMemory(dumperContext); dumpError(dumperContext); dumpNetwork(dumperContext); dumpTel(dumperContext); } else { usage(dumperContext); if (command != null) { throw new DumpUsageException("Unknown command: " + command); } } }
private void dumpBuildConfig(DumperContext dumperContext) throws DumpException { dumpTypeMap(dumperContext, new BuildConfigDumper()); }
private void dumpPermission(DumperContext dumperContext) throws DumpException { dumpTypeList(dumperContext, new PermissionDumper()); }