aboutsummaryrefslogtreecommitdiffstats
path: root/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device
diff options
context:
space:
mode:
Diffstat (limited to 'hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device')
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java67
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DdmViewDebugDevice.java417
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java695
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceConnection.java100
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java57
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/IHvDevice.java62
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewServerDevice.java169
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/WindowUpdater.java160
8 files changed, 0 insertions, 1727 deletions
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java
deleted file mode 100644
index e330168..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/AbstractHvDevice.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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/DdmViewDebugDevice.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DdmViewDebugDevice.java
deleted file mode 100644
index 0172995..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DdmViewDebugDevice.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * 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.AndroidDebugBridge;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.HandleViewDebug;
-import com.android.ddmlib.HandleViewDebug.ViewDumpHandler;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-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;
-import org.eclipse.swt.widgets.Display;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class DdmViewDebugDevice extends AbstractHvDevice implements IDeviceChangeListener {
- private static final String TAG = "DdmViewDebugDevice";
-
- private final IDevice mDevice;
- private Map<Client, List<String>> mViewRootsPerClient = new HashMap<Client, List<String>>(40);
-
- public DdmViewDebugDevice(IDevice device) {
- mDevice = device;
- }
-
- @Override
- public boolean initializeViewDebug() {
- AndroidDebugBridge.addDeviceChangeListener(this);
- return reloadWindows();
- }
-
- private static class ListViewRootsHandler extends ViewDumpHandler {
- private List<String> mViewRoots = Collections.synchronizedList(new ArrayList<String>(10));
-
- public ListViewRootsHandler() {
- super(HandleViewDebug.CHUNK_VULW);
- }
-
- @Override
- protected void handleViewDebugResult(ByteBuffer data) {
- int nWindows = data.getInt();
-
- for (int i = 0; i < nWindows; i++) {
- int len = data.getInt();
- mViewRoots.add(getString(data, len));
- }
- }
-
- public List<String> getViewRoots(long timeout, TimeUnit unit) {
- waitForResult(timeout, unit);
- return mViewRoots;
- }
- }
-
- private static class CaptureByteArrayHandler extends ViewDumpHandler {
- public CaptureByteArrayHandler(int type) {
- super(type);
- }
-
- private AtomicReference<byte[]> mData = new AtomicReference<byte[]>();
-
- @Override
- protected void handleViewDebugResult(ByteBuffer data) {
- byte[] b = new byte[data.remaining()];
- data.get(b);
- mData.set(b);
-
- }
-
- public byte[] getData(long timeout, TimeUnit unit) {
- waitForResult(timeout, unit);
- return mData.get();
- }
- }
-
- private static class CaptureLayersHandler extends ViewDumpHandler {
- private AtomicReference<PsdFile> mPsd = new AtomicReference<PsdFile>();
-
- public CaptureLayersHandler() {
- super(HandleViewDebug.CHUNK_VURT);
- }
-
- @Override
- protected void handleViewDebugResult(ByteBuffer data) {
- byte[] b = new byte[data.remaining()];
- data.get(b);
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
- try {
- mPsd.set(DeviceBridge.parsePsd(dis));
- } catch (IOException e) {
- Log.e(TAG, e);
- }
- }
-
- public PsdFile getPsdFile(long timeout, TimeUnit unit) {
- waitForResult(timeout, unit);
- return mPsd.get();
- }
- }
-
- @Override
- public boolean reloadWindows() {
- mViewRootsPerClient = new HashMap<Client, List<String>>(40);
-
- for (Client c : mDevice.getClients()) {
- ClientData cd = c.getClientData();
- if (cd != null && cd.hasFeature(ClientData.FEATURE_VIEW_HIERARCHY)) {
- ListViewRootsHandler handler = new ListViewRootsHandler();
-
- try {
- HandleViewDebug.listViewRoots(c, handler);
- } catch (IOException e) {
- Log.i(TAG, "No connection to client: " + cd.getClientDescription());
- continue;
- }
-
- List<String> viewRoots = new ArrayList<String>(
- handler.getViewRoots(200, TimeUnit.MILLISECONDS));
- mViewRootsPerClient.put(c, viewRoots);
- }
- }
-
- return true;
- }
-
- @Override
- public void terminateViewDebug() {
- // nothing to terminate
- }
-
- @Override
- public boolean isViewDebugEnabled() {
- return true;
- }
-
- @Override
- public boolean supportsDisplayListDump() {
- return true;
- }
-
- @Override
- public Window[] getWindows() {
- List<Window> windows = new ArrayList<Window>(10);
-
- for (Client c: mViewRootsPerClient.keySet()) {
- for (String viewRoot: mViewRootsPerClient.get(c)) {
- windows.add(new Window(this, viewRoot, c));
- }
- }
-
- return windows.toArray(new Window[windows.size()]);
- }
-
- @Override
- public int getFocusedWindow() {
- // TODO: add support for identifying view in focus
- return -1;
- }
-
- @Override
- public IDevice getDevice() {
- return mDevice;
- }
-
- @Override
- public ViewNode loadWindowData(Window window) {
- Client c = window.getClient();
- if (c == null) {
- return null;
- }
-
- String viewRoot = window.getTitle();
- CaptureByteArrayHandler handler = new CaptureByteArrayHandler(HandleViewDebug.CHUNK_VURT);
- try {
- HandleViewDebug.dumpViewHierarchy(c, viewRoot,
- false /* skipChildren */,
- true /* includeProperties */,
- handler);
- } catch (IOException e) {
- Log.e(TAG, e);
- return null;
- }
-
- byte[] data = handler.getData(20, TimeUnit.SECONDS);
- if (data == null) {
- return null;
- }
-
- String viewHierarchy = new String(data, Charset.forName("UTF-8"));
- return DeviceBridge.parseViewHierarchy(new BufferedReader(new StringReader(viewHierarchy)),
- window);
- }
-
- @Override
- public void loadProfileData(Window window, ViewNode viewNode) {
- Client c = window.getClient();
- if (c == null) {
- return;
- }
-
- String viewRoot = window.getTitle();
- CaptureByteArrayHandler handler = new CaptureByteArrayHandler(HandleViewDebug.CHUNK_VUOP);
- try {
- HandleViewDebug.profileView(c, viewRoot, viewNode.toString(), handler);
- } catch (IOException e) {
- Log.e(TAG, e);
- return;
- }
-
- byte[] data = handler.getData(30, TimeUnit.SECONDS);
- if (data == null) {
- Log.e(TAG, "Timed out waiting for profile data");
- return;
- }
-
- try {
- boolean success = DeviceBridge.loadProfileDataRecursive(viewNode,
- new BufferedReader(new StringReader(new String(data))));
- if (success) {
- viewNode.setProfileRatings();
- }
- } catch (IOException e) {
- Log.e(TAG, e);
- return;
- }
- }
-
- @Override
- public Image loadCapture(Window window, ViewNode viewNode) {
- Client c = window.getClient();
- if (c == null) {
- return null;
- }
-
- String viewRoot = window.getTitle();
- CaptureByteArrayHandler handler = new CaptureByteArrayHandler(HandleViewDebug.CHUNK_VUOP);
-
- try {
- HandleViewDebug.captureView(c, viewRoot, viewNode.toString(), handler);
- } catch (IOException e) {
- Log.e(TAG, e);
- return null;
- }
-
- byte[] data = handler.getData(10, TimeUnit.SECONDS);
- return (data == null) ? null :
- new Image(Display.getDefault(), new ByteArrayInputStream(data));
- }
-
- @Override
- public PsdFile captureLayers(Window window) {
- Client c = window.getClient();
- if (c == null) {
- return null;
- }
-
- String viewRoot = window.getTitle();
- CaptureLayersHandler handler = new CaptureLayersHandler();
- try {
- HandleViewDebug.captureLayers(c, viewRoot, handler);
- } catch (IOException e) {
- Log.e(TAG, e);
- return null;
- }
-
- return handler.getPsdFile(20, TimeUnit.SECONDS);
- }
-
- @Override
- public void invalidateView(ViewNode viewNode) {
- Window window = viewNode.window;
- Client c = window.getClient();
- if (c == null) {
- return;
- }
-
- String viewRoot = window.getTitle();
- try {
- HandleViewDebug.invalidateView(c, viewRoot, viewNode.toString());
- } catch (IOException e) {
- Log.e(TAG, e);
- }
- }
-
- @Override
- public void requestLayout(ViewNode viewNode) {
- Window window = viewNode.window;
- Client c = window.getClient();
- if (c == null) {
- return;
- }
-
- String viewRoot = window.getTitle();
- try {
- HandleViewDebug.requestLayout(c, viewRoot, viewNode.toString());
- } catch (IOException e) {
- Log.e(TAG, e);
- }
- }
-
- @Override
- public void outputDisplayList(ViewNode viewNode) {
- Window window = viewNode.window;
- Client c = window.getClient();
- if (c == null) {
- return;
- }
-
- String viewRoot = window.getTitle();
- try {
- HandleViewDebug.dumpDisplayList(c, viewRoot, viewNode.toString());
- } catch (IOException e) {
- Log.e(TAG, e);
- }
- }
-
- @Override
- public void addWindowChangeListener(IWindowChangeListener l) {
- // TODO: add support for listening to view root changes
- }
-
- @Override
- public void removeWindowChangeListener(IWindowChangeListener l) {
- // TODO: add support for listening to view root changes
- }
-
- @Override
- public void deviceConnected(IDevice device) {
- // pass
- }
-
- @Override
- public void deviceDisconnected(IDevice device) {
- // pass
- }
-
- @Override
- public void deviceChanged(IDevice device, int changeMask) {
- if ((changeMask & IDevice.CHANGE_CLIENT_LIST) != 0) {
- reloadWindows();
- }
- }
-
- @Override
- public boolean isViewUpdateEnabled() {
- return true;
- }
-
- @Override
- public void invokeViewMethod(Window window, ViewNode viewNode, String method,
- List<?> args) {
- Client c = window.getClient();
- if (c == null) {
- return;
- }
-
- String viewRoot = window.getTitle();
- try {
- HandleViewDebug.invokeMethod(c, viewRoot, viewNode.toString(), method, args.toArray());
- } catch (IOException e) {
- Log.e(TAG, e);
- }
- }
-
- @Override
- public boolean setLayoutParameter(Window window, ViewNode viewNode, String property,
- int value) {
- Client c = window.getClient();
- if (c == null) {
- return false;
- }
-
- String viewRoot = window.getTitle();
- try {
- HandleViewDebug.setLayoutParameter(c, viewRoot, viewNode.toString(), property, value);
- } catch (IOException e) {
- Log.e(TAG, e);
- return false;
- }
-
- return true;
- }
-}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
deleted file mode 100644
index 30fa6f6..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * Copyright (C) 2010 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.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-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;
-import org.eclipse.swt.widgets.Display;
-
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.image.BufferedImage;
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.imageio.ImageIO;
-
-/**
- * A bridge to the device.
- */
-public class DeviceBridge {
-
- public static final String TAG = "hierarchyviewer";
-
- private static final int DEFAULT_SERVER_PORT = 4939;
-
- // These codes must match the auto-generated codes in IWindowManager.java
- // See IWindowManager.aidl as well
- private static final int SERVICE_CODE_START_SERVER = 1;
-
- private static final int SERVICE_CODE_STOP_SERVER = 2;
-
- private static final int SERVICE_CODE_IS_SERVER_RUNNING = 3;
-
- private static AndroidDebugBridge sBridge;
-
- private static final HashMap<IDevice, Integer> sDevicePortMap = new HashMap<IDevice, Integer>();
-
- private static final HashMap<IDevice, ViewServerInfo> sViewServerInfo =
- new HashMap<IDevice, ViewServerInfo>();
-
- private static int sNextLocalPort = DEFAULT_SERVER_PORT;
-
- public static class ViewServerInfo {
- public final int protocolVersion;
-
- public final int serverVersion;
-
- ViewServerInfo(int serverVersion, int protocolVersion) {
- this.protocolVersion = protocolVersion;
- this.serverVersion = serverVersion;
- }
- }
-
- /**
- * Init the DeviceBridge with an existing {@link AndroidDebugBridge}.
- * @param bridge the bridge object to use
- */
- public static void acquireBridge(AndroidDebugBridge bridge) {
- sBridge = bridge;
- }
-
- /**
- * Creates an {@link AndroidDebugBridge} connected to adb at the given location.
- *
- * If a bridge is already running, this disconnects it and creates a new one.
- *
- * @param adbLocation the location to adb.
- */
- public static void initDebugBridge(String adbLocation) {
- if (sBridge == null) {
- AndroidDebugBridge.init(true /* debugger support */);
- }
- if (sBridge == null || !sBridge.isConnected()) {
- sBridge = AndroidDebugBridge.createBridge(adbLocation, true);
- }
- }
-
- /** Disconnects the current {@link AndroidDebugBridge}. */
- public static void terminate() {
- AndroidDebugBridge.terminate();
- }
-
- public static IDevice[] getDevices() {
- if (sBridge == null) {
- return new IDevice[0];
- }
- return sBridge.getDevices();
- }
-
- /*
- * This adds a listener to the debug bridge. The listener is notified of
- * connecting/disconnecting devices, devices coming online, etc.
- */
- public static void startListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
- AndroidDebugBridge.addDeviceChangeListener(listener);
- }
-
- public static void stopListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
- AndroidDebugBridge.removeDeviceChangeListener(listener);
- }
-
- /**
- * Sets up a just-connected device to work with the view server.
- * <p/>
- * This starts a port forwarding between a local port and a port on the
- * device.
- *
- * @param device
- */
- public static void setupDeviceForward(IDevice device) {
- synchronized (sDevicePortMap) {
- if (device.getState() == IDevice.DeviceState.ONLINE) {
- int localPort = sNextLocalPort++;
- try {
- device.createForward(localPort, DEFAULT_SERVER_PORT);
- sDevicePortMap.put(device, localPort);
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout setting up port forwarding for " + device);
- } catch (AdbCommandRejectedException e) {
- Log.e(TAG, String.format("Adb rejected forward command for device %1$s: %2$s",
- device, e.getMessage()));
- } catch (IOException e) {
- Log.e(TAG, String.format("Failed to create forward for device %1$s: %2$s",
- device, e.getMessage()));
- }
- }
- }
- }
-
- public static void removeDeviceForward(IDevice device) {
- synchronized (sDevicePortMap) {
- final Integer localPort = sDevicePortMap.get(device);
- if (localPort != null) {
- try {
- device.removeForward(localPort, DEFAULT_SERVER_PORT);
- sDevicePortMap.remove(device);
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout removing port forwarding for " + device);
- } catch (AdbCommandRejectedException e) {
- // In this case, we want to fail silently.
- } catch (IOException e) {
- Log.e(TAG, String.format("Failed to remove forward for device %1$s: %2$s",
- device, e.getMessage()));
- }
- }
- }
- }
-
- public static int getDeviceLocalPort(IDevice device) {
- synchronized (sDevicePortMap) {
- Integer port = sDevicePortMap.get(device);
- if (port != null) {
- return port;
- }
-
- Log.e(TAG, "Missing forwarded port for " + device.getSerialNumber());
- return -1;
- }
-
- }
-
- public static boolean isViewServerRunning(IDevice device) {
- final boolean[] result = new boolean[1];
- try {
- if (device.isOnline()) {
- device.executeShellCommand(buildIsServerRunningShellCommand(),
- new BooleanResultReader(result));
- if (!result[0]) {
- ViewServerInfo serverInfo = loadViewServerInfo(device);
- if (serverInfo != null && serverInfo.protocolVersion > 2) {
- result[0] = true;
- }
- }
- }
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout checking status of view server on device " + device);
- } catch (IOException e) {
- Log.e(TAG, "Unable to check status of view server on device " + device);
- } catch (AdbCommandRejectedException e) {
- Log.e(TAG, "Adb rejected command to check status of view server on device " + device);
- } catch (ShellCommandUnresponsiveException e) {
- Log.e(TAG, "Unable to execute command to check status of view server on device "
- + device);
- }
- return result[0];
- }
-
- public static boolean startViewServer(IDevice device) {
- return startViewServer(device, DEFAULT_SERVER_PORT);
- }
-
- public static boolean startViewServer(IDevice device, int port) {
- final boolean[] result = new boolean[1];
- try {
- if (device.isOnline()) {
- device.executeShellCommand(buildStartServerShellCommand(port),
- new BooleanResultReader(result));
- }
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout starting view server on device " + device);
- } catch (IOException e) {
- Log.e(TAG, "Unable to start view server on device " + device);
- } catch (AdbCommandRejectedException e) {
- Log.e(TAG, "Adb rejected command to start view server on device " + device);
- } catch (ShellCommandUnresponsiveException e) {
- Log.e(TAG, "Unable to execute command to start view server on device " + device);
- }
- return result[0];
- }
-
- public static boolean stopViewServer(IDevice device) {
- final boolean[] result = new boolean[1];
- try {
- if (device.isOnline()) {
- device.executeShellCommand(buildStopServerShellCommand(), new BooleanResultReader(
- result));
- }
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout stopping view server on device " + device);
- } catch (IOException e) {
- Log.e(TAG, "Unable to stop view server on device " + device);
- } catch (AdbCommandRejectedException e) {
- Log.e(TAG, "Adb rejected command to stop view server on device " + device);
- } catch (ShellCommandUnresponsiveException e) {
- Log.e(TAG, "Unable to execute command to stop view server on device " + device);
- }
- return result[0];
- }
-
- private static String buildStartServerShellCommand(int port) {
- return String.format("service call window %d i32 %d", SERVICE_CODE_START_SERVER, port); //$NON-NLS-1$
- }
-
- private static String buildStopServerShellCommand() {
- return String.format("service call window %d", SERVICE_CODE_STOP_SERVER); //$NON-NLS-1$
- }
-
- private static String buildIsServerRunningShellCommand() {
- return String.format("service call window %d", SERVICE_CODE_IS_SERVER_RUNNING); //$NON-NLS-1$
- }
-
- private static class BooleanResultReader extends MultiLineReceiver {
- private final boolean[] mResult;
-
- public BooleanResultReader(boolean[] result) {
- mResult = result;
- }
-
- @Override
- public void processNewLines(String[] strings) {
- if (strings.length > 0) {
- Pattern pattern = Pattern.compile(".*?\\([0-9]{8} ([0-9]{8}).*"); //$NON-NLS-1$
- Matcher matcher = pattern.matcher(strings[0]);
- if (matcher.matches()) {
- if (Integer.parseInt(matcher.group(1)) == 1) {
- mResult[0] = true;
- }
- }
- }
- }
-
- @Override
- public boolean isCancelled() {
- return false;
- }
- }
-
- public static ViewServerInfo loadViewServerInfo(IDevice device) {
- int server = -1;
- int protocol = -1;
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(device);
- connection.sendCommand("SERVER"); //$NON-NLS-1$
- String line = connection.getInputStream().readLine();
- if (line != null) {
- server = Integer.parseInt(line);
- }
- } catch (Exception e) {
- Log.e(TAG, "Unable to get view server version from device " + device);
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- connection = null;
- try {
- connection = new DeviceConnection(device);
- connection.sendCommand("PROTOCOL"); //$NON-NLS-1$
- String line = connection.getInputStream().readLine();
- if (line != null) {
- protocol = Integer.parseInt(line);
- }
- } catch (Exception e) {
- Log.e(TAG, "Unable to get view server protocol version from device " + device);
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- if (server == -1 || protocol == -1) {
- return null;
- }
- ViewServerInfo returnValue = new ViewServerInfo(server, protocol);
- synchronized (sViewServerInfo) {
- sViewServerInfo.put(device, returnValue);
- }
- return returnValue;
- }
-
- public static ViewServerInfo getViewServerInfo(IDevice device) {
- synchronized (sViewServerInfo) {
- return sViewServerInfo.get(device);
- }
- }
-
- public static void removeViewServerInfo(IDevice device) {
- synchronized (sViewServerInfo) {
- sViewServerInfo.remove(device);
- }
- }
-
- /*
- * This loads the list of windows from the specified device. The format is:
- * hashCode1 title1 hashCode2 title2 ... hashCodeN titleN DONE.
- */
- public static Window[] loadWindows(IHvDevice hvDevice, IDevice device) {
- ArrayList<Window> windows = new ArrayList<Window>();
- DeviceConnection connection = null;
- ViewServerInfo serverInfo = getViewServerInfo(device);
- try {
- connection = new DeviceConnection(device);
- connection.sendCommand("LIST"); //$NON-NLS-1$
- BufferedReader in = connection.getInputStream();
- String line;
- while ((line = in.readLine()) != null) {
- if ("DONE.".equalsIgnoreCase(line)) { //$NON-NLS-1$
- break;
- }
-
- int index = line.indexOf(' ');
- if (index != -1) {
- String windowId = line.substring(0, index);
-
- int id;
- if (serverInfo.serverVersion > 2) {
- id = (int) Long.parseLong(windowId, 16);
- } else {
- id = Integer.parseInt(windowId, 16);
- }
-
- Window w = new Window(hvDevice, line.substring(index + 1), id);
- windows.add(w);
- }
- }
- // Automatic refreshing of windows was added in protocol version 3.
- // Before, the user needed to specify explicitly that he wants to
- // 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(hvDevice));
- }
- } catch (Exception e) {
- Log.e(TAG, "Unable to load the window list from device " + device);
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- // The server returns the list of windows from the window at the bottom
- // to the top. We want the reverse order to put the top window on top of
- // the list.
- Window[] returnValue = new Window[windows.size()];
- for (int i = windows.size() - 1; i >= 0; i--) {
- returnValue[returnValue.length - i - 1] = windows.get(i);
- }
- return returnValue;
- }
-
- /*
- * This gets the hash code of the window that has focus. Only works with
- * protocol version 3 and above.
- */
- public static int getFocusedWindow(IDevice device) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(device);
- connection.sendCommand("GET_FOCUS"); //$NON-NLS-1$
- String line = connection.getInputStream().readLine();
- if (line == null || line.length() == 0) {
- return -1;
- }
- return (int) Long.parseLong(line.substring(0, line.indexOf(' ')), 16);
- } catch (Exception e) {
- Log.e(TAG, "Unable to get the focused window from device " + device);
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- return -1;
- }
-
- public static ViewNode loadWindowData(Window window) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(window.getDevice());
- connection.sendCommand("DUMP " + window.encode()); //$NON-NLS-1$
- BufferedReader in = connection.getInputStream();
- ViewNode currentNode = parseViewHierarchy(in, window);
- ViewServerInfo serverInfo = getViewServerInfo(window.getDevice());
- if (serverInfo != null) {
- currentNode.protocolVersion = serverInfo.protocolVersion;
- }
- return currentNode;
- } catch (Exception e) {
- Log.e(TAG, "Unable to load window data for window " + window.getTitle() + " on device "
- + window.getDevice());
- Log.e(TAG, e.getMessage());
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- return null;
- }
-
- public static ViewNode parseViewHierarchy(BufferedReader in, Window window) {
- ViewNode currentNode = null;
- int currentDepth = -1;
- String line;
- try {
- while ((line = in.readLine()) != null) {
- if ("DONE.".equalsIgnoreCase(line)) {
- break;
- }
- int depth = 0;
- while (line.charAt(depth) == ' ') {
- depth++;
- }
- while (depth <= currentDepth) {
- if (currentNode != null) {
- currentNode = currentNode.parent;
- }
- currentDepth--;
- }
- currentNode = new ViewNode(window, currentNode, line.substring(depth));
- currentDepth = depth;
- }
- } catch (IOException e) {
- Log.e(TAG, "Error reading view hierarchy stream: " + e.getMessage());
- return null;
- }
- if (currentNode == null) {
- return null;
- }
- while (currentNode.parent != null) {
- currentNode = currentNode.parent;
- }
-
- return currentNode;
- }
-
- public static boolean loadProfileData(Window window, ViewNode viewNode) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(window.getDevice());
- connection.sendCommand("PROFILE " + window.encode() + " " + viewNode.toString()); //$NON-NLS-1$
- BufferedReader in = connection.getInputStream();
- int protocol;
- synchronized (sViewServerInfo) {
- protocol = sViewServerInfo.get(window.getDevice()).protocolVersion;
- }
- if (protocol < 3) {
- return loadProfileData(viewNode, in);
- } else {
- boolean ret = loadProfileDataRecursive(viewNode, in);
- if (ret) {
- viewNode.setProfileRatings();
- }
- return ret;
- }
- } catch (Exception e) {
- Log.e(TAG, "Unable to load profiling data for window " + window.getTitle()
- + " on device " + window.getDevice());
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- return false;
- }
-
- private static boolean loadProfileData(ViewNode node, BufferedReader in) throws IOException {
- String line;
- if ((line = in.readLine()) == null || line.equalsIgnoreCase("-1 -1 -1") //$NON-NLS-1$
- || line.equalsIgnoreCase("DONE.")) { //$NON-NLS-1$
- return false;
- }
- String[] data = line.split(" ");
- node.measureTime = (Long.parseLong(data[0]) / 1000.0) / 1000.0;
- node.layoutTime = (Long.parseLong(data[1]) / 1000.0) / 1000.0;
- node.drawTime = (Long.parseLong(data[2]) / 1000.0) / 1000.0;
- return true;
- }
-
- public static boolean loadProfileDataRecursive(ViewNode node, BufferedReader in)
- throws IOException {
- if (!loadProfileData(node, in)) {
- return false;
- }
- for (int i = 0; i < node.children.size(); i++) {
- if (!loadProfileDataRecursive(node.children.get(i), in)) {
- return false;
- }
- }
- return true;
- }
-
- public static Image loadCapture(Window window, ViewNode viewNode) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(window.getDevice());
- connection.getSocket().setSoTimeout(5000);
- connection.sendCommand("CAPTURE " + window.encode() + " " + viewNode.toString()); //$NON-NLS-1$
- return new Image(Display.getDefault(), connection.getSocket().getInputStream());
- } catch (Exception e) {
- Log.e(TAG, "Unable to capture data for node " + viewNode + " in window "
- + window.getTitle() + " on device " + window.getDevice());
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- return null;
- }
-
- public static PsdFile captureLayers(Window window) {
- DeviceConnection connection = null;
- DataInputStream in = null;
-
- try {
- connection = new DeviceConnection(window.getDevice());
- connection.sendCommand("CAPTURE_LAYERS " + window.encode()); //$NON-NLS-1$
-
- in =
- new DataInputStream(new BufferedInputStream(connection.getSocket()
- .getInputStream()));
-
- return parsePsd(in);
- } catch (IOException e) {
- Log.e(TAG, "Unable to capture layers for window " + window.getTitle() + " on device "
- + window.getDevice());
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (Exception ex) {
- }
- }
-
- if (connection != null) {
- connection.close();
- }
- }
-
- return null;
- }
-
- public static PsdFile parsePsd(DataInputStream in) throws IOException {
- int width = in.readInt();
- int height = in.readInt();
-
- PsdFile psd = new PsdFile(width, height);
-
- while (readLayer(in, psd)) {
- }
-
- return psd;
- }
-
- private static boolean readLayer(DataInputStream in, PsdFile psd) {
- try {
- if (in.read() == 2) {
- return false;
- }
- String name = in.readUTF();
- boolean visible = in.read() == 1;
- int x = in.readInt();
- int y = in.readInt();
- int dataSize = in.readInt();
-
- byte[] data = new byte[dataSize];
- int read = 0;
- while (read < dataSize) {
- read += in.read(data, read, dataSize - read);
- }
-
- ByteArrayInputStream arrayIn = new ByteArrayInputStream(data);
- BufferedImage chunk = ImageIO.read(arrayIn);
-
- // Ensure the image is in the right format
- BufferedImage image =
- new BufferedImage(chunk.getWidth(), chunk.getHeight(),
- BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = image.createGraphics();
- g.drawImage(chunk, null, 0, 0);
- g.dispose();
-
- psd.addLayer(name, image, new Point(x, y), visible);
-
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- public static void invalidateView(ViewNode viewNode) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(viewNode.window.getDevice());
- connection.sendCommand("INVALIDATE " + viewNode.window.encode() + " " + viewNode); //$NON-NLS-1$
- } catch (Exception e) {
- Log.e(TAG, "Unable to invalidate view " + viewNode + " in window " + viewNode.window
- + " on device " + viewNode.window.getDevice());
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
-
- public static void requestLayout(ViewNode viewNode) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(viewNode.window.getDevice());
- connection.sendCommand("REQUEST_LAYOUT " + viewNode.window.encode() + " " + viewNode); //$NON-NLS-1$
- } catch (Exception e) {
- Log.e(TAG, "Unable to request layout for node " + viewNode + " in window "
- + viewNode.window + " on device " + viewNode.window.getDevice());
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
-
- public static void outputDisplayList(ViewNode viewNode) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(viewNode.window.getDevice());
- connection.sendCommand("OUTPUT_DISPLAYLIST " +
- viewNode.window.encode() + " " + viewNode); //$NON-NLS-1$
- } catch (Exception e) {
- Log.e(TAG, "Unable to dump displaylist for node " + viewNode + " in window "
- + viewNode.window + " on device " + viewNode.window.getDevice());
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
-
-}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceConnection.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceConnection.java
deleted file mode 100644
index f750d5c..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceConnection.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 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 java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.channels.SocketChannel;
-
-/**
- * This class is used for connecting to a device in debug mode running the view
- * server.
- */
-public class DeviceConnection {
-
- // Now a socket channel, since socket channels are friendly with interrupts.
- private SocketChannel mSocketChannel;
-
- private BufferedReader mIn;
-
- private BufferedWriter mOut;
-
- public DeviceConnection(IDevice device) throws IOException {
- mSocketChannel = SocketChannel.open();
- int port = DeviceBridge.getDeviceLocalPort(device);
-
- if (port == -1) {
- throw new IOException();
- }
-
- mSocketChannel.connect(new InetSocketAddress("127.0.0.1", port)); //$NON-NLS-1$
- mSocketChannel.socket().setSoTimeout(40000);
- }
-
- public BufferedReader getInputStream() throws IOException {
- if (mIn == null) {
- mIn = new BufferedReader(new InputStreamReader(mSocketChannel.socket().getInputStream()));
- }
- return mIn;
- }
-
- public BufferedWriter getOutputStream() throws IOException {
- if (mOut == null) {
- mOut =
- new BufferedWriter(new OutputStreamWriter(mSocketChannel.socket()
- .getOutputStream()));
- }
- return mOut;
- }
-
- public Socket getSocket() {
- return mSocketChannel.socket();
- }
-
- public void sendCommand(String command) throws IOException {
- BufferedWriter out = getOutputStream();
- out.write(command);
- out.newLine();
- out.flush();
- }
-
- public void close() {
- try {
- if (mIn != null) {
- mIn.close();
- }
- } catch (IOException e) {
- }
- try {
- if (mOut != null) {
- mOut.close();
- }
- } catch (IOException e) {
- }
- try {
- mSocketChannel.close();
- } catch (IOException e) {
- }
- }
-}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java
deleted file mode 100644
index 24a5a4f..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/HvDeviceFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.IDevice;
-
-public class HvDeviceFactory {
- private static final String sHvProtoEnvVar =
- System.getenv("ANDROID_HVPROTO"); //$NON-NLS-1$
-
- public static IHvDevice create(IDevice device) {
- // default to old mechanism until the new one is fully tested
- if (sHvProtoEnvVar == null ||
- !"ddm".equalsIgnoreCase(sHvProtoEnvVar)) { //$NON-NLS-1$
- return new ViewServerDevice(device);
- }
-
- // Wait for a few seconds after the device has been connected to
- // allow all the clients to be initialized. Specifically, we need to wait
- // until the client data is filled with the list of features supported
- // by the client.
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- // ignore
- }
-
- boolean ddmViewHierarchy = false;
-
- // see if any of the clients on the device support view hierarchy via DDMS
- for (Client c : device.getClients()) {
- ClientData cd = c.getClientData();
- if (cd != null && cd.hasFeature(ClientData.FEATURE_VIEW_HIERARCHY)) {
- ddmViewHierarchy = true;
- break;
- }
- }
-
- return ddmViewHierarchy ? new DdmViewDebugDevice(device) : 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
deleted file mode 100644
index 6f1fd37..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/IHvDevice.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-
-/** 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);
-
- boolean isViewUpdateEnabled();
- void invokeViewMethod(Window window, ViewNode viewNode, String method, List<?> args);
- boolean setLayoutParameter(Window window, ViewNode viewNode, String property, int value);
-
- 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
deleted file mode 100644
index 4445e9a..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/ViewServerDevice.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-
-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 != null && mViewServerInfo.protocolVersion >= 3) {
- WindowUpdater.startListenForWindowChanges(l, mDevice);
- }
- }
-
- @Override
- public void removeWindowChangeListener(IWindowChangeListener l) {
- if (mViewServerInfo != null && mViewServerInfo.protocolVersion >= 3) {
- WindowUpdater.stopListenForWindowChanges(l, mDevice);
- }
- }
-
- @Override
- public boolean isViewUpdateEnabled() {
- return false;
- }
-
- @Override
- public void invokeViewMethod(Window window, ViewNode viewNode, String method,
- List<?> args) {
- // not supported
- }
-
- @Override
- public boolean setLayoutParameter(Window window, ViewNode viewNode, String property,
- int value) {
- // not supported
- return false;
- }
-}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/WindowUpdater.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/WindowUpdater.java
deleted file mode 100644
index a67d400..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/WindowUpdater.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2010 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 java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * This class handles automatic updating of the list of windows in the device
- * selector for device with protocol version 3 or above of the view server. It
- * connects to the devices, keeps the connection open and listens for messages.
- * It notifies all it's listeners of changes.
- */
-public class WindowUpdater {
- private static HashMap<IDevice, ArrayList<IWindowChangeListener>> sWindowChangeListeners =
- new HashMap<IDevice, ArrayList<IWindowChangeListener>>();
-
- private static HashMap<IDevice, Thread> sListeningThreads = new HashMap<IDevice, Thread>();
-
- public static interface IWindowChangeListener {
- public void windowsChanged(IDevice device);
-
- public void focusChanged(IDevice device);
- }
-
- public static void terminate() {
- synchronized (sListeningThreads) {
- for (IDevice device : sListeningThreads.keySet()) {
- sListeningThreads.get(device).interrupt();
-
- }
- }
- }
-
- public static void startListenForWindowChanges(IWindowChangeListener listener, IDevice device) {
- synchronized (sWindowChangeListeners) {
- // In this case, a listening thread already exists, so we don't need
- // to create another one.
- if (sWindowChangeListeners.containsKey(device)) {
- sWindowChangeListeners.get(device).add(listener);
- return;
- }
- ArrayList<IWindowChangeListener> listeners = new ArrayList<IWindowChangeListener>();
- listeners.add(listener);
- sWindowChangeListeners.put(device, listeners);
- }
- // Start listening
- Thread listeningThread = new Thread(new WindowChangeMonitor(device));
- synchronized (sListeningThreads) {
- sListeningThreads.put(device, listeningThread);
- }
- listeningThread.start();
- }
-
- public static void stopListenForWindowChanges(IWindowChangeListener listener, IDevice device) {
- synchronized (sWindowChangeListeners) {
- ArrayList<IWindowChangeListener> listeners = sWindowChangeListeners.get(device);
- if (listeners == null) {
- return;
- }
- listeners.remove(listener);
- // There are more listeners, so don't stop the listening thread.
- if (listeners.size() != 0) {
- return;
- }
- sWindowChangeListeners.remove(device);
- }
- // Everybody left, so the party's over!
- Thread listeningThread;
- synchronized (sListeningThreads) {
- listeningThread = sListeningThreads.get(device);
- sListeningThreads.remove(device);
- }
- listeningThread.interrupt();
- }
-
- private static IWindowChangeListener[] getWindowChangeListenersAsArray(IDevice device) {
- IWindowChangeListener[] listeners;
- synchronized (sWindowChangeListeners) {
- ArrayList<IWindowChangeListener> windowChangeListenerList =
- sWindowChangeListeners.get(device);
- if (windowChangeListenerList == null) {
- return null;
- }
- listeners =
- windowChangeListenerList
- .toArray(new IWindowChangeListener[windowChangeListenerList.size()]);
- }
- return listeners;
- }
-
- public static void notifyWindowsChanged(IDevice device) {
- IWindowChangeListener[] listeners = getWindowChangeListenersAsArray(device);
- if (listeners != null) {
- for (int i = 0; i < listeners.length; i++) {
- listeners[i].windowsChanged(device);
- }
- }
- }
-
- public static void notifyFocusChanged(IDevice device) {
- IWindowChangeListener[] listeners = getWindowChangeListenersAsArray(device);
- if (listeners != null) {
- for (int i = 0; i < listeners.length; i++) {
- listeners[i].focusChanged(device);
- }
- }
- }
-
- private static class WindowChangeMonitor implements Runnable {
- private IDevice device;
-
- public WindowChangeMonitor(IDevice device) {
- this.device = device;
- }
-
- @Override
- public void run() {
- while (!Thread.currentThread().isInterrupted()) {
- DeviceConnection connection = null;
- try {
- connection = new DeviceConnection(device);
- connection.sendCommand("AUTOLIST");
- String line;
- while (!Thread.currentThread().isInterrupted()
- && (line = connection.getInputStream().readLine()) != null) {
- if (line.equalsIgnoreCase("LIST UPDATE")) {
- notifyWindowsChanged(device);
- } else if (line.equalsIgnoreCase("FOCUS UPDATE")) {
- notifyFocusChanged(device);
- }
- }
-
- } catch (IOException e) {
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
- }
- }
-}