diff options
| author | Andy McFadden <> | 2009-03-24 18:15:57 -0700 | 
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-24 18:15:57 -0700 | 
| commit | 07970839eb39a1a18013c8bd15052b761736208e (patch) | |
| tree | fda1c6a0138cb5fdd3df169f162c591a235c0894 /core/java/android/ddm | |
| parent | d4c5f8919b0522bcaab41a5863c313fec52d3a79 (diff) | |
| download | frameworks_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.java | 44 | ||||
| -rw-r--r-- | core/java/android/ddm/DdmHandleHello.java | 51 | ||||
| -rw-r--r-- | core/java/android/ddm/DdmHandleProfiling.java | 137 | ||||
| -rw-r--r-- | core/java/android/ddm/DdmRegister.java | 1 | 
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(); | 
