aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/AllocTrackerView.java47
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java877
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java42
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java111
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java181
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java47
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java120
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java47
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NetworkStatisticsView.java47
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/OldLogCatView.java385
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java71
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SysInfoView.java29
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java101
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java47
14 files changed, 2152 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/AllocTrackerView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/AllocTrackerView.java
new file mode 100644
index 000000000..e8b73ff51
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/AllocTrackerView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.AllocationPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class AllocTrackerView extends TableView {
+
+ public static final String ID = "com.android.ide.eclipse.ddms.views.AllocTrackerView"; //$NON-NLS-1$
+ private AllocationPanel mPanel;
+
+ public AllocTrackerView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mPanel = new AllocationPanel();
+ mPanel.createPanel(parent);
+
+ setSelectionDependentPanel(mPanel);
+
+ // listen to focus changes for table(s) of the panel.
+ setupTableFocusListener(mPanel, parent);
+ }
+
+ @Override
+ public void setFocus() {
+ mPanel.setFocus();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
new file mode 100644
index 000000000..c70c38803
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
@@ -0,0 +1,877 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.ClientData.IHprofDumpHandler;
+import com.android.ddmlib.ClientData.MethodProfilingStatus;
+import com.android.ddmlib.CollectingOutputReceiver;
+import com.android.ddmlib.DdmPreferences;
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.SyncException;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
+import com.android.ddmlib.TimeoutException;
+import com.android.ddmuilib.DevicePanel;
+import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
+import com.android.ddmuilib.ImageLoader;
+import com.android.ddmuilib.ScreenShotDialog;
+import com.android.ddmuilib.SyncProgressHelper;
+import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
+import com.android.ddmuilib.handler.BaseFileHandler;
+import com.android.ddmuilib.handler.MethodProfilingHandler;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.IClientAction;
+import com.android.ide.eclipse.ddms.IDebuggerConnector;
+import com.android.ide.eclipse.ddms.editors.UiAutomatorViewer;
+import com.android.ide.eclipse.ddms.i18n.Messages;
+import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
+import com.android.ide.eclipse.ddms.systrace.ISystraceOptions;
+import com.android.ide.eclipse.ddms.systrace.ISystraceOptionsDialog;
+import com.android.ide.eclipse.ddms.systrace.SystraceOptionsDialogV1;
+import com.android.ide.eclipse.ddms.systrace.SystraceOptionsDialogV2;
+import com.android.ide.eclipse.ddms.systrace.SystraceOutputParser;
+import com.android.ide.eclipse.ddms.systrace.SystraceTask;
+import com.android.ide.eclipse.ddms.systrace.SystraceVersionDetector;
+import com.android.uiautomator.UiAutomatorHelper;
+import com.android.uiautomator.UiAutomatorHelper.UiAutomatorException;
+import com.android.uiautomator.UiAutomatorHelper.UiAutomatorResult;
+import com.google.common.io.Files;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+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.ErrorDialog;
+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.jface.resource.ImageDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+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;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class DeviceView extends ViewPart implements IUiSelectionListener, IClientChangeListener {
+
+ private final static boolean USE_SELECTED_DEBUG_PORT = true;
+
+ public static final String ID = "com.android.ide.eclipse.ddms.views.DeviceView"; //$NON-NLS-1$
+
+ private static DeviceView sThis;
+
+ private Shell mParentShell;
+ private DevicePanel mDeviceList;
+
+ private Action mResetAdbAction;
+ private Action mCaptureAction;
+ private Action mViewUiAutomatorHierarchyAction;
+ private Action mSystraceAction;
+ private Action mUpdateThreadAction;
+ private Action mUpdateHeapAction;
+ private Action mGcAction;
+ private Action mKillAppAction;
+ private Action mDebugAction;
+ private Action mHprofAction;
+ private Action mTracingAction;
+
+ private ImageDescriptor mTracingStartImage;
+ private ImageDescriptor mTracingStopImage;
+
+ public class HProfHandler extends BaseFileHandler 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$
+
+ HProfHandler(Shell parentShell) {
+ super(parentShell);
+ }
+
+ @Override
+ protected String getDialogTitle() {
+ return Messages.DeviceView_HPROF_Error;
+ }
+
+ @Override
+ public void onEndFailure(final Client client, final String message) {
+ mParentShell.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ displayErrorFromUiThread(
+ Messages.DeviceView_Unable_Create_HPROF_For_Application,
+ client.getClientData().getClientDescription(),
+ message != null ? message + "\n\n" : ""); //$NON-NLS-1$ //$NON-NLS-2$
+ } 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());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onSuccess(final String remoteFilePath, final Client client) {
+ mParentShell.getDisplay().asyncExec(new Runnable() {
+ @Override
+ 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) {
+ // 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$
+ final String tempPath = temp.getAbsolutePath();
+ SyncProgressHelper.run(new SyncRunnable() {
+
+ @Override
+ public void run(ISyncProgressMonitor monitor)
+ throws SyncException, IOException,
+ TimeoutException {
+ sync.pullFile(remoteFilePath, tempPath, monitor);
+ }
+
+ @Override
+ public void close() {
+ sync.close();
+ }
+ },
+ String.format(Messages.DeviceView_Pulling_From_Device,
+ remoteFilePath),
+ mParentShell);
+
+ open(tempPath);
+ } else {
+ // default action is ACTION_SAVE
+ promptAndPull(sync,
+ client.getClientData().getClientDescription() + DOT_HPROF,
+ remoteFilePath, Messages.DeviceView_Save_HPROF_File);
+
+ }
+ } else {
+ displayErrorFromUiThread(
+ Messages.DeviceView_Unable_Download_HPROF_From_Device_One_Param_First_Message,
+ device.getSerialNumber());
+ }
+ } catch (SyncException e) {
+ if (e.wasCanceled() == false) {
+ displayErrorFromUiThread(
+ Messages.DeviceView_Unable_Download_HPROF_From_Device_Two_Param,
+ device.getSerialNumber(), e.getMessage());
+ }
+ } catch (Exception e) {
+ displayErrorFromUiThread(
+ Messages.DeviceView_Unable_Download_HPROF_From_Device_One_Param_Second_Message,
+ 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());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onSuccess(final byte[] data, final Client client) {
+ mParentShell.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ // 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)) {
+ try {
+ // no need to give an extension since we're going to
+ // convert the
+ // file anyway after.
+ File tempFile = saveTempFile(data, null /* extension */);
+ open(tempFile.getAbsolutePath());
+ } catch (Exception e) {
+ String errorMsg = e.getMessage();
+ displayErrorFromUiThread(
+ Messages.DeviceView_Failed_To_Save_HPROF_Data,
+ errorMsg != null ? ":\n" + errorMsg : "."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ // default action is ACTION_SAVE
+ promptAndSave(client.getClientData().getClientDescription() + DOT_HPROF,
+ data, Messages.DeviceView_Save_HPROF_File);
+ }
+ }
+ });
+ }
+
+ 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); //$NON-NLS-1$
+ 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()) {
+ // before we open the file in an editor window, we make sure the
+ // current
+ // workbench page has an editor area (typically the ddms
+ // perspective doesn't).
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ IWorkbenchPage page = window.getActivePage();
+ if (page == null) {
+ return;
+ }
+
+ if (page.isEditorAreaVisible() == false) {
+ IAdaptable input;
+ input = page.getInput();
+ try {
+ workbench.showPerspective("org.eclipse.debug.ui.DebugPerspective", //$NON-NLS-1$
+ window, input);
+ } catch (WorkbenchException e) {
+ }
+ }
+
+ IDE.openEditorOnFileStore(page, fileStore);
+ }
+ }
+ }
+
+ public DeviceView() {
+ // the view is declared with allowMultiple="false" so we
+ // can safely do this.
+ sThis = this;
+ }
+
+ public static DeviceView getInstance() {
+ return sThis;
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mParentShell = parent.getShell();
+
+ ImageLoader loader = ImageLoader.getDdmUiLibLoader();
+
+ mDeviceList = new DevicePanel(USE_SELECTED_DEBUG_PORT);
+ mDeviceList.createPanel(parent);
+ mDeviceList.addSelectionListener(this);
+
+ DdmsPlugin plugin = DdmsPlugin.getDefault();
+ mDeviceList.addSelectionListener(plugin);
+ plugin.setListeningState(true);
+
+ mCaptureAction = new Action(Messages.DeviceView_Screen_Capture) {
+ @Override
+ public void run() {
+ ScreenShotDialog dlg = new ScreenShotDialog(
+ DdmsPlugin.getDisplay().getActiveShell());
+ dlg.open(mDeviceList.getSelectedDevice());
+ }
+ };
+ mCaptureAction.setToolTipText(Messages.DeviceView_Screen_Capture_Tooltip);
+ mCaptureAction.setImageDescriptor(loader.loadDescriptor("capture.png")); //$NON-NLS-1$
+
+ mViewUiAutomatorHierarchyAction = new Action("Dump View Hierarchy for UI Automator") {
+ @Override
+ public void run() {
+ takeUiAutomatorSnapshot(mDeviceList.getSelectedDevice(),
+ DdmsPlugin.getDisplay().getActiveShell());
+ }
+ };
+ mViewUiAutomatorHierarchyAction.setToolTipText("Dump View Hierarchy for UI Automator");
+ mViewUiAutomatorHierarchyAction.setImageDescriptor(
+ DdmsPlugin.getImageDescriptor("icons/uiautomator.png")); //$NON-NLS-1$
+
+ mSystraceAction = new Action("Capture System Wide Trace") {
+ @Override
+ public void run() {
+ launchSystrace(mDeviceList.getSelectedDevice(),
+ DdmsPlugin.getDisplay().getActiveShell());
+ }
+ };
+ mSystraceAction.setToolTipText("Capture system wide trace using Android systrace");
+ mSystraceAction.setImageDescriptor(
+ DdmsPlugin.getImageDescriptor("icons/systrace.png")); //$NON-NLS-1$
+ mSystraceAction.setEnabled(true);
+
+ mResetAdbAction = new Action(Messages.DeviceView_Reset_ADB) {
+ @Override
+ public void run() {
+ AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+ if (bridge != null) {
+ if (bridge.restart() == false) {
+ // get the current Display
+ final Display display = DdmsPlugin.getDisplay();
+
+ // dialog box only run in ui thread..
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ Shell shell = display.getActiveShell();
+ MessageDialog.openError(shell, Messages.DeviceView_ADB_Error,
+ Messages.DeviceView_ADB_Failed_Restart);
+ }
+ });
+ }
+ }
+ }
+ };
+ mResetAdbAction.setToolTipText(Messages.DeviceView_Reset_ADB_Host_Deamon);
+ mResetAdbAction.setImageDescriptor(PlatformUI.getWorkbench()
+ .getSharedImages().getImageDescriptor(
+ ISharedImages.IMG_OBJS_WARN_TSK));
+
+ mKillAppAction = new Action() {
+ @Override
+ public void run() {
+ mDeviceList.killSelectedClient();
+ }
+ };
+
+ mKillAppAction.setText(Messages.DeviceView_Stop_Process);
+ mKillAppAction.setToolTipText(Messages.DeviceView_Stop_Process_Tooltip);
+ mKillAppAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_HALT));
+
+ mGcAction = new Action() {
+ @Override
+ public void run() {
+ mDeviceList.forceGcOnSelectedClient();
+ }
+ };
+
+ mGcAction.setText(Messages.DeviceView_Cause_GC);
+ mGcAction.setToolTipText(Messages.DeviceView_Cause_GC_Tooltip);
+ mGcAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_GC));
+
+ mHprofAction = new Action() {
+ @Override
+ public void run() {
+ mDeviceList.dumpHprof();
+ doSelectionChanged(mDeviceList.getSelectedClient());
+ }
+ };
+ mHprofAction.setText(Messages.DeviceView_Dump_HPROF_File);
+ mHprofAction.setToolTipText(Messages.DeviceView_Dump_HPROF_File_Tooltip);
+ mHprofAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_HPROF));
+
+ mUpdateHeapAction = new Action(Messages.DeviceView_Update_Heap, IAction.AS_CHECK_BOX) {
+ @Override
+ public void run() {
+ boolean enable = mUpdateHeapAction.isChecked();
+ mDeviceList.setEnabledHeapOnSelectedClient(enable);
+ }
+ };
+ mUpdateHeapAction.setToolTipText(Messages.DeviceView_Update_Heap_Tooltip);
+ mUpdateHeapAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_HEAP));
+
+ mUpdateThreadAction = new Action(Messages.DeviceView_Threads, IAction.AS_CHECK_BOX) {
+ @Override
+ public void run() {
+ boolean enable = mUpdateThreadAction.isChecked();
+ mDeviceList.setEnabledThreadOnSelectedClient(enable);
+ }
+ };
+ mUpdateThreadAction.setToolTipText(Messages.DeviceView_Threads_Tooltip);
+ mUpdateThreadAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_THREAD));
+
+ mTracingAction = new Action() {
+ @Override
+ public void run() {
+ mDeviceList.toggleMethodProfiling();
+ }
+ };
+ mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
+ mTracingAction.setToolTipText(Messages.DeviceView_Start_Method_Profiling_Tooltip);
+ mTracingStartImage = loader.loadDescriptor(DevicePanel.ICON_TRACING_START);
+ mTracingStopImage = loader.loadDescriptor(DevicePanel.ICON_TRACING_STOP);
+ mTracingAction.setImageDescriptor(mTracingStartImage);
+
+ mDebugAction = new Action(Messages.DeviceView_Debug_Process) {
+ @Override
+ public void run() {
+ if (DdmsPlugin.getDefault().hasDebuggerConnectors()) {
+ Client currentClient = mDeviceList.getSelectedClient();
+ if (currentClient != null) {
+ ClientData clientData = currentClient.getClientData();
+
+ // make sure the client can be debugged
+ switch (clientData.getDebuggerConnectionStatus()) {
+ case ERROR: {
+ Display display = DdmsPlugin.getDisplay();
+ Shell shell = display.getActiveShell();
+ MessageDialog.openError(shell,
+ Messages.DeviceView_Debug_Process_Title,
+ Messages.DeviceView_Process_Debug_Already_In_Use);
+ return;
+ }
+ case ATTACHED: {
+ Display display = DdmsPlugin.getDisplay();
+ Shell shell = display.getActiveShell();
+ MessageDialog.openError(shell,
+ Messages.DeviceView_Debug_Process_Title,
+ Messages.DeviceView_Process_Already_Being_Debugged);
+ return;
+ }
+ }
+
+ // get the name of the client
+ String packageName = clientData.getClientDescription();
+ if (packageName != null) {
+
+ // try all connectors till one returns true.
+ IDebuggerConnector[] connectors =
+ DdmsPlugin.getDefault().getDebuggerConnectors();
+
+ if (connectors != null) {
+ for (IDebuggerConnector connector : connectors) {
+ try {
+ if (connector.connectDebugger(packageName,
+ currentClient.getDebuggerListenPort(),
+ DdmPreferences.getSelectedDebugPort())) {
+ return;
+ }
+ } catch (Throwable t) {
+ // ignore, we'll just not use this
+ // implementation
+ }
+ }
+ }
+
+ // if we get to this point, then we failed to find a
+ // project
+ // that matched the application to debug
+ Display display = DdmsPlugin.getDisplay();
+ Shell shell = display.getActiveShell();
+ MessageDialog.openError(shell, Messages.DeviceView_Debug_Process_Title,
+ String.format(
+ Messages.DeviceView_Debug_Session_Failed,
+ packageName));
+ }
+ }
+ }
+ }
+ };
+ mDebugAction.setToolTipText(Messages.DeviceView_Debug_Process_Tooltip);
+ mDebugAction.setImageDescriptor(loader.loadDescriptor("debug-attach.png")); //$NON-NLS-1$
+ mDebugAction.setEnabled(DdmsPlugin.getDefault().hasDebuggerConnectors());
+
+ placeActions();
+
+ // disabling all action buttons
+ selectionChanged(null, null);
+
+ ClientData.setHprofDumpHandler(new HProfHandler(mParentShell));
+ AndroidDebugBridge.addClientChangeListener(this);
+ ClientData.setMethodProfilingHandler(new MethodProfilingHandler(mParentShell) {
+ @Override
+ protected void open(String tempPath) {
+ if (DdmsPlugin.getDefault().launchTraceview(tempPath) == false) {
+ super.open(tempPath);
+ }
+ }
+ });
+ }
+
+ private void takeUiAutomatorSnapshot(final IDevice device, final Shell shell) {
+ ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
+ try {
+ dialog.run(true, false, new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException,
+ InterruptedException {
+ UiAutomatorResult result = null;
+ try {
+ result = UiAutomatorHelper.takeSnapshot(device, monitor);
+ } catch (UiAutomatorException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+
+ UiAutomatorViewer.openEditor(result);
+ }
+ });
+ } catch (Exception e) {
+ Throwable t = e;
+ if (e instanceof InvocationTargetException) {
+ t = ((InvocationTargetException) e).getTargetException();
+ }
+ Status s = new Status(IStatus.ERROR, DdmsPlugin.PLUGIN_ID,
+ "Error obtaining UI hierarchy", t);
+ ErrorDialog.openError(shell, "UI Automator",
+ "Unexpected error while obtaining UI hierarchy", s);
+ }
+ };
+
+ private void launchSystrace(final IDevice device, final Shell parentShell) {
+ final File systraceAssets = new File(DdmsPlugin.getPlatformToolsFolder(), "systrace"); //$NON-NLS-1$
+ if (!systraceAssets.isDirectory()) {
+ MessageDialog.openError(parentShell, "Systrace",
+ "Updated version of platform-tools (18.0.1 or greater) is required.\n"
+ + "Please update your platform-tools using SDK Manager.");
+ return;
+ }
+
+ SystraceVersionDetector detector = new SystraceVersionDetector(device);
+ try {
+ new ProgressMonitorDialog(parentShell).run(true, false, detector);
+ } catch (InvocationTargetException e) {
+ MessageDialog.openError(parentShell,
+ "Systrace",
+ "Unexpected error while detecting atrace version: " + e);
+ return;
+ } catch (InterruptedException e) {
+ return;
+ }
+
+ final ISystraceOptionsDialog dlg;
+ if (detector.getVersion() == SystraceVersionDetector.SYSTRACE_V1) {
+ dlg = new SystraceOptionsDialogV1(parentShell);
+ } else {
+ Client[] clients = device.getClients();
+ List<String> apps = new ArrayList<String>(clients.length);
+ for (int i = 0; i < clients.length; i++) {
+ String name = clients[i].getClientData().getClientDescription();
+ if (name != null && !name.isEmpty()) {
+ apps.add(name);
+ }
+ }
+ dlg = new SystraceOptionsDialogV2(parentShell, detector.getTags(), apps);
+ }
+
+ if (dlg.open() != SystraceOptionsDialogV1.OK) {
+ return;
+ }
+
+ final ISystraceOptions options = dlg.getSystraceOptions();
+
+ // set trace tag if necessary:
+ // adb shell setprop debug.atrace.tags.enableflags <tag>
+ String tag = options.getTags();
+ if (tag != null) {
+ CountDownLatch setTagLatch = new CountDownLatch(1);
+ CollectingOutputReceiver receiver = new CollectingOutputReceiver(setTagLatch);
+ try {
+ String cmd = "setprop debug.atrace.tags.enableflags " + tag;
+ device.executeShellCommand(cmd, receiver);
+ setTagLatch.await(5, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ MessageDialog.openError(parentShell,
+ "Systrace",
+ "Unexpected error while setting trace tags: " + e);
+ return;
+ }
+
+ String shellOutput = receiver.getOutput();
+ if (shellOutput.contains("Error type")) { //$NON-NLS-1$
+ throw new RuntimeException(receiver.getOutput());
+ }
+ }
+
+ // obtain the output of "adb shell atrace <trace-options>" and generate the html file
+ ProgressMonitorDialog d = new ProgressMonitorDialog(parentShell);
+ try {
+ d.run(true, true, new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException,
+ InterruptedException {
+ boolean COMPRESS_DATA = true;
+
+ monitor.setTaskName("Collecting Trace Information");
+ final String atraceOptions = options.getOptions()
+ + (COMPRESS_DATA ? " -z" : "");
+ SystraceTask task = new SystraceTask(device, atraceOptions);
+ Thread t = new Thread(task, "Systrace Output Receiver");
+ t.start();
+
+ // check if the user has cancelled tracing every so often
+ while (true) {
+ t.join(1000);
+
+ if (t.isAlive()) {
+ if (monitor.isCanceled()) {
+ task.cancel();
+ return;
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (task.getError() != null) {
+ throw new RuntimeException(task.getError());
+ }
+
+ monitor.setTaskName("Saving trace information");
+ SystraceOutputParser parser = new SystraceOutputParser(
+ COMPRESS_DATA,
+ SystraceOutputParser.getJs(systraceAssets),
+ SystraceOutputParser.getCss(systraceAssets),
+ SystraceOutputParser.getHtmlPrefix(systraceAssets),
+ SystraceOutputParser.getHtmlSuffix(systraceAssets));
+
+ parser.parse(task.getAtraceOutput());
+
+ String html = parser.getSystraceHtml();
+ try {
+ Files.write(html.getBytes(), new File(dlg.getTraceFilePath()));
+ } catch (IOException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ });
+ } catch (InvocationTargetException e) {
+ ErrorDialog.openError(parentShell, "Systrace",
+ "Unable to collect system trace.",
+ new Status(Status.ERROR,
+ DdmsPlugin.PLUGIN_ID,
+ "Unexpected error while collecting system trace.",
+ e.getCause()));
+ } catch (InterruptedException ignore) {
+ }
+ }
+
+ @Override
+ public void setFocus() {
+ mDeviceList.setFocus();
+ }
+
+ /**
+ * Sent when a new {@link IDevice} and {@link Client} are selected.
+ *
+ * @param selectedDevice the selected device. If null, no devices are
+ * selected.
+ * @param selectedClient The selected client. If null, no clients are
+ * selected.
+ */
+ @Override
+ public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
+ // update the buttons
+ doSelectionChanged(selectedClient);
+ doSelectionChanged(selectedDevice);
+ }
+
+ private void doSelectionChanged(Client selectedClient) {
+ // update the buttons
+ if (selectedClient != null) {
+ if (USE_SELECTED_DEBUG_PORT) {
+ // set the client as the debug client
+ selectedClient.setAsSelectedClient();
+ }
+
+ mDebugAction.setEnabled(DdmsPlugin.getDefault().hasDebuggerConnectors());
+ mKillAppAction.setEnabled(true);
+ mGcAction.setEnabled(true);
+
+ mUpdateHeapAction.setEnabled(true);
+ mUpdateHeapAction.setChecked(selectedClient.isHeapUpdateEnabled());
+
+ mUpdateThreadAction.setEnabled(true);
+ mUpdateThreadAction.setChecked(selectedClient.isThreadUpdateEnabled());
+
+ ClientData data = selectedClient.getClientData();
+
+ if (data.hasFeature(ClientData.FEATURE_HPROF)) {
+ mHprofAction.setEnabled(data.hasPendingHprofDump() == false);
+ mHprofAction.setToolTipText(Messages.DeviceView_Dump_HPROF_File);
+ } else {
+ mHprofAction.setEnabled(false);
+ mHprofAction
+ .setToolTipText(Messages.DeviceView_Dump_HPROF_File_Not_Supported_By_VM);
+ }
+
+ if (data.hasFeature(ClientData.FEATURE_PROFILING)) {
+ mTracingAction.setEnabled(true);
+ if (data.getMethodProfilingStatus() == MethodProfilingStatus.TRACER_ON
+ || data.getMethodProfilingStatus() == MethodProfilingStatus.SAMPLER_ON) {
+ mTracingAction
+ .setToolTipText(Messages.DeviceView_Stop_Method_Profiling_Tooltip);
+ mTracingAction.setText(Messages.DeviceView_Stop_Method_Profiling);
+ mTracingAction.setImageDescriptor(mTracingStopImage);
+ } else {
+ mTracingAction
+ .setToolTipText(Messages.DeviceView_Start_Method_Profiling_Tooltip);
+ mTracingAction.setImageDescriptor(mTracingStartImage);
+ mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
+ }
+ } else {
+ mTracingAction.setEnabled(false);
+ mTracingAction.setImageDescriptor(mTracingStartImage);
+ mTracingAction
+ .setToolTipText(Messages.DeviceView_Start_Method_Profiling_Not_Suported_By_Vm);
+ mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
+ }
+ } else {
+ if (USE_SELECTED_DEBUG_PORT) {
+ // set the client as the debug client
+ AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+ if (bridge != null) {
+ bridge.setSelectedClient(null);
+ }
+ }
+
+ mDebugAction.setEnabled(false);
+ mKillAppAction.setEnabled(false);
+ mGcAction.setEnabled(false);
+ mUpdateHeapAction.setChecked(false);
+ mUpdateHeapAction.setEnabled(false);
+ mUpdateThreadAction.setEnabled(false);
+ mUpdateThreadAction.setChecked(false);
+ mHprofAction.setEnabled(false);
+
+ mHprofAction.setEnabled(false);
+ mHprofAction.setToolTipText(Messages.DeviceView_Dump_HPROF_File);
+
+ mTracingAction.setEnabled(false);
+ mTracingAction.setImageDescriptor(mTracingStartImage);
+ mTracingAction.setToolTipText(Messages.DeviceView_Start_Method_Profiling_Tooltip);
+ mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
+ }
+
+ for (IClientAction a : DdmsPlugin.getDefault().getClientSpecificActions()) {
+ a.selectedClientChanged(selectedClient);
+ }
+ }
+
+ private void doSelectionChanged(IDevice selectedDevice) {
+ boolean validDevice = selectedDevice != null;
+
+ mCaptureAction.setEnabled(validDevice);
+ mViewUiAutomatorHierarchyAction.setEnabled(validDevice);
+ mSystraceAction.setEnabled(validDevice);
+ }
+
+ /**
+ * Place the actions in the ui.
+ */
+ private final void placeActions() {
+ IActionBars actionBars = getViewSite().getActionBars();
+
+ // first in the menu
+ IMenuManager menuManager = actionBars.getMenuManager();
+ menuManager.removeAll();
+ menuManager.add(mDebugAction);
+ menuManager.add(new Separator());
+ menuManager.add(mUpdateHeapAction);
+ menuManager.add(mHprofAction);
+ menuManager.add(mGcAction);
+ menuManager.add(new Separator());
+ menuManager.add(mUpdateThreadAction);
+ menuManager.add(mTracingAction);
+ menuManager.add(new Separator());
+ menuManager.add(mKillAppAction);
+ menuManager.add(new Separator());
+ menuManager.add(mCaptureAction);
+ menuManager.add(new Separator());
+ menuManager.add(mViewUiAutomatorHierarchyAction);
+ menuManager.add(new Separator());
+ menuManager.add(mSystraceAction);
+ menuManager.add(new Separator());
+ menuManager.add(mResetAdbAction);
+ for (IClientAction a : DdmsPlugin.getDefault().getClientSpecificActions()) {
+ menuManager.add(a.getAction());
+ }
+
+ // and then in the toolbar
+ IToolBarManager toolBarManager = actionBars.getToolBarManager();
+ toolBarManager.removeAll();
+ toolBarManager.add(mDebugAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mUpdateHeapAction);
+ toolBarManager.add(mHprofAction);
+ toolBarManager.add(mGcAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mUpdateThreadAction);
+ toolBarManager.add(mTracingAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mKillAppAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mCaptureAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mViewUiAutomatorHierarchyAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mSystraceAction);
+ for (IClientAction a : DdmsPlugin.getDefault().getClientSpecificActions()) {
+ toolBarManager.add(a.getAction());
+ }
+ }
+
+ @Override
+ public void clientChanged(final Client client, int changeMask) {
+ if ((changeMask & Client.CHANGE_METHOD_PROFILING_STATUS) == Client.CHANGE_METHOD_PROFILING_STATUS) {
+ if (mDeviceList.getSelectedClient() == client) {
+ mParentShell.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ // force refresh of the button enabled state.
+ doSelectionChanged(client);
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java
new file mode 100644
index 000000000..0dda7ef61
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.EmulatorControlPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class EmulatorControlView extends SelectionDependentViewPart {
+
+ public static final String ID =
+ "com.android.ide.eclipse.ddms.views.EmulatorControlView"; //$NON-NLS-1$
+
+ private EmulatorControlPanel mPanel;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mPanel = new EmulatorControlPanel();
+ mPanel.createPanel(parent);
+ setSelectionDependentPanel(mPanel);
+ }
+
+ @Override
+ public void setFocus() {
+ mPanel.setFocus();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java
new file mode 100644
index 000000000..653f17f43
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.ddmuilib.log.event.EventLogPanel;
+import com.android.ide.eclipse.ddms.CommonAction;
+import com.android.ide.eclipse.ddms.i18n.Messages;
+
+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.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+
+public class EventLogView extends SelectionDependentViewPart {
+
+ private EventLogPanel mLogPanel;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ ImageLoader loader = ImageLoader.getDdmUiLibLoader();
+
+ // create the external actions
+ CommonAction optionsAction = new CommonAction(Messages.EventLogView_Options);
+ optionsAction.setToolTipText(Messages.EventLogView_Opens_Options_Panel);
+ optionsAction.setImageDescriptor(loader.loadDescriptor("edit.png")); //$NON-NLS-1$
+
+ CommonAction clearLogAction = new CommonAction(Messages.EventLogView_Clear_Log);
+ clearLogAction.setToolTipText(Messages.EventLogView_Clears_Event_Log);
+ clearLogAction.setImageDescriptor(loader.loadDescriptor("clear.png")); //$NON-NLS-1$
+
+ CommonAction saveAction = new CommonAction(Messages.EventLogView_Save_Log);
+ saveAction.setToolTipText(Messages.EventLogView_Saves_Event_Log);
+ saveAction.setImageDescriptor(loader.loadDescriptor("save.png")); //$NON-NLS-1$
+
+ CommonAction loadAction = new CommonAction(Messages.EventLogView_Load_Log);
+ loadAction.setToolTipText(Messages.EventLogView_Loads_Event_Log);
+ loadAction.setImageDescriptor(loader.loadDescriptor("load.png")); //$NON-NLS-1$
+
+ CommonAction importBugAction = new CommonAction(Messages.EventLogView_Import_Bug_Report_Log);
+ importBugAction.setToolTipText(Messages.EventLogView_Imports_Bug_Report);
+ importBugAction.setImageDescriptor(loader.loadDescriptor("importBug.png")); //$NON-NLS-1$
+
+ placeActions(optionsAction, clearLogAction, saveAction, loadAction, importBugAction);
+
+ mLogPanel = new EventLogPanel();
+ mLogPanel
+ .setActions(optionsAction, clearLogAction, saveAction, loadAction, importBugAction);
+ mLogPanel.createPanel(parent);
+ setSelectionDependentPanel(mLogPanel);
+ }
+
+ @Override
+ public void setFocus() {
+ mLogPanel.setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ if (mLogPanel != null) {
+ mLogPanel.stopEventLog(true);
+ }
+ }
+
+ /**
+ * Places the actions in the toolbar and in the menu.
+ *
+ * @param importBugAction
+ */
+ private void placeActions(IAction optionAction, IAction clearAction, IAction saveAction,
+ IAction loadAction, CommonAction importBugAction) {
+ IActionBars actionBars = getViewSite().getActionBars();
+
+ // first in the menu
+ IMenuManager menuManager = actionBars.getMenuManager();
+ menuManager.add(clearAction);
+ menuManager.add(new Separator());
+ menuManager.add(saveAction);
+ menuManager.add(loadAction);
+ menuManager.add(importBugAction);
+ menuManager.add(new Separator());
+ menuManager.add(optionAction);
+
+ // and then in the toolbar
+ IToolBarManager toolBarManager = actionBars.getToolBarManager();
+ toolBarManager.add(clearAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(saveAction);
+ toolBarManager.add(loadAction);
+ toolBarManager.add(importBugAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(optionAction);
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java
new file mode 100644
index 000000000..41796dcfd
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.IDevice;
+import com.android.ddmuilib.ImageLoader;
+import com.android.ddmuilib.explorer.DeviceExplorer;
+import com.android.ide.eclipse.ddms.CommonAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.DdmsPlugin.ISelectionListener;
+import com.android.ide.eclipse.ddms.i18n.Messages;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+public class FileExplorerView extends ViewPart implements ISelectionListener {
+
+ public static final String ID = "com.android.ide.eclipse.ddms.views.FileExplorerView"; //$NON-NLS-1$
+
+ private final static String COLUMN_NAME =
+ DdmsPlugin.PLUGIN_ID + ".explorer.name"; //$NON-NLS-1S
+ private final static String COLUMN_SIZE =
+ DdmsPlugin.PLUGIN_ID + ".explorer.size"; //$NON-NLS-1S
+ private final static String COLUMN_DATE =
+ DdmsPlugin.PLUGIN_ID + ".explorer.data"; //$NON-NLS-1S
+ private final static String COLUMN_TIME =
+ DdmsPlugin.PLUGIN_ID + ".explorer.time"; //$NON-NLS-1S
+ private final static String COLUMN_PERMISSIONS =
+ DdmsPlugin.PLUGIN_ID + ".explorer.permissions"; //$NON-NLS-1S
+ private final static String COLUMN_INFO =
+ DdmsPlugin.PLUGIN_ID + ".explorer.info"; //$NON-NLS-1$
+
+ private DeviceExplorer mExplorer;
+
+ public FileExplorerView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ ImageLoader loader = ImageLoader.getDdmUiLibLoader();
+
+ DeviceExplorer.COLUMN_NAME = COLUMN_NAME;
+ DeviceExplorer.COLUMN_SIZE = COLUMN_SIZE;
+ DeviceExplorer.COLUMN_DATE = COLUMN_DATE;
+ DeviceExplorer.COLUMN_TIME = COLUMN_TIME;
+ DeviceExplorer.COLUMN_PERMISSIONS = COLUMN_PERMISSIONS;
+ DeviceExplorer.COLUMN_INFO = COLUMN_INFO;
+
+ // device explorer
+ mExplorer = new DeviceExplorer();
+
+ mExplorer.setCustomImages(
+ PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE),
+ PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER),
+ null /* apk image */,
+ PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT)
+ );
+
+ // creates the actions
+ CommonAction pushAction = new CommonAction(Messages.FileExplorerView_Push_File) {
+ @Override
+ public void run() {
+ mExplorer.pushIntoSelection();
+ }
+ };
+ pushAction.setToolTipText(Messages.FileExplorerView_Push_File_Onto_Device);
+ pushAction.setImageDescriptor(loader.loadDescriptor("push.png")); //$NON-NLS-1$
+ pushAction.setEnabled(false);
+
+ CommonAction pullAction = new CommonAction(Messages.FileExplorerView_Pull_File) {
+ @Override
+ public void run() {
+ mExplorer.pullSelection();
+ }
+ };
+ pullAction.setToolTipText(Messages.FileExplorerView_Pull_File_From_File);
+ pullAction.setImageDescriptor(loader.loadDescriptor("pull.png")); //$NON-NLS-1$
+ pullAction.setEnabled(false);
+
+ CommonAction deleteAction = new CommonAction(Messages.FileExplorerView_Delete) {
+ @Override
+ public void run() {
+ mExplorer.deleteSelection();
+ }
+ };
+ deleteAction.setToolTipText(Messages.FileExplorerView_Delete_The_Selection);
+ deleteAction.setImageDescriptor(loader.loadDescriptor("delete.png")); //$NON-NLS-1$
+ deleteAction.setEnabled(false);
+
+ CommonAction createNewFolderAction = new CommonAction("New Folder") {
+ @Override
+ public void run() {
+ mExplorer.createNewFolderInSelection();
+ }
+ };
+ createNewFolderAction.setToolTipText("New Folder");
+ createNewFolderAction.setImageDescriptor(loader.loadDescriptor("add.png")); //$NON-NLS-1$
+ createNewFolderAction.setEnabled(false);
+
+ // set up the actions in the explorer
+ mExplorer.setActions(pushAction, pullAction, deleteAction, createNewFolderAction);
+
+ // and in the ui
+ IActionBars actionBars = getViewSite().getActionBars();
+ IMenuManager menuManager = actionBars.getMenuManager();
+ IToolBarManager toolBarManager = actionBars.getToolBarManager();
+
+ menuManager.add(pullAction);
+ menuManager.add(pushAction);
+ menuManager.add(new Separator());
+ menuManager.add(deleteAction);
+ menuManager.add(new Separator());
+ menuManager.add(createNewFolderAction);
+
+ toolBarManager.add(pullAction);
+ toolBarManager.add(pushAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(deleteAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(createNewFolderAction);
+
+ mExplorer.createPanel(parent);
+
+ DdmsPlugin.getDefault().addSelectionListener(this);
+ }
+
+ @Override
+ public void setFocus() {
+ mExplorer.setFocus();
+ }
+
+ /**
+ * Sent when a new {@link Client} is selected.
+ *
+ * @param selectedClient The selected client.
+ */
+ @Override
+ public void selectionChanged(Client selectedClient) {
+ // pass
+ }
+
+ /**
+ * Sent when a new {@link Device} is selected.
+ *
+ * @param selectedDevice the selected device.
+ */
+ @Override
+ public void selectionChanged(IDevice selectedDevice) {
+ mExplorer.switchDevice(selectedDevice);
+ }
+
+ /**
+ * Sent when there is no current selection.
+ */
+ public void selectionRemoved() {
+
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java
new file mode 100644
index 000000000..5745e8efc
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.HeapPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class HeapView extends TableView {
+
+ public static final String ID = "com.android.ide.eclipse.ddms.views.HeapView"; //$NON-NLS-1$
+ private HeapPanel mPanel;
+
+ public HeapView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mPanel = new HeapPanel();
+ mPanel.createPanel(parent);
+
+ setSelectionDependentPanel(mPanel);
+
+ // listen to focus changes for table(s) of the panel.
+ setupTableFocusListener(mPanel, parent);
+ }
+
+ @Override
+ public void setFocus() {
+ mPanel.setFocus();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
new file mode 100644
index 000000000..9f78c4aa1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.logcat.LogCatMessage;
+import com.android.ddmuilib.logcat.ILogCatMessageSelectionListener;
+import com.android.ddmuilib.logcat.LogCatPanel;
+import com.android.ddmuilib.logcat.LogCatStackTraceParser;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.JavaSourceRevealer;
+import com.android.ide.eclipse.ddms.i18n.Messages;
+import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+
+public class LogCatView extends SelectionDependentViewPart {
+ /** LogCatView ID as defined in plugin.xml. */
+ public static final String ID = "com.android.ide.eclipse.ddms.views.LogCatView"; //$NON-NLS-1$
+
+ /** Switch perspective when a Java file is opened from logcat view. */
+ public static final boolean DEFAULT_SWITCH_PERSPECTIVE = true;
+
+ /** Target perspective to open when a Java file is opened from logcat view. */
+ public static final String DEFAULT_PERSPECTIVE_ID =
+ "org.eclipse.jdt.ui.JavaPerspective"; //$NON-NLS-1$
+
+ private LogCatPanel mLogCatPanel;
+ private LogCatStackTraceParser mStackTraceParser = new LogCatStackTraceParser();
+
+ private Clipboard mClipboard;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new FillLayout());
+
+ IPreferenceStore prefStore = DdmsPlugin.getDefault().getPreferenceStore();
+ mLogCatPanel = new LogCatPanel(prefStore);
+ mLogCatPanel.createPanel(parent);
+ setSelectionDependentPanel(mLogCatPanel);
+
+ mLogCatPanel.addLogCatMessageSelectionListener(new ILogCatMessageSelectionListener() {
+ @Override
+ public void messageDoubleClicked(LogCatMessage m) {
+ onDoubleClick(m);
+ }
+ });
+
+ mClipboard = new Clipboard(parent.getDisplay());
+ IActionBars actionBars = getViewSite().getActionBars();
+ actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
+ new Action(Messages.LogCatView_Copy) {
+ @Override
+ public void run() {
+ mLogCatPanel.copySelectionToClipboard(mClipboard);
+ }
+ });
+
+ actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
+ new Action(Messages.LogCatView_Select_All) {
+ @Override
+ public void run() {
+ mLogCatPanel.selectAll();
+ }
+ });
+
+ actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(),
+ new Action("Find") {
+ @Override
+ public void run() {
+ mLogCatPanel.showFindDialog();
+ }
+ });
+ }
+
+ @Override
+ public void setFocus() {
+ }
+
+ private void onDoubleClick(LogCatMessage m) {
+ String msg = m.getMessage();
+ if (!mStackTraceParser.isValidExceptionTrace(msg)) {
+ return;
+ }
+
+ IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+ String perspectiveId = null;
+ if (store.getBoolean(PreferenceInitializer.ATTR_SWITCH_PERSPECTIVE)) {
+ perspectiveId = store.getString(PreferenceInitializer.ATTR_PERSPECTIVE_ID);
+ }
+
+
+ String fileName = mStackTraceParser.getFileName(msg);
+ int lineNumber = mStackTraceParser.getLineNumber(msg);
+ String methodName = mStackTraceParser.getMethodName(msg);
+ JavaSourceRevealer.revealMethod(methodName, fileName, lineNumber, perspectiveId);
+ }
+
+ public void selectTransientAppFilter(String appName) {
+ mLogCatPanel.selectTransientAppFilter(appName);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java
new file mode 100644
index 000000000..91c8022b7
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.NativeHeapPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class NativeHeapView extends TableView {
+
+ public static final String ID =
+ "com.android.ide.eclipse.ddms.views.NativeHeapView"; //$NON-NLS-1$
+ private NativeHeapPanel mPanel;
+
+ public NativeHeapView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mPanel = new NativeHeapPanel();
+ mPanel.createPanel(parent);
+
+ setSelectionDependentPanel(mPanel);
+
+ // listen to focus changes for table(s) of the panel.
+ setupTableFocusListener(mPanel, parent);
+ }
+
+ @Override
+ public void setFocus() {
+ mPanel.setFocus();
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NetworkStatisticsView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NetworkStatisticsView.java
new file mode 100644
index 000000000..f90189c6d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NetworkStatisticsView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.net.NetworkPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class NetworkStatisticsView extends TableView {
+ public static final String ID = "com.android.ide.eclipse.ddms.views.NetworkStatsView";
+
+ private NetworkPanel mPanel;
+
+ public NetworkStatisticsView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mPanel = new NetworkPanel();
+ mPanel.createPanel(parent);
+
+ setSelectionDependentPanel(mPanel);
+
+ // listen to focus changes for table(s) of the panel.
+ setupTableFocusListener(mPanel, parent);
+ }
+
+ @Override
+ public void setFocus() {
+ mPanel.setFocus();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/OldLogCatView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/OldLogCatView.java
new file mode 100644
index 000000000..d0b1fb442
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/OldLogCatView.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.ImageLoader;
+import com.android.ddmuilib.logcat.LogColors;
+import com.android.ddmuilib.logcat.LogFilter;
+import com.android.ddmuilib.logcat.LogPanel;
+import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
+import com.android.ddmuilib.logcat.LogPanel.LogCatViewInterface;
+import com.android.ide.eclipse.ddms.CommonAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.i18n.Messages;
+import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Status;
+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.preference.IPreferenceStore;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IPerspectiveRegistry;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.ide.IDE;
+
+import java.util.ArrayList;
+
+/**
+ * The log cat view displays log output from the current device selection.
+ */
+public final class OldLogCatView extends SelectionDependentViewPart implements LogCatViewInterface {
+
+ public static final String ID = "com.android.ide.eclipse.ddms.views.OldLogCatView"; //$NON-NLS-1$
+
+ private static final String PREFS_COL_TIME =
+ DdmsPlugin.PLUGIN_ID + ".logcat.time"; //$NON-NLS-1$
+ private static final String PREFS_COL_LEVEL =
+ DdmsPlugin.PLUGIN_ID + ".logcat.level"; //$NON-NLS-1$
+ private static final String PREFS_COL_PID =
+ DdmsPlugin.PLUGIN_ID + ".logcat.pid"; //$NON-NLS-1$
+ private static final String PREFS_COL_TAG =
+ DdmsPlugin.PLUGIN_ID + ".logcat.tag"; //$NON-NLS-1$
+ private static final String PREFS_COL_MESSAGE =
+ DdmsPlugin.PLUGIN_ID + ".logcat.message"; //$NON-NLS-1$
+
+ private static final String PREFS_FILTERS =
+ DdmsPlugin.PLUGIN_ID + ".logcat.filters"; //$NON-NLS-1$
+
+ public static final String CHOICE_METHOD_DECLARATION =
+ DdmsPlugin.PLUGIN_ID + ".logcat.MethodDeclaration"; //$NON-NLS-1$
+ public static final String CHOICE_ERROR_LINE =
+ DdmsPlugin.PLUGIN_ID + ".logcat.ErrorLine"; //$NON-NLS-1$
+
+ /* Default values for the switch of perspective. */
+ public static final boolean DEFAULT_SWITCH_PERSPECTIVE = true;
+ public static final String DEFAULT_PERSPECTIVE_ID = "org.eclipse.jdt.ui.JavaPerspective"; //$NON-NLS-1$
+ private static OldLogCatView sThis;
+ private LogPanel mLogPanel;
+
+ private CommonAction mCreateFilterAction;
+ private CommonAction mDeleteFilterAction;
+ private CommonAction mEditFilterAction;
+ private CommonAction mExportAction;
+
+ private CommonAction[] mLogLevelActions;
+ private String[] mLogLevelIcons = {
+ "v.png", //$NON-NLS-1S
+ "d.png", //$NON-NLS-1S
+ "i.png", //$NON-NLS-1S
+ "w.png", //$NON-NLS-1S
+ "e.png", //$NON-NLS-1S
+ };
+
+ private Action mClearAction;
+
+ private Clipboard mClipboard;
+
+ /**
+ * An implementation of {@link ILogFilterStorageManager} to bridge to the
+ * eclipse preference store, and saves the log filters.
+ */
+ private final class FilterStorage implements ILogFilterStorageManager {
+
+ @Override
+ public LogFilter[] getFilterFromStore() {
+ String filterPrefs = DdmsPlugin.getDefault().getPreferenceStore().getString(
+ PREFS_FILTERS);
+
+ // split in a string per filter
+ String[] filters = filterPrefs.split("\\|"); //$NON-NLS-1$
+
+ ArrayList<LogFilter> list =
+ new ArrayList<LogFilter>(filters.length);
+
+ for (String f : filters) {
+ if (f.length() > 0) {
+ LogFilter logFilter = new LogFilter();
+ if (logFilter.loadFromString(f)) {
+ list.add(logFilter);
+ }
+ }
+ }
+
+ return list.toArray(new LogFilter[list.size()]);
+ }
+
+ @Override
+ public void saveFilters(LogFilter[] filters) {
+ StringBuilder sb = new StringBuilder();
+ for (LogFilter f : filters) {
+ String filterString = f.toString();
+ sb.append(filterString);
+ sb.append('|');
+ }
+
+ DdmsPlugin.getDefault().getPreferenceStore().setValue(PREFS_FILTERS, sb.toString());
+ }
+
+ @Override
+ public boolean requiresDefaultFilter() {
+ return true;
+ }
+ }
+
+ public OldLogCatView() {
+ sThis = this;
+ LogPanel.PREFS_TIME = PREFS_COL_TIME;
+ LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
+ LogPanel.PREFS_PID = PREFS_COL_PID;
+ LogPanel.PREFS_TAG = PREFS_COL_TAG;
+ LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
+ }
+
+ /**
+ * Returns the singleton instance.
+ */
+ public static OldLogCatView getInstance() {
+ return sThis;
+ }
+
+ /**
+ * Sets the display font.
+ *
+ * @param font The font.
+ */
+ public static void setFont(Font font) {
+ if (sThis != null && sThis.mLogPanel != null) {
+ sThis.mLogPanel.setFont(font);
+ }
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ Display d = parent.getDisplay();
+ LogColors colors = new LogColors();
+
+ ImageLoader loader = ImageLoader.getDdmUiLibLoader();
+
+ colors.infoColor = new Color(d, 0, 127, 0);
+ colors.debugColor = new Color(d, 0, 0, 127);
+ colors.errorColor = new Color(d, 255, 0, 0);
+ colors.warningColor = new Color(d, 255, 127, 0);
+ colors.verboseColor = new Color(d, 0, 0, 0);
+
+ mCreateFilterAction = new CommonAction(Messages.LogCatView_Create_Filter) {
+ @Override
+ public void run() {
+ mLogPanel.addFilter();
+ }
+ };
+ mCreateFilterAction.setToolTipText(Messages.LogCatView_Create_Filter_Tooltip);
+ mCreateFilterAction.setImageDescriptor(loader.loadDescriptor("add.png")); //$NON-NLS-1$
+
+ mEditFilterAction = new CommonAction(Messages.LogCatView_Edit_Filter) {
+ @Override
+ public void run() {
+ mLogPanel.editFilter();
+ }
+ };
+ mEditFilterAction.setToolTipText(Messages.LogCatView_Edit_Filter_Tooltip);
+ mEditFilterAction.setImageDescriptor(loader.loadDescriptor("edit.png")); //$NON-NLS-1$
+
+ mDeleteFilterAction = new CommonAction(Messages.LogCatView_Delete_Filter) {
+ @Override
+ public void run() {
+ mLogPanel.deleteFilter();
+ }
+ };
+ mDeleteFilterAction.setToolTipText(Messages.LogCatView_Delete_Filter_Tooltip);
+ mDeleteFilterAction.setImageDescriptor(loader.loadDescriptor("delete.png")); //$NON-NLS-1$
+
+ mExportAction = new CommonAction(Messages.LogCatView_Export_Selection_As_Text) {
+ @Override
+ public void run() {
+ mLogPanel.save();
+ }
+ };
+ mExportAction.setToolTipText(Messages.LogCatView_Export_Selection_As_Text_Tooltip);
+ mExportAction.setImageDescriptor(loader.loadDescriptor("save.png")); //$NON-NLS-1$
+
+ LogLevel[] levels = LogLevel.values();
+ mLogLevelActions = new CommonAction[mLogLevelIcons.length];
+ for (int i = 0; i < mLogLevelActions.length; i++) {
+ String name = levels[i].getStringValue();
+ mLogLevelActions[i] = new CommonAction(name, IAction.AS_CHECK_BOX) {
+ @Override
+ public void run() {
+ // disable the other actions and record current index
+ for (int j = 0; j < mLogLevelActions.length; j++) {
+ Action a = mLogLevelActions[j];
+ if (a == this) {
+ a.setChecked(true);
+
+ // set the log level
+ mLogPanel.setCurrentFilterLogLevel(j + 2);
+ } else {
+ a.setChecked(false);
+ }
+ }
+ }
+ };
+
+ mLogLevelActions[i].setToolTipText(name);
+ mLogLevelActions[i].setImageDescriptor(loader.loadDescriptor(mLogLevelIcons[i]));
+ }
+
+ mClearAction = new Action(Messages.LogCatView_Clear_Log) {
+ @Override
+ public void run() {
+ mLogPanel.clear();
+ }
+ };
+ mClearAction.setImageDescriptor(loader.loadDescriptor("clear.png")); //$NON-NLS-1$
+
+ // now create the log view
+ mLogPanel = new LogPanel(colors, new FilterStorage(), LogPanel.FILTER_MANUAL);
+ mLogPanel.setLogCatViewInterface(this);
+ mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
+
+ // get the font
+ String fontStr = DdmsPlugin.getDefault().getPreferenceStore().getString(
+ PreferenceInitializer.ATTR_LOGCAT_FONT);
+ if (fontStr != null) {
+ FontData data = new FontData(fontStr);
+
+ if (fontStr != null) {
+ mLogPanel.setFont(new Font(parent.getDisplay(), data));
+ }
+ }
+
+ mLogPanel.createPanel(parent);
+ setSelectionDependentPanel(mLogPanel);
+
+ // place the actions.
+ placeActions();
+
+ // setup the copy action
+ mClipboard = new Clipboard(d);
+ IActionBars actionBars = getViewSite().getActionBars();
+ actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), new Action(
+ Messages.LogCatView_Copy) {
+ @Override
+ public void run() {
+ mLogPanel.copy(mClipboard);
+ }
+ });
+
+ // setup the select all action
+ actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
+ new Action(Messages.LogCatView_Select_All) {
+ @Override
+ public void run() {
+ mLogPanel.selectAll();
+ }
+ });
+ }
+
+ @Override
+ public void dispose() {
+ mLogPanel.stopLogCat(true);
+ mClipboard.dispose();
+ }
+
+ @Override
+ public void setFocus() {
+ mLogPanel.setFocus();
+ }
+
+ /**
+ * Place the actions in the ui.
+ */
+ private void placeActions() {
+ IActionBars actionBars = getViewSite().getActionBars();
+
+ // first in the menu
+ IMenuManager menuManager = actionBars.getMenuManager();
+ menuManager.add(mCreateFilterAction);
+ menuManager.add(mEditFilterAction);
+ menuManager.add(mDeleteFilterAction);
+ menuManager.add(new Separator());
+ menuManager.add(mClearAction);
+ menuManager.add(new Separator());
+ menuManager.add(mExportAction);
+
+ // and then in the toolbar
+ IToolBarManager toolBarManager = actionBars.getToolBarManager();
+ for (CommonAction a : mLogLevelActions) {
+ toolBarManager.add(a);
+ }
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mCreateFilterAction);
+ toolBarManager.add(mEditFilterAction);
+ toolBarManager.add(mDeleteFilterAction);
+ toolBarManager.add(new Separator());
+ toolBarManager.add(mClearAction);
+ }
+
+ void openFile(IFile file, IMarker marker) {
+ try {
+ IWorkbenchPage page = getViewSite().getWorkbenchWindow()
+ .getActivePage();
+ if (page != null) {
+ IDE.openEditor(page, marker);
+ marker.delete();
+ }
+ } catch (CoreException e) {
+ Status s = new Status(Status.ERROR, DdmsPlugin.PLUGIN_ID, e.getMessage(), e);
+ DdmsPlugin.getDefault().getLog().log(s);
+ }
+ }
+
+ void switchPerspective() {
+ IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+ if (store.getBoolean(PreferenceInitializer.ATTR_SWITCH_PERSPECTIVE)) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ IPerspectiveRegistry perspectiveRegistry = workbench.getPerspectiveRegistry();
+ String perspectiveId = store.getString(PreferenceInitializer.ATTR_PERSPECTIVE_ID);
+ if (perspectiveId != null
+ && perspectiveId.length() > 0
+ && perspectiveRegistry.findPerspectiveWithId(perspectiveId) != null) {
+ try {
+ workbench.showPerspective(perspectiveId, window);
+ } catch (WorkbenchException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onDoubleClick() {
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
new file mode 100644
index 000000000..3326d0138
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.IDevice;
+import com.android.ddmuilib.SelectionDependentPanel;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.DdmsPlugin.ISelectionListener;
+
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * A Workbench {@link ViewPart} that requires {@link Device}/{@link Client} selection notifications
+ * from {@link DdmsPlugin} through the {@link ISelectionListener} interface.
+ */
+public abstract class SelectionDependentViewPart extends ViewPart implements ISelectionListener {
+
+ private SelectionDependentPanel mPanel;
+
+ protected final void setSelectionDependentPanel(SelectionDependentPanel panel) {
+ // remember the panel
+ mPanel = panel;
+
+ // and add ourself as listener of selection events.
+ DdmsPlugin.getDefault().addSelectionListener(this);
+ }
+
+ @Override
+ public void dispose() {
+ DdmsPlugin.getDefault().removeSelectionListener(this);
+ super.dispose();
+ }
+
+ /**
+ * Sent when a new {@link Client} is selected.
+ * @param selectedClient The selected client.
+ *
+ * @see ISelectionListener
+ */
+ @Override
+ public final void selectionChanged(Client selectedClient) {
+ mPanel.clientSelected(selectedClient);
+ }
+
+ /**
+ * Sent when a new {@link Device} is selected.
+ * @param selectedDevice the selected device.
+ *
+ * @see ISelectionListener
+ */
+ @Override
+ public final void selectionChanged(IDevice selectedDevice) {
+ mPanel.deviceSelected(selectedDevice);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SysInfoView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SysInfoView.java
new file mode 100644
index 000000000..e4939250e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SysInfoView.java
@@ -0,0 +1,29 @@
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.SysinfoPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class SysInfoView extends SelectionDependentViewPart {
+ public static final String ID = "com.android.ide.eclipse.ddms.views.SysInfoView"; //$NON-NLS-1$
+
+ private SysinfoPanel mSysInfoPanel;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mSysInfoPanel = new SysinfoPanel();
+ mSysInfoPanel.createPanel(parent);
+ setSelectionDependentPanel(mSysInfoPanel);
+ }
+
+ @Override
+ public void setFocus() {
+ mSysInfoPanel.setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ mSysInfoPanel.dispose();
+ super.dispose();
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java
new file mode 100644
index 000000000..1f9f0db53
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.ITableFocusListener;
+import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
+import com.android.ddmuilib.TablePanel;
+import com.android.ide.eclipse.ddms.i18n.Messages;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+
+/**
+ * Base class for view containing Table that needs to support copy, and select
+ * all.
+ */
+public abstract class TableView extends SelectionDependentViewPart {
+
+ /** Activator for the current Table that has the focus */
+ IFocusedTableActivator mActivator = null;
+
+ private Clipboard mClipboard;
+
+ private Action mCopyAction;
+ private Action mSelectAllAction;
+
+ /**
+ * Setup the listener for the Table objects of <code>Panel</code>, and setup
+ * the copy and select all actions.
+ *
+ * @param panel The panel to setup
+ * @param parent The parent composite of the Panel's content.
+ */
+ void setupTableFocusListener(TablePanel panel, Composite parent) {
+ panel.setTableFocusListener(new ITableFocusListener() {
+ @Override
+ public void focusGained(IFocusedTableActivator activator) {
+ mActivator = activator;
+ mCopyAction.setEnabled(true);
+ mSelectAllAction.setEnabled(true);
+ }
+
+ @Override
+ public void focusLost(IFocusedTableActivator activator) {
+ if (activator == mActivator) {
+ mActivator = null;
+ mCopyAction.setEnabled(false);
+ mSelectAllAction.setEnabled(false);
+ }
+ }
+ });
+
+ // setup the copy action
+ mClipboard = new Clipboard(parent.getDisplay());
+ IActionBars actionBars = getViewSite().getActionBars();
+ actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
+ mCopyAction = new Action(Messages.TableView_Copy) {
+ @Override
+ public void run() {
+ if (mActivator != null) {
+ mActivator.copy(mClipboard);
+ }
+ }
+ });
+
+ // setup the select all action
+ actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
+ mSelectAllAction = new Action(Messages.TableView_Select_All) {
+ @Override
+ public void run() {
+ if (mActivator != null) {
+ mActivator.selectAll();
+ }
+ }
+ });
+
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ mClipboard.dispose();
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java
new file mode 100644
index 000000000..9d4eeb74a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.ThreadPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class ThreadView extends TableView {
+
+ public static final String ID =
+ "com.android.ide.eclipse.ddms.views.ThreadView"; //$NON-NLS-1$
+ private ThreadPanel mPanel;
+
+ public ThreadView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ mPanel = new ThreadPanel();
+ mPanel.createPanel(parent);
+
+ setSelectionDependentPanel(mPanel);
+
+ // listen to focus changes for table(s) of the panel.
+ setupTableFocusListener(mPanel, parent);
+ }
+
+ @Override
+ public void setFocus() {
+ mPanel.setFocus();
+ }
+}