Commit b89355c2 authored by Tim Volodine's avatar Tim Volodine Committed by Commit Bot

[Android WebView] Chromium side implementation of WebView Tracing API.

This patch implements the mechanism for the tracing api in the chromium
part of android webview. Contains AwTracingController.java and its native
counterpart aw_tracing_controller.{h,cc} with JNI. There is not more
than one instance of AwTracingController which is created on first
call to getTracingController() in AwBrowserContext.

Also makes sure that the TraceRecordMode enum Java counterparts are
created in org.chromium.base.

BUG=781249

Change-Id: Ie407117efb97da0894f8441e9db5d1c5b60e5a7e
Reviewed-on: https://chromium-review.googlesource.com/824605
Commit-Queue: Tim Volodine <timvolodine@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#526715}
parent f482af24
......@@ -57,6 +57,7 @@ generate_jni("native_jni") {
"java/src/org/chromium/android_webview/AwResource.java",
"java/src/org/chromium/android_webview/AwSettings.java",
"java/src/org/chromium/android_webview/AwTokenBindingManager.java",
"java/src/org/chromium/android_webview/AwTracingController.java",
"java/src/org/chromium/android_webview/AwWebContentsDelegate.java",
"java/src/org/chromium/android_webview/AwWebResourceResponse.java",
"java/src/org/chromium/android_webview/InputStreamUtil.java",
......@@ -616,6 +617,8 @@ source_set("common") {
"browser/surfaces_instance.cc",
"browser/surfaces_instance.h",
"browser/token_binding_manager_bridge.cc",
"browser/tracing/aw_tracing_controller.cc",
"browser/tracing/aw_tracing_controller.h",
"browser/tracing/aw_tracing_delegate.cc",
"browser/tracing/aw_tracing_delegate.h",
"common/android_webview_message_generator.cc",
......@@ -808,6 +811,7 @@ android_library("android_webview_java") {
"java/src/org/chromium/android_webview/AwSettings.java",
"java/src/org/chromium/android_webview/AwSwitches.java",
"java/src/org/chromium/android_webview/AwTokenBindingManager.java",
"java/src/org/chromium/android_webview/AwTracingController.java",
"java/src/org/chromium/android_webview/AwViewMethods.java",
"java/src/org/chromium/android_webview/AwViewAndroidDelegate.java",
"java/src/org/chromium/android_webview/AwWebContentsDelegate.java",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "android_webview/browser/tracing/aw_tracing_controller.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/task_scheduler/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/tracing_controller.h"
#include "jni/AwTracingController_jni.h"
using base::android::JavaParamRef;
namespace {
base::android::ScopedJavaLocalRef<jbyteArray> StringToJavaBytes(
JNIEnv* env,
const std::string& str) {
return base::android::ToJavaByteArray(
env, reinterpret_cast<const uint8_t*>(str.data()), str.size());
}
class AwTraceDataEndpoint
: public content::TracingController::TraceDataEndpoint {
public:
typedef base::Callback<void(std::unique_ptr<std::string>)>
ReceivedChunkCallback;
typedef base::Callback<void(std::unique_ptr<const base::DictionaryValue>)>
CompletedCallback;
static scoped_refptr<content::TracingController::TraceDataEndpoint> Create(
ReceivedChunkCallback received_chunk_callback,
CompletedCallback completed_callback) {
return new AwTraceDataEndpoint(received_chunk_callback, completed_callback);
}
void ReceiveTraceFinalContents(
std::unique_ptr<const base::DictionaryValue> metadata) override {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(completed_callback_, base::Passed(std::move(metadata))));
}
void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(received_chunk_callback_, base::Passed(std::move(chunk))));
}
explicit AwTraceDataEndpoint(ReceivedChunkCallback received_chunk_callback,
CompletedCallback completed_callback)
: received_chunk_callback_(received_chunk_callback),
completed_callback_(completed_callback) {}
private:
~AwTraceDataEndpoint() override {}
ReceivedChunkCallback received_chunk_callback_;
CompletedCallback completed_callback_;
DISALLOW_COPY_AND_ASSIGN(AwTraceDataEndpoint);
};
} // namespace
namespace android_webview {
static jlong JNI_AwTracingController_Init(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
AwTracingController* controller = new AwTracingController(env, obj);
return reinterpret_cast<intptr_t>(controller);
}
AwTracingController::AwTracingController(JNIEnv* env, jobject obj)
: weak_java_object_(env, obj), weak_factory_(this) {}
AwTracingController::~AwTracingController() {}
bool AwTracingController::Start(JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& jcategories,
jint jmode) {
std::string categories =
base::android::ConvertJavaStringToUTF8(env, jcategories);
base::trace_event::TraceConfig trace_config(
categories, static_cast<base::trace_event::TraceRecordMode>(jmode));
return content::TracingController::GetInstance()->StartTracing(
trace_config, content::TracingController::StartTracingDoneCallback());
}
bool AwTracingController::StopAndFlush(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
return content::TracingController::GetInstance()->StopTracing(
AwTraceDataEndpoint::Create(
base::Bind(&AwTracingController::OnTraceDataReceived,
weak_factory_.GetWeakPtr()),
base::Bind(&AwTracingController::OnTraceDataComplete,
weak_factory_.GetWeakPtr())));
}
void AwTracingController::OnTraceDataComplete(
std::unique_ptr<const base::DictionaryValue> metadata) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> obj = weak_java_object_.get(env);
if (obj.obj()) {
Java_AwTracingController_onTraceDataComplete(env, obj);
}
}
void AwTracingController::OnTraceDataReceived(
std::unique_ptr<std::string> chunk) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> obj = weak_java_object_.get(env);
if (obj.obj()) {
base::android::ScopedJavaLocalRef<jbyteArray> java_trace_data =
StringToJavaBytes(env, *chunk);
Java_AwTracingController_onTraceDataChunkReceived(env, obj,
java_trace_data);
}
}
bool AwTracingController::IsTracing(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
return content::TracingController::GetInstance()->IsTracing();
}
} // namespace android_webview
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ANDROID_WEBVIEW_BROWSER_TRACING_AW_TRACING_CONTROLLER_H_
#define ANDROID_WEBVIEW_BROWSER_TRACING_AW_TRACING_CONTROLLER_H_
#include "base/android/jni_weak_ref.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/tracing_controller.h"
namespace android_webview {
class AwTracingController {
public:
AwTracingController(JNIEnv* env, jobject obj);
bool Start(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& categories,
jint mode);
bool StopAndFlush(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
bool IsTracing(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
private:
~AwTracingController();
void OnTraceDataReceived(std::unique_ptr<std::string> chunk);
void OnTraceDataComplete(
std::unique_ptr<const base::DictionaryValue> metadata);
JavaObjectWeakGlobalRef weak_java_object_;
base::WeakPtrFactory<AwTracingController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AwTracingController);
};
} // namespace android_webview
#endif // ANDROID_WEBVIEW_BROWSER_TRACING_AW_TRACING_CONTROLLER_H_
......@@ -24,6 +24,7 @@ public class AwBrowserContext {
private AwGeolocationPermissions mGeolocationPermissions;
private AwFormDatabase mFormDatabase;
private AwServiceWorkerController mServiceWorkerController;
private AwTracingController mTracingController;
private Context mApplicationContext;
public AwBrowserContext(SharedPreferences sharedPreferences, Context applicationContext) {
......@@ -54,6 +55,13 @@ public class AwBrowserContext {
return mServiceWorkerController;
}
public AwTracingController getTracingController() {
if (mTracingController == null) {
mTracingController = new AwTracingController();
}
return mTracingController;
}
/**
* @see android.webkit.WebView#pauseTimers()
*/
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview;
import android.support.annotation.Nullable;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
/**
* Manages tracing functionality in WebView.
*/
@JNINamespace("android_webview")
public class AwTracingController {
private static final String TAG = "cr.AwTracingController";
private AwTracingOutputStream mOutputStream;
// TODO: consider caching a mIsTracing value for efficiency.
// boolean mIsTracing;
/**
* Interface for the callbacks to return tracing data.
*/
public interface AwTracingOutputStream {
public void write(byte[] chunk);
public void complete();
}
public AwTracingController() {
mNativeAwTracingController = nativeInit();
}
// Start tracing.
public boolean start(String categoryFilter, int mode) {
if (isTracing()) {
return false;
}
boolean result = nativeStart(mNativeAwTracingController, categoryFilter, mode);
return result;
}
// Stop tracing and flush tracing data.
public boolean stopAndFlush(@Nullable AwTracingOutputStream outputStream) {
if (!isTracing()) return false;
mOutputStream = outputStream;
nativeStopAndFlush(mNativeAwTracingController);
return true;
}
public boolean isTracing() {
return nativeIsTracing(mNativeAwTracingController);
}
@CalledByNative
private void onTraceDataChunkReceived(byte[] data) {
if (mOutputStream != null) {
mOutputStream.write(data);
}
}
@CalledByNative
private void onTraceDataComplete() {
if (mOutputStream != null) {
mOutputStream.complete();
}
}
private long mNativeAwTracingController;
private native long nativeInit();
private native boolean nativeStart(
long nativeAwTracingController, String categories, int traceMode);
private native boolean nativeStopAndFlush(long nativeAwTracingController);
private native boolean nativeIsTracing(long nativeAwTracingController);
}
......@@ -2860,6 +2860,7 @@ if (is_android) {
"android/library_loader/library_loader_hooks.h",
"memory/memory_pressure_listener.h",
"metrics/histogram_base.h",
"trace_event/trace_config.h",
]
}
......
......@@ -26,6 +26,8 @@ namespace trace_event {
class ConvertableToTraceFormat;
// Options determines how the trace buffer stores data.
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
enum TraceRecordMode {
// Record until the trace buffer is full.
RECORD_UNTIL_FULL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment