| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.content.BroadcastReceiver; | 7 import android.content.BroadcastReceiver; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.Intent; | 9 import android.content.Intent; |
| 10 import android.content.IntentFilter; | 10 import android.content.IntentFilter; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 * Note that the name of these intents change depending on which application | 39 * Note that the name of these intents change depending on which application |
| 40 * is being traced, but the general form is [app package name].GPU_PROFILER_{STA
RT,STOP}. | 40 * is being traced, but the general form is [app package name].GPU_PROFILER_{STA
RT,STOP}. |
| 41 */ | 41 */ |
| 42 @JNINamespace("content") | 42 @JNINamespace("content") |
| 43 public class TracingControllerAndroid { | 43 public class TracingControllerAndroid { |
| 44 | 44 |
| 45 private static final String TAG = "TracingControllerAndroid"; | 45 private static final String TAG = "TracingControllerAndroid"; |
| 46 | 46 |
| 47 private static final String ACTION_START = "GPU_PROFILER_START"; | 47 private static final String ACTION_START = "GPU_PROFILER_START"; |
| 48 private static final String ACTION_STOP = "GPU_PROFILER_STOP"; | 48 private static final String ACTION_STOP = "GPU_PROFILER_STOP"; |
| 49 private static final String ACTION_GET_CATEGORY = "GPU_PROFILER_LIST_CATEGOR
Y"; |
| 49 private static final String FILE_EXTRA = "file"; | 50 private static final String FILE_EXTRA = "file"; |
| 50 private static final String CATEGORIES_EXTRA = "categories"; | 51 private static final String CATEGORIES_EXTRA = "categories"; |
| 51 private static final String RECORD_CONTINUOUSLY_EXTRA = "continuous"; | 52 private static final String RECORD_CONTINUOUSLY_EXTRA = "continuous"; |
| 52 private static final String DEFAULT_CHROME_CATEGORIES_PLACE_HOLDER = | 53 private static final String DEFAULT_CHROME_CATEGORIES_PLACE_HOLDER = |
| 53 "_DEFAULT_CHROME_CATEGORIES"; | 54 "_DEFAULT_CHROME_CATEGORIES"; |
| 54 | 55 |
| 55 private final Context mContext; | 56 private final Context mContext; |
| 56 private final TracingBroadcastReceiver mBroadcastReceiver; | 57 private final TracingBroadcastReceiver mBroadcastReceiver; |
| 57 private final TracingIntentFilter mIntentFilter; | 58 private final TracingIntentFilter mIntentFilter; |
| 58 private boolean mIsTracing; | 59 private boolean mIsTracing; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 mShowToasts = showToasts; | 146 mShowToasts = showToasts; |
| 146 | 147 |
| 147 String filePath = generateTracingFilePath(); | 148 String filePath = generateTracingFilePath(); |
| 148 if (filePath == null) { | 149 if (filePath == null) { |
| 149 logAndToastError( | 150 logAndToastError( |
| 150 mContext.getString(R.string.profiler_no_storage_toast)); | 151 mContext.getString(R.string.profiler_no_storage_toast)); |
| 151 } | 152 } |
| 152 return startTracing(filePath, showToasts, categories, recordContinuously
); | 153 return startTracing(filePath, showToasts, categories, recordContinuously
); |
| 153 } | 154 } |
| 154 | 155 |
| 156 private void initializeNativeControllerIfNeeded() { |
| 157 if (mNativeTracingControllerAndroid == 0) { |
| 158 mNativeTracingControllerAndroid = nativeInit(); |
| 159 } |
| 160 } |
| 161 |
| 155 /** | 162 /** |
| 156 * Start profiling to the specified file. Returns true on success. | 163 * Start profiling to the specified file. Returns true on success. |
| 157 * | 164 * |
| 158 * Only one TracingControllerAndroid can be running at the same time. If ano
ther profiler | 165 * Only one TracingControllerAndroid can be running at the same time. If ano
ther profiler |
| 159 * is running when this method is called, it will be cancelled. If this | 166 * is running when this method is called, it will be cancelled. If this |
| 160 * profiler is already running, this method does nothing and returns false. | 167 * profiler is already running, this method does nothing and returns false. |
| 161 * | 168 * |
| 162 * @param filename The name of the file to output the profile data to. | 169 * @param filename The name of the file to output the profile data to. |
| 163 * @param showToasts Whether or not we want to show toasts during this profi
ling session. | 170 * @param showToasts Whether or not we want to show toasts during this profi
ling session. |
| 164 * When we are timing the profile run we might not want to incur extra draw
overhead of showing | 171 * When we are timing the profile run we might not want to incur extra draw
overhead of showing |
| 165 * notifications about the profiling system. | 172 * notifications about the profiling system. |
| 166 * @param categories Which categories to trace. See TracingControllerAndroid
::BeginTracing() | 173 * @param categories Which categories to trace. See TracingControllerAndroid
::BeginTracing() |
| 167 * (in content/public/browser/trace_controller.h) for the format. | 174 * (in content/public/browser/trace_controller.h) for the format. |
| 168 * @param recordContinuously Record until the user ends the trace. The trace
buffer is fixed | 175 * @param recordContinuously Record until the user ends the trace. The trace
buffer is fixed |
| 169 * size and we use it as a ring buffer during recording. | 176 * size and we use it as a ring buffer during recording. |
| 170 */ | 177 */ |
| 171 public boolean startTracing(String filename, boolean showToasts, String cate
gories, | 178 public boolean startTracing(String filename, boolean showToasts, String cate
gories, |
| 172 boolean recordContinuously) { | 179 boolean recordContinuously) { |
| 173 mShowToasts = showToasts; | 180 mShowToasts = showToasts; |
| 174 if (isTracing()) { | 181 if (isTracing()) { |
| 175 // Don't need a toast because this shouldn't happen via the UI. | 182 // Don't need a toast because this shouldn't happen via the UI. |
| 176 Log.e(TAG, "Received startTracing, but we're already tracing"); | 183 Log.e(TAG, "Received startTracing, but we're already tracing"); |
| 177 return false; | 184 return false; |
| 178 } | 185 } |
| 179 // Lazy initialize the native side, to allow construction before the lib
rary is loaded. | 186 // Lazy initialize the native side, to allow construction before the lib
rary is loaded. |
| 180 if (mNativeTracingControllerAndroid == 0) { | 187 initializeNativeControllerIfNeeded(); |
| 181 mNativeTracingControllerAndroid = nativeInit(); | |
| 182 } | |
| 183 if (!nativeStartTracing(mNativeTracingControllerAndroid, categories, | 188 if (!nativeStartTracing(mNativeTracingControllerAndroid, categories, |
| 184 recordContinuously)) { | 189 recordContinuously)) { |
| 185 logAndToastError(mContext.getString(R.string.profiler_error_toast)); | 190 logAndToastError(mContext.getString(R.string.profiler_error_toast)); |
| 186 return false; | 191 return false; |
| 187 } | 192 } |
| 188 | 193 |
| 189 logAndToastInfo(mContext.getString(R.string.profiler_started_toast) + ":
" + categories); | 194 logAndToastInfo(mContext.getString(R.string.profiler_started_toast) + ":
" + categories); |
| 190 mFilename = filename; | 195 mFilename = filename; |
| 191 mIsTracing = true; | 196 mIsTracing = true; |
| 192 return true; | 197 return true; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 211 Log.e(TAG, "Received onTracingStopped, but we aren't tracing"); | 216 Log.e(TAG, "Received onTracingStopped, but we aren't tracing"); |
| 212 return; | 217 return; |
| 213 } | 218 } |
| 214 | 219 |
| 215 logAndToastInfo( | 220 logAndToastInfo( |
| 216 mContext.getString(R.string.profiler_stopped_toast, mFilename)); | 221 mContext.getString(R.string.profiler_stopped_toast, mFilename)); |
| 217 mIsTracing = false; | 222 mIsTracing = false; |
| 218 mFilename = null; | 223 mFilename = null; |
| 219 } | 224 } |
| 220 | 225 |
| 226 /** |
| 227 * Get known category groups. |
| 228 */ |
| 229 public void getCategoryGroups() { |
| 230 // Lazy initialize the native side, to allow construction before the lib
rary is loaded. |
| 231 initializeNativeControllerIfNeeded(); |
| 232 if (!nativeGetKnownCategoryGroupsAsync(mNativeTracingControllerAndroid))
{ |
| 233 onCategoryGroupsReceived(null); |
| 234 return; |
| 235 } |
| 236 } |
| 237 |
| 238 /** |
| 239 * Called by native code when we receive the result of ping for known catego
ry groups. |
| 240 */ |
| 241 @CalledByNative |
| 242 protected void onCategoryGroupsReceived(String categoryList) { |
| 243 if (categoryList != null) |
| 244 Log.i(TAG, "{\"traceCategoriesList\": " + categoryList + "}"); |
| 245 else |
| 246 Log.i(TAG, "Failed to fetch tracing category list."); |
| 247 } |
| 248 |
| 221 @Override | 249 @Override |
| 222 protected void finalize() { | 250 protected void finalize() { |
| 223 if (mNativeTracingControllerAndroid != 0) { | 251 if (mNativeTracingControllerAndroid != 0) { |
| 224 nativeDestroy(mNativeTracingControllerAndroid); | 252 nativeDestroy(mNativeTracingControllerAndroid); |
| 225 mNativeTracingControllerAndroid = 0; | 253 mNativeTracingControllerAndroid = 0; |
| 226 } | 254 } |
| 227 } | 255 } |
| 228 | 256 |
| 229 void logAndToastError(String str) { | 257 void logAndToastError(String str) { |
| 230 Log.e(TAG, str); | 258 Log.e(TAG, str); |
| 231 if (mShowToasts) Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show(
); | 259 if (mShowToasts) Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show(
); |
| 232 } | 260 } |
| 233 | 261 |
| 234 void logAndToastInfo(String str) { | 262 void logAndToastInfo(String str) { |
| 235 Log.i(TAG, str); | 263 Log.i(TAG, str); |
| 236 if (mShowToasts) Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show(
); | 264 if (mShowToasts) Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show(
); |
| 237 } | 265 } |
| 238 | 266 |
| 239 private static class TracingIntentFilter extends IntentFilter { | 267 private static class TracingIntentFilter extends IntentFilter { |
| 240 TracingIntentFilter(Context context) { | 268 TracingIntentFilter(Context context) { |
| 241 addAction(context.getPackageName() + "." + ACTION_START); | 269 addAction(context.getPackageName() + "." + ACTION_START); |
| 242 addAction(context.getPackageName() + "." + ACTION_STOP); | 270 addAction(context.getPackageName() + "." + ACTION_STOP); |
| 271 addAction(context.getPackageName() + "." + ACTION_GET_CATEGORY); |
| 243 } | 272 } |
| 244 } | 273 } |
| 245 | 274 |
| 246 class TracingBroadcastReceiver extends BroadcastReceiver { | 275 class TracingBroadcastReceiver extends BroadcastReceiver { |
| 247 @Override | 276 @Override |
| 248 public void onReceive(Context context, Intent intent) { | 277 public void onReceive(Context context, Intent intent) { |
| 249 if (intent.getAction().endsWith(ACTION_START)) { | 278 if (intent.getAction().endsWith(ACTION_START)) { |
| 250 String categories = intent.getStringExtra(CATEGORIES_EXTRA); | 279 String categories = intent.getStringExtra(CATEGORIES_EXTRA); |
| 251 if (TextUtils.isEmpty(categories)) { | 280 if (TextUtils.isEmpty(categories)) { |
| 252 categories = nativeGetDefaultCategories(); | 281 categories = nativeGetDefaultCategories(); |
| 253 } else { | 282 } else { |
| 254 categories = categories.replaceFirst( | 283 categories = categories.replaceFirst( |
| 255 DEFAULT_CHROME_CATEGORIES_PLACE_HOLDER, nativeGetDef
aultCategories()); | 284 DEFAULT_CHROME_CATEGORIES_PLACE_HOLDER, nativeGetDef
aultCategories()); |
| 256 } | 285 } |
| 257 boolean recordContinuously = | 286 boolean recordContinuously = |
| 258 intent.getStringExtra(RECORD_CONTINUOUSLY_EXTRA) != null
; | 287 intent.getStringExtra(RECORD_CONTINUOUSLY_EXTRA) != null
; |
| 259 String filename = intent.getStringExtra(FILE_EXTRA); | 288 String filename = intent.getStringExtra(FILE_EXTRA); |
| 260 if (filename != null) { | 289 if (filename != null) { |
| 261 startTracing(filename, true, categories, recordContinuously)
; | 290 startTracing(filename, true, categories, recordContinuously)
; |
| 262 } else { | 291 } else { |
| 263 startTracing(true, categories, recordContinuously); | 292 startTracing(true, categories, recordContinuously); |
| 264 } | 293 } |
| 265 } else if (intent.getAction().endsWith(ACTION_STOP)) { | 294 } else if (intent.getAction().endsWith(ACTION_STOP)) { |
| 266 stopTracing(); | 295 stopTracing(); |
| 296 } else if (intent.getAction().endsWith(ACTION_GET_CATEGORY)) { |
| 297 getCategoryGroups(); |
| 267 } else { | 298 } else { |
| 268 Log.e(TAG, "Unexpected intent: " + intent); | 299 Log.e(TAG, "Unexpected intent: " + intent); |
| 269 } | 300 } |
| 270 } | 301 } |
| 271 } | 302 } |
| 272 | 303 |
| 273 private long mNativeTracingControllerAndroid; | 304 private long mNativeTracingControllerAndroid; |
| 274 private native long nativeInit(); | 305 private native long nativeInit(); |
| 275 private native void nativeDestroy(long nativeTracingControllerAndroid); | 306 private native void nativeDestroy(long nativeTracingControllerAndroid); |
| 276 private native boolean nativeStartTracing( | 307 private native boolean nativeStartTracing( |
| 277 long nativeTracingControllerAndroid, String categories, boolean reco
rdContinuously); | 308 long nativeTracingControllerAndroid, String categories, boolean reco
rdContinuously); |
| 278 private native void nativeStopTracing(long nativeTracingControllerAndroid, S
tring filename); | 309 private native void nativeStopTracing(long nativeTracingControllerAndroid, S
tring filename); |
| 310 private native boolean nativeGetKnownCategoryGroupsAsync(long nativeTracingC
ontrollerAndroid); |
| 279 private native String nativeGetDefaultCategories(); | 311 private native String nativeGetDefaultCategories(); |
| 280 } | 312 } |
| OLD | NEW |