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 3 // found in the LICENSE file. 4 5 #include "content/browser/android/tracing_controller_android.h" 6 7 #include "base/android/jni_android.h" 8 #include "base/android/jni_string.h" 9 #include "base/debug/trace_event.h" 10 #include "base/json/json_writer.h" 11 #include "base/logging.h" 12 #include "content/public/browser/tracing_controller.h" 13 #include "jni/TracingControllerAndroid_jni.h" 14 15 namespace content { 16 17 static jlong Init(JNIEnv* env, jobject obj) { 18 TracingControllerAndroid* profiler = new TracingControllerAndroid(env, obj); 19 return reinterpret_cast<intptr_t>(profiler); 20 } 21 22 TracingControllerAndroid::TracingControllerAndroid(JNIEnv* env, jobject obj) 23 : weak_java_object_(env, obj), 24 weak_factory_(this) {} 25 26 TracingControllerAndroid::~TracingControllerAndroid() {} 27 28 void TracingControllerAndroid::Destroy(JNIEnv* env, jobject obj) { 29 delete this; 30 } 31 32 bool TracingControllerAndroid::StartTracing(JNIEnv* env, 33 jobject obj, 34 jstring jcategories, 35 jboolean record_continuously) { 36 std::string categories = 37 base::android::ConvertJavaStringToUTF8(env, jcategories); 38 39 // This log is required by adb_profile_chrome.py. 40 LOG(WARNING) << "Logging performance trace to file"; 41 42 return TracingController::GetInstance()->EnableRecording( 43 categories, 44 record_continuously ? TracingController::RECORD_CONTINUOUSLY 45 : TracingController::DEFAULT_OPTIONS, 46 TracingController::EnableRecordingDoneCallback()); 47 } 48 49 void TracingControllerAndroid::StopTracing(JNIEnv* env, 50 jobject obj, 51 jstring jfilepath) { 52 base::FilePath file_path( 53 base::android::ConvertJavaStringToUTF8(env, jfilepath)); 54 if (!TracingController::GetInstance()->DisableRecording( 55 file_path, 56 base::Bind(&TracingControllerAndroid::OnTracingStopped, 57 weak_factory_.GetWeakPtr()))) { 58 LOG(ERROR) << "EndTracingAsync failed, forcing an immediate stop"; 59 OnTracingStopped(file_path); 60 } 61 } 62 63 void TracingControllerAndroid::GenerateTracingFilePath( 64 base::FilePath* file_path) { 65 JNIEnv* env = base::android::AttachCurrentThread(); 66 ScopedJavaLocalRef<jstring> jfilename = 67 Java_TracingControllerAndroid_generateTracingFilePath(env); 68 *file_path = base::FilePath( 69 base::android::ConvertJavaStringToUTF8(env, jfilename.obj())); 70 } 71 72 void TracingControllerAndroid::OnTracingStopped( 73 const base::FilePath& file_path) { 74 JNIEnv* env = base::android::AttachCurrentThread(); 75 base::android::ScopedJavaLocalRef<jobject> obj = weak_java_object_.get(env); 76 if (obj.obj()) 77 Java_TracingControllerAndroid_onTracingStopped(env, obj.obj()); 78 } 79 80 bool TracingControllerAndroid::GetKnownCategoryGroupsAsync(JNIEnv* env, 81 jobject obj) { 82 if (!TracingController::GetInstance()->GetCategories( 83 base::Bind(&TracingControllerAndroid::OnKnownCategoriesReceived, 84 weak_factory_.GetWeakPtr()))) { 85 return false; 86 } 87 return true; 88 } 89 90 void TracingControllerAndroid::OnKnownCategoriesReceived( 91 const std::set<std::string>& categories_received) { 92 scoped_ptr<base::ListValue> category_list(new base::ListValue()); 93 for (std::set<std::string>::const_iterator it = categories_received.begin(); 94 it != categories_received.end(); 95 ++it) { 96 category_list->AppendString(*it); 97 } 98 std::string received_category_list; 99 base::JSONWriter::Write(category_list.get(), &received_category_list); 100 101 // This log is required by adb_profile_chrome.py. 102 LOG(WARNING) << "{\"traceCategoriesList\": " << received_category_list << "}"; 103 } 104 105 static jstring GetDefaultCategories(JNIEnv* env, jobject obj) { 106 return base::android::ConvertUTF8ToJavaString(env, 107 base::debug::CategoryFilter::kDefaultCategoryFilterString).Release(); 108 } 109 110 bool RegisterTracingControllerAndroid(JNIEnv* env) { 111 return RegisterNativesImpl(env); 112 } 113 114 } // namespace content 115