blob: 537763dae99a6742825cfcad9c689e8ee28f04b1 [file] [log] [blame]
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -07001/*
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
17package android.ddm;
18
19import org.apache.harmony.dalvik.ddmc.Chunk;
20import org.apache.harmony.dalvik.ddmc.ChunkHandler;
21import org.apache.harmony.dalvik.ddmc.DdmServer;
22import android.os.Debug;
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070023import android.util.Log;
24import java.io.IOException;
25import java.nio.ByteBuffer;
26
27/**
28 * Handle profiling requests.
29 */
30public class DdmHandleProfiling extends ChunkHandler {
31
32 public static final int CHUNK_MPRS = type("MPRS");
33 public static final int CHUNK_MPRE = type("MPRE");
Andy McFadden72a20db0c2010-01-22 12:20:41 -080034 public static final int CHUNK_MPSS = type("MPSS");
35 public static final int CHUNK_MPSE = type("MPSE");
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070036 public static final int CHUNK_MPRQ = type("MPRQ");
Jeff Haoffee6262013-08-22 15:53:12 -070037 public static final int CHUNK_SPSS = type("SPSS");
38 public static final int CHUNK_SPSE = type("SPSE");
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070039
Jeff Hao6c7bac62013-08-26 18:47:18 -070040 private static final boolean DEBUG = false;
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070041 private static DdmHandleProfiling mInstance = new DdmHandleProfiling();
42
43
44 /* singleton, do not instantiate */
45 private DdmHandleProfiling() {}
46
47 /**
48 * Register for the messages we're interested in.
49 */
50 public static void register() {
51 DdmServer.registerHandler(CHUNK_MPRS, mInstance);
52 DdmServer.registerHandler(CHUNK_MPRE, mInstance);
Andy McFadden72a20db0c2010-01-22 12:20:41 -080053 DdmServer.registerHandler(CHUNK_MPSS, mInstance);
54 DdmServer.registerHandler(CHUNK_MPSE, mInstance);
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070055 DdmServer.registerHandler(CHUNK_MPRQ, mInstance);
Jeff Haoffee6262013-08-22 15:53:12 -070056 DdmServer.registerHandler(CHUNK_SPSS, mInstance);
57 DdmServer.registerHandler(CHUNK_SPSE, mInstance);
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070058 }
59
60 /**
61 * Called when the DDM server connects. The handler is allowed to
62 * send messages to the server.
63 */
64 public void connected() {}
65
66 /**
67 * Called when the DDM server disconnects. Can be used to disable
68 * periodic transmissions or clean up saved state.
69 */
70 public void disconnected() {}
71
72 /**
73 * Handle a chunk of data.
74 */
75 public Chunk handleChunk(Chunk request) {
Jeff Hao6c7bac62013-08-26 18:47:18 -070076 if (DEBUG)
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070077 Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
78 int type = request.type;
79
80 if (type == CHUNK_MPRS) {
81 return handleMPRS(request);
82 } else if (type == CHUNK_MPRE) {
83 return handleMPRE(request);
Andy McFadden72a20db0c2010-01-22 12:20:41 -080084 } else if (type == CHUNK_MPSS) {
85 return handleMPSS(request);
86 } else if (type == CHUNK_MPSE) {
Jeff Hao6c7bac62013-08-26 18:47:18 -070087 return handleMPSEOrSPSE(request, "Method");
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070088 } else if (type == CHUNK_MPRQ) {
89 return handleMPRQ(request);
Jeff Haoffee6262013-08-22 15:53:12 -070090 } else if (type == CHUNK_SPSS) {
91 return handleSPSS(request);
92 } else if (type == CHUNK_SPSE) {
Jeff Hao6c7bac62013-08-26 18:47:18 -070093 return handleMPSEOrSPSE(request, "Sample");
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -070094 } else {
95 throw new RuntimeException("Unknown packet "
96 + ChunkHandler.name(type));
97 }
98 }
99
100 /*
101 * Handle a "Method PRofiling Start" request.
102 */
103 private Chunk handleMPRS(Chunk request) {
104 ByteBuffer in = wrapChunk(request);
105
106 int bufferSize = in.getInt();
107 int flags = in.getInt();
108 int len = in.getInt();
109 String fileName = getString(in, len);
Jeff Hao6c7bac62013-08-26 18:47:18 -0700110 if (DEBUG)
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700111 Log.v("ddm-heap", "Method profiling start: filename='" + fileName
112 + "', size=" + bufferSize + ", flags=" + flags);
113
114 try {
115 Debug.startMethodTracing(fileName, bufferSize, flags);
116 return null; // empty response
117 } catch (RuntimeException re) {
118 return createFailChunk(1, re.getMessage());
119 }
120 }
121
122 /*
123 * Handle a "Method PRofiling End" request.
124 */
125 private Chunk handleMPRE(Chunk request) {
126 byte result;
127
128 try {
129 Debug.stopMethodTracing();
130 result = 0;
131 } catch (RuntimeException re) {
132 Log.w("ddm-heap", "Method profiling end failed: "
133 + re.getMessage());
134 result = 1;
135 }
136
137 /* create a non-empty reply so the handler fires on completion */
138 byte[] reply = { result };
139 return new Chunk(CHUNK_MPRE, reply, 0, reply.length);
140 }
141
142 /*
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800143 * Handle a "Method Profiling w/Streaming Start" request.
144 */
145 private Chunk handleMPSS(Chunk request) {
146 ByteBuffer in = wrapChunk(request);
147
148 int bufferSize = in.getInt();
149 int flags = in.getInt();
Jeff Hao6c7bac62013-08-26 18:47:18 -0700150 if (DEBUG) {
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800151 Log.v("ddm-heap", "Method prof stream start: size=" + bufferSize
152 + ", flags=" + flags);
153 }
154
155 try {
Jeff Haoffee6262013-08-22 15:53:12 -0700156 Debug.startMethodTracingDdms(bufferSize, flags, false, 0);
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800157 return null; // empty response
158 } catch (RuntimeException re) {
159 return createFailChunk(1, re.getMessage());
160 }
161 }
162
163 /*
Jeff Hao6c7bac62013-08-26 18:47:18 -0700164 * Handle a "Method Profiling w/Streaming End" request or a
165 * "Sample Profiling w/Streaming End" request.
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800166 */
Jeff Hao6c7bac62013-08-26 18:47:18 -0700167 private Chunk handleMPSEOrSPSE(Chunk request, String type) {
168 if (DEBUG) {
169 Log.v("ddm-heap", type + " prof stream end");
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800170 }
171
172 try {
173 Debug.stopMethodTracing();
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800174 } catch (RuntimeException re) {
Jeff Hao6c7bac62013-08-26 18:47:18 -0700175 Log.w("ddm-heap", type + " prof stream end failed: "
Andy McFadden72a20db0c2010-01-22 12:20:41 -0800176 + re.getMessage());
177 return createFailChunk(1, re.getMessage());
178 }
179
180 /* VM sent the (perhaps very large) response directly */
181 return null;
182 }
183
184 /*
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700185 * Handle a "Method PRofiling Query" request.
186 */
187 private Chunk handleMPRQ(Chunk request) {
Jeff Haoac277052013-08-29 11:19:39 -0700188 int result = Debug.getMethodTracingMode();
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700189
190 /* create a non-empty reply so the handler fires on completion */
191 byte[] reply = { (byte) result };
192 return new Chunk(CHUNK_MPRQ, reply, 0, reply.length);
193 }
Jeff Haoffee6262013-08-22 15:53:12 -0700194
195 /*
196 * Handle a "Sample Profiling w/Streaming Start" request.
197 */
198 private Chunk handleSPSS(Chunk request) {
199 ByteBuffer in = wrapChunk(request);
200
201 int bufferSize = in.getInt();
202 int flags = in.getInt();
203 int interval = in.getInt();
Jeff Hao6c7bac62013-08-26 18:47:18 -0700204 if (DEBUG) {
Jeff Haoffee6262013-08-22 15:53:12 -0700205 Log.v("ddm-heap", "Sample prof stream start: size=" + bufferSize
206 + ", flags=" + flags + ", interval=" + interval);
207 }
208
209 try {
210 Debug.startMethodTracingDdms(bufferSize, flags, true, interval);
211 return null; // empty response
212 } catch (RuntimeException re) {
213 return createFailChunk(1, re.getMessage());
214 }
215 }
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -0700216}
217