Home | History | Annotate | Download | only in ddm
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.ddm;
     18 
     19 import org.apache.harmony.dalvik.ddmc.Chunk;
     20 import org.apache.harmony.dalvik.ddmc.ChunkHandler;
     21 import org.apache.harmony.dalvik.ddmc.DdmServer;
     22 import android.os.Debug;
     23 import android.util.Log;
     24 import java.nio.ByteBuffer;
     25 
     26 /**
     27  * Handle profiling requests.
     28  */
     29 public class DdmHandleProfiling extends ChunkHandler {
     30 
     31     public static final int CHUNK_MPRS = type("MPRS");
     32     public static final int CHUNK_MPRE = type("MPRE");
     33     public static final int CHUNK_MPSS = type("MPSS");
     34     public static final int CHUNK_MPSE = type("MPSE");
     35     public static final int CHUNK_MPRQ = type("MPRQ");
     36     public static final int CHUNK_SPSS = type("SPSS");
     37     public static final int CHUNK_SPSE = type("SPSE");
     38 
     39     private static final boolean DEBUG = false;
     40     private static DdmHandleProfiling mInstance = new DdmHandleProfiling();
     41 
     42 
     43     /* singleton, do not instantiate */
     44     private DdmHandleProfiling() {}
     45 
     46     /**
     47      * Register for the messages we're interested in.
     48      */
     49     public static void register() {
     50         DdmServer.registerHandler(CHUNK_MPRS, mInstance);
     51         DdmServer.registerHandler(CHUNK_MPRE, mInstance);
     52         DdmServer.registerHandler(CHUNK_MPSS, mInstance);
     53         DdmServer.registerHandler(CHUNK_MPSE, mInstance);
     54         DdmServer.registerHandler(CHUNK_MPRQ, mInstance);
     55         DdmServer.registerHandler(CHUNK_SPSS, mInstance);
     56         DdmServer.registerHandler(CHUNK_SPSE, mInstance);
     57     }
     58 
     59     /**
     60      * Called when the DDM server connects.  The handler is allowed to
     61      * send messages to the server.
     62      */
     63     public void connected() {}
     64 
     65     /**
     66      * Called when the DDM server disconnects.  Can be used to disable
     67      * periodic transmissions or clean up saved state.
     68      */
     69     public void disconnected() {}
     70 
     71     /**
     72      * Handle a chunk of data.
     73      */
     74     public Chunk handleChunk(Chunk request) {
     75         if (DEBUG)
     76             Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
     77         int type = request.type;
     78 
     79         if (type == CHUNK_MPRS) {
     80             return handleMPRS(request);
     81         } else if (type == CHUNK_MPRE) {
     82             return handleMPRE(request);
     83         } else if (type == CHUNK_MPSS) {
     84             return handleMPSS(request);
     85         } else if (type == CHUNK_MPSE) {
     86             return handleMPSEOrSPSE(request, "Method");
     87         } else if (type == CHUNK_MPRQ) {
     88             return handleMPRQ(request);
     89         } else if (type == CHUNK_SPSS) {
     90             return handleSPSS(request);
     91         } else if (type == CHUNK_SPSE) {
     92             return handleMPSEOrSPSE(request, "Sample");
     93         } else {
     94             throw new RuntimeException("Unknown packet "
     95                 + ChunkHandler.name(type));
     96         }
     97     }
     98 
     99     /*
    100      * Handle a "Method PRofiling Start" request.
    101      */
    102     private Chunk handleMPRS(Chunk request) {
    103         ByteBuffer in = wrapChunk(request);
    104 
    105         int bufferSize = in.getInt();
    106         int flags = in.getInt();
    107         int len = in.getInt();
    108         String fileName = getString(in, len);
    109         if (DEBUG)
    110             Log.v("ddm-heap", "Method profiling start: filename='" + fileName
    111                 + "', size=" + bufferSize + ", flags=" + flags);
    112 
    113         try {
    114             Debug.startMethodTracing(fileName, bufferSize, flags);
    115             return null;        // empty response
    116         } catch (RuntimeException re) {
    117             return createFailChunk(1, re.getMessage());
    118         }
    119     }
    120 
    121     /*
    122      * Handle a "Method PRofiling End" request.
    123      */
    124     private Chunk handleMPRE(Chunk request) {
    125         byte result;
    126 
    127         try {
    128             Debug.stopMethodTracing();
    129             result = 0;
    130         } catch (RuntimeException re) {
    131             Log.w("ddm-heap", "Method profiling end failed: "
    132                 + re.getMessage());
    133             result = 1;
    134         }
    135 
    136         /* create a non-empty reply so the handler fires on completion */
    137         byte[] reply = { result };
    138         return new Chunk(CHUNK_MPRE, reply, 0, reply.length);
    139     }
    140 
    141     /*
    142      * Handle a "Method Profiling w/Streaming Start" request.
    143      */
    144     private Chunk handleMPSS(Chunk request) {
    145         ByteBuffer in = wrapChunk(request);
    146 
    147         int bufferSize = in.getInt();
    148         int flags = in.getInt();
    149         if (DEBUG) {
    150             Log.v("ddm-heap", "Method prof stream start: size=" + bufferSize
    151                 + ", flags=" + flags);
    152         }
    153 
    154         try {
    155             Debug.startMethodTracingDdms(bufferSize, flags, false, 0);
    156             return null;        // empty response
    157         } catch (RuntimeException re) {
    158             return createFailChunk(1, re.getMessage());
    159         }
    160     }
    161 
    162     /*
    163      * Handle a "Method Profiling w/Streaming End" request or a
    164      * "Sample Profiling w/Streaming End" request.
    165      */
    166     private Chunk handleMPSEOrSPSE(Chunk request, String type) {
    167         if (DEBUG) {
    168             Log.v("ddm-heap", type + " prof stream end");
    169         }
    170 
    171         try {
    172             Debug.stopMethodTracing();
    173         } catch (RuntimeException re) {
    174             Log.w("ddm-heap", type + " prof stream end failed: "
    175                 + re.getMessage());
    176             return createFailChunk(1, re.getMessage());
    177         }
    178 
    179         /* VM sent the (perhaps very large) response directly */
    180         return null;
    181     }
    182 
    183     /*
    184      * Handle a "Method PRofiling Query" request.
    185      */
    186     private Chunk handleMPRQ(Chunk request) {
    187         int result = Debug.getMethodTracingMode();
    188 
    189         /* create a non-empty reply so the handler fires on completion */
    190         byte[] reply = { (byte) result };
    191         return new Chunk(CHUNK_MPRQ, reply, 0, reply.length);
    192     }
    193 
    194     /*
    195      * Handle a "Sample Profiling w/Streaming Start" request.
    196      */
    197     private Chunk handleSPSS(Chunk request) {
    198         ByteBuffer in = wrapChunk(request);
    199 
    200         int bufferSize = in.getInt();
    201         int flags = in.getInt();
    202         int interval = in.getInt();
    203         if (DEBUG) {
    204             Log.v("ddm-heap", "Sample prof stream start: size=" + bufferSize
    205                 + ", flags=" + flags + ", interval=" + interval);
    206         }
    207 
    208         try {
    209             Debug.startMethodTracingDdms(bufferSize, flags, true, interval);
    210             return null;        // empty response
    211         } catch (RuntimeException re) {
    212             return createFailChunk(1, re.getMessage());
    213         }
    214     }
    215 }
    216 
    217