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.io.IOException;
     25 import java.nio.ByteBuffer;
     26 
     27 /**
     28  * Handle profiling requests.
     29  */
     30 public class DdmHandleProfiling extends ChunkHandler {
     31 
     32     public static final int CHUNK_MPRS = type("MPRS");
     33     public static final int CHUNK_MPRE = type("MPRE");
     34     public static final int CHUNK_MPSS = type("MPSS");
     35     public static final int CHUNK_MPSE = type("MPSE");
     36     public static final int CHUNK_MPRQ = type("MPRQ");
     37     public static final int CHUNK_SPSS = type("SPSS");
     38     public static final int CHUNK_SPSE = type("SPSE");
     39 
     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 (false)
     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 handleMPSE(request);
     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 handleSPSE(request);
     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 (false)
    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 (false) {
    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.
    164      */
    165     private Chunk handleMPSE(Chunk request) {
    166         byte result;
    167 
    168         if (false) {
    169             Log.v("ddm-heap", "Method prof stream end");
    170         }
    171 
    172         try {
    173             Debug.stopMethodTracing();
    174             result = 0;
    175         } catch (RuntimeException re) {
    176             Log.w("ddm-heap", "Method prof stream end failed: "
    177                 + re.getMessage());
    178             return createFailChunk(1, re.getMessage());
    179         }
    180 
    181         /* VM sent the (perhaps very large) response directly */
    182         return null;
    183     }
    184 
    185     /*
    186      * Handle a "Method PRofiling Query" request.
    187      */
    188     private Chunk handleMPRQ(Chunk request) {
    189         int result = Debug.getMethodTracingMode();
    190 
    191         /* create a non-empty reply so the handler fires on completion */
    192         byte[] reply = { (byte) result };
    193         return new Chunk(CHUNK_MPRQ, reply, 0, reply.length);
    194     }
    195 
    196     /*
    197      * Handle a "Sample Profiling w/Streaming Start" request.
    198      */
    199     private Chunk handleSPSS(Chunk request) {
    200         ByteBuffer in = wrapChunk(request);
    201 
    202         int bufferSize = in.getInt();
    203         int flags = in.getInt();
    204         int interval = in.getInt();
    205         if (false) {
    206             Log.v("ddm-heap", "Sample prof stream start: size=" + bufferSize
    207                 + ", flags=" + flags + ", interval=" + interval);
    208         }
    209 
    210         try {
    211             Debug.startMethodTracingDdms(bufferSize, flags, true, interval);
    212             return null;        // empty response
    213         } catch (RuntimeException re) {
    214             return createFailChunk(1, re.getMessage());
    215         }
    216     }
    217 
    218     /*
    219      * Handle a "Sample Profiling w/Streaming End" request.
    220      */
    221     private Chunk handleSPSE(Chunk request) {
    222         if (false) {
    223             Log.v("ddm-heap", "Sample prof stream end");
    224         }
    225 
    226         try {
    227             Debug.stopMethodTracing();
    228         } catch (RuntimeException re) {
    229             Log.w("ddm-heap", "Sample prof stream end failed: "
    230                 + re.getMessage());
    231             return createFailChunk(1, re.getMessage());
    232         }
    233 
    234         /* VM sent the (perhaps very large) response directly */
    235         return null;
    236     }
    237 }
    238 
    239