summaryrefslogtreecommitdiffstats
path: root/core/java/android/ddm
diff options
context:
space:
mode:
authorAndy McFadden <>2009-03-24 18:15:57 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-24 18:15:57 -0700
commit07970839eb39a1a18013c8bd15052b761736208e (patch)
treefda1c6a0138cb5fdd3df169f162c591a235c0894 /core/java/android/ddm
parentd4c5f8919b0522bcaab41a5863c313fec52d3a79 (diff)
downloadframeworks_base-07970839eb39a1a18013c8bd15052b761736208e.zip
frameworks_base-07970839eb39a1a18013c8bd15052b761736208e.tar.gz
frameworks_base-07970839eb39a1a18013c8bd15052b761736208e.tar.bz2
Automated import from //branches/donutburger/...@140700,140700
Diffstat (limited to 'core/java/android/ddm')
-rw-r--r--core/java/android/ddm/DdmHandleHeap.java44
-rw-r--r--core/java/android/ddm/DdmHandleHello.java51
-rw-r--r--core/java/android/ddm/DdmHandleProfiling.java137
-rw-r--r--core/java/android/ddm/DdmRegister.java1
4 files changed, 228 insertions, 5 deletions
diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java
index 54457c2..95fa0a2 100644
--- a/core/java/android/ddm/DdmHandleHeap.java
+++ b/core/java/android/ddm/DdmHandleHeap.java
@@ -20,17 +20,20 @@ import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
+import android.os.Debug;
import android.util.Config;
import android.util.Log;
+import java.io.IOException;
import java.nio.ByteBuffer;
/**
- * Handle thread-related traffic.
+ * Handle native and virtual heap requests.
*/
public class DdmHandleHeap extends ChunkHandler {
public static final int CHUNK_HPIF = type("HPIF");
public static final int CHUNK_HPSG = type("HPSG");
+ public static final int CHUNK_HPDU = type("HPDU");
public static final int CHUNK_NHSG = type("NHSG");
public static final int CHUNK_HPGC = type("HPGC");
public static final int CHUNK_REAE = type("REAE");
@@ -49,6 +52,7 @@ public class DdmHandleHeap extends ChunkHandler {
public static void register() {
DdmServer.registerHandler(CHUNK_HPIF, mInstance);
DdmServer.registerHandler(CHUNK_HPSG, mInstance);
+ DdmServer.registerHandler(CHUNK_HPDU, mInstance);
DdmServer.registerHandler(CHUNK_NHSG, mInstance);
DdmServer.registerHandler(CHUNK_HPGC, mInstance);
DdmServer.registerHandler(CHUNK_REAE, mInstance);
@@ -80,6 +84,8 @@ public class DdmHandleHeap extends ChunkHandler {
return handleHPIF(request);
} else if (type == CHUNK_HPSG) {
return handleHPSGNHSG(request, false);
+ } else if (type == CHUNK_HPDU) {
+ return handleHPDU(request);
} else if (type == CHUNK_NHSG) {
return handleHPSGNHSG(request, true);
} else if (type == CHUNK_HPGC) {
@@ -97,7 +103,7 @@ public class DdmHandleHeap extends ChunkHandler {
}
/*
- * Handle a "HeaP InFo request".
+ * Handle a "HeaP InFo" request.
*/
private Chunk handleHPIF(Chunk request) {
ByteBuffer in = wrapChunk(request);
@@ -137,6 +143,40 @@ public class DdmHandleHeap extends ChunkHandler {
}
/*
+ * Handle a "HeaP DUmp" request.
+ *
+ * This currently just returns a result code. We could pull up
+ * the entire contents of the file and return them, but hprof dump
+ * files can be a few megabytes.
+ */
+ private Chunk handleHPDU(Chunk request) {
+ ByteBuffer in = wrapChunk(request);
+ byte result;
+
+ /* get the filename for the output file */
+ int len = in.getInt();
+ String fileName = getString(in, len);
+ if (Config.LOGD)
+ Log.d("ddm-heap", "Heap dump: file='" + fileName + "'");
+
+ try {
+ Debug.dumpHprofData(fileName);
+ result = 0;
+ } catch (UnsupportedOperationException uoe) {
+ Log.w("ddm-heap", "hprof dumps not supported in this VM");
+ result = -1;
+ } catch (IOException ioe) {
+ result = -1;
+ } catch (RuntimeException ioe) {
+ result = -1;
+ }
+
+ /* create a non-empty reply so the handler fires on completion */
+ byte[] reply = { result };
+ return new Chunk(CHUNK_HPDU, reply, 0, reply.length);
+ }
+
+ /*
* Handle a "HeaP Garbage Collection" request.
*/
private Chunk handleHPGC(Chunk request) {
diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java
index e4d630e..c5d591f 100644
--- a/core/java/android/ddm/DdmHandleHello.java
+++ b/core/java/android/ddm/DdmHandleHello.java
@@ -26,12 +26,13 @@ import android.os.Debug;
import java.nio.ByteBuffer;
/**
- * Handle a HELO chunk.
+ * Handle "hello" messages and feature discovery.
*/
public class DdmHandleHello extends ChunkHandler {
public static final int CHUNK_HELO = type("HELO");
public static final int CHUNK_WAIT = type("WAIT");
+ public static final int CHUNK_FEAT = type("FEAT");
private static DdmHandleHello mInstance = new DdmHandleHello();
@@ -44,6 +45,7 @@ public class DdmHandleHello extends ChunkHandler {
*/
public static void register() {
DdmServer.registerHandler(CHUNK_HELO, mInstance);
+ DdmServer.registerHandler(CHUNK_FEAT, mInstance);
}
/**
@@ -73,12 +75,27 @@ public class DdmHandleHello extends ChunkHandler {
}
/**
- * Handle a chunk of data. We're only registered for "HELO".
+ * Handle a chunk of data.
*/
public Chunk handleChunk(Chunk request) {
if (Config.LOGV)
- Log.v("ddm-hello", "Handling " + name(request.type) + " chunk");
+ Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
+ int type = request.type;
+
+ if (type == CHUNK_HELO) {
+ return handleHELO(request);
+ } else if (type == CHUNK_FEAT) {
+ return handleFEAT(request);
+ } else {
+ throw new RuntimeException("Unknown packet "
+ + ChunkHandler.name(type));
+ }
+ }
+ /*
+ * Handle introductory packet.
+ */
+ private Chunk handleHELO(Chunk request) {
if (false)
return createFailChunk(123, "This is a test");
@@ -125,6 +142,34 @@ public class DdmHandleHello extends ChunkHandler {
return reply;
}
+ /*
+ * Handle request for list of supported features.
+ */
+ private Chunk handleFEAT(Chunk request) {
+ // TODO: query the VM to ensure that support for these features
+ // is actually compiled in
+ final String[] features = {
+ "hprof-heap-dump", "method-trace-profiling"
+ };
+
+ if (Config.LOGD)
+ Log.d("ddm-heap", "Got feature list request");
+
+ int size = 4 + 4 * features.length;
+ for (int i = features.length-1; i >= 0; i--)
+ size += features[i].length() * 2;
+
+ ByteBuffer out = ByteBuffer.allocate(size);
+ out.order(ChunkHandler.CHUNK_ORDER);
+ out.putInt(features.length);
+ for (int i = features.length-1; i >= 0; i--) {
+ out.putInt(features[i].length());
+ putString(out, features[i]);
+ }
+
+ return new Chunk(CHUNK_FEAT, out);
+ }
+
/**
* Send up a WAIT chunk. The only currently defined value for "reason"
* is zero, which means "waiting for a debugger".
diff --git a/core/java/android/ddm/DdmHandleProfiling.java b/core/java/android/ddm/DdmHandleProfiling.java
new file mode 100644
index 0000000..beed505
--- /dev/null
+++ b/core/java/android/ddm/DdmHandleProfiling.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2009 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 android.ddm;
+
+import org.apache.harmony.dalvik.ddmc.Chunk;
+import org.apache.harmony.dalvik.ddmc.ChunkHandler;
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+import android.os.Debug;
+import android.util.Config;
+import android.util.Log;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle profiling requests.
+ */
+public class DdmHandleProfiling extends ChunkHandler {
+
+ public static final int CHUNK_MPRS = type("MPRS");
+ public static final int CHUNK_MPRE = type("MPRE");
+ public static final int CHUNK_MPRQ = type("MPRQ");
+
+ private static DdmHandleProfiling mInstance = new DdmHandleProfiling();
+
+
+ /* singleton, do not instantiate */
+ private DdmHandleProfiling() {}
+
+ /**
+ * Register for the messages we're interested in.
+ */
+ public static void register() {
+ DdmServer.registerHandler(CHUNK_MPRS, mInstance);
+ DdmServer.registerHandler(CHUNK_MPRE, mInstance);
+ DdmServer.registerHandler(CHUNK_MPRQ, mInstance);
+ }
+
+ /**
+ * Called when the DDM server connects. The handler is allowed to
+ * send messages to the server.
+ */
+ public void connected() {}
+
+ /**
+ * Called when the DDM server disconnects. Can be used to disable
+ * periodic transmissions or clean up saved state.
+ */
+ public void disconnected() {}
+
+ /**
+ * Handle a chunk of data.
+ */
+ public Chunk handleChunk(Chunk request) {
+ if (Config.LOGV)
+ Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
+ int type = request.type;
+
+ if (type == CHUNK_MPRS) {
+ return handleMPRS(request);
+ } else if (type == CHUNK_MPRE) {
+ return handleMPRE(request);
+ } else if (type == CHUNK_MPRQ) {
+ return handleMPRQ(request);
+ } else {
+ throw new RuntimeException("Unknown packet "
+ + ChunkHandler.name(type));
+ }
+ }
+
+ /*
+ * Handle a "Method PRofiling Start" request.
+ */
+ private Chunk handleMPRS(Chunk request) {
+ ByteBuffer in = wrapChunk(request);
+
+ int bufferSize = in.getInt();
+ int flags = in.getInt();
+ int len = in.getInt();
+ String fileName = getString(in, len);
+ if (Config.LOGV)
+ Log.v("ddm-heap", "Method profiling start: filename='" + fileName
+ + "', size=" + bufferSize + ", flags=" + flags);
+
+ try {
+ Debug.startMethodTracing(fileName, bufferSize, flags);
+ return null; // empty response
+ } catch (RuntimeException re) {
+ return createFailChunk(1, re.getMessage());
+ }
+ }
+
+ /*
+ * Handle a "Method PRofiling End" request.
+ */
+ private Chunk handleMPRE(Chunk request) {
+ byte result;
+
+ try {
+ Debug.stopMethodTracing();
+ result = 0;
+ } catch (RuntimeException re) {
+ Log.w("ddm-heap", "Method profiling end failed: "
+ + re.getMessage());
+ result = 1;
+ }
+
+ /* create a non-empty reply so the handler fires on completion */
+ byte[] reply = { result };
+ return new Chunk(CHUNK_MPRE, reply, 0, reply.length);
+ }
+
+ /*
+ * Handle a "Method PRofiling Query" request.
+ */
+ private Chunk handleMPRQ(Chunk request) {
+ int result = Debug.isMethodTracingActive() ? 1 : 0;
+
+ /* create a non-empty reply so the handler fires on completion */
+ byte[] reply = { (byte) result };
+ return new Chunk(CHUNK_MPRQ, reply, 0, reply.length);
+ }
+}
+
diff --git a/core/java/android/ddm/DdmRegister.java b/core/java/android/ddm/DdmRegister.java
index b7f1ab8..debf189 100644
--- a/core/java/android/ddm/DdmRegister.java
+++ b/core/java/android/ddm/DdmRegister.java
@@ -50,6 +50,7 @@ public class DdmRegister {
DdmHandleThread.register();
DdmHandleHeap.register();
DdmHandleNativeHeap.register();
+ DdmHandleProfiling.register();
DdmHandleExit.register();
DdmServer.registrationComplete();