diff options
author | Xavier Ducrohet <xav@android.com> | 2009-08-31 18:02:44 -0700 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2009-08-31 18:06:49 -0700 |
commit | a62ab1bf42fa310a4be441f07235d574b62af567 (patch) | |
tree | 50d3b9ba692fa9a59bea52d9c60021c7b3e086bc | |
parent | b50425a25f4be7d25a43e0d49ba507f31e47a8cb (diff) | |
download | sdk-a62ab1bf42fa310a4be441f07235d574b62af567.zip sdk-a62ab1bf42fa310a4be441f07235d574b62af567.tar.gz sdk-a62ab1bf42fa310a4be441f07235d574b62af567.tar.bz2 |
DDMS now queries the VM for its features.
This is a first step to support method profiling on/off and hprof dump from
DDMS.
Change-Id: Id95767b458a8405a31bcbe295bb969597f0e6e03
4 files changed, 72 insertions, 21 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java index 64fbef6..c8e5498 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java @@ -604,7 +604,7 @@ public class Client { "Good handshake from client, sending HELO to " + mClientData.getPid()); JdwpPacket.consumeHandshake(mReadBuffer); mConnState = ST_NEED_DDM_PKT; - HandleHello.sendHELO(this, SERVER_PROTOCOL_VERSION); + HandleHello.sendHelloCommands(this, SERVER_PROTOCOL_VERSION); // see if we have another packet in the buffer return getJdwpPacket(); case JdwpPacket.HANDSHAKE_BAD: diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java b/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java index 2b46b6f..d396d15 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -46,7 +47,7 @@ public class ClientData { * access should be synchronized against the ClientData object. */ - + /** Temporary name of VM to be ignored. */ private final static String PRE_INITIALIZED = "<pre-initialized>"; //$NON-NLS-1$ @@ -62,7 +63,7 @@ public class ClientData { /** Debugger connection status: The listening port for debugger connection failed to listen. * No debugger will be able to connect. */ public static final int DEBUGGER_ERROR = 4; - + /** * Allocation tracking status: unknown. * <p/>This happens right after a {@link Client} is discovered @@ -99,6 +100,18 @@ public class ClientData { */ public final static String HEAP_OBJECTS_ALLOCATED = "objectsAllocated"; // $NON-NLS-1$ + /** + * String for feature enabling starting/stopping method profiling + * @see #hasFeature(String) + */ + public final static String FEATURE_PROFILING = "method-trace-profiling"; // $NON-NLS-1$ + + /** + * String for feature allowing to dump hprof files + * @see #hasFeature(String) + */ + public final static String FEATURE_HPROF = "hprof-heap-dump"; // $NON-NLS-1$ + // is this a DDM-aware client? private boolean mIsDdmAware; @@ -114,6 +127,9 @@ public class ClientData { // how interested are we in a debugger? private int mDebuggerInterest; + // List of supported feature by the client. + private final HashSet<String> mFeatures = new HashSet<String>(); + // Thread tracking (THCR, THDE). private TreeMap<Integer,ThreadInfo> mThreadMap; @@ -232,11 +248,11 @@ public class ClientData { public void setProcessedHeapMap(Map<Integer, ArrayList<HeapSegmentElement>> heapMap) { mProcessedHeapMap = heapMap; } - + public Map<Integer, ArrayList<HeapSegmentElement>> getProcessedHeapMap() { return mProcessedHeapMap; } - + } @@ -250,7 +266,7 @@ public class ClientData { mDebuggerInterest = DEBUGGER_DEFAULT; mThreadMap = new TreeMap<Integer,ThreadInfo>(); } - + /** * Returns whether the process is DDM-aware. */ @@ -290,7 +306,7 @@ public class ClientData { * Returns the client description. * <p/>This is generally the name of the package defined in the * <code>AndroidManifest.xml</code>. - * + * * @return the client description or <code>null</code> if not the description was not yet * sent by the client. */ @@ -319,7 +335,7 @@ public class ClientData { } } } - + /** * Returns the debugger connection status. Possible values are {@link #DEBUGGER_DEFAULT}, * {@link #DEBUGGER_WAITING}, {@link #DEBUGGER_ATTACHED}, and {@link #DEBUGGER_ERROR}. @@ -422,7 +438,7 @@ public class ClientData { synchronized ThreadInfo getThread(int threadId) { return mThreadMap.get(threadId); } - + synchronized void clearThreads() { mThreadMap.clear(); } @@ -474,7 +490,7 @@ public class ClientData { public synchronized Iterator<NativeLibraryMapInfo> getNativeLibraryMapInfo() { return mNativeLibMapInfo.iterator(); } - + synchronized void setAllocationStatus(boolean enabled) { mAllocationStatus = enabled ? ALLOCATION_TRACKING_ON : ALLOCATION_TRACKING_OFF; } @@ -486,11 +502,11 @@ public class ClientData { public synchronized int getAllocationStatus() { return mAllocationStatus; } - + synchronized void setAllocations(AllocationInfo[] allocs) { mAllocations = allocs; } - + /** * Returns the list of tracked allocations. * @see Client#requestAllocationDetails() @@ -498,5 +514,21 @@ public class ClientData { public synchronized AllocationInfo[] getAllocations() { return mAllocations; } + + void addFeature(String feature) { + mFeatures.add(feature); + } + + /** + * Returns true if the {@link Client} supports the given <var>feature</var> + * @param feature The feature to test. + * @return true if the feature is supported + * + * @see ClientData#FEATURE_PROFILING + * @see ClientData#FEATURE_HPROF + */ + public boolean hasFeature(String feature) { + return mFeatures.contains(feature); + } } diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java index fb9697c..4818bd0 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java @@ -29,7 +29,6 @@ final class HandleHello extends ChunkHandler { private static final HandleHello mInst = new HandleHello(); - private HandleHello() {} /** @@ -56,6 +55,18 @@ final class HandleHello extends ChunkHandler { } /** + * Sends HELLO-type commands to the VM after a good handshake. + * @param client + * @param serverProtocolVersion + * @throws IOException + */ + public static void sendHelloCommands(Client client, int serverProtocolVersion) + throws IOException { + sendHELO(client, serverProtocolVersion); + sendFEAT(client); + } + + /** * Chunk handler entry point. */ @Override @@ -87,12 +98,12 @@ final class HandleHello extends ChunkHandler { vmIdent = getString(data, vmIdentLen); appName = getString(data, appNameLen); - + Log.d("ddm-hello", "HELO: v=" + version + ", pid=" + pid + ", vm='" + vmIdent + "', app='" + appName + "'"); ClientData cd = client.getClientData(); - + synchronized (cd) { if (cd.getPid() == pid) { cd.setVmIdentifier(vmIdent); @@ -141,6 +152,7 @@ final class HandleHello extends ChunkHandler { for (i = 0; i < featureCount; i++) { int len = data.getInt(); String feature = getString(data, len); + client.getClientData().addFeature(feature); Log.d("ddm-hello", "Feature: " + feature); } @@ -160,6 +172,5 @@ final class HandleHello extends ChunkHandler { Log.d("ddm-heap", "Sending " + name(CHUNK_FEAT)); client.sendAndConsume(packet, mInst); } - } diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java index 72cbb4a..35e071d 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java @@ -39,11 +39,15 @@ public class InfoPanel extends TablePanel { "App description:", "VM version:", "Process ID:", + "Supports Profiling Control:", + "Supports HPROF Control:", }; - private static final int ENT_DDM_AWARE = 0; - private static final int ENT_APP_DESCR = 1; - private static final int ENT_VM_VERSION = 2; - private static final int ENT_PROCESS_ID = 3; + private static final int ENT_DDM_AWARE = 0; + private static final int ENT_APP_DESCR = 1; + private static final int ENT_VM_VERSION = 2; + private static final int ENT_PROCESS_ID = 3; + private static final int ENT_SUPPORTS_PROFILING = 4; + private static final int ENT_SUPPORTS_HPROF = 5; /** * Create our control(s). @@ -71,7 +75,7 @@ public class InfoPanel extends TablePanel { return mTable; } - + /** * Sets the focus to the proper control inside the panel. */ @@ -160,6 +164,10 @@ public class InfoPanel extends TablePanel { item.setText(1, isDdmAware); item = mTable.getItem(ENT_PROCESS_ID); item.setText(1, pid); + item = mTable.getItem(ENT_SUPPORTS_PROFILING); + item.setText(1, Boolean.toString(cd.hasFeature(ClientData.FEATURE_PROFILING))); + item = mTable.getItem(ENT_SUPPORTS_HPROF); + item.setText(1, Boolean.toString(cd.hasFeature(ClientData.FEATURE_HPROF))); } mCol2.pack(); |