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