am 2b6f5d17: Merge change 23740 into eclair
Merge commit '2b6f5d17a3c3eff47cb804b1a6210cfd8a640a3d' into eclair-plus-aosp * commit '2b6f5d17a3c3eff47cb804b1a6210cfd8a640a3d': Add support for opening HPROF files in Eclipse.
This commit is contained in:
@@ -230,6 +230,9 @@
|
||||
<import plugin="org.eclipse.ui"/>
|
||||
<import plugin="org.eclipse.core.runtime"/>
|
||||
<import plugin="org.eclipse.ui.console"/>
|
||||
<import plugin="org.eclipse.core.resources"/>
|
||||
<import plugin="org.eclipse.ui.ide"/>
|
||||
<import plugin="org.eclipse.core.filesystem"/>
|
||||
</requires>
|
||||
|
||||
<plugin
|
||||
|
||||
@@ -8,7 +8,10 @@ Bundle-Vendor: The Android Open Source Project
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.ui.console
|
||||
org.eclipse.ui.console,
|
||||
org.eclipse.core.resources,
|
||||
org.eclipse.ui.ide,
|
||||
org.eclipse.core.filesystem
|
||||
Eclipse-LazyStart: true
|
||||
Export-Package: com.android.ddmlib,
|
||||
com.android.ddmlib.log,
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.eclipse.ui.console.MessageConsoleStream;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
@@ -55,6 +56,21 @@ import java.util.Calendar;
|
||||
public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeListener,
|
||||
IUiSelectionListener {
|
||||
|
||||
public final static int PLATFORM_UNKNOWN = 0;
|
||||
public final static int PLATFORM_LINUX = 1;
|
||||
public final static int PLATFORM_WINDOWS = 2;
|
||||
public final static int PLATFORM_DARWIN = 3;
|
||||
|
||||
/**
|
||||
* Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
|
||||
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
|
||||
*/
|
||||
public final static int CURRENT_PLATFORM = currentPlatform();
|
||||
|
||||
/** hprof-conv executable (with extension for the current OS) */
|
||||
public final static String FN_HPROF_CONVERTER = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
|
||||
"hprof-conv.exe" : "hprof-conv"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "com.android.ide.eclipse.ddms"; // $NON-NLS-1$
|
||||
|
||||
@@ -65,12 +81,15 @@ public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeL
|
||||
|
||||
/** Location of the adb command line executable */
|
||||
private static String sAdbLocation;
|
||||
private static String sToolsFolder;
|
||||
private static String sHprofConverter;
|
||||
|
||||
/**
|
||||
* Debug Launcher for already running apps
|
||||
*/
|
||||
private static IDebugLauncher sRunningAppDebugLauncher;
|
||||
|
||||
|
||||
/** Console for DDMS log message */
|
||||
private MessageConsole mDdmsConsole;
|
||||
|
||||
@@ -217,7 +236,7 @@ public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeL
|
||||
|
||||
// read the adb location from the prefs to attempt to start it properly without
|
||||
// having to wait for ADT to start
|
||||
sAdbLocation = eclipseStore.getString(ADB_LOCATION);
|
||||
setAdbLocation(eclipseStore.getString(ADB_LOCATION));
|
||||
|
||||
// start it in a thread to return from start() asap.
|
||||
new Thread() {
|
||||
@@ -278,13 +297,32 @@ public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeL
|
||||
return sAdbLocation;
|
||||
}
|
||||
|
||||
public static String getToolsFolder() {
|
||||
return sToolsFolder;
|
||||
}
|
||||
|
||||
public static String getHprofConverter() {
|
||||
return sHprofConverter;
|
||||
}
|
||||
|
||||
private static void setAdbLocation(String adbLocation) {
|
||||
sAdbLocation = adbLocation;
|
||||
|
||||
File adb = new File(sAdbLocation);
|
||||
File toolsFolder = adb.getParentFile();
|
||||
sToolsFolder = toolsFolder.getAbsolutePath();
|
||||
|
||||
File hprofConverter = new File(toolsFolder, FN_HPROF_CONVERTER);
|
||||
sHprofConverter = hprofConverter.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of the adb executable and optionally starts adb
|
||||
* @param adb location of adb
|
||||
* @param startAdb flag to start adb
|
||||
*/
|
||||
public static void setAdb(String adb, boolean startAdb) {
|
||||
sAdbLocation = adb;
|
||||
setAdbLocation(adb);
|
||||
|
||||
// store the location for future ddms only start.
|
||||
sPlugin.getPreferenceStore().setValue(ADB_LOCATION, sAdbLocation);
|
||||
@@ -562,4 +600,23 @@ public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeL
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns current platform
|
||||
*
|
||||
* @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
|
||||
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
|
||||
*/
|
||||
public static int currentPlatform() {
|
||||
String os = System.getProperty("os.name"); //$NON-NLS-1$
|
||||
if (os.startsWith("Mac OS")) { //$NON-NLS-1$
|
||||
return PLATFORM_DARWIN;
|
||||
} else if (os.startsWith("Windows")) { //$NON-NLS-1$
|
||||
return PLATFORM_WINDOWS;
|
||||
} else if (os.startsWith("Linux")) { //$NON-NLS-1$
|
||||
return PLATFORM_LINUX;
|
||||
}
|
||||
|
||||
return PLATFORM_UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.ide.eclipse.ddms.preferences;
|
||||
|
||||
import com.android.ide.eclipse.ddms.DdmsPlugin;
|
||||
import com.android.ide.eclipse.ddms.views.DeviceView.HProfHandler;
|
||||
import com.android.ddmlib.DdmPreferences;
|
||||
import com.android.ddmuilib.DdmUiPreferences;
|
||||
|
||||
@@ -57,6 +58,9 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer {
|
||||
public final static String ATTR_LOGCAT_FONT =
|
||||
DdmsPlugin.PLUGIN_ID + ".logcatFont"; //$NON-NLS-1$
|
||||
|
||||
public final static String ATTR_HPROF_ACTION =
|
||||
DdmsPlugin.PLUGIN_ID + ".hprofAction"; //$NON-NLS-1$
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -84,6 +88,8 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer {
|
||||
|
||||
store.setDefault(ATTR_LOGCAT_FONT,
|
||||
new FontData("Courier", 10, SWT.NORMAL).toString()); //$NON-NLS-1$
|
||||
|
||||
store.setDefault(ATTR_HPROF_ACTION, HProfHandler.ACTION_OPEN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
package com.android.ide.eclipse.ddms.preferences;
|
||||
|
||||
import com.android.ide.eclipse.ddms.DdmsPlugin;
|
||||
import com.android.ide.eclipse.ddms.views.DeviceView.HProfHandler;
|
||||
import com.android.ddmlib.Log.LogLevel;
|
||||
import com.android.ddmuilib.PortFieldEditor;
|
||||
|
||||
import org.eclipse.jface.preference.BooleanFieldEditor;
|
||||
import org.eclipse.jface.preference.ComboFieldEditor;
|
||||
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
||||
import org.eclipse.jface.preference.IntegerFieldEditor;
|
||||
import org.eclipse.jface.preference.RadioGroupFieldEditor;
|
||||
@@ -63,6 +65,13 @@ public class PreferencePage extends FieldEditorPreferencePage implements
|
||||
ife.setValidRange(1, 60);
|
||||
addField(ife);
|
||||
|
||||
ComboFieldEditor cfe = new ComboFieldEditor(PreferenceInitializer.ATTR_HPROF_ACTION,
|
||||
"HPROF Action:", new String[][] {
|
||||
{ "Save to disk", HProfHandler.ACTION_SAVE },
|
||||
{ "Open in Eclipse", HProfHandler.ACTION_OPEN },
|
||||
}, getFieldEditorParent());
|
||||
addField(cfe);
|
||||
|
||||
RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor(PreferenceInitializer.ATTR_LOG_LEVEL,
|
||||
"Logging Level", 1, new String[][] {
|
||||
{ "Verbose", LogLevel.VERBOSE.getStringValue() },
|
||||
@@ -74,7 +83,6 @@ public class PreferencePage extends FieldEditorPreferencePage implements
|
||||
},
|
||||
getFieldEditorParent(), true);
|
||||
addField(rgfe);
|
||||
|
||||
}
|
||||
|
||||
public void init(IWorkbench workbench) {
|
||||
|
||||
@@ -30,8 +30,12 @@ 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 com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
|
||||
|
||||
import org.eclipse.core.filesystem.EFS;
|
||||
import org.eclipse.core.filesystem.IFileStore;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.action.IMenuManager;
|
||||
@@ -40,6 +44,7 @@ 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.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
@@ -47,10 +52,14 @@ 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.PartInitException;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.ide.IDE;
|
||||
import org.eclipse.ui.part.ViewPart;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class DeviceView extends ViewPart implements IUiSelectionListener {
|
||||
|
||||
@@ -72,11 +81,15 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
|
||||
private Action mHprofAction;
|
||||
private IDebugLauncher mDebugLauncher;
|
||||
|
||||
private class HProfHandler implements IHprofDumpHandler {
|
||||
public class HProfHandler implements IHprofDumpHandler {
|
||||
public final static String ACTION_SAVE ="hprof.save"; //$NON-NLS-1$
|
||||
public final static String ACTION_OPEN = "hprof.open"; //$NON-NLS-1$
|
||||
|
||||
public final static String DOT_HPROF = ".hprof"; //$NON-NLS-1$
|
||||
|
||||
private final Shell mParentShell;
|
||||
|
||||
public HProfHandler(Shell parentShell) {
|
||||
HProfHandler(Shell parentShell) {
|
||||
mParentShell = parentShell;
|
||||
}
|
||||
|
||||
@@ -98,7 +111,7 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
|
||||
});
|
||||
}
|
||||
|
||||
public void onSuccess(final String file, final Client client) {
|
||||
public void onSuccess(final String remoteFile, final Client client) {
|
||||
mParentShell.getDisplay().asyncExec(new Runnable() {
|
||||
public void run() {
|
||||
final IDevice device = client.getDevice();
|
||||
@@ -106,7 +119,19 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
|
||||
// get the sync service to pull the HPROF file
|
||||
final SyncService sync = client.getDevice().getSyncService();
|
||||
if (sync != null) {
|
||||
promptAndPull(device, client, sync, file);
|
||||
// get from the preference what action to take
|
||||
IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
|
||||
String value = store.getString(PreferenceInitializer.ATTR_HPROF_ACTION);
|
||||
if (ACTION_OPEN.equals(value)) {
|
||||
File temp = File.createTempFile("android", DOT_HPROF); //$NON-NLS-1$
|
||||
String tempPath = temp.getAbsolutePath();
|
||||
pull(sync, tempPath, remoteFile);
|
||||
|
||||
open(tempPath);
|
||||
} else {
|
||||
// default action is ACTION_SAVE
|
||||
promptAndPull(device, client, sync, remoteFile);
|
||||
}
|
||||
} else {
|
||||
MessageDialog.openError(mParentShell, "HPROF Error",
|
||||
String.format(
|
||||
@@ -134,29 +159,11 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
|
||||
|
||||
fileDialog.setText("Save HPROF file");
|
||||
fileDialog.setFileName(
|
||||
client.getClientData().getClientDescription() + ".hprof");
|
||||
client.getClientData().getClientDescription() + DOT_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();
|
||||
}
|
||||
});
|
||||
pull(sync, localFileName, remoteFile);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
MessageDialog.openError(mParentShell, "HPROF Error",
|
||||
@@ -164,6 +171,50 @@ public class DeviceView extends ViewPart implements IUiSelectionListener {
|
||||
device.getSerialNumber()));
|
||||
}
|
||||
}
|
||||
|
||||
private void pull(final SyncService sync,
|
||||
final String localFileName, final String remoteFile)
|
||||
throws InvocationTargetException, InterruptedException {
|
||||
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",
|
||||
remoteFile)));
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void open(String path) throws IOException, InterruptedException, PartInitException {
|
||||
// make a temp file to convert the hprof into something
|
||||
// readable by normal tools
|
||||
File temp = File.createTempFile("android", DOT_HPROF);
|
||||
String tempPath = temp.getAbsolutePath();
|
||||
|
||||
String[] command = new String[3];
|
||||
command[0] = DdmsPlugin.getHprofConverter();
|
||||
command[1] = path;
|
||||
command[2] = tempPath;
|
||||
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
p.waitFor();
|
||||
|
||||
IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(tempPath));
|
||||
if (!fileStore.fetchInfo().isDirectory() && fileStore.fetchInfo().exists()) {
|
||||
IDE.openEditorOnFileStore(
|
||||
getSite().getWorkbenchWindow().getActivePage(),
|
||||
fileStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user