diff options
author | Daniel Sandler <dsandler@android.com> | 2013-06-26 01:39:02 -0400 |
---|---|---|
committer | Daniel Sandler <dsandler@android.com> | 2013-06-26 14:30:19 -0400 |
commit | 8540bb8d72496dca3182ac091c2cafaaad597457 (patch) | |
tree | 1e366e439b3ca86c1c0c535f7ef1d455b871a07d /src/com/android/launcher3 | |
parent | 566da1026c33a68157bf9caf93d2071ad2870f46 (diff) | |
download | android_packages_apps_Trebuchet-8540bb8d72496dca3182ac091c2cafaaad597457.tar.gz android_packages_apps_Trebuchet-8540bb8d72496dca3182ac091c2cafaaad597457.tar.bz2 android_packages_apps_Trebuchet-8540bb8d72496dca3182ac091c2cafaaad597457.zip |
Include all processes in hprof dumps.
The emailed file is now a zipfile containing one .ahprof
file for each process known to MemoryTracker.
Change-Id: If4a73df9afd38756cc01ff37b2d249346e5f7e9f
Diffstat (limited to 'src/com/android/launcher3')
-rw-r--r-- | src/com/android/launcher3/MemoryDumpActivity.java | 140 | ||||
-rw-r--r-- | src/com/android/launcher3/MemoryTracker.java | 21 |
2 files changed, 124 insertions, 37 deletions
diff --git a/src/com/android/launcher3/MemoryDumpActivity.java b/src/com/android/launcher3/MemoryDumpActivity.java index 51bc30808..b437c22e2 100644 --- a/src/com/android/launcher3/MemoryDumpActivity.java +++ b/src/com/android/launcher3/MemoryDumpActivity.java @@ -17,66 +17,136 @@ package com.android.launcher3; import android.app.Activity; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Debug; -import android.os.Environment; +import android.os.*; import android.util.Log; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; public class MemoryDumpActivity extends Activity { + private static final String TAG = "MemoryDumpActivity"; + + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } - public static void dumpHprofAndShare(final Context context) { + public static String zipUp(ArrayList<String> paths) { + final int BUFSIZ = 256 * 1024; // 256K + final byte[] buf = new byte[BUFSIZ]; + final String zipfilePath = String.format("%s/hprof-%d.zip", + Environment.getExternalStorageDirectory(), + System.currentTimeMillis()); + ZipOutputStream zos = null; try { - final String path = String.format("%s/launcher-memory-%d.ahprof", - Environment.getExternalStorageDirectory(), - System.currentTimeMillis()); - Log.v(Launcher.TAG, "Dumping memory info to " + path); - - android.os.Debug.dumpHprofData(path); // will block + OutputStream os = new FileOutputStream(zipfilePath); + zos = new ZipOutputStream(new BufferedOutputStream(os)); + for (String filename : paths) { + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(filename)); + ZipEntry entry = new ZipEntry(filename); + zos.putNextEntry(entry); + int len; + while ( 0 < (len = is.read(buf, 0, BUFSIZ)) ) { + zos.write(buf, 0, len); + } + zos.closeEntry(); + } finally { + is.close(); + } + } + } catch (IOException e) { + Log.e(TAG, "error zipping up profile data", e); + return null; + } finally { + if (zos != null) { + try { + zos.close(); + } catch (IOException e) { + // ugh, whatever + } + } + } + return zipfilePath; + } - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("application/vnd.android.bugreport"); + public static void dumpHprofAndShare(final Context context, MemoryTracker tracker) { + final StringBuilder body = new StringBuilder(); - final long pss = Debug.getPss(); - final PackageManager pm = context.getPackageManager(); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("Launcher memory dump (PSS=%d)", pss)); - String appVersion; + final ArrayList<String> paths = new ArrayList<String>(); + for (int pid : tracker.getTrackedProcesses()) { + final String path = String.format("%s/launcher-memory-%d.ahprof", + Environment.getExternalStorageDirectory(), + pid); + Log.v(TAG, "Dumping memory info for process " + pid + " to " + path); + MemoryTracker.ProcessMemInfo info = tracker.getMemInfo(pid); + body.append("pid ").append(pid).append(":") + .append(" up=").append(info.getUptime()) + .append(" pss=").append(info.currentPss) + .append(" uss=").append(info.currentUss) + .append("\n"); try { - appVersion = pm.getPackageInfo(context.getPackageName(), 0).versionName; - } catch (PackageManager.NameNotFoundException e) { - appVersion = "?"; + android.os.Debug.dumpHprofData(path); // will block + } catch (IOException e) { + Log.e(TAG, "error dumping memory:", e); } - shareIntent.putExtra(Intent.EXTRA_TEXT, String.format("App version: %s\nBuild: %s", - appVersion, Build.DISPLAY)); - shareIntent.setType("application/vnd.android.hprof"); - //shareIntent.putExtra(Intent.EXTRA_TEXT, android.os.SystemProperties.get("ro.build.description")); + paths.add(path); + } - final File pathFile = new File(path); - final Uri pathUri = Uri.fromFile(pathFile); + String zipfile = zipUp(paths); - shareIntent.putExtra(Intent.EXTRA_STREAM, pathUri); - context.startActivity(shareIntent); - } catch (IOException e) { - e.printStackTrace(); + if (zipfile == null) return; + + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("application/zip"); + + final PackageManager pm = context.getPackageManager(); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("Launcher memory dump")); + String appVersion; + try { + appVersion = pm.getPackageInfo(context.getPackageName(), 0).versionName; + } catch (PackageManager.NameNotFoundException e) { + appVersion = "?"; } + + body.append("\nApp version: ").append(appVersion).append("\nBuild: ").append(Build.DISPLAY).append("\n"); + shareIntent.putExtra(Intent.EXTRA_TEXT, body.toString()); + + final File pathFile = new File(zipfile); + final Uri pathUri = Uri.fromFile(pathFile); + + shareIntent.putExtra(Intent.EXTRA_STREAM, pathUri); + context.startActivity(shareIntent); } @Override public void onStart() { super.onStart(); - dumpHprofAndShare(this); - finish(); + + final ServiceConnection connection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + Log.v(TAG, "service connected, dumping..."); + dumpHprofAndShare(MemoryDumpActivity.this, + ((MemoryTracker.MemoryTrackerInterface)service).getService()); + unbindService(this); + finish(); + } + + public void onServiceDisconnected(ComponentName className) { + } + }; + Log.v(TAG, "attempting to bind to memory tracker"); + bindService(new Intent(this, MemoryTracker.class), + connection, Context.BIND_AUTO_CREATE); } -}
\ No newline at end of file +} diff --git a/src/com/android/launcher3/MemoryTracker.java b/src/com/android/launcher3/MemoryTracker.java index c1057a8df..395bf9ef0 100644 --- a/src/com/android/launcher3/MemoryTracker.java +++ b/src/com/android/launcher3/MemoryTracker.java @@ -40,6 +40,7 @@ public class MemoryTracker extends Service { public static class ProcessMemInfo { public int pid; public String name; + public long startTime; public long currentPss, currentUss; public long[] pss = new long[256]; public long[] uss = new long[256]; @@ -49,6 +50,10 @@ public class MemoryTracker extends Service { public ProcessMemInfo(int pid, String name) { this.pid = pid; this.name = name; + this.startTime = System.currentTimeMillis(); + } + public long getUptime() { + return System.currentTimeMillis() - startTime; } }; public final LongSparseArray<ProcessMemInfo> mData = new LongSparseArray<ProcessMemInfo>(); @@ -77,6 +82,14 @@ public class MemoryTracker extends Service { ActivityManager mAm; + public static void startTrackingMe(Context context, String name) { + context.startService(new Intent(context, MemoryTracker.class) + .setAction(MemoryTracker.ACTION_START_TRACKING) + .putExtra("pid", android.os.Process.myPid()) + .putExtra("name", name) + ); + } + public ProcessMemInfo getMemInfo(int pid) { return mData.get(pid); } @@ -86,7 +99,11 @@ public class MemoryTracker extends Service { } public void startTrackingProcess(int pid, String name) { - mPids.add(new Long(pid)); + final Long lpid = new Long(pid); + + if (mPids.contains(lpid)) return; + + mPids.add(lpid); final int N = mPids.size(); mPidsArray = new int[N]; StringBuffer sb = new StringBuffer("Now tracking processes: "); @@ -110,7 +127,7 @@ public class MemoryTracker extends Service { info.uss[info.head] = info.currentUss = dinfo.getTotalPrivateDirty(); if (info.currentPss > info.max) info.max = info.currentPss; if (info.currentUss > info.max) info.max = info.currentUss; - //Log.v(TAG, "update: pid " + pid + " pss=" + info.currentPss + " uss=" + info.currentUss); + Log.v(TAG, "update: pid " + pid + " pss=" + info.currentPss + " uss=" + info.currentUss); } // XXX: notify listeners |