diff options
author | Siva Velusamy <vsiva@google.com> | 2013-01-13 15:18:17 -0800 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2013-01-13 15:18:17 -0800 |
commit | 4caec4d11e2c3e16a8396f2b56bf235ed56a3e2a (patch) | |
tree | 145400ddb9e119d88d6b0fff1cfce25775d44c87 | |
parent | 52887098816f1e49a0709923e3e9c93c4816f12b (diff) | |
parent | 736d88eb9fac11610390958b3d4000d6deaa1711 (diff) | |
download | sdk-4caec4d11e2c3e16a8396f2b56bf235ed56a3e2a.zip sdk-4caec4d11e2c3e16a8396f2b56bf235ed56a3e2a.tar.gz sdk-4caec4d11e2c3e16a8396f2b56bf235ed56a3e2a.tar.bz2 |
Merge "hv: Refactor to interact with the device via IHvDevice"
22 files changed, 545 insertions, 265 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/src/com/android/ide/eclipse/hierarchyviewer/HierarchyViewerPluginDirector.java b/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/src/com/android/ide/eclipse/hierarchyviewer/HierarchyViewerPluginDirector.java index e950c60..597f7a4 100644 --- a/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/src/com/android/ide/eclipse/hierarchyviewer/HierarchyViewerPluginDirector.java +++ b/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/src/com/android/ide/eclipse/hierarchyviewer/HierarchyViewerPluginDirector.java @@ -16,9 +16,9 @@ package com.android.ide.eclipse.hierarchyviewer; -import com.android.ddmlib.IDevice; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.Window; +import com.android.hierarchyviewerlib.device.IHvDevice; +import com.android.hierarchyviewerlib.models.Window; import com.android.ide.eclipse.hierarchyviewer.views.PixelPerfectTreeView; import com.android.ide.eclipse.hierarchyviewer.views.PropertyView; @@ -97,7 +97,7 @@ public class HierarchyViewerPluginDirector extends HierarchyViewerDirector { } @Override - public void loadPixelPerfectData(IDevice device) { + public void loadPixelPerfectData(IHvDevice device) { super.loadPixelPerfectData(device); // The windows tab hides the tree tab, so let's bring the tree tab diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java index dd5ea84..3257e1c 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java @@ -39,7 +39,7 @@ 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.device.IHvDevice; import com.android.hierarchyviewerlib.models.DeviceSelectionModel; import com.android.hierarchyviewerlib.models.PixelPerfectModel; import com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener; @@ -669,9 +669,9 @@ 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) { + + IHvDevice hvDevice = DeviceSelectionModel.getModel().getSelectedDevice(); + if (hvDevice.supportsDisplayListDump()) { treeViewMenu.add(DumpDisplayListAction.getAction()); dumpDisplayList.setVisible(true); } else { 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; |