am d06f8e2f: Merge change 1730 into donut
Merge commit 'd06f8e2f4cb97b5a397793ba7b53e62ab73925f8' * commit 'd06f8e2f4cb97b5a397793ba7b53e62ab73925f8': Make the ddmlib API use IDevice instead of Device
This commit is contained in:
committed by
The Android Open Source Project
commit
47d9b4efb2
@@ -29,7 +29,7 @@ import java.nio.channels.SocketChannel;
|
||||
/**
|
||||
* Helper class to handle requests and connections to adb.
|
||||
* <p/>{@link DebugBridgeServer} is the public API to connection to adb, while {@link AdbHelper}
|
||||
* does the low level stuff.
|
||||
* does the low level stuff.
|
||||
* <p/>This currently uses spin-wait non-blocking I/O. A Selector would be more efficient,
|
||||
* but seems like overkill for what we're doing here.
|
||||
*/
|
||||
@@ -272,14 +272,14 @@ final class AdbHelper {
|
||||
try {
|
||||
adbChan = SocketChannel.open(adbSockAddr);
|
||||
adbChan.configureBlocking(false);
|
||||
|
||||
|
||||
// if the device is not -1, then we first tell adb we're looking to talk
|
||||
// to a specific device
|
||||
setDevice(adbChan, device);
|
||||
|
||||
|
||||
if (write(adbChan, request) == false)
|
||||
throw new IOException("failed asking for frame buffer");
|
||||
|
||||
|
||||
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
|
||||
if (!resp.ioSuccess || !resp.okay) {
|
||||
Log.w("ddms", "Got timeout or unhappy response from ADB fb req: "
|
||||
@@ -287,7 +287,7 @@ final class AdbHelper {
|
||||
adbChan.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
reply = new byte[16];
|
||||
if (read(adbChan, reply) == false) {
|
||||
Log.w("ddms", "got partial reply from ADB fb:");
|
||||
@@ -297,19 +297,19 @@ final class AdbHelper {
|
||||
}
|
||||
ByteBuffer buf = ByteBuffer.wrap(reply);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
|
||||
imageParams.bpp = buf.getInt();
|
||||
imageParams.size = buf.getInt();
|
||||
imageParams.width = buf.getInt();
|
||||
imageParams.height = buf.getInt();
|
||||
|
||||
|
||||
Log.d("ddms", "image params: bpp=" + imageParams.bpp + ", size="
|
||||
+ imageParams.size + ", width=" + imageParams.width
|
||||
+ ", height=" + imageParams.height);
|
||||
|
||||
|
||||
if (write(adbChan, nudge) == false)
|
||||
throw new IOException("failed nudging");
|
||||
|
||||
|
||||
reply = new byte[imageParams.size];
|
||||
if (read(adbChan, reply) == false) {
|
||||
Log.w("ddms", "got truncated reply from ADB fb data");
|
||||
@@ -416,34 +416,34 @@ final class AdbHelper {
|
||||
public static void runLogService(InetSocketAddress adbSockAddr, Device device, String logName,
|
||||
LogReceiver rcvr) throws IOException {
|
||||
SocketChannel adbChan = null;
|
||||
|
||||
|
||||
try {
|
||||
adbChan = SocketChannel.open(adbSockAddr);
|
||||
adbChan.configureBlocking(false);
|
||||
|
||||
|
||||
// if the device is not -1, then we first tell adb we're looking to talk
|
||||
// to a specific device
|
||||
setDevice(adbChan, device);
|
||||
|
||||
|
||||
byte[] request = formAdbRequest("log:" + logName);
|
||||
if (write(adbChan, request) == false) {
|
||||
throw new IOException("failed to submit the log command");
|
||||
}
|
||||
|
||||
|
||||
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
|
||||
if (!resp.ioSuccess || !resp.okay) {
|
||||
throw new IOException("Device rejected log command: " + resp.message);
|
||||
}
|
||||
|
||||
|
||||
byte[] data = new byte[16384];
|
||||
ByteBuffer buf = ByteBuffer.wrap(data);
|
||||
while (true) {
|
||||
int count;
|
||||
|
||||
|
||||
if (rcvr != null && rcvr.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
count = adbChan.read(buf);
|
||||
if (count < 0) {
|
||||
break;
|
||||
@@ -465,7 +465,7 @@ final class AdbHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a port forwarding between a local and a remote port.
|
||||
* @param adbSockAddr the socket address to connect to adb
|
||||
@@ -473,7 +473,7 @@ final class AdbHelper {
|
||||
* @param localPort the local port to forward
|
||||
* @param remotePort the remote port.
|
||||
* @return <code>true</code> if success.
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean createForward(InetSocketAddress adbSockAddr, Device device, int localPort,
|
||||
int remotePort) throws IOException {
|
||||
@@ -482,15 +482,15 @@ final class AdbHelper {
|
||||
try {
|
||||
adbChan = SocketChannel.open(adbSockAddr);
|
||||
adbChan.configureBlocking(false);
|
||||
|
||||
|
||||
byte[] request = formAdbRequest(String.format(
|
||||
"host-serial:%1$s:forward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
|
||||
device.serialNumber, localPort, remotePort));
|
||||
|
||||
device.getSerialNumber(), localPort, remotePort));
|
||||
|
||||
if (write(adbChan, request) == false) {
|
||||
throw new IOException("failed to submit the forward command.");
|
||||
}
|
||||
|
||||
|
||||
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
|
||||
if (!resp.ioSuccess || !resp.okay) {
|
||||
throw new IOException("Device rejected command: " + resp.message);
|
||||
@@ -500,7 +500,7 @@ final class AdbHelper {
|
||||
adbChan.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -520,15 +520,15 @@ final class AdbHelper {
|
||||
try {
|
||||
adbChan = SocketChannel.open(adbSockAddr);
|
||||
adbChan.configureBlocking(false);
|
||||
|
||||
|
||||
byte[] request = formAdbRequest(String.format(
|
||||
"host-serial:%1$s:killforward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
|
||||
device.serialNumber, localPort, remotePort));
|
||||
|
||||
device.getSerialNumber(), localPort, remotePort));
|
||||
|
||||
if (!write(adbChan, request)) {
|
||||
throw new IOException("failed to submit the remove forward command.");
|
||||
}
|
||||
|
||||
|
||||
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
|
||||
if (!resp.ioSuccess || !resp.okay) {
|
||||
throw new IOException("Device rejected command: " + resp.message);
|
||||
@@ -563,7 +563,7 @@ final class AdbHelper {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads from the socket until the array is filled, or no more data is coming (because
|
||||
* the socket closed or the timeout expired).
|
||||
@@ -572,7 +572,7 @@ final class AdbHelper {
|
||||
* mode for timeouts to work
|
||||
* @param data the buffer to store the read data into.
|
||||
* @return "true" if all data was read.
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
static boolean read(SocketChannel chan, byte[] data) {
|
||||
try {
|
||||
@@ -581,7 +581,7 @@ final class AdbHelper {
|
||||
Log.d("ddms", "readAll: IOException: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ final class AdbHelper {
|
||||
* @param data the buffer to store the read data into.
|
||||
* @param length the length to read or -1 to fill the data buffer completely
|
||||
* @param timeout The timeout value. A timeout of zero means "wait forever".
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
static void read(SocketChannel chan, byte[] data, int length, int timeout) throws IOException {
|
||||
ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
|
||||
@@ -653,7 +653,7 @@ final class AdbHelper {
|
||||
* @param data the buffer to send.
|
||||
* @param length the length to write or -1 to send the whole buffer.
|
||||
* @param timeout The timeout value. A timeout of zero means "wait forever".
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
static void write(SocketChannel chan, byte[] data, int length, int timeout)
|
||||
throws IOException {
|
||||
@@ -697,7 +697,7 @@ final class AdbHelper {
|
||||
// if the device is not -1, then we first tell adb we're looking to talk
|
||||
// to a specific device
|
||||
if (device != null) {
|
||||
String msg = "host:transport:" + device.serialNumber; //$NON-NLS-1$
|
||||
String msg = "host:transport:" + device.getSerialNumber(); //$NON-NLS-1$
|
||||
byte[] device_query = formAdbRequest(msg);
|
||||
|
||||
if (write(adbChan, device_query) == false)
|
||||
|
||||
@@ -107,7 +107,7 @@ public final class AndroidDebugBridge {
|
||||
|
||||
/**
|
||||
* Classes which implement this interface provide methods that deal
|
||||
* with {@link Device} addition, deletion, and changes.
|
||||
* with {@link IDevice} addition, deletion, and changes.
|
||||
*/
|
||||
public interface IDeviceChangeListener {
|
||||
/**
|
||||
@@ -116,7 +116,7 @@ public final class AndroidDebugBridge {
|
||||
* This is sent from a non UI thread.
|
||||
* @param device the new device.
|
||||
*/
|
||||
public void deviceConnected(Device device);
|
||||
public void deviceConnected(IDevice device);
|
||||
|
||||
/**
|
||||
* Sent when the a device is connected to the {@link AndroidDebugBridge}.
|
||||
@@ -124,7 +124,7 @@ public final class AndroidDebugBridge {
|
||||
* This is sent from a non UI thread.
|
||||
* @param device the new device.
|
||||
*/
|
||||
public void deviceDisconnected(Device device);
|
||||
public void deviceDisconnected(IDevice device);
|
||||
|
||||
/**
|
||||
* Sent when a device data changed, or when clients are started/terminated on the device.
|
||||
@@ -132,10 +132,10 @@ public final class AndroidDebugBridge {
|
||||
* This is sent from a non UI thread.
|
||||
* @param device the device that was updated.
|
||||
* @param changeMask the mask describing what changed. It can contain any of the following
|
||||
* values: {@link Device#CHANGE_BUILD_INFO}, {@link Device#CHANGE_STATE},
|
||||
* {@link Device#CHANGE_CLIENT_LIST}
|
||||
* values: {@link IDevice#CHANGE_BUILD_INFO}, {@link IDevice#CHANGE_STATE},
|
||||
* {@link IDevice#CHANGE_CLIENT_LIST}
|
||||
*/
|
||||
public void deviceChanged(Device device, int changeMask);
|
||||
public void deviceChanged(IDevice device, int changeMask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,7 +215,7 @@ public final class AndroidDebugBridge {
|
||||
|
||||
/**
|
||||
* Returns whether the ddmlib is setup to support monitoring and interacting with
|
||||
* {@link Client}s running on the {@link Device}s.
|
||||
* {@link Client}s running on the {@link IDevice}s.
|
||||
*/
|
||||
static boolean getClientSupport() {
|
||||
return sClientSupport;
|
||||
@@ -391,7 +391,7 @@ public final class AndroidDebugBridge {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the listener to the collection of listeners who will be notified when a {@link Device}
|
||||
* Adds the listener to the collection of listeners who will be notified when a {@link IDevice}
|
||||
* is connected, disconnected, or when its properties or its {@link Client} list changed,
|
||||
* by sending it one of the messages defined in the {@link IDeviceChangeListener} interface.
|
||||
* @param listener The listener which should be notified.
|
||||
@@ -406,7 +406,7 @@ public final class AndroidDebugBridge {
|
||||
|
||||
/**
|
||||
* Removes the listener from the collection of listeners who will be notified when a
|
||||
* {@link Device} is connected, disconnected, or when its properties or its {@link Client}
|
||||
* {@link IDevice} is connected, disconnected, or when its properties or its {@link Client}
|
||||
* list changed.
|
||||
* @param listener The listener which should no longer be notified.
|
||||
*/
|
||||
@@ -446,23 +446,23 @@ public final class AndroidDebugBridge {
|
||||
* Returns the devices.
|
||||
* @see #hasInitialDeviceList()
|
||||
*/
|
||||
public Device[] getDevices() {
|
||||
public IDevice[] getDevices() {
|
||||
synchronized (sLock) {
|
||||
if (mDeviceMonitor != null) {
|
||||
return mDeviceMonitor.getDevices();
|
||||
}
|
||||
}
|
||||
|
||||
return new Device[0];
|
||||
return new IDevice[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the bridge has acquired the initial list from adb after being created.
|
||||
* <p/>Calling {@link #getDevices()} right after {@link #createBridge(String, boolean)} will
|
||||
* generally result in an empty list. This is due to the internal asynchronous communication
|
||||
* mechanism with <code>adb</code> that does not guarantee that the {@link Device} list has been
|
||||
* mechanism with <code>adb</code> that does not guarantee that the {@link IDevice} list has been
|
||||
* built before the call to {@link #getDevices()}.
|
||||
* <p/>The recommended way to get the list of {@link Device} objects is to create a
|
||||
* <p/>The recommended way to get the list of {@link IDevice} objects is to create a
|
||||
* {@link IDeviceChangeListener} object.
|
||||
*/
|
||||
public boolean hasInitialDeviceList() {
|
||||
@@ -719,19 +719,19 @@ public final class AndroidDebugBridge {
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the listener of a new {@link Device}.
|
||||
* Notify the listener of a new {@link IDevice}.
|
||||
* <p/>
|
||||
* The notification of the listeners is done in a synchronized block. It is important to
|
||||
* expect the listeners to potentially access various methods of {@link Device} as well as
|
||||
* expect the listeners to potentially access various methods of {@link IDevice} as well as
|
||||
* {@link #getDevices()} which use internal locks.
|
||||
* <p/>
|
||||
* For this reason, any call to this method from a method of {@link DeviceMonitor},
|
||||
* {@link Device} which is also inside a synchronized block, should first synchronize on
|
||||
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
|
||||
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
|
||||
* @param device the new <code>Device</code>.
|
||||
* @param device the new <code>IDevice</code>.
|
||||
* @see #getLock()
|
||||
*/
|
||||
void deviceConnected(Device device) {
|
||||
void deviceConnected(IDevice device) {
|
||||
// because the listeners could remove themselves from the list while processing
|
||||
// their event callback, we make a copy of the list and iterate on it instead of
|
||||
// the main list.
|
||||
@@ -755,19 +755,19 @@ public final class AndroidDebugBridge {
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the listener of a disconnected {@link Device}.
|
||||
* Notify the listener of a disconnected {@link IDevice}.
|
||||
* <p/>
|
||||
* The notification of the listeners is done in a synchronized block. It is important to
|
||||
* expect the listeners to potentially access various methods of {@link Device} as well as
|
||||
* expect the listeners to potentially access various methods of {@link IDevice} as well as
|
||||
* {@link #getDevices()} which use internal locks.
|
||||
* <p/>
|
||||
* For this reason, any call to this method from a method of {@link DeviceMonitor},
|
||||
* {@link Device} which is also inside a synchronized block, should first synchronize on
|
||||
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
|
||||
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
|
||||
* @param device the disconnected <code>Device</code>.
|
||||
* @param device the disconnected <code>IDevice</code>.
|
||||
* @see #getLock()
|
||||
*/
|
||||
void deviceDisconnected(Device device) {
|
||||
void deviceDisconnected(IDevice device) {
|
||||
// because the listeners could remove themselves from the list while processing
|
||||
// their event callback, we make a copy of the list and iterate on it instead of
|
||||
// the main list.
|
||||
@@ -791,19 +791,19 @@ public final class AndroidDebugBridge {
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the listener of a modified {@link Device}.
|
||||
* Notify the listener of a modified {@link IDevice}.
|
||||
* <p/>
|
||||
* The notification of the listeners is done in a synchronized block. It is important to
|
||||
* expect the listeners to potentially access various methods of {@link Device} as well as
|
||||
* expect the listeners to potentially access various methods of {@link IDevice} as well as
|
||||
* {@link #getDevices()} which use internal locks.
|
||||
* <p/>
|
||||
* For this reason, any call to this method from a method of {@link DeviceMonitor},
|
||||
* {@link Device} which is also inside a synchronized block, should first synchronize on
|
||||
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
|
||||
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
|
||||
* @param device the modified <code>Device</code>.
|
||||
* @param device the modified <code>IDevice</code>.
|
||||
* @see #getLock()
|
||||
*/
|
||||
void deviceChanged(Device device, int changeMask) {
|
||||
void deviceChanged(IDevice device, int changeMask) {
|
||||
// because the listeners could remove themselves from the list while processing
|
||||
// their event callback, we make a copy of the list and iterate on it instead of
|
||||
// the main list.
|
||||
@@ -830,11 +830,11 @@ public final class AndroidDebugBridge {
|
||||
* Notify the listener of a modified {@link Client}.
|
||||
* <p/>
|
||||
* The notification of the listeners is done in a synchronized block. It is important to
|
||||
* expect the listeners to potentially access various methods of {@link Device} as well as
|
||||
* expect the listeners to potentially access various methods of {@link IDevice} as well as
|
||||
* {@link #getDevices()} which use internal locks.
|
||||
* <p/>
|
||||
* For this reason, any call to this method from a method of {@link DeviceMonitor},
|
||||
* {@link Device} which is also inside a synchronized block, should first synchronize on
|
||||
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
|
||||
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
|
||||
* @param device the modified <code>Client</code>.
|
||||
* @param changeMask the mask indicating what changed in the <code>Client</code>
|
||||
|
||||
@@ -199,7 +199,7 @@ abstract class ChunkHandler {
|
||||
protected static Client checkDebuggerPortForAppName(Client client, String appName) {
|
||||
IDebugPortProvider provider = DebugPortManager.getProvider();
|
||||
if (provider != null) {
|
||||
Device device = client.getDevice();
|
||||
Device device = client.getDeviceImpl();
|
||||
int newPort = provider.getPort(device, appName);
|
||||
|
||||
if (newPort != IDebugPortProvider.NO_STATIC_PORT &&
|
||||
|
||||
@@ -133,7 +133,7 @@ public class Client {
|
||||
mConnState = ST_INIT;
|
||||
|
||||
mClientData = new ClientData(pid);
|
||||
|
||||
|
||||
mThreadUpdateEnabled = DdmPreferences.getInitialThreadUpdate();
|
||||
mHeapUpdateEnabled = DdmPreferences.getInitialHeapUpdate();
|
||||
}
|
||||
@@ -147,9 +147,15 @@ public class Client {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Device} on which this Client is running.
|
||||
* Returns the {@link IDevice} on which this Client is running.
|
||||
*/
|
||||
public Device getDevice() {
|
||||
public IDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
/** Returns the {@link Device} on which this Client is running.
|
||||
*/
|
||||
Device getDeviceImpl() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
@@ -238,7 +244,7 @@ public class Client {
|
||||
|
||||
update(CHANGE_THREAD_MODE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the thread update is enabled.
|
||||
*/
|
||||
@@ -268,7 +274,7 @@ public class Client {
|
||||
public void requestThreadStackTrace(int threadId) {
|
||||
HandleThread.requestThreadStackCallRefresh(this, threadId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enables or disables the heap update.
|
||||
* <p/>If <code>true</code>, any GC will cause the client to send its heap information.
|
||||
@@ -320,7 +326,7 @@ public class Client {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enables or disables the Allocation tracker for this client.
|
||||
* <p/>If enabled, the VM will start tracking allocation informations. A call to
|
||||
@@ -336,7 +342,7 @@ public class Client {
|
||||
Log.e("ddmlib", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a request to the VM to send the enable status of the allocation tracking.
|
||||
* This is asynchronous.
|
||||
@@ -350,9 +356,9 @@ public class Client {
|
||||
HandleHeap.sendREAQ(this);
|
||||
} catch (IOException e) {
|
||||
Log.e("ddmlib", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a request to the VM to send the information about all the allocations that have
|
||||
* happened since the call to {@link #enableAllocationTracker(boolean)} with <var>enable</var>
|
||||
@@ -457,7 +463,7 @@ public class Client {
|
||||
}
|
||||
|
||||
mConnState = ST_AWAIT_SHAKE;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -638,7 +644,7 @@ public class Client {
|
||||
*/
|
||||
Log.e("ddms", "Receiving data in state = " + mConnState);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -753,7 +759,7 @@ public class Client {
|
||||
|
||||
mDevice.removeClient(this, notify);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this {@link Client} has a valid connection to the application VM.
|
||||
*/
|
||||
|
||||
@@ -19,12 +19,12 @@ package com.android.ddmlib;
|
||||
import com.android.ddmlib.Device;
|
||||
|
||||
/**
|
||||
* Centralized point to provide a {@link IDebugPortProvider} to ddmlib.
|
||||
*
|
||||
* Centralized point to provide a {@link IDebugPortProvider} to ddmlib.
|
||||
*
|
||||
* <p/>When {@link Client} objects are created, they start listening for debuggers on a specific
|
||||
* port. The default behavior is to start with {@link DdmPreferences#getDebugPortBase()} and
|
||||
* port. The default behavior is to start with {@link DdmPreferences#getDebugPortBase()} and
|
||||
* increment this value for each new <code>Client</code>.
|
||||
*
|
||||
*
|
||||
* <p/>This {@link DebugPortManager} allows applications using ddmlib to provide a custom
|
||||
* port provider on a per-<code>Client</code> basis, depending on the device/emulator they are
|
||||
* running on, and/or their names.
|
||||
@@ -48,7 +48,7 @@ public class DebugPortManager {
|
||||
* @return The non-random debugger port or {@link #NO_STATIC_PORT} if the {@link Client}
|
||||
* should use the automatic debugger port provider.
|
||||
*/
|
||||
public int getPort(Device device, String appName);
|
||||
public int getPort(IDevice device, String appName);
|
||||
}
|
||||
|
||||
private static IDebugPortProvider sProvider = null;
|
||||
@@ -63,7 +63,7 @@ public class DebugPortManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the
|
||||
* Returns the
|
||||
* @return
|
||||
*/
|
||||
static IDebugPortProvider getProvider() {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.ddmlib;
|
||||
|
||||
import com.android.ddmlib.Client;
|
||||
import com.android.ddmlib.log.LogReceiver;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -30,50 +29,20 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* A Device. It can be a physical device or an emulator.
|
||||
*
|
||||
* TODO: make this class package-protected, and shift all callers to use IDevice
|
||||
*/
|
||||
public final class Device implements IDevice {
|
||||
/**
|
||||
* The state of a device.
|
||||
*/
|
||||
public static enum DeviceState {
|
||||
BOOTLOADER("bootloader"), //$NON-NLS-1$
|
||||
OFFLINE("offline"), //$NON-NLS-1$
|
||||
ONLINE("device"); //$NON-NLS-1$
|
||||
|
||||
private String mState;
|
||||
|
||||
DeviceState(String state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link DeviceState} from the string returned by <code>adb devices</code>.
|
||||
* @param state the device state.
|
||||
* @return a {@link DeviceState} object or <code>null</code> if the state is unknown.
|
||||
*/
|
||||
public static DeviceState getState(String state) {
|
||||
for (DeviceState deviceState : values()) {
|
||||
if (deviceState.mState.equals(state)) {
|
||||
return deviceState;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final class Device implements IDevice {
|
||||
|
||||
/** Emulator Serial Number regexp. */
|
||||
final static String RE_EMULATOR_SN = "emulator-(\\d+)"; //$NON-NLS-1$
|
||||
|
||||
/** Serial number of the device */
|
||||
String serialNumber = null;
|
||||
private String mSerialNumber = null;
|
||||
|
||||
/** Name of the AVD */
|
||||
String mAvdName = null;
|
||||
private String mAvdName = null;
|
||||
|
||||
/** State of the device. */
|
||||
DeviceState state = null;
|
||||
private DeviceState mState = null;
|
||||
|
||||
/** Device properties. */
|
||||
private final Map<String, String> mProperties = new HashMap<String, String>();
|
||||
@@ -91,22 +60,42 @@ public final class Device implements IDevice {
|
||||
* @see com.android.ddmlib.IDevice#getSerialNumber()
|
||||
*/
|
||||
public String getSerialNumber() {
|
||||
return serialNumber;
|
||||
return mSerialNumber;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String getAvdName() {
|
||||
return mAvdName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the AVD
|
||||
*/
|
||||
void setAvdName(String avdName) {
|
||||
if (isEmulator() == false) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot set the AVD name of the device is not an emulator");
|
||||
}
|
||||
|
||||
mAvdName = avdName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.android.ddmlib.IDevice#getState()
|
||||
*/
|
||||
public DeviceState getState() {
|
||||
return state;
|
||||
return mState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the state of the device.
|
||||
*/
|
||||
void setState(DeviceState state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.android.ddmlib.IDevice#getProperties()
|
||||
@@ -134,7 +123,7 @@ public final class Device implements IDevice {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return serialNumber;
|
||||
return mSerialNumber;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,7 +131,7 @@ public final class Device implements IDevice {
|
||||
* @see com.android.ddmlib.IDevice#isOnline()
|
||||
*/
|
||||
public boolean isOnline() {
|
||||
return state == DeviceState.ONLINE;
|
||||
return mState == DeviceState.ONLINE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,7 +139,7 @@ public final class Device implements IDevice {
|
||||
* @see com.android.ddmlib.IDevice#isEmulator()
|
||||
*/
|
||||
public boolean isEmulator() {
|
||||
return serialNumber.matches(RE_EMULATOR_SN);
|
||||
return mSerialNumber.matches(RE_EMULATOR_SN);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,7 +147,7 @@ public final class Device implements IDevice {
|
||||
* @see com.android.ddmlib.IDevice#isOffline()
|
||||
*/
|
||||
public boolean isOffline() {
|
||||
return state == DeviceState.OFFLINE;
|
||||
return mState == DeviceState.OFFLINE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,7 +155,7 @@ public final class Device implements IDevice {
|
||||
* @see com.android.ddmlib.IDevice#isBootLoader()
|
||||
*/
|
||||
public boolean isBootLoader() {
|
||||
return state == DeviceState.BOOTLOADER;
|
||||
return mState == DeviceState.BOOTLOADER;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -305,8 +294,10 @@ public final class Device implements IDevice {
|
||||
}
|
||||
|
||||
|
||||
Device(DeviceMonitor monitor) {
|
||||
Device(DeviceMonitor monitor, String serialNumber, DeviceState deviceState) {
|
||||
mMonitor = monitor;
|
||||
mSerialNumber = serialNumber;
|
||||
mState = deviceState;
|
||||
}
|
||||
|
||||
DeviceMonitor getMonitor() {
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.android.ddmlib;
|
||||
|
||||
import com.android.ddmlib.AdbHelper.AdbResponse;
|
||||
import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
|
||||
import com.android.ddmlib.Device.DeviceState;
|
||||
import com.android.ddmlib.IDevice.DeviceState;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@@ -112,11 +112,11 @@ final class DeviceMonitor {
|
||||
boolean isMonitoring() {
|
||||
return mMonitoring;
|
||||
}
|
||||
|
||||
|
||||
int getConnectionAttemptCount() {
|
||||
return mConnectionAttempt;
|
||||
}
|
||||
|
||||
|
||||
int getRestartAttemptCount() {
|
||||
return mRestartAttemptCount;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ final class DeviceMonitor {
|
||||
return mDevices.toArray(new Device[mDevices.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean hasInitialDeviceList() {
|
||||
return mInitialDeviceListDone;
|
||||
}
|
||||
@@ -184,11 +184,11 @@ final class DeviceMonitor {
|
||||
if (mMonitoring) {
|
||||
// read the length of the incoming message
|
||||
int length = readLength(mMainAdbConnection, mLengthBuffer);
|
||||
|
||||
|
||||
if (length >= 0) {
|
||||
// read the incoming message
|
||||
processIncomingDeviceData(length);
|
||||
|
||||
|
||||
// flag the fact that we have build the list at least once.
|
||||
mInitialDeviceListDone = true;
|
||||
}
|
||||
@@ -278,20 +278,19 @@ final class DeviceMonitor {
|
||||
*/
|
||||
private void processIncomingDeviceData(int length) throws IOException {
|
||||
ArrayList<Device> list = new ArrayList<Device>();
|
||||
|
||||
|
||||
if (length > 0) {
|
||||
byte[] buffer = new byte[length];
|
||||
String result = read(mMainAdbConnection, buffer);
|
||||
|
||||
|
||||
String[] devices = result.split("\n"); // $NON-NLS-1$
|
||||
|
||||
for (String d : devices) {
|
||||
String[] param = d.split("\t"); // $NON-NLS-1$
|
||||
if (param.length == 2) {
|
||||
// new adb uses only serial numbers to identify devices
|
||||
Device device = new Device(this);
|
||||
device.serialNumber = param[0];
|
||||
device.state = DeviceState.getState(param[1]);
|
||||
Device device = new Device(this, param[0] /*serialnumber*/,
|
||||
DeviceState.getState(param[1]));
|
||||
|
||||
//add the device to the list
|
||||
list.add(device);
|
||||
@@ -319,24 +318,24 @@ final class DeviceMonitor {
|
||||
// * if we do not find it, we remove it from the current list.
|
||||
// Once this is done, the new list contains device we aren't monitoring yet, so we
|
||||
// add them to the list, and start monitoring them.
|
||||
|
||||
|
||||
for (int d = 0 ; d < mDevices.size() ;) {
|
||||
Device device = mDevices.get(d);
|
||||
|
||||
|
||||
// look for a similar device in the new list.
|
||||
int count = newList.size();
|
||||
boolean foundMatch = false;
|
||||
for (int dd = 0 ; dd < count ; dd++) {
|
||||
Device newDevice = newList.get(dd);
|
||||
// see if it matches in id and serial number.
|
||||
if (newDevice.serialNumber.equals(device.serialNumber)) {
|
||||
if (newDevice.getSerialNumber().equals(device.getSerialNumber())) {
|
||||
foundMatch = true;
|
||||
|
||||
|
||||
// update the state if needed.
|
||||
if (device.state != newDevice.state) {
|
||||
device.state = newDevice.state;
|
||||
if (device.getState() != newDevice.getState()) {
|
||||
device.setState(newDevice.getState());
|
||||
device.update(Device.CHANGE_STATE);
|
||||
|
||||
|
||||
// if the device just got ready/online, we need to start
|
||||
// monitoring it.
|
||||
if (device.isOnline()) {
|
||||
@@ -344,7 +343,7 @@ final class DeviceMonitor {
|
||||
if (startMonitoringDevice(device) == false) {
|
||||
Log.e("DeviceMonitor",
|
||||
"Failed to start monitoring "
|
||||
+ device.serialNumber);
|
||||
+ device.getSerialNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,13 +352,13 @@ final class DeviceMonitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// remove the new device from the list since it's been used
|
||||
newList.remove(dd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (foundMatch == false) {
|
||||
// the device is gone, we need to remove it, and keep current index
|
||||
// to process the next one.
|
||||
@@ -370,21 +369,21 @@ final class DeviceMonitor {
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// at this point we should still have some new devices in newList, so we
|
||||
// process them.
|
||||
for (Device newDevice : newList) {
|
||||
// add them to the list
|
||||
mDevices.add(newDevice);
|
||||
mServer.deviceConnected(newDevice);
|
||||
|
||||
|
||||
// start monitoring them.
|
||||
if (AndroidDebugBridge.getClientSupport() == true) {
|
||||
if (newDevice.isOnline()) {
|
||||
startMonitoringDevice(newDevice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// look for their build info.
|
||||
if (newDevice.isOnline()) {
|
||||
queryNewDeviceForInfo(newDevice);
|
||||
@@ -398,7 +397,7 @@ final class DeviceMonitor {
|
||||
private void removeDevice(Device device) {
|
||||
device.clearClientList();
|
||||
mDevices.remove(device);
|
||||
|
||||
|
||||
SocketChannel channel = device.getClientMonitoringSocket();
|
||||
if (channel != null) {
|
||||
try {
|
||||
@@ -419,12 +418,12 @@ final class DeviceMonitor {
|
||||
// first get the list of properties.
|
||||
device.executeShellCommand(GetPropReceiver.GETPROP_COMMAND,
|
||||
new GetPropReceiver(device));
|
||||
|
||||
|
||||
// now get the emulator Virtual Device name (if applicable).
|
||||
if (device.isEmulator()) {
|
||||
EmulatorConsole console = EmulatorConsole.getConsole(device);
|
||||
if (console != null) {
|
||||
device.mAvdName = console.getAvdName();
|
||||
device.setAvdName(console.getAvdName());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -510,7 +509,7 @@ final class DeviceMonitor {
|
||||
MonitorThread monitorThread = MonitorThread.getInstance();
|
||||
|
||||
for (Client client : clients) {
|
||||
Device device = client.getDevice();
|
||||
Device device = client.getDeviceImpl();
|
||||
int pid = client.getClientData().getPid();
|
||||
|
||||
monitorThread.dropClient(client, false /* notify */);
|
||||
@@ -623,10 +622,10 @@ final class DeviceMonitor {
|
||||
if (length > 0) {
|
||||
byte[] buffer = new byte[length];
|
||||
String result = read(monitorSocket, buffer);
|
||||
|
||||
|
||||
// split each line in its own list and create an array of integer pid
|
||||
String[] pids = result.split("\n"); //$NON-NLS-1$
|
||||
|
||||
|
||||
for (String pid : pids) {
|
||||
try {
|
||||
pidList.add(Integer.valueOf(pid));
|
||||
@@ -662,7 +661,7 @@ final class DeviceMonitor {
|
||||
for (int c = 0 ; c < clients.size() ;) {
|
||||
Client client = clients.get(c);
|
||||
int pid = client.getClientData().getPid();
|
||||
|
||||
|
||||
// look for a matching pid
|
||||
Integer match = null;
|
||||
for (Integer matchingPid : pidList) {
|
||||
@@ -671,7 +670,7 @@ final class DeviceMonitor {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (match != null) {
|
||||
pidList.remove(match);
|
||||
c++; // move on to the next client.
|
||||
@@ -705,7 +704,7 @@ final class DeviceMonitor {
|
||||
* @return
|
||||
*/
|
||||
private void openClient(Device device, int pid, int port, MonitorThread monitorThread) {
|
||||
|
||||
|
||||
SocketChannel clientSocket;
|
||||
try {
|
||||
clientSocket = AdbHelper.createPassThroughConnection(
|
||||
@@ -721,7 +720,7 @@ final class DeviceMonitor {
|
||||
"Failed to connect to client '" + pid + "': " + ioe.getMessage());
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
createClient(device, pid, clientSocket, port, monitorThread);
|
||||
}
|
||||
|
||||
@@ -814,7 +813,7 @@ final class DeviceMonitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the length of the next message from a socket.
|
||||
* @param socket The {@link SocketChannel} to read from.
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.regex.Pattern;
|
||||
* code removes <code>\r</code> and waits for <code>\n</code>.
|
||||
* <p/>However this means you <i>may</i> receive <code>\r\n</code> when reading from the console.
|
||||
* <p/>
|
||||
* <b>This API will change in the near future.</b>
|
||||
* <b>This API will change in the near future.</b>
|
||||
*/
|
||||
public final class EmulatorConsole {
|
||||
|
||||
@@ -65,7 +65,7 @@ public final class EmulatorConsole {
|
||||
private final static String COMMAND_NETWORK_STATUS = "network status\r\n"; //$NON-NLS-1$
|
||||
private final static String COMMAND_NETWORK_SPEED = "network speed %1$s\r\n"; //$NON-NLS-1$
|
||||
private final static String COMMAND_NETWORK_LATENCY = "network delay %1$s\r\n"; //$NON-NLS-1$
|
||||
private final static String COMMAND_GPS =
|
||||
private final static String COMMAND_GPS =
|
||||
"geo nmea $GPGGA,%1$02d%2$02d%3$02d.%4$03d," + //$NON-NLS-1$
|
||||
"%5$03d%6$09.6f,%7$c,%8$03d%9$09.6f,%10$c," + //$NON-NLS-1$
|
||||
"1,10,0.0,0.0,0,0.0,0,0.0,0000\r\n"; //$NON-NLS-1$
|
||||
@@ -202,9 +202,9 @@ public final class EmulatorConsole {
|
||||
* @param d The device that the console links to.
|
||||
* @return an <code>EmulatorConsole</code> object or <code>null</code> if the connection failed.
|
||||
*/
|
||||
public static synchronized EmulatorConsole getConsole(Device d) {
|
||||
public static synchronized EmulatorConsole getConsole(IDevice d) {
|
||||
// we need to make sure that the device is an emulator
|
||||
Matcher m = sEmulatorRegexp.matcher(d.serialNumber);
|
||||
Matcher m = sEmulatorRegexp.matcher(d.getSerialNumber());
|
||||
if (m.matches()) {
|
||||
// get the port number. This is the console port.
|
||||
int port;
|
||||
@@ -308,7 +308,7 @@ public final class EmulatorConsole {
|
||||
RemoveConsole(mPort);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public synchronized String getAvdName() {
|
||||
if (sendCommand(COMMAND_AVD_NAME)) {
|
||||
String[] result = readLines();
|
||||
@@ -323,7 +323,7 @@ public final class EmulatorConsole {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -517,18 +517,18 @@ public final class EmulatorConsole {
|
||||
String command = String.format(COMMAND_NETWORK_LATENCY, NETWORK_LATENCIES[selectionIndex]);
|
||||
return processCommand(command);
|
||||
}
|
||||
|
||||
|
||||
public synchronized String sendLocation(double longitude, double latitude, double elevation) {
|
||||
|
||||
|
||||
Calendar c = Calendar.getInstance();
|
||||
|
||||
|
||||
double absLong = Math.abs(longitude);
|
||||
int longDegree = (int)Math.floor(absLong);
|
||||
char longDirection = 'E';
|
||||
if (longitude < 0) {
|
||||
longDirection = 'W';
|
||||
}
|
||||
|
||||
|
||||
double longMinute = (absLong - Math.floor(absLong)) * 60;
|
||||
|
||||
double absLat = Math.abs(latitude);
|
||||
@@ -537,15 +537,15 @@ public final class EmulatorConsole {
|
||||
if (latitude < 0) {
|
||||
latDirection = 'S';
|
||||
}
|
||||
|
||||
|
||||
double latMinute = (absLat - Math.floor(absLat)) * 60;
|
||||
|
||||
|
||||
String command = String.format(COMMAND_GPS,
|
||||
c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
|
||||
c.get(Calendar.SECOND), c.get(Calendar.MILLISECOND),
|
||||
latDegree, latMinute, latDirection,
|
||||
longDegree, longMinute, longDirection);
|
||||
|
||||
|
||||
return processCommand(command);
|
||||
}
|
||||
|
||||
@@ -617,7 +617,7 @@ public final class EmulatorConsole {
|
||||
ByteBuffer buf = ByteBuffer.wrap(mBuffer, 0, mBuffer.length);
|
||||
int numWaits = 0;
|
||||
boolean stop = false;
|
||||
|
||||
|
||||
while (buf.position() != buf.limit() && stop == false) {
|
||||
int count;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.ddmlib;
|
||||
|
||||
import com.android.ddmlib.Device.DeviceState;
|
||||
import com.android.ddmlib.log.LogReceiver;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -40,6 +39,35 @@ public interface IDevice {
|
||||
/** Device change bit mask: build info change. */
|
||||
public static final int CHANGE_BUILD_INFO = 0x0004;
|
||||
|
||||
/**
|
||||
* The state of a device.
|
||||
*/
|
||||
public static enum DeviceState {
|
||||
BOOTLOADER("bootloader"), //$NON-NLS-1$
|
||||
OFFLINE("offline"), //$NON-NLS-1$
|
||||
ONLINE("device"); //$NON-NLS-1$
|
||||
|
||||
private String mState;
|
||||
|
||||
DeviceState(String state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link DeviceState} from the string returned by <code>adb devices</code>.
|
||||
* @param state the device state.
|
||||
* @return a {@link DeviceState} object or <code>null</code> if the state is unknown.
|
||||
*/
|
||||
public static DeviceState getState(String state) {
|
||||
for (DeviceState deviceState : values()) {
|
||||
if (deviceState.mState.equals(state)) {
|
||||
return deviceState;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number of the device.
|
||||
*/
|
||||
|
||||
@@ -103,7 +103,7 @@ final class MonitorThread extends Thread {
|
||||
|
||||
|
||||
/**
|
||||
* Sets or changes the port number for "debug selected".
|
||||
* Sets or changes the port number for "debug selected".
|
||||
*/
|
||||
synchronized void setDebugSelectedPort(int port) throws IllegalStateException {
|
||||
if (mInstance == null) {
|
||||
@@ -206,7 +206,7 @@ final class MonitorThread extends Thread {
|
||||
}
|
||||
|
||||
while (!mQuit) {
|
||||
|
||||
|
||||
try {
|
||||
/*
|
||||
* sync with new registrations: we wait until addClient is done before going through
|
||||
@@ -215,7 +215,7 @@ final class MonitorThread extends Thread {
|
||||
*/
|
||||
synchronized (mClientList) {
|
||||
}
|
||||
|
||||
|
||||
// (re-)open the "debug selected" port, if it's not opened yet or
|
||||
// if the port changed.
|
||||
try {
|
||||
@@ -234,7 +234,7 @@ final class MonitorThread extends Thread {
|
||||
Log.e("ddms", ioe);
|
||||
mNewDebugSelectedPort = mDebugSelectedPort; // no retry
|
||||
}
|
||||
|
||||
|
||||
int count;
|
||||
try {
|
||||
count = mSelector.select();
|
||||
@@ -244,20 +244,20 @@ final class MonitorThread extends Thread {
|
||||
} catch (CancelledKeyException cke) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (count == 0) {
|
||||
// somebody called wakeup() ?
|
||||
// Log.i("ddms", "selector looping");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Set<SelectionKey> keys = mSelector.selectedKeys();
|
||||
Iterator<SelectionKey> iter = keys.iterator();
|
||||
|
||||
|
||||
while (iter.hasNext()) {
|
||||
SelectionKey key = iter.next();
|
||||
iter.remove();
|
||||
|
||||
|
||||
try {
|
||||
if (key.attachment() instanceof Client) {
|
||||
processClientActivity(key);
|
||||
@@ -300,7 +300,7 @@ final class MonitorThread extends Thread {
|
||||
*/
|
||||
private void processClientActivity(SelectionKey key) {
|
||||
Client client = (Client)key.attachment();
|
||||
|
||||
|
||||
try {
|
||||
if (key.isReadable() == false || key.isValid() == false) {
|
||||
Log.d("ddms", "Invalid key from " + client + ". Dropping client.");
|
||||
@@ -423,7 +423,7 @@ final class MonitorThread extends Thread {
|
||||
* @param notify
|
||||
*/
|
||||
synchronized void dropClient(Client client, boolean notify) {
|
||||
if (mInstance == null) {
|
||||
if (mInstance == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -551,13 +551,13 @@ final class MonitorThread extends Thread {
|
||||
|
||||
// we should drop the client, but also attempt to reopen it.
|
||||
// This is done by the DeviceMonitor.
|
||||
client.getDevice().getMonitor().addClientToDropAndReopen(client,
|
||||
client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
|
||||
IDebugPortProvider.NO_STATIC_PORT);
|
||||
} else {
|
||||
Log.i("ddms", " (recycling client connection as well)");
|
||||
// we should drop the client, but also attempt to reopen it.
|
||||
// This is done by the DeviceMonitor.
|
||||
client.getDevice().getMonitor().addClientToDropAndReopen(client,
|
||||
client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
|
||||
IDebugPortProvider.NO_STATIC_PORT);
|
||||
}
|
||||
}
|
||||
@@ -644,7 +644,7 @@ final class MonitorThread extends Thread {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Broadcast an event to all message handlers.
|
||||
*/
|
||||
@@ -719,7 +719,7 @@ final class MonitorThread extends Thread {
|
||||
}
|
||||
|
||||
mDebugSelectedChan.register(mSelector, SelectionKey.OP_ACCEPT, this);
|
||||
|
||||
|
||||
return true;
|
||||
} catch (java.net.BindException e) {
|
||||
displayDebugSelectedBindError(mNewDebugSelectedPort);
|
||||
@@ -727,7 +727,7 @@ final class MonitorThread extends Thread {
|
||||
// do not attempt to reopen it.
|
||||
mDebugSelectedChan = null;
|
||||
mNewDebugSelectedPort = -1;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.ddmlib.log;
|
||||
|
||||
import com.android.ddmlib.Device;
|
||||
import com.android.ddmlib.IDevice;
|
||||
import com.android.ddmlib.Log;
|
||||
import com.android.ddmlib.MultiLineReceiver;
|
||||
import com.android.ddmlib.log.EventContainer.EventValueType;
|
||||
@@ -55,7 +55,7 @@ public final class EventLogParser {
|
||||
private final static int EVENT_TYPE_LONG = 1;
|
||||
private final static int EVENT_TYPE_STRING = 2;
|
||||
private final static int EVENT_TYPE_LIST = 3;
|
||||
|
||||
|
||||
private final static Pattern PATTERN_SIMPLE_TAG = Pattern.compile(
|
||||
"^(\\d+)\\s+([A-Za-z0-9_]+)\\s*$"); //$NON-NLS-1$
|
||||
private final static Pattern PATTERN_TAG_WITH_DESC = Pattern.compile(
|
||||
@@ -67,9 +67,9 @@ public final class EventLogParser {
|
||||
"(\\d\\d)-(\\d\\d)\\s(\\d\\d):(\\d\\d):(\\d\\d).(\\d{3})\\s+I/([a-zA-Z0-9_]+)\\s*\\(\\s*(\\d+)\\):\\s+(.*)"); //$NON-NLS-1$
|
||||
|
||||
private final TreeMap<Integer, String> mTagMap = new TreeMap<Integer, String>();
|
||||
|
||||
|
||||
private final TreeMap<Integer, EventValueDescription[]> mValueDescriptionMap =
|
||||
new TreeMap<Integer, EventValueDescription[]>();
|
||||
new TreeMap<Integer, EventValueDescription[]>();
|
||||
|
||||
public EventLogParser() {
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public final class EventLogParser {
|
||||
* @param device The device.
|
||||
* @return <code>true</code> if success, <code>false</code> if failure or cancellation.
|
||||
*/
|
||||
public boolean init(Device device) {
|
||||
public boolean init(IDevice device) {
|
||||
// read the event tag map file on the device.
|
||||
try {
|
||||
device.executeShellCommand("cat " + EVENT_TAG_MAP_FILE, //$NON-NLS-1$
|
||||
@@ -103,7 +103,7 @@ public final class EventLogParser {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inits the parser with the content of a tag file.
|
||||
* @param tagFileContent the lines of a tag file.
|
||||
@@ -115,7 +115,7 @@ public final class EventLogParser {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inits the parser with a specified event-log-tags file.
|
||||
* @param filePath
|
||||
@@ -124,7 +124,7 @@ public final class EventLogParser {
|
||||
public boolean init(String filePath) {
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(filePath));
|
||||
|
||||
|
||||
String line = null;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
@@ -132,13 +132,13 @@ public final class EventLogParser {
|
||||
processTagLine(line);
|
||||
}
|
||||
} while (line != null);
|
||||
|
||||
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes a line from the event-log-tags file.
|
||||
* @param line the line to process
|
||||
@@ -154,7 +154,7 @@ public final class EventLogParser {
|
||||
if (name != null && mTagMap.get(value) == null) {
|
||||
mTagMap.put(value, name);
|
||||
}
|
||||
|
||||
|
||||
// special case for the GC tag. We ignore what is in the file,
|
||||
// and take what the custom GcEventContainer class tells us.
|
||||
// This is due to the event encoding several values on 2 longs.
|
||||
@@ -163,12 +163,12 @@ public final class EventLogParser {
|
||||
mValueDescriptionMap.put(value,
|
||||
GcEventContainer.getValueDescriptions());
|
||||
} else {
|
||||
|
||||
|
||||
String description = m.group(3);
|
||||
if (description != null && description.length() > 0) {
|
||||
EventValueDescription[] desc =
|
||||
processDescription(description);
|
||||
|
||||
|
||||
if (desc != null) {
|
||||
mValueDescriptionMap.put(value, desc);
|
||||
}
|
||||
@@ -189,12 +189,12 @@ public final class EventLogParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private EventValueDescription[] processDescription(String description) {
|
||||
String[] descriptions = description.split("\\s*,\\s*"); //$NON-NLS-1$
|
||||
|
||||
|
||||
ArrayList<EventValueDescription> list = new ArrayList<EventValueDescription>();
|
||||
|
||||
|
||||
for (String desc : descriptions) {
|
||||
Matcher m = PATTERN_DESCRIPTION.matcher(desc);
|
||||
if (m.matches()) {
|
||||
@@ -208,15 +208,15 @@ public final class EventLogParser {
|
||||
// just ignore this description if the value is not recognized.
|
||||
// TODO: log the error.
|
||||
}
|
||||
|
||||
|
||||
typeString = m.group(3);
|
||||
if (typeString != null && typeString.length() > 0) {
|
||||
//skip the |
|
||||
typeString = typeString.substring(1);
|
||||
|
||||
|
||||
typeValue = Integer.parseInt(typeString);
|
||||
ValueType valueType = ValueType.getValueType(typeValue);
|
||||
|
||||
|
||||
list.add(new EventValueDescription(name, eventValueType, valueType));
|
||||
} else {
|
||||
list.add(new EventValueDescription(name, eventValueType));
|
||||
@@ -233,15 +233,15 @@ public final class EventLogParser {
|
||||
String.format("Can't parse %1$s", description)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (list.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return list.toArray(new EventValueDescription[list.size()]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public EventContainer parse(LogEntry entry) {
|
||||
if (entry.len < 4) {
|
||||
return null;
|
||||
@@ -251,7 +251,7 @@ public final class EventLogParser {
|
||||
|
||||
int tagValue = ArrayHelper.swap32bitFromArray(entry.data, inOffset);
|
||||
inOffset += 4;
|
||||
|
||||
|
||||
String tag = mTagMap.get(tagValue);
|
||||
if (tag == null) {
|
||||
Log.e("EventLogParser", String.format("unknown tag number: %1$d", tagValue));
|
||||
@@ -275,10 +275,10 @@ public final class EventLogParser {
|
||||
} else {
|
||||
event = new EventContainer(entry, tagValue, data);
|
||||
}
|
||||
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
public EventContainer parse(String textLogLine) {
|
||||
// line will look like
|
||||
// 04-29 23:16:16.691 I/dvm_gc_info( 427): <data>
|
||||
@@ -289,7 +289,7 @@ public final class EventLogParser {
|
||||
if (textLogLine.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// parse the header first
|
||||
Matcher m = TEXT_LOG_LINE.matcher(textLogLine);
|
||||
if (m.matches()) {
|
||||
@@ -300,7 +300,7 @@ public final class EventLogParser {
|
||||
int minutes = Integer.parseInt(m.group(4));
|
||||
int seconds = Integer.parseInt(m.group(5));
|
||||
int milliseconds = Integer.parseInt(m.group(6));
|
||||
|
||||
|
||||
// convert into seconds since epoch and nano-seconds.
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(cal.get(Calendar.YEAR), month-1, day, hours, minutes, seconds);
|
||||
@@ -308,7 +308,7 @@ public final class EventLogParser {
|
||||
int nsec = milliseconds * 1000000;
|
||||
|
||||
String tag = m.group(7);
|
||||
|
||||
|
||||
// get the numerical tag value
|
||||
int tagValue = -1;
|
||||
Set<Entry<Integer, String>> tagSet = mTagMap.entrySet();
|
||||
@@ -318,18 +318,18 @@ public final class EventLogParser {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tagValue == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
int pid = Integer.parseInt(m.group(8));
|
||||
|
||||
|
||||
Object data = parseTextData(m.group(9), tagValue);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// now we can allocate and return the EventContainer
|
||||
EventContainer event = null;
|
||||
if (tagValue == GcEventContainer.GC_EVENT_TAG) {
|
||||
@@ -337,20 +337,20 @@ public final class EventLogParser {
|
||||
} else {
|
||||
event = new EventContainer(tagValue, pid, -1 /* tid */, sec, nsec, data);
|
||||
}
|
||||
|
||||
|
||||
return event;
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Map<Integer, String> getTagMap() {
|
||||
return mTagMap;
|
||||
}
|
||||
|
||||
|
||||
public Map<Integer, EventValueDescription[]> getEventInfoMap() {
|
||||
return mValueDescriptionMap;
|
||||
}
|
||||
@@ -370,7 +370,7 @@ public final class EventLogParser {
|
||||
|
||||
if (eventData.length - dataOffset < 1)
|
||||
return -1;
|
||||
|
||||
|
||||
int offset = dataOffset;
|
||||
|
||||
int type = eventData[offset++];
|
||||
@@ -385,7 +385,7 @@ public final class EventLogParser {
|
||||
return -1;
|
||||
ival = ArrayHelper.swap32bitFromArray(eventData, offset);
|
||||
offset += 4;
|
||||
|
||||
|
||||
list.add(new Integer(ival));
|
||||
}
|
||||
break;
|
||||
@@ -396,7 +396,7 @@ public final class EventLogParser {
|
||||
return -1;
|
||||
lval = ArrayHelper.swap64bitFromArray(eventData, offset);
|
||||
offset += 8;
|
||||
|
||||
|
||||
list.add(new Long(lval));
|
||||
}
|
||||
break;
|
||||
@@ -410,7 +410,7 @@ public final class EventLogParser {
|
||||
|
||||
if (eventData.length - offset < strLen)
|
||||
return -1;
|
||||
|
||||
|
||||
// get the string
|
||||
try {
|
||||
String str = new String(eventData, offset, strLen, "UTF-8"); //$NON-NLS-1$
|
||||
@@ -434,7 +434,7 @@ public final class EventLogParser {
|
||||
if (result == -1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
offset += result;
|
||||
}
|
||||
|
||||
@@ -446,59 +446,59 @@ public final class EventLogParser {
|
||||
String.format("Unknown binary event type %1$d", type)); //$NON-NLS-1$
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return offset - dataOffset;
|
||||
}
|
||||
|
||||
|
||||
private Object parseTextData(String data, int tagValue) {
|
||||
// first, get the description of what we're supposed to parse
|
||||
EventValueDescription[] desc = mValueDescriptionMap.get(tagValue);
|
||||
|
||||
|
||||
if (desc == null) {
|
||||
// TODO parse and create string values.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (desc.length == 1) {
|
||||
return getObjectFromString(data, desc[0].getEventValueType());
|
||||
} else if (data.startsWith("[") && data.endsWith("]")) {
|
||||
data = data.substring(1, data.length() - 1);
|
||||
|
||||
|
||||
// get each individual values as String
|
||||
String[] values = data.split(",");
|
||||
|
||||
|
||||
if (tagValue == GcEventContainer.GC_EVENT_TAG) {
|
||||
// special case for the GC event!
|
||||
Object[] objects = new Object[2];
|
||||
|
||||
|
||||
objects[0] = getObjectFromString(values[0], EventValueType.LONG);
|
||||
objects[1] = getObjectFromString(values[1], EventValueType.LONG);
|
||||
|
||||
|
||||
return objects;
|
||||
} else {
|
||||
// must be the same number as the number of descriptors.
|
||||
if (values.length != desc.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Object[] objects = new Object[values.length];
|
||||
|
||||
|
||||
for (int i = 0 ; i < desc.length ; i++) {
|
||||
Object obj = getObjectFromString(values[i], desc[i].getEventValueType());
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
objects[i] = obj;
|
||||
objects[i] = obj;
|
||||
}
|
||||
|
||||
|
||||
return objects;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Object getObjectFromString(String value, EventValueType type) {
|
||||
try {
|
||||
switch (type) {
|
||||
@@ -512,14 +512,14 @@ public final class EventLogParser {
|
||||
} catch (NumberFormatException e) {
|
||||
// do nothing, we'll return null.
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreates the event-log-tags at the specified file path.
|
||||
* Recreates the event-log-tags at the specified file path.
|
||||
* @param filePath the file path to write the file.
|
||||
* @throws IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void saveTags(String filePath) throws IOException {
|
||||
File destFile = new File(filePath);
|
||||
@@ -527,16 +527,16 @@ public final class EventLogParser {
|
||||
FileOutputStream fos = null;
|
||||
|
||||
try {
|
||||
|
||||
|
||||
fos = new FileOutputStream(destFile);
|
||||
|
||||
|
||||
for (Integer key : mTagMap.keySet()) {
|
||||
// get the tag name
|
||||
String tagName = mTagMap.get(key);
|
||||
|
||||
|
||||
// get the value descriptions
|
||||
EventValueDescription[] descriptors = mValueDescriptionMap.get(key);
|
||||
|
||||
|
||||
String line = null;
|
||||
if (descriptors != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@@ -557,12 +557,12 @@ public final class EventLogParser {
|
||||
sb.append("|)"); //$NON-NLS-1$
|
||||
}
|
||||
sb.append("\n"); //$NON-NLS-1$
|
||||
|
||||
|
||||
line = sb.toString();
|
||||
} else {
|
||||
line = String.format("%1$d %2$s\n", key, tagName); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
|
||||
byte[] buffer = line.getBytes();
|
||||
fos.write(buffer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user