diff options
author | Siva Velusamy <vsiva@google.com> | 2013-01-10 10:46:05 -0800 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2013-01-13 15:17:39 -0800 |
commit | 736d88eb9fac11610390958b3d4000d6deaa1711 (patch) | |
tree | f817b56feb6353b80443688315e578f68da67d0f /hierarchyviewer2/libs/hierarchyviewerlib/src/com/android | |
parent | 5b30d8114124620147d411c4e74bac426b7d34d4 (diff) | |
download | sdk-736d88eb9fac11610390958b3d4000d6deaa1711.zip sdk-736d88eb9fac11610390958b3d4000d6deaa1711.tar.gz sdk-736d88eb9fac11610390958b3d4000d6deaa1711.tar.bz2 |
hv: Refactor to interact with the device via IHvDevice
Hierarchy Viewer currently interacts with a View Server that
is present on the device. This is available only on eng devices
due to security restrictions on the View Server.
Rather than use this custom view server, we ought to use DDM
for communication with the device. Such a scheme has a number of
benefits apart from security.
This CL is primarily just a refactoring of the existing host
side code. The main objective is to hide the communication to
the device behind a IHvDevice interface. The ViewServerDevice
implementation of this interface allows communicating with
existing devices that use the ViewServer implementation on
the device. A subsequent CL will provide a new implementation
of this interface that communicates via DDM.
Change-Id: I7d63e5a59c6ec9c96dbd07af9dc03f93779fd2ec
Diffstat (limited to 'hierarchyviewer2/libs/hierarchyviewerlib/src/com/android')
20 files changed, 538 insertions, 258 deletions
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java index 2e03f11..867446d 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java @@ -16,22 +16,20 @@ package com.android.hierarchyviewerlib; -import com.android.ddmlib.AdbCommandRejectedException; import com.android.ddmlib.AndroidDebugBridge; import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener; import com.android.ddmlib.IDevice; import com.android.ddmlib.Log; -import com.android.ddmlib.RawImage; -import com.android.ddmlib.TimeoutException; import com.android.hierarchyviewerlib.device.DeviceBridge; -import com.android.hierarchyviewerlib.device.DeviceBridge.ViewServerInfo; -import com.android.hierarchyviewerlib.device.ViewNode; -import com.android.hierarchyviewerlib.device.Window; +import com.android.hierarchyviewerlib.device.HvDeviceFactory; +import com.android.hierarchyviewerlib.device.IHvDevice; import com.android.hierarchyviewerlib.device.WindowUpdater; import com.android.hierarchyviewerlib.device.WindowUpdater.IWindowChangeListener; import com.android.hierarchyviewerlib.models.DeviceSelectionModel; import com.android.hierarchyviewerlib.models.PixelPerfectModel; import com.android.hierarchyviewerlib.models.TreeViewModel; +import com.android.hierarchyviewerlib.models.ViewNode; +import com.android.hierarchyviewerlib.models.Window; import com.android.hierarchyviewerlib.ui.CaptureDisplay; import com.android.hierarchyviewerlib.ui.TreeView; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode; @@ -42,15 +40,15 @@ import org.eclipse.swt.SWTException; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; -import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.IOException; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Timer; import java.util.TimerTask; @@ -78,6 +76,9 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, private String mFilterText = ""; //$NON-NLS-1$ + private static final Object mDevicesLock = new Object(); + private Map<IDevice, IHvDevice> mDevices = new HashMap<IDevice, IHvDevice>(10); + public void terminate() { WindowUpdater.terminate(); mPixelPerfectRefreshTimer.cancel(); @@ -134,60 +135,46 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Connecting device", new Runnable() { @Override public void run() { - if (DeviceSelectionModel.getModel().containsDevice(device)) { - windowsChanged(device); - } else if (device.isOnline()) { - DeviceBridge.setupDeviceForward(device); - if (!DeviceBridge.isViewServerRunning(device)) { - if (!DeviceBridge.startViewServer(device)) { - // Let's do something interesting here... Try again - // in 2 seconds. - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - } - if (!DeviceBridge.startViewServer(device)) { - Log.e(TAG, "Unable to debug device " + device); - DeviceBridge.removeDeviceForward(device); - } else { - loadViewServerInfoAndWindows(device); - } - return; - } + IHvDevice hvDevice; + synchronized (mDevicesLock) { + hvDevice = mDevices.get(device); + if (hvDevice == null) { + hvDevice = HvDeviceFactory.create(device); + hvDevice.initializeViewDebug(); + hvDevice.addWindowChangeListener(getDirector()); + mDevices.put(device, hvDevice); + } else { + // attempt re-initializing view server if device state has changed + hvDevice.initializeViewDebug(); } - loadViewServerInfoAndWindows(device); } + + DeviceSelectionModel.getModel().addDevice(hvDevice); + focusChanged(device); } }); } - private void loadViewServerInfoAndWindows(final IDevice device) { - - ViewServerInfo viewServerInfo = DeviceBridge.loadViewServerInfo(device); - if (viewServerInfo == null) { - return; - } - Window[] windows = DeviceBridge.loadWindows(device); - DeviceSelectionModel.getModel().addDevice(device, windows, viewServerInfo); - if (viewServerInfo.protocolVersion >= 3) { - WindowUpdater.startListenForWindowChanges(HierarchyViewerDirector.this, device); - focusChanged(device); - } - - } - @Override public void deviceDisconnected(final IDevice device) { executeInBackground("Disconnecting device", new Runnable() { @Override public void run() { - ViewServerInfo viewServerInfo = DeviceBridge.getViewServerInfo(device); - if (viewServerInfo != null && viewServerInfo.protocolVersion >= 3) { - WindowUpdater.stopListenForWindowChanges(HierarchyViewerDirector.this, device); + IHvDevice hvDevice; + synchronized (mDevicesLock) { + hvDevice = mDevices.get(device); + if (hvDevice != null) { + mDevices.remove(device); + } } - DeviceBridge.removeDeviceForward(device); - DeviceBridge.removeViewServerInfo(device); - DeviceSelectionModel.getModel().removeDevice(device); + + if (hvDevice == null) { + return; + } + + hvDevice.terminateViewDebug(); + hvDevice.removeWindowChangeListener(getDirector()); + DeviceSelectionModel.getModel().removeDevice(hvDevice); if (PixelPerfectModel.getModel().getDevice() == device) { PixelPerfectModel.getModel().setData(null, null, null); } @@ -201,25 +188,13 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, } @Override - public void deviceChanged(IDevice device, int changeMask) { - if ((changeMask & IDevice.CHANGE_STATE) != 0 && device.isOnline()) { - deviceConnected(device); - } - } - - @Override public void windowsChanged(final IDevice device) { executeInBackground("Refreshing windows", new Runnable() { @Override public void run() { - if (!DeviceBridge.isViewServerRunning(device)) { - if (!DeviceBridge.startViewServer(device)) { - Log.e(TAG, "Unable to debug device " + device); - return; - } - } - Window[] windows = DeviceBridge.loadWindows(device); - DeviceSelectionModel.getModel().updateDevice(device, windows); + IHvDevice hvDevice = getHvDevice(device); + hvDevice.reloadWindows(); + DeviceSelectionModel.getModel().updateDevice(hvDevice); } }); } @@ -229,12 +204,20 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Updating focus", new Runnable() { @Override public void run() { - int focusedWindow = DeviceBridge.getFocusedWindow(device); - DeviceSelectionModel.getModel().updateFocusedWindow(device, focusedWindow); + IHvDevice hvDevice = getHvDevice(device); + int focusedWindow = hvDevice.getFocusedWindow(); + DeviceSelectionModel.getModel().updateFocusedWindow(hvDevice, focusedWindow); } }); } + @Override + public void deviceChanged(IDevice device, int changeMask) { + if ((changeMask & IDevice.CHANGE_STATE) != 0 && device.isOnline()) { + deviceConnected(device); + } + } + public void refreshPixelPerfect() { final IDevice device = PixelPerfectModel.getModel().getDevice(); if (device != null) { @@ -253,7 +236,7 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Refreshing pixel perfect screenshot", new Runnable() { @Override public void run() { - Image screenshotImage = getScreenshotImage(device); + Image screenshotImage = getScreenshotImage(getHvDevice(device)); if (screenshotImage != null) { PixelPerfectModel.getModel().setImage(screenshotImage); } @@ -273,8 +256,9 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Refreshing pixel perfect tree", new Runnable() { @Override public void run() { + IHvDevice hvDevice = getHvDevice(device); ViewNode viewNode = - DeviceBridge.loadWindowData(Window.getFocusedWindow(device)); + hvDevice.loadWindowData(Window.getFocusedWindow(hvDevice)); if (viewNode != null) { PixelPerfectModel.getModel().setTree(viewNode); } @@ -284,64 +268,43 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, } } - public void loadPixelPerfectData(final IDevice device) { + public void loadPixelPerfectData(final IHvDevice hvDevice) { executeInBackground("Loading pixel perfect data", new Runnable() { @Override public void run() { - Image screenshotImage = getScreenshotImage(device); + Image screenshotImage = getScreenshotImage(hvDevice); if (screenshotImage != null) { ViewNode viewNode = - DeviceBridge.loadWindowData(Window.getFocusedWindow(device)); + hvDevice.loadWindowData(Window.getFocusedWindow(hvDevice)); if (viewNode != null) { - PixelPerfectModel.getModel().setData(device, screenshotImage, viewNode); + PixelPerfectModel.getModel().setData(hvDevice.getDevice(), + screenshotImage, viewNode); } } } }); } - private Image getScreenshotImage(IDevice device) { - try { - final RawImage screenshot = device.getScreenshot(); - if (screenshot == null) { - return null; - } - class ImageContainer { - public Image image; - } - final ImageContainer imageContainer = new ImageContainer(); - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - ImageData imageData = - new ImageData(screenshot.width, screenshot.height, screenshot.bpp, - new PaletteData(screenshot.getRedMask(), screenshot - .getGreenMask(), screenshot.getBlueMask()), 1, - screenshot.data); - imageContainer.image = new Image(Display.getDefault(), imageData); - } - }); - return imageContainer.image; - } catch (IOException e) { - Log.e(TAG, "Unable to load screenshot from device " + device); - } catch (TimeoutException e) { - Log.e(TAG, "Timeout loading screenshot from device " + device); - } catch (AdbCommandRejectedException e) { - Log.e(TAG, "Adb rejected command to load screenshot from device " + device); + private IHvDevice getHvDevice(IDevice device) { + synchronized (mDevicesLock) { + return mDevices.get(device); } - return null; + } + + private Image getScreenshotImage(IHvDevice hvDevice) { + return (hvDevice == null) ? null : hvDevice.getScreenshotImage(); } public void loadViewTreeData(final Window window) { executeInBackground("Loading view hierarchy", new Runnable() { @Override public void run() { - mFilterText = ""; //$NON-NLS-1$ - ViewNode viewNode = DeviceBridge.loadWindowData(window); + IHvDevice hvDevice = window.getHvDevice(); + ViewNode viewNode = hvDevice.loadWindowData(window); if (viewNode != null) { - DeviceBridge.loadProfileData(window, viewNode); + hvDevice.loadProfileData(window, viewNode); viewNode.setViewCount(); TreeViewModel.getModel().setData(window, viewNode); } @@ -393,7 +356,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, } public Image loadCapture(ViewNode viewNode) { - final Image image = DeviceBridge.loadCapture(viewNode.window, viewNode); + IHvDevice hvDevice = viewNode.window.getHvDevice(); + final Image image = hvDevice.loadCapture(viewNode.window, viewNode); if (image != null) { viewNode.image = image; @@ -423,7 +387,11 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Refreshing windows", new Runnable() { @Override public void run() { - IDevice[] devicesA = DeviceSelectionModel.getModel().getDevices(); + IHvDevice[] hvDevicesA = DeviceSelectionModel.getModel().getDevices(); + IDevice[] devicesA = new IDevice[hvDevicesA.length]; + for (int i = 0; i < hvDevicesA.length; i++) { + devicesA[i] = hvDevicesA[i].getDevice(); + } IDevice[] devicesB = DeviceBridge.getDevices(); HashSet<IDevice> deviceSet = new HashSet<IDevice>(); for (int i = 0; i < devicesB.length; i++) { @@ -452,7 +420,7 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, } public void inspectScreenshot() { - IDevice device = DeviceSelectionModel.getModel().getSelectedDevice(); + IHvDevice device = DeviceSelectionModel.getModel().getSelectedDevice(); if (device != null) { loadPixelPerfectData(device); } @@ -562,7 +530,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Saving window layers", new Runnable() { @Override public void run() { - PsdFile psdFile = DeviceBridge.captureLayers(window); + IHvDevice hvDevice = getHvDevice(window.getDevice()); + PsdFile psdFile = hvDevice.captureLayers(window); if (psdFile != null) { String extensionedFileName = fileName; if (!extensionedFileName.toLowerCase().endsWith(".psd")) { //$NON-NLS-1$ @@ -595,7 +564,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Invalidating view", new Runnable() { @Override public void run() { - DeviceBridge.invalidateView(selectedNode.viewNode); + IHvDevice hvDevice = getHvDevice(selectedNode.viewNode.window.getDevice()); + hvDevice.invalidateView(selectedNode.viewNode); } }); } @@ -607,7 +577,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Request layout", new Runnable() { @Override public void run() { - DeviceBridge.requestLayout(selectedNode.viewNode); + IHvDevice hvDevice = getHvDevice(selectedNode.viewNode.window.getDevice()); + hvDevice.requestLayout(selectedNode.viewNode); } }); } @@ -619,7 +590,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, executeInBackground("Dump displaylist", new Runnable() { @Override public void run() { - DeviceBridge.outputDisplayList(selectedNode.viewNode); + IHvDevice hvDevice = getHvDevice(selectedNode.viewNode.window.getDevice()); + hvDevice.outputDisplayList(selectedNode.viewNode); } }); } @@ -640,7 +612,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener, } private void loadViewRecursive(ViewNode viewNode) { - Image image = DeviceBridge.loadCapture(viewNode.window, viewNode); + IHvDevice hvDevice = getHvDevice(viewNode.window.getDevice()); + Image image = hvDevice.loadCapture(viewNode.window, viewNode); if (image == null) { return; } diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java index 708c7b1..388c057 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java @@ -16,12 +16,12 @@ package com.android.hierarchyviewerlib.actions; -import com.android.ddmlib.IDevice; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.Window; +import com.android.hierarchyviewerlib.device.IHvDevice; import com.android.hierarchyviewerlib.models.DeviceSelectionModel; import com.android.hierarchyviewerlib.models.DeviceSelectionModel.IWindowChangeListener; +import com.android.hierarchyviewerlib.models.Window; import org.eclipse.jface.action.Action; import org.eclipse.jface.resource.ImageDescriptor; @@ -65,27 +65,27 @@ public class InspectScreenshotAction extends Action implements ImageAction, IWin } @Override - public void deviceChanged(IDevice device) { + public void deviceChanged(IHvDevice device) { // pass } @Override - public void deviceConnected(IDevice device) { + public void deviceConnected(IHvDevice device) { // pass } @Override - public void deviceDisconnected(IDevice device) { + public void deviceDisconnected(IHvDevice device) { // pass } @Override - public void focusChanged(IDevice device) { + public void focusChanged(IHvDevice device) { // pass } @Override - public void selectionChanged(final IDevice device, final Window window) { + public void selectionChanged(final IHvDevice device, final Window window) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java index f2dbaee..6666315 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java @@ -16,12 +16,12 @@ package com.android.hierarchyviewerlib.actions; -import com.android.ddmlib.IDevice; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.Window; +import com.android.hierarchyviewerlib.device.IHvDevice; import com.android.hierarchyviewerlib.models.DeviceSelectionModel; import com.android.hierarchyviewerlib.models.DeviceSelectionModel.IWindowChangeListener; +import com.android.hierarchyviewerlib.models.Window; import org.eclipse.jface.action.Action; import org.eclipse.jface.resource.ImageDescriptor; @@ -65,27 +65,27 @@ public class LoadViewHierarchyAction extends Action implements ImageAction, IWin } @Override - public void deviceChanged(IDevice device) { + public void deviceChanged(IHvDevice device) { // pass } @Override - public void deviceConnected(IDevice device) { + public void deviceConnected(IHvDevice device) { // pass } @Override - public void deviceDisconnected(IDevice device) { + public void deviceDisconnected(IHvDevice device) { // pass } @Override - public void focusChanged(IDevice device) { + public void focusChanged(IHvDevice device) { // pass } @Override - public void selectionChanged(final IDevice device, final Window window) { + public void selectionChanged(final IHvDevice device, final Window window) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java new file mode 100644 index 0000000..e330168 --- /dev/null +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013 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.device; + +import com.android.ddmlib.AdbCommandRejectedException; +import com.android.ddmlib.IDevice; +import com.android.ddmlib.Log; +import com.android.ddmlib.RawImage; +import com.android.ddmlib.TimeoutException; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.widgets.Display; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicReference; + +public abstract class AbstractHvDevice implements IHvDevice { + private static final String TAG = "HierarchyViewer"; + + @Override + public Image getScreenshotImage() { + IDevice device = getDevice(); + final AtomicReference<Image> imageRef = new AtomicReference<Image>(); + + try { + final RawImage screenshot = device.getScreenshot(); + if (screenshot == null) { + return null; + } + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + ImageData imageData = + new ImageData(screenshot.width, screenshot.height, screenshot.bpp, + new PaletteData(screenshot.getRedMask(), screenshot + .getGreenMask(), screenshot.getBlueMask()), 1, + screenshot.data); + imageRef.set(new Image(Display.getDefault(), imageData)); + } + }); + return imageRef.get(); + } catch (IOException e) { + Log.e(TAG, "Unable to load screenshot from device " + device.getName()); + } catch (TimeoutException e) { + Log.e(TAG, "Timeout loading screenshot from device " + device.getName()); + } catch (AdbCommandRejectedException e) { + Log.e(TAG, "Adb rejected command to load screenshot from device " + device.getName()); + } + return null; + } +} 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 10308a3..da29703 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java @@ -23,6 +23,8 @@ import com.android.ddmlib.Log; import com.android.ddmlib.MultiLineReceiver; import com.android.ddmlib.ShellCommandUnresponsiveException; import com.android.ddmlib.TimeoutException; +import com.android.hierarchyviewerlib.models.ViewNode; +import com.android.hierarchyviewerlib.models.Window; import com.android.hierarchyviewerlib.ui.util.PsdFile; import org.eclipse.swt.graphics.Image; @@ -353,7 +355,7 @@ public class DeviceBridge { * This loads the list of windows from the specified device. The format is: * hashCode1 title1 hashCode2 title2 ... hashCodeN titleN DONE. */ - public static Window[] loadWindows(IDevice device) { + public static Window[] loadWindows(IHvDevice hvDevice, IDevice device) { ArrayList<Window> windows = new ArrayList<Window>(); DeviceConnection connection = null; ViewServerInfo serverInfo = getViewServerInfo(device); @@ -378,7 +380,7 @@ public class DeviceBridge { id = Integer.parseInt(windowId, 16); } - Window w = new Window(device, line.substring(index + 1), id); + Window w = new Window(hvDevice, line.substring(index + 1), id); windows.add(w); } } @@ -387,7 +389,7 @@ public class DeviceBridge { // get the focused window, which was done using a special type of // window with hash code -1. if (serverInfo.protocolVersion < 3) { - windows.add(Window.getFocusedWindow(device)); + windows.add(Window.getFocusedWindow(hvDevice)); } } catch (Exception e) { Log.e(TAG, "Unable to load the window list from device " + device); @@ -448,7 +450,9 @@ public class DeviceBridge { depth++; } while (depth <= currentDepth) { - currentNode = currentNode.parent; + if (currentNode != null) { + currentNode = currentNode.parent; + } currentDepth--; } currentNode = new ViewNode(window, currentNode, line.substring(depth)); @@ -557,7 +561,6 @@ public class DeviceBridge { try { connection = new DeviceConnection(window.getDevice()); - connection.sendCommand("CAPTURE_LAYERS " + window.encode()); //$NON-NLS-1$ in = @@ -583,7 +586,10 @@ public class DeviceBridge { } catch (Exception ex) { } } - connection.close(); + + if (connection != null) { + connection.close(); + } } return null; @@ -634,7 +640,9 @@ public class DeviceBridge { Log.e(TAG, "Unable to invalidate view " + viewNode + " in window " + viewNode.window + " on device " + viewNode.window.getDevice()); } finally { - connection.close(); + if (connection != null) { + connection.close(); + } } } @@ -647,7 +655,9 @@ public class DeviceBridge { Log.e(TAG, "Unable to request layout for node " + viewNode + " in window " + viewNode.window + " on device " + viewNode.window.getDevice()); } finally { - connection.close(); + if (connection != null) { + connection.close(); + } } } @@ -661,7 +671,9 @@ public class DeviceBridge { Log.e(TAG, "Unable to dump displaylist for node " + viewNode + " in window " + viewNode.window + " on device " + viewNode.window.getDevice()); } finally { - connection.close(); + if (connection != null) { + connection.close(); + } } } diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java new file mode 100644 index 0000000..e1fdab3 --- /dev/null +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 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.device; + +import com.android.ddmlib.IDevice; + +public class HvDeviceFactory { + public static IHvDevice create(IDevice device) { + return new ViewServerDevice(device); + } +} diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/IHvDevice.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/IHvDevice.java new file mode 100644 index 0000000..fe8d1ba --- /dev/null +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/IHvDevice.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 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.device; + +import com.android.ddmlib.IDevice; +import com.android.hierarchyviewerlib.device.WindowUpdater.IWindowChangeListener; +import com.android.hierarchyviewerlib.models.ViewNode; +import com.android.hierarchyviewerlib.models.Window; +import com.android.hierarchyviewerlib.ui.util.PsdFile; + +import org.eclipse.swt.graphics.Image; + +/** Represents a device that can perform view debug operations. */ +public interface IHvDevice { + /** + * Initializes view debugging on the device. + * @return true if the on device component was successfully initialized + */ + boolean initializeViewDebug(); + boolean reloadWindows(); + + void terminateViewDebug(); + boolean isViewDebugEnabled(); + boolean supportsDisplayListDump(); + + Window[] getWindows(); + int getFocusedWindow(); + + IDevice getDevice(); + + Image getScreenshotImage(); + ViewNode loadWindowData(Window window); + void loadProfileData(Window window, ViewNode viewNode); + Image loadCapture(Window window, ViewNode viewNode); + PsdFile captureLayers(Window window); + void invalidateView(ViewNode viewNode); + void requestLayout(ViewNode viewNode); + void outputDisplayList(ViewNode viewNode); + + void addWindowChangeListener(IWindowChangeListener l); + void removeWindowChangeListener(IWindowChangeListener l); +} diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewServerDevice.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewServerDevice.java new file mode 100644 index 0000000..4bd5d6b --- /dev/null +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewServerDevice.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2013 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.device; + +import com.android.ddmlib.IDevice; +import com.android.ddmlib.Log; +import com.android.hierarchyviewerlib.device.DeviceBridge.ViewServerInfo; +import com.android.hierarchyviewerlib.device.WindowUpdater.IWindowChangeListener; +import com.android.hierarchyviewerlib.models.ViewNode; +import com.android.hierarchyviewerlib.models.Window; +import com.android.hierarchyviewerlib.ui.util.PsdFile; + +import org.eclipse.swt.graphics.Image; + +public class ViewServerDevice extends AbstractHvDevice { + static final String TAG = "ViewServerDevice"; + + final IDevice mDevice; + private ViewServerInfo mViewServerInfo; + private Window[] mWindows; + + public ViewServerDevice(IDevice device) { + mDevice = device; + } + + @Override + public boolean initializeViewDebug() { + if (!mDevice.isOnline()) { + return false; + } + + DeviceBridge.setupDeviceForward(mDevice); + + return reloadWindows(); + } + + @Override + public boolean reloadWindows() { + if (!DeviceBridge.isViewServerRunning(mDevice)) { + if (!DeviceBridge.startViewServer(mDevice)) { + Log.e(TAG, "Unable to debug device: " + mDevice.getName()); + DeviceBridge.removeDeviceForward(mDevice); + return false; + } + } + + mViewServerInfo = DeviceBridge.loadViewServerInfo(mDevice); + if (mViewServerInfo == null) { + return false; + } + + mWindows = DeviceBridge.loadWindows(this, mDevice); + return true; + } + + @Override + public boolean supportsDisplayListDump() { + return mViewServerInfo != null && mViewServerInfo.protocolVersion >= 4; + } + + @Override + public void terminateViewDebug() { + DeviceBridge.removeDeviceForward(mDevice); + DeviceBridge.removeViewServerInfo(mDevice); + } + + @Override + public boolean isViewDebugEnabled() { + return mViewServerInfo != null; + } + + @Override + public Window[] getWindows() { + return mWindows; + } + + @Override + public int getFocusedWindow() { + return DeviceBridge.getFocusedWindow(mDevice); + } + + @Override + public IDevice getDevice() { + return mDevice; + } + + @Override + public ViewNode loadWindowData(Window window) { + return DeviceBridge.loadWindowData(window); + } + + @Override + public void loadProfileData(Window window, ViewNode viewNode) { + DeviceBridge.loadProfileData(window, viewNode); + } + + @Override + public Image loadCapture(Window window, ViewNode viewNode) { + return DeviceBridge.loadCapture(window, viewNode); + } + + @Override + public PsdFile captureLayers(Window window) { + return DeviceBridge.captureLayers(window); + } + + @Override + public void invalidateView(ViewNode viewNode) { + DeviceBridge.invalidateView(viewNode); + } + + @Override + public void requestLayout(ViewNode viewNode) { + DeviceBridge.requestLayout(viewNode); + } + + @Override + public void outputDisplayList(ViewNode viewNode) { + DeviceBridge.outputDisplayList(viewNode); + } + + @Override + public void addWindowChangeListener(IWindowChangeListener l) { + if (mViewServerInfo.protocolVersion >= 3) { + WindowUpdater.startListenForWindowChanges(l, mDevice); + } + } + + @Override + public void removeWindowChangeListener(IWindowChangeListener l) { + if (mViewServerInfo.protocolVersion >= 3) { + WindowUpdater.stopListenForWindowChanges(l, mDevice); + } + } +} 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 b00a1dc..9ac9b40 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java @@ -16,12 +16,12 @@ package com.android.hierarchyviewerlib.models; -import com.android.ddmlib.IDevice; -import com.android.hierarchyviewerlib.device.DeviceBridge.ViewServerInfo; -import com.android.hierarchyviewerlib.device.Window; +import com.android.hierarchyviewerlib.device.IHvDevice; import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; +import java.util.Set; /** * This class stores the list of windows for each connected device. It notifies @@ -29,17 +29,14 @@ import java.util.HashMap; * in the device selector. */ public class DeviceSelectionModel { - - private final HashMap<IDevice, DeviceInfo> mDeviceMap = new HashMap<IDevice, DeviceInfo>(); - - private final HashMap<IDevice, Integer> mFocusedWindowHashes = new HashMap<IDevice, Integer>(); - - private final ArrayList<IDevice> mDeviceList = new ArrayList<IDevice>(); + private final Map<IHvDevice, DeviceInfo> mDeviceMap = new HashMap<IHvDevice, DeviceInfo>(10); + private final Map<IHvDevice, Integer> mFocusedWindowHashes = + new HashMap<IHvDevice, Integer>(20); private final ArrayList<IWindowChangeListener> mWindowChangeListeners = new ArrayList<IWindowChangeListener>(); - private IDevice mSelectedDevice; + private IHvDevice mSelectedDevice; private Window mSelectedWindow; @@ -47,11 +44,9 @@ public class DeviceSelectionModel { private static class DeviceInfo { Window[] windows; - ViewServerInfo viewServerInfo; - private DeviceInfo(Window[] windows, ViewServerInfo viewServerInfo) { + private DeviceInfo(Window[] windows) { this.windows = windows; - this.viewServerInfo = viewServerInfo; } } public static DeviceSelectionModel getModel() { @@ -61,51 +56,40 @@ public class DeviceSelectionModel { return sModel; } - public boolean containsDevice(IDevice device) { + public void addDevice(IHvDevice hvDevice) { synchronized (mDeviceMap) { - return mDeviceMap.containsKey(device); + DeviceInfo info = new DeviceInfo(hvDevice.getWindows()); + mDeviceMap.put(hvDevice, info); } - } - public void addDevice(IDevice device, Window[] windows, ViewServerInfo info) { - synchronized (mDeviceMap) { - mDeviceMap.put(device, new DeviceInfo(windows, info)); - mDeviceList.add(device); - } - notifyDeviceConnected(device); + notifyDeviceConnected(hvDevice); } - public void removeDevice(IDevice device) { + public void removeDevice(IHvDevice hvDevice) { boolean selectionChanged = false; synchronized (mDeviceMap) { - mDeviceList.remove(device); - if (!mDeviceList.contains(device)) { - mDeviceMap.remove(device); - mFocusedWindowHashes.remove(device); - if (mSelectedDevice == device) { - mSelectedDevice = null; - mSelectedWindow = null; - selectionChanged = true; - } + mDeviceMap.remove(hvDevice); + mFocusedWindowHashes.remove(hvDevice); + if (mSelectedDevice == hvDevice) { + mSelectedDevice = null; + mSelectedWindow = null; + selectionChanged = true; } } - notifyDeviceDisconnected(device); + notifyDeviceDisconnected(hvDevice); if (selectionChanged) { notifySelectionChanged(mSelectedDevice, mSelectedWindow); } } - public void updateDevice(IDevice device, Window[] windows) { + public void updateDevice(IHvDevice hvDevice) { boolean selectionChanged = false; synchronized (mDeviceMap) { - DeviceInfo oldDeviceInfo = mDeviceMap.get(device); - ViewServerInfo oldViewServerInfo = null; - if (oldDeviceInfo != null) { - oldViewServerInfo = oldDeviceInfo.viewServerInfo; - } - mDeviceMap.put(device, new DeviceInfo(windows, oldViewServerInfo)); + Window[] windows = hvDevice.getWindows(); + mDeviceMap.put(hvDevice, new DeviceInfo(windows)); + // If the selected window no longer exists, we clear the selection. - if (mSelectedDevice == device && mSelectedWindow != null) { + if (mSelectedDevice == hvDevice && mSelectedWindow != null) { boolean windowStillExists = false; for (int i = 0; i < windows.length && !windowStillExists; i++) { if (windows[i].equals(mSelectedWindow)) { @@ -119,7 +103,8 @@ public class DeviceSelectionModel { } } } - notifyDeviceChanged(device); + + notifyDeviceChanged(hvDevice); if (selectionChanged) { notifySelectionChanged(mSelectedDevice, mSelectedWindow); } @@ -128,7 +113,7 @@ public class DeviceSelectionModel { /* * Change which window has focus and notify the listeners. */ - public void updateFocusedWindow(IDevice device, int focusedWindow) { + public void updateFocusedWindow(IHvDevice device, int focusedWindow) { Integer oldValue = null; synchronized (mDeviceMap) { oldValue = mFocusedWindowHashes.put(device, new Integer(focusedWindow)); @@ -141,15 +126,15 @@ public class DeviceSelectionModel { } public static interface IWindowChangeListener { - public void deviceConnected(IDevice device); + public void deviceConnected(IHvDevice device); - public void deviceChanged(IDevice device); + public void deviceChanged(IHvDevice device); - public void deviceDisconnected(IDevice device); + public void deviceDisconnected(IHvDevice device); - public void focusChanged(IDevice device); + public void focusChanged(IHvDevice device); - public void selectionChanged(IDevice device, Window window); + public void selectionChanged(IHvDevice device, Window window); } private IWindowChangeListener[] getWindowChangeListenerList() { @@ -165,7 +150,7 @@ public class DeviceSelectionModel { return listeners; } - private void notifyDeviceConnected(IDevice device) { + private void notifyDeviceConnected(IHvDevice device) { IWindowChangeListener[] listeners = getWindowChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { @@ -174,7 +159,7 @@ public class DeviceSelectionModel { } } - private void notifyDeviceChanged(IDevice device) { + private void notifyDeviceChanged(IHvDevice device) { IWindowChangeListener[] listeners = getWindowChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { @@ -183,7 +168,7 @@ public class DeviceSelectionModel { } } - private void notifyDeviceDisconnected(IDevice device) { + private void notifyDeviceDisconnected(IHvDevice device) { IWindowChangeListener[] listeners = getWindowChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { @@ -192,7 +177,7 @@ public class DeviceSelectionModel { } } - private void notifyFocusChanged(IDevice device) { + private void notifyFocusChanged(IHvDevice device) { IWindowChangeListener[] listeners = getWindowChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { @@ -201,7 +186,7 @@ public class DeviceSelectionModel { } } - private void notifySelectionChanged(IDevice device, Window window) { + private void notifySelectionChanged(IHvDevice device, Window window) { IWindowChangeListener[] listeners = getWindowChangeListenerList(); if (listeners != null) { for (int i = 0; i < listeners.length; i++) { @@ -222,27 +207,28 @@ public class DeviceSelectionModel { } } - public IDevice[] getDevices() { + public IHvDevice[] getDevices() { synchronized (mDeviceMap) { - return mDeviceList.toArray(new IDevice[mDeviceList.size()]); + Set<IHvDevice> devices = mDeviceMap.keySet(); + return devices.toArray(new IHvDevice[devices.size()]); } } - public Window[] getWindows(IDevice device) { - Window[] windows = null; + public Window[] getWindows(IHvDevice device) { synchronized (mDeviceMap) { DeviceInfo info = mDeviceMap.get(device); if (info != null) { - windows = mDeviceMap.get(device).windows; + return info.windows; } } - return windows; + + return null; } // Returns the window that currently has focus or -1. Note that this means // that a window with hashcode -1 gets highlighted. If you remember, this is // the infamous <Focused Window> - public int getFocusedWindow(IDevice device) { + public int getFocusedWindow(IHvDevice device) { synchronized (mDeviceMap) { Integer focusedWindow = mFocusedWindowHashes.get(device); if (focusedWindow == null) { @@ -252,7 +238,7 @@ public class DeviceSelectionModel { } } - public void setSelection(IDevice device, Window window) { + public void setSelection(IHvDevice device, Window window) { synchronized (mDeviceMap) { mSelectedDevice = device; mSelectedWindow = window; @@ -260,7 +246,7 @@ public class DeviceSelectionModel { notifySelectionChanged(device, window); } - public IDevice getSelectedDevice() { + public IHvDevice getSelectedDevice() { synchronized (mDeviceMap) { return mSelectedDevice; } @@ -271,15 +257,4 @@ public class DeviceSelectionModel { return mSelectedWindow; } } - - public ViewServerInfo getSelectedDeviceInfo() { - synchronized (mDeviceMap) { - ViewServerInfo viewServerInfo = null; - if (mSelectedDevice != null) { - return mDeviceMap.get(mSelectedDevice).viewServerInfo; - } - return null; - } - } - } diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java index 81331ed..a425b47 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java @@ -17,7 +17,6 @@ package com.android.hierarchyviewerlib.models; import com.android.ddmlib.IDevice; -import com.android.hierarchyviewerlib.device.ViewNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/TreeViewModel.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/TreeViewModel.java index 279b5fd..6dac1e6 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/TreeViewModel.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/TreeViewModel.java @@ -16,8 +16,6 @@ package com.android.hierarchyviewerlib.models; -import com.android.hierarchyviewerlib.device.ViewNode; -import com.android.hierarchyviewerlib.device.Window; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Point; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Rectangle; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewNode.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/ViewNode.java index 4ab4fc6..49bdf8f 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewNode.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/ViewNode.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.hierarchyviewerlib.device; +package com.android.hierarchyviewerlib.models; import org.eclipse.swt.graphics.Image; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/Window.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/Window.java index af79081..7298ab2 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/Window.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/Window.java @@ -14,24 +14,22 @@ * limitations under the License. */ -package com.android.hierarchyviewerlib.device; +package com.android.hierarchyviewerlib.models; import com.android.ddmlib.IDevice; +import com.android.hierarchyviewerlib.device.IHvDevice; /** * Used for storing a window from the window manager service on the device. * These are the windows that the device selector shows. */ public class Window { + private final String mTitle; + private final int mHashCode; + private final IHvDevice mHvDevice; - private String mTitle; - - private int mHashCode; - - private IDevice mDevice; - - public Window(IDevice device, String title, int hashCode) { - this.mDevice = device; + public Window(IHvDevice device, String title, int hashCode) { + this.mHvDevice = device; this.mTitle = title; this.mHashCode = hashCode; } @@ -53,11 +51,15 @@ public class Window { return mTitle; } + public IHvDevice getHvDevice() { + return mHvDevice; + } + public IDevice getDevice() { - return mDevice; + return mHvDevice.getDevice(); } - public static Window getFocusedWindow(IDevice device) { + public static Window getFocusedWindow(IHvDevice device) { return new Window(device, "<Focused Window>", -1); } @@ -67,11 +69,35 @@ public class Window { * work in the device selector unless the equals method is defined here. */ @Override - public boolean equals(Object other) { - if (other instanceof Window) { - return mHashCode == ((Window) other).mHashCode - && mDevice.getSerialNumber().equals(((Window) other).mDevice.getSerialNumber()); - } - return false; + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + Window other = (Window) obj; + if (mHvDevice == null) { + if (other.mHvDevice != null) + return false; + } else if (!mHvDevice.getDevice().getSerialNumber().equals( + other.mHvDevice.getDevice().getSerialNumber())) + return false; + + if (mHashCode != other.mHashCode) + return false; + + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((mHvDevice == null) ? 0 : mHvDevice.getDevice().getSerialNumber().hashCode()); + result = prime * result + mHashCode; + return result; } } diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java index fb277e8..7d4fdba 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java @@ -18,7 +18,7 @@ package com.android.hierarchyviewerlib.ui; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.ViewNode; +import com.android.hierarchyviewerlib.models.ViewNode; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java index 84841ef..c3154c8 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java @@ -16,12 +16,12 @@ package com.android.hierarchyviewerlib.ui; -import com.android.ddmlib.IDevice; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.Window; +import com.android.hierarchyviewerlib.device.IHvDevice; import com.android.hierarchyviewerlib.models.DeviceSelectionModel; import com.android.hierarchyviewerlib.models.DeviceSelectionModel.IWindowChangeListener; +import com.android.hierarchyviewerlib.models.Window; import org.eclipse.jface.viewers.IFontProvider; import org.eclipse.jface.viewers.ILabelProvider; @@ -69,8 +69,8 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, private class ContentProvider implements ITreeContentProvider, ILabelProvider, IFontProvider { @Override public Object[] getChildren(Object parentElement) { - if (parentElement instanceof IDevice && mDoTreeViewStuff) { - Window[] list = mModel.getWindows((IDevice) parentElement); + if (parentElement instanceof IHvDevice && mDoTreeViewStuff) { + Window[] list = mModel.getWindows((IHvDevice) parentElement); if (list != null) { return list; } @@ -88,8 +88,8 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, @Override public boolean hasChildren(Object element) { - if (element instanceof IDevice && mDoTreeViewStuff) { - Window[] list = mModel.getWindows((IDevice) element); + if (element instanceof IHvDevice && mDoTreeViewStuff) { + Window[] list = mModel.getWindows((IHvDevice) element); if (list != null) { return list.length != 0; } @@ -117,8 +117,8 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, @Override public Image getImage(Object element) { - if (element instanceof IDevice) { - if (((IDevice) element).isEmulator()) { + if (element instanceof IHvDevice) { + if (((IHvDevice) element).getDevice().isEmulator()) { return mEmulatorImage; } return mDeviceImage; @@ -128,8 +128,8 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, @Override public String getText(Object element) { - if (element instanceof IDevice) { - return ((IDevice) element).toString(); + if (element instanceof IHvDevice) { + return ((IHvDevice) element).getDevice().getName(); } else if (element instanceof Window) { return ((Window) element).getTitle(); } @@ -139,7 +139,7 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, @Override public Font getFont(Object element) { if (element instanceof Window) { - int focusedWindow = mModel.getFocusedWindow(((Window) element).getDevice()); + int focusedWindow = mModel.getFocusedWindow(((Window) element).getHvDevice()); if (focusedWindow == ((Window) element).getHashCode()) { return mBoldFont; } @@ -263,7 +263,7 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, } @Override - public void deviceConnected(final IDevice device) { + public void deviceConnected(final IHvDevice device) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { @@ -274,7 +274,7 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, } @Override - public void deviceChanged(final IDevice device) { + public void deviceChanged(final IHvDevice device) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { @@ -289,7 +289,7 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, } @Override - public void deviceDisconnected(final IDevice device) { + public void deviceDisconnected(final IHvDevice device) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { @@ -299,7 +299,7 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, } @Override - public void focusChanged(final IDevice device) { + public void focusChanged(final IHvDevice device) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { @@ -314,15 +314,15 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, } @Override - public void selectionChanged(IDevice device, Window window) { + public void selectionChanged(IHvDevice device, Window window) { // pass } @Override public void widgetDefaultSelected(SelectionEvent e) { Object selection = ((TreeItem) e.item).getData(); - if (selection instanceof IDevice && mDoPixelPerfectStuff) { - HierarchyViewerDirector.getDirector().loadPixelPerfectData((IDevice) selection); + if (selection instanceof IHvDevice && mDoPixelPerfectStuff) { + HierarchyViewerDirector.getDirector().loadPixelPerfectData((IHvDevice) selection); } else if (selection instanceof Window && mDoTreeViewStuff) { HierarchyViewerDirector.getDirector().loadViewTreeData((Window) selection); } @@ -331,10 +331,10 @@ public class DeviceSelector extends Composite implements IWindowChangeListener, @Override public void widgetSelected(SelectionEvent e) { Object selection = ((TreeItem) e.item).getData(); - if (selection instanceof IDevice) { - mModel.setSelection((IDevice) selection, null); + if (selection instanceof IHvDevice) { + mModel.setSelection((IHvDevice) selection, null); } else if (selection instanceof Window) { - mModel.setSelection(((Window) selection).getDevice(), (Window) selection); + mModel.setSelection(((Window) selection).getHvDevice(), (Window) selection); } } } diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java index 533b840..069fb61 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java @@ -16,8 +16,8 @@ package com.android.hierarchyviewerlib.ui; -import com.android.hierarchyviewerlib.device.ViewNode; import com.android.hierarchyviewerlib.models.PixelPerfectModel; +import com.android.hierarchyviewerlib.models.ViewNode; import com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener; import org.eclipse.swt.SWT; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java index e9848d8..f2b0189 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java @@ -17,8 +17,8 @@ package com.android.hierarchyviewerlib.ui; import com.android.ddmuilib.ImageLoader; -import com.android.hierarchyviewerlib.device.ViewNode; import com.android.hierarchyviewerlib.models.PixelPerfectModel; +import com.android.hierarchyviewerlib.models.ViewNode; import com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener; import org.eclipse.jface.viewers.ILabelProvider; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java index 919d178..90d2405 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java @@ -16,10 +16,10 @@ package com.android.hierarchyviewerlib.ui; -import com.android.hierarchyviewerlib.device.ViewNode; -import com.android.hierarchyviewerlib.device.ViewNode.Property; import com.android.hierarchyviewerlib.models.TreeViewModel; +import com.android.hierarchyviewerlib.models.ViewNode; import com.android.hierarchyviewerlib.models.TreeViewModel.ITreeChangeListener; +import com.android.hierarchyviewerlib.models.ViewNode.Property; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode; import com.android.hierarchyviewerlib.ui.util.TreeColumnResizer; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java index 9449ccc..5617239 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java @@ -18,9 +18,9 @@ package com.android.hierarchyviewerlib.ui; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.ViewNode.ProfileRating; import com.android.hierarchyviewerlib.models.TreeViewModel; import com.android.hierarchyviewerlib.models.TreeViewModel.ITreeChangeListener; +import com.android.hierarchyviewerlib.models.ViewNode.ProfileRating; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Point; import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Rectangle; diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/util/DrawableViewNode.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/util/DrawableViewNode.java index b196aaf..3c3b718 100644 --- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/util/DrawableViewNode.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/util/DrawableViewNode.java @@ -16,7 +16,7 @@ package com.android.hierarchyviewerlib.ui.util; -import com.android.hierarchyviewerlib.device.ViewNode; +import com.android.hierarchyviewerlib.models.ViewNode; import java.util.ArrayList; |