aboutsummaryrefslogtreecommitdiffstats
path: root/hierarchyviewer2
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2011-05-04 18:00:46 -0700
committerAndroid Code Review <code-review@android.com>2011-05-04 18:00:46 -0700
commit38d97f3b67fc379107a423eb507b46665556731b (patch)
treef63eed2e836ee6daf91b9eab009ad92ffd72331b /hierarchyviewer2
parent5429213ea1c9621564692d81e585eed2ee26bc6e (diff)
parent3fe16ced4294bdeeab31008e93b5e2d004da7437 (diff)
downloadsdk-38d97f3b67fc379107a423eb507b46665556731b.zip
sdk-38d97f3b67fc379107a423eb507b46665556731b.tar.gz
sdk-38d97f3b67fc379107a423eb507b46665556731b.tar.bz2
Merge "hierarchyviewer can dump displaylists for selected nodes."
Diffstat (limited to 'hierarchyviewer2')
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java23
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java4
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java13
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DumpDisplayListAction.java56
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java14
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java41
6 files changed, 141 insertions, 10 deletions
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
index 54a5fd6..bf18965 100644
--- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
@@ -26,6 +26,7 @@ import com.android.hierarchyviewer.util.ActionButton;
import com.android.hierarchyviewerlib.HierarchyViewerDirector;
import com.android.hierarchyviewerlib.actions.CapturePSDAction;
import com.android.hierarchyviewerlib.actions.DisplayViewAction;
+import com.android.hierarchyviewerlib.actions.DumpDisplayListAction;
import com.android.hierarchyviewerlib.actions.InspectScreenshotAction;
import com.android.hierarchyviewerlib.actions.InvalidateAction;
import com.android.hierarchyviewerlib.actions.LoadOverlayAction;
@@ -38,6 +39,8 @@ import com.android.hierarchyviewerlib.actions.RefreshWindowsAction;
import com.android.hierarchyviewerlib.actions.RequestLayoutAction;
import com.android.hierarchyviewerlib.actions.SavePixelPerfectAction;
import com.android.hierarchyviewerlib.actions.SaveTreeViewAction;
+import com.android.hierarchyviewerlib.device.DeviceBridge.ViewServerInfo;
+import com.android.hierarchyviewerlib.models.DeviceSelectionModel;
import com.android.hierarchyviewerlib.models.PixelPerfectModel;
import com.android.hierarchyviewerlib.models.TreeViewModel;
import com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener;
@@ -86,8 +89,8 @@ import org.eclipse.swt.widgets.Shell;
public class HierarchyViewerApplication extends ApplicationWindow {
private static final String APP_NAME = "Hierarchy Viewer";
- private static final int INITIAL_WIDTH = 1024;
- private static final int INITIAL_HEIGHT = 768;
+ private static final int INITIAL_WIDTH = 1280;
+ private static final int INITIAL_HEIGHT = 800;
private static HierarchyViewerApplication sMainWindow;
@@ -124,6 +127,8 @@ public class HierarchyViewerApplication extends ApplicationWindow {
private PixelPerfectLoupe mPixelPerfectLoupe;
private Composite mTreeViewControls;
+ private ActionButton dumpDisplayList;
+
private HierarchyViewerDirector mDirector;
/*
@@ -366,7 +371,7 @@ public class HierarchyViewerApplication extends ApplicationWindow {
Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
- GridLayout innerButtonPanelLayout = new GridLayout(6, true);
+ GridLayout innerButtonPanelLayout = new GridLayout(7, true);
innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
innerButtonPanel.setLayout(innerButtonPanelLayout);
@@ -394,6 +399,10 @@ public class HierarchyViewerApplication extends ApplicationWindow {
new ActionButton(innerButtonPanel, RequestLayoutAction.getAction());
requestLayout.setLayoutData(new GridData(GridData.FILL_BOTH));
+ dumpDisplayList =
+ new ActionButton(innerButtonPanel, DumpDisplayListAction.getAction());
+ dumpDisplayList.setLayoutData(new GridData(GridData.FILL_BOTH));
+
SashForm mainSash = new SashForm(mTreeViewPanel, SWT.HORIZONTAL | SWT.SMOOTH);
mainSash.setLayoutData(new GridData(GridData.FILL_BOTH));
Composite treeViewContainer = new Composite(mainSash, SWT.BORDER);
@@ -657,6 +666,14 @@ public class HierarchyViewerApplication extends ApplicationWindow {
treeViewMenu.add(new Separator());
treeViewMenu.add(RefreshViewAction.getAction());
treeViewMenu.add(DisplayViewAction.getAction(getShell()));
+ // Only make the DumpDisplayList action visible if the protocol supports it.
+ ViewServerInfo info = DeviceSelectionModel.getModel().getSelectedDeviceInfo();
+ if (info != null && info.protocolVersion >= 4) {
+ treeViewMenu.add(DumpDisplayListAction.getAction());
+ dumpDisplayList.setVisible(true);
+ } else {
+ dumpDisplayList.setVisible(false);
+ }
treeViewMenu.add(new Separator());
treeViewMenu.add(InvalidateAction.getAction());
treeViewMenu.add(RequestLayoutAction.getAction());
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java
index 4681c40..ca3c689 100644
--- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java
@@ -73,4 +73,8 @@ public class ActionButton implements IPropertyChangeListener, SelectionListener
public void addSelectionListener(SelectionListener listener) {
mButton.addSelectionListener(listener);
}
+
+ public void setVisible(boolean visible) {
+ mButton.setVisible(visible);
+ }
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java
index 77f8d74..23dfbea 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java
@@ -166,7 +166,7 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
return;
}
Window[] windows = DeviceBridge.loadWindows(device);
- DeviceSelectionModel.getModel().addDevice(device, windows);
+ DeviceSelectionModel.getModel().addDevice(device, windows, viewServerInfo);
if (viewServerInfo.protocolVersion >= 3) {
WindowUpdater.startListenForWindowChanges(HierarchyViewerDirector.this, device);
focusChanged(device);
@@ -586,6 +586,17 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
}
}
+ public void dumpDisplayListForCurrentNode() {
+ final DrawableViewNode selectedNode = TreeViewModel.getModel().getSelection();
+ if (selectedNode != null) {
+ executeInBackground("Dump displaylist", new Runnable() {
+ public void run() {
+ DeviceBridge.outputDisplayList(selectedNode.viewNode);
+ }
+ });
+ }
+ }
+
public void loadAllViews() {
executeInBackground("Loading all views", new Runnable() {
public void run() {
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DumpDisplayListAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DumpDisplayListAction.java
new file mode 100644
index 0000000..8b9ba29
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DumpDisplayListAction.java
@@ -0,0 +1,56 @@
+/*
+ * 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.hierarchyviewerlib.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class DumpDisplayListAction extends SelectedNodeEnabledAction implements ImageAction {
+
+ private static DumpDisplayListAction sAction;
+
+ private Image mImage;
+
+ private DumpDisplayListAction() {
+ super("Dump DisplayList");
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ mImage = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault()); //$NON-NLS-1$
+ setImageDescriptor(ImageDescriptor.createFromImage(mImage));
+ setToolTipText("Request the view to output its displaylist to logcat");
+ }
+
+ public static DumpDisplayListAction getAction() {
+ if (sAction == null) {
+ sAction = new DumpDisplayListAction();
+ }
+ return sAction;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().dumpDisplayListForCurrentNode();
+ }
+
+ public Image getImage() {
+ return mImage;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
index 40cc3a9..610f7b3 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
@@ -643,4 +643,18 @@ public class DeviceBridge {
}
}
+ public static void outputDisplayList(ViewNode viewNode) {
+ DeviceConnection connection = null;
+ try {
+ connection = new DeviceConnection(viewNode.window.getDevice());
+ connection.sendCommand("OUTPUT_DISPLAYLIST " +
+ viewNode.window.encode() + " " + viewNode); //$NON-NLS-1$
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to dump displaylist for node " + viewNode + " in window "
+ + viewNode.window + " on device " + viewNode.window.getDevice());
+ } finally {
+ connection.close();
+ }
+ }
+
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java
index d029d39..b00a1dc 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java
@@ -17,6 +17,7 @@
package com.android.hierarchyviewerlib.models;
import com.android.ddmlib.IDevice;
+import com.android.hierarchyviewerlib.device.DeviceBridge.ViewServerInfo;
import com.android.hierarchyviewerlib.device.Window;
import java.util.ArrayList;
@@ -29,7 +30,7 @@ import java.util.HashMap;
*/
public class DeviceSelectionModel {
- private final HashMap<IDevice, Window[]> mDeviceMap = new HashMap<IDevice, Window[]>();
+ private final HashMap<IDevice, DeviceInfo> mDeviceMap = new HashMap<IDevice, DeviceInfo>();
private final HashMap<IDevice, Integer> mFocusedWindowHashes = new HashMap<IDevice, Integer>();
@@ -44,6 +45,15 @@ public class DeviceSelectionModel {
private static DeviceSelectionModel sModel;
+ private static class DeviceInfo {
+ Window[] windows;
+ ViewServerInfo viewServerInfo;
+
+ private DeviceInfo(Window[] windows, ViewServerInfo viewServerInfo) {
+ this.windows = windows;
+ this.viewServerInfo = viewServerInfo;
+ }
+ }
public static DeviceSelectionModel getModel() {
if (sModel == null) {
sModel = new DeviceSelectionModel();
@@ -57,9 +67,9 @@ public class DeviceSelectionModel {
}
}
- public void addDevice(IDevice device, Window[] windows) {
+ public void addDevice(IDevice device, Window[] windows, ViewServerInfo info) {
synchronized (mDeviceMap) {
- mDeviceMap.put(device, windows);
+ mDeviceMap.put(device, new DeviceInfo(windows, info));
mDeviceList.add(device);
}
notifyDeviceConnected(device);
@@ -88,7 +98,12 @@ public class DeviceSelectionModel {
public void updateDevice(IDevice device, Window[] windows) {
boolean selectionChanged = false;
synchronized (mDeviceMap) {
- mDeviceMap.put(device, windows);
+ DeviceInfo oldDeviceInfo = mDeviceMap.get(device);
+ ViewServerInfo oldViewServerInfo = null;
+ if (oldDeviceInfo != null) {
+ oldViewServerInfo = oldDeviceInfo.viewServerInfo;
+ }
+ mDeviceMap.put(device, new DeviceInfo(windows, oldViewServerInfo));
// If the selected window no longer exists, we clear the selection.
if (mSelectedDevice == device && mSelectedWindow != null) {
boolean windowStillExists = false;
@@ -214,9 +229,12 @@ public class DeviceSelectionModel {
}
public Window[] getWindows(IDevice device) {
- Window[] windows;
+ Window[] windows = null;
synchronized (mDeviceMap) {
- windows = mDeviceMap.get(device);
+ DeviceInfo info = mDeviceMap.get(device);
+ if (info != null) {
+ windows = mDeviceMap.get(device).windows;
+ }
}
return windows;
}
@@ -253,4 +271,15 @@ public class DeviceSelectionModel {
return mSelectedWindow;
}
}
+
+ public ViewServerInfo getSelectedDeviceInfo() {
+ synchronized (mDeviceMap) {
+ ViewServerInfo viewServerInfo = null;
+ if (mSelectedDevice != null) {
+ return mDeviceMap.get(mSelectedDevice).viewServerInfo;
+ }
+ return null;
+ }
+ }
+
}