summaryrefslogtreecommitdiffstats
path: root/tools/eclipse
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2009-09-01 16:23:16 -0700
committerXavier Ducrohet <xav@android.com>2009-09-01 16:29:18 -0700
commitd2d24351d3414d60807b7fe6b091ebe1548d0f61 (patch)
tree5cdf071618d06b37cdf44f1d4d82bbcd50d139be /tools/eclipse
parentbc4a352b19fb86913e9ed8eef96039ec30878609 (diff)
downloadandroid_development-d2d24351d3414d60807b7fe6b091ebe1548d0f61.tar.gz
android_development-d2d24351d3414d60807b7fe6b091ebe1548d0f61.tar.bz2
android_development-d2d24351d3414d60807b7fe6b091ebe1548d0f61.zip
Add "Dump HPROF file" to DDMS/DDMS plugin
This uses the (new in cupcake) VM command through JDWP. Older VMs are detected through the (also new) 'FEAT' command that notifies which features the VM supports. The hprof file is right now saved in /sdcard. Due to donut+ apps not having the SD Card permission by default, we may need to change this in the (near) future. Upon completion of the dump by the VM, DDMS will give the user a file selector to choose a place to save the file on the host machine. Future improvements: run (our own) hat, or hprof-conv and a standard hprof tool (Eclipse MAT integration for instance). This should be configurable by the user. Change-Id: I33696b0263e3d0788ad5d90cedf3cd17393d2f9b
Diffstat (limited to 'tools/eclipse')
-rw-r--r--tools/eclipse/plugins/.gitignore1
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java133
-rwxr-xr-xtools/eclipse/scripts/create_ddms_symlinks.sh2
3 files changed, 133 insertions, 3 deletions
diff --git a/tools/eclipse/plugins/.gitignore b/tools/eclipse/plugins/.gitignore
index 63ac0cf1d..cc105d221 100644
--- a/tools/eclipse/plugins/.gitignore
+++ b/tools/eclipse/plugins/.gitignore
@@ -30,6 +30,7 @@ com.android.ide.eclipse.ddms/icons/forward.png
com.android.ide.eclipse.ddms/icons/gc.png
com.android.ide.eclipse.ddms/icons/halt.png
com.android.ide.eclipse.ddms/icons/heap.png
+com.android.ide.eclipse.ddms/icons/hprof.png
com.android.ide.eclipse.ddms/icons/i.png
com.android.ide.eclipse.ddms/icons/importBug.png
com.android.ide.eclipse.ddms/icons/load.png
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
index 30172f59d..7f9c3c895 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
@@ -17,30 +17,41 @@
package com.android.ide.eclipse.ddms.views;
+import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Client;
import com.android.ddmlib.ClientData;
-import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.ClientData.IHprofDumpHandler;
+import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmuilib.DevicePanel;
import com.android.ddmuilib.ScreenShotDialog;
+import com.android.ddmuilib.SyncProgressMonitor;
import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.android.ide.eclipse.ddms.DdmsPlugin.IDebugLauncher;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
+import java.io.File;
+
public class DeviceView extends ViewPart implements IUiSelectionListener {
private final static boolean USE_SELECTED_DEBUG_PORT = true;
@@ -48,6 +59,8 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
public static final String ID =
"com.android.ide.eclipse.ddms.views.DeviceView"; //$NON-NLS-1$
+ private static DeviceView sThis;
+
private DevicePanel mDeviceList;
private Action mResetAdbAction;
private Action mCaptureAction;
@@ -56,9 +69,103 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
private Action mGcAction;
private Action mKillAppAction;
private Action mDebugAction;
+ private Action mHprofAction;
private IDebugLauncher mDebugLauncher;
- private static DeviceView sThis;
+ private class HProfHandler implements IHprofDumpHandler {
+
+ private final Shell mParentShell;
+
+ public HProfHandler(Shell parentShell) {
+ mParentShell = parentShell;
+ }
+
+ public void onFailure(final Client client) {
+ mParentShell.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ try {
+ MessageDialog.openError(mParentShell, "HPROF Error",
+ String.format(
+ "Unable to create HPROF file for application '%1$s'.\n" +
+ "Check logcat for more information.",
+ client.getClientData().getClientDescription()));
+ } finally {
+ // this will make sure the dump hprof button is re-enabled for the
+ // current selection. as the client is finished dumping an hprof file
+ doSelectionChanged(mDeviceList.getSelectedClient());
+ }
+ }
+ });
+ }
+
+ public void onSuccess(final String file, final Client client) {
+ mParentShell.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ final IDevice device = client.getDevice();
+ try {
+ // get the sync service to pull the HPROF file
+ final SyncService sync = client.getDevice().getSyncService();
+ if (sync != null) {
+ promptAndPull(device, client, sync, file);
+ } else {
+ MessageDialog.openError(mParentShell, "HPROF Error",
+ String.format(
+ "Unable to download HPROF file from device '%1$s'.",
+ device.getSerialNumber()));
+ }
+ } catch (Exception e) {
+ MessageDialog.openError(mParentShell, "HPROF Error",
+ String.format("Unable to download HPROF file from device '%1$s'.",
+ device.getSerialNumber()));
+
+ } finally {
+ // this will make sure the dump hprof button is re-enabled for the
+ // current selection. as the client is finished dumping an hprof file
+ doSelectionChanged(mDeviceList.getSelectedClient());
+ }
+ }
+ });
+ }
+
+ private void promptAndPull(final IDevice device, final Client client,
+ final SyncService sync, final String remoteFile) {
+ try {
+ FileDialog fileDialog = new FileDialog(mParentShell, SWT.SAVE);
+
+ fileDialog.setText("Save HPROF file");
+ fileDialog.setFileName(
+ client.getClientData().getClientDescription() + ".hprof");
+
+ final String localFileName = fileDialog.open();
+ if (localFileName != null) {
+ final File localFile = new File(localFileName);
+
+ new ProgressMonitorDialog(mParentShell).run(true, true,
+ new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ SyncResult result = sync.pullFile(remoteFile, localFileName,
+ new SyncProgressMonitor(monitor, String.format(
+ "Pulling %1$s from the device",
+ localFile.getName())));
+
+ if (result.getCode() != SyncService.RESULT_OK) {
+ MessageDialog.openError(mParentShell, "HPROF Error",
+ String.format("Failed to pull %1$s: %2$s", remoteFile,
+ result.getMessage()));
+ }
+
+ sync.close();
+ }
+ });
+ }
+ } catch (Exception e) {
+ MessageDialog.openError(mParentShell, "HPROF Error",
+ String.format("Unable to download HPROF file from device '%1$s'.",
+ device.getSerialNumber()));
+ }
+ }
+ }
+
public DeviceView() {
// the view is declared with allowMultiple="false" so we
@@ -86,6 +193,8 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
@Override
public void createPartControl(Composite parent) {
+ ClientData.setHprofDumpHandler(new HProfHandler(parent.getShell()));
+
mDeviceList = new DevicePanel(DdmsPlugin.getImageLoader(), USE_SELECTED_DEBUG_PORT);
mDeviceList.createPanel(parent);
mDeviceList.addSelectionListener(this);
@@ -156,6 +265,18 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
mGcAction.setImageDescriptor(DdmsPlugin.getImageLoader()
.loadDescriptor(DevicePanel.ICON_GC));
+ mHprofAction = new Action() {
+ @Override
+ public void run() {
+ mDeviceList.dumpHprof();
+ doSelectionChanged(mDeviceList.getSelectedClient());
+ }
+ };
+ mHprofAction.setText("Dump HPROF file");
+ mHprofAction.setToolTipText("Dump HPROF file");
+ mHprofAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+ .loadDescriptor(DevicePanel.ICON_HPROF));
+
mUpdateHeapAction = new Action("Update Heap", IAction.AS_CHECK_BOX) {
@Override
public void run() {
@@ -270,6 +391,9 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
mUpdateThreadAction.setEnabled(true);
mUpdateThreadAction.setChecked(selectedClient.isThreadUpdateEnabled());
+ mHprofAction.setEnabled(
+ selectedClient.getClientData().hasFeature(ClientData.FEATURE_HPROF) &&
+ selectedClient.getClientData().hasPendingHprofDump() == false);
} else {
if (USE_SELECTED_DEBUG_PORT) {
// set the client as the debug client
@@ -286,6 +410,7 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
mUpdateHeapAction.setEnabled(false);
mUpdateThreadAction.setEnabled(false);
mUpdateThreadAction.setChecked(false);
+ mHprofAction.setEnabled(false);
}
}
@@ -307,6 +432,7 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
menuManager.add(mUpdateHeapAction);
menuManager.add(new Separator());
menuManager.add(mGcAction);
+ menuManager.add(mHprofAction);
menuManager.add(new Separator());
menuManager.add(mKillAppAction);
menuManager.add(new Separator());
@@ -321,6 +447,9 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
toolBarManager.add(mUpdateThreadAction);
toolBarManager.add(mUpdateHeapAction);
toolBarManager.add(new Separator());
+ toolBarManager.add(mGcAction);
+ toolBarManager.add(mHprofAction);
+ toolBarManager.add(new Separator());
toolBarManager.add(mKillAppAction);
toolBarManager.add(new Separator());
toolBarManager.add(mCaptureAction);
diff --git a/tools/eclipse/scripts/create_ddms_symlinks.sh b/tools/eclipse/scripts/create_ddms_symlinks.sh
index 276cf9b2b..a5b20a879 100755
--- a/tools/eclipse/scripts/create_ddms_symlinks.sh
+++ b/tools/eclipse/scripts/create_ddms_symlinks.sh
@@ -65,7 +65,7 @@ for i in \
e.png edit.png empty.png emulator.png \
forward.png \
gc.png \
- heap.png halt.png \
+ heap.png halt.png hprof.png \
i.png importBug.png \
load.png \
pause.png play.png pull.png push.png \