• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
DdmHandleProfiling()44     private DdmHandleProfiling() {}
45 
46     /**
47      * Register for the messages we're interested in.
48      */
register()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      */
connected()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      */
disconnected()69     public void disconnected() {}
70 
71     /**
72      * Handle a chunk of data.
73      */
handleChunk(Chunk request)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      */
handleMPRS(Chunk request)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      */
handleMPRE(Chunk request)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      */
handleMPSS(Chunk request)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      */
handleMPSE(Chunk request)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      */
handleMPRQ(Chunk request)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      */
handleSPSS(Chunk request)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      */
handleSPSE(Chunk request)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