| Index: base/android/early_trace_event.cc
|
| diff --git a/base/android/early_trace_event.cc b/base/android/early_trace_event.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d354a3aeb9b2efff0929d495f3b0ea5e798e456a
|
| --- /dev/null
|
| +++ b/base/android/early_trace_event.cc
|
| @@ -0,0 +1,123 @@
|
| +// Copyright 2015 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 "base/android/early_trace_event.h"
|
| +
|
| +#include <jni.h>
|
| +
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/android/jni_array.h"
|
| +#include "base/basictypes.h"
|
| +#include "base/time/time.h"
|
| +#include "base/trace_event/trace_event.h"
|
| +#include "jni/EarlyTraceEvent_jni.h"
|
| +
|
| +namespace base {
|
| +namespace android {
|
| +namespace {
|
| +
|
| +int64_t MillisecondsToMicroseconds(int64_t value) {
|
| + return value * 1000;
|
| +}
|
| +
|
| +// Converts events recorded on the Java side in milliseconds (since boot time)
|
| +// to microsecond-precision TimeTicks (as TraceLog expects).
|
| +TimeTicks ConvertJavaTimeSinceBoot(int64_t time_since_boot_msec,
|
| + int64_t time_offset_msec) {
|
| + return TimeTicks::FromInternalValue(
|
| + MillisecondsToMicroseconds(time_since_boot_msec - time_offset_msec));
|
| +}
|
| +
|
| +TimeTicks ConvertJavaThreadTime(int64_t time_msec) {
|
| + return TimeTicks::FromInternalValue(MillisecondsToMicroseconds(time_msec));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +bool RegisterEarlyTraceEvent(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| +EarlyTraceEvent::EarlyTraceEvent() {}
|
| +
|
| +EarlyTraceEvent::~EarlyTraceEvent() {}
|
| +
|
| +void GetAllEarlyTraceEvents(std::vector<EarlyTraceEvent>* trace_events) {
|
| + JNIEnv* const env = AttachCurrentThread();
|
| + const ScopedJavaLocalRef<jobject> early_events_reader =
|
| + Java_EarlyTraceEvent_getAll(env);
|
| +
|
| + // Convert the name string array.
|
| + std::vector<std::string> names_vector;
|
| +
|
| + const ScopedJavaLocalRef<jobjectArray> jni_event_names =
|
| + Java_EarlyTraceEventsNativeReader_readNames(
|
| + env, early_events_reader.obj());
|
| + AppendJavaStringArrayToStringVector(
|
| + env, jni_event_names.obj(), &names_vector);
|
| +
|
| + // Convert all the long arrays.
|
| + std::vector<int64_t> thread_ids_vector;
|
| + std::vector<int64_t> begin_times_since_boot_vector;
|
| + std::vector<int64_t> begin_thread_times_vector;
|
| + std::vector<int64_t> end_times_since_boot_vector;
|
| + std::vector<int64_t> end_thread_times_vector;
|
| +
|
| + static const struct {
|
| + ScopedJavaLocalRef<jlongArray> (* const jni_function)(JNIEnv*, jobject);
|
| + std::vector<int64_t>* const output_vector;
|
| + } long_array_descriptors[] = {
|
| + { Java_EarlyTraceEventsNativeReader_readThreadIds, &thread_ids_vector },
|
| + { Java_EarlyTraceEventsNativeReader_readBeginTimesSinceBootMsec,
|
| + &begin_times_since_boot_vector },
|
| + { Java_EarlyTraceEventsNativeReader_readBeginThreadTimesMsec,
|
| + &begin_thread_times_vector },
|
| + { Java_EarlyTraceEventsNativeReader_readEndTimesSinceBootMsec,
|
| + &end_times_since_boot_vector },
|
| + { Java_EarlyTraceEventsNativeReader_readEndThreadTimesMsec,
|
| + &end_thread_times_vector },
|
| + };
|
| +
|
| + for (size_t i = 0;
|
| + i < sizeof(long_array_descriptors) / sizeof(long_array_descriptors[0]);
|
| + ++i) {
|
| + const android::ScopedJavaLocalRef<jlongArray> jni_array =
|
| + long_array_descriptors[i].jni_function(env, early_events_reader.obj());
|
| + AppendJavaLongArrayToLongVector(
|
| + env, jni_array.obj(), long_array_descriptors[i].output_vector);
|
| + }
|
| +
|
| + // The Java side uses times since boot whereas TraceLog uses
|
| + // TimeTicks::NowFromSystemTraceTime(). The difference between those two time
|
| + // systems must be propagated to all the early trace events that were
|
| + // recorded.
|
| + const int64_t time_offset_msec =
|
| + Java_EarlyTraceEvent_getMsecTimeSinceBoot(env) -
|
| + TimeTicks::NowFromSystemTraceTime().ToInternalValue() / 1000;
|
| +
|
| + const size_t events_count = names_vector.size();
|
| + trace_events->reserve(events_count);
|
| +
|
| + for (size_t i = 0; i < events_count; ++i) {
|
| + trace_events->push_back(EarlyTraceEvent());
|
| + EarlyTraceEvent* const event = &trace_events->back();
|
| +
|
| + event->name.swap(names_vector[i]);
|
| + event->thread_id = thread_ids_vector[i];
|
| +
|
| + event->begin_timestamp = ConvertJavaTimeSinceBoot(
|
| + begin_times_since_boot_vector[i], time_offset_msec);
|
| + event->end_timestamp = ConvertJavaTimeSinceBoot(
|
| + end_times_since_boot_vector[i], time_offset_msec);
|
| +
|
| + event->begin_thread_time = ConvertJavaThreadTime(
|
| + begin_thread_times_vector[i]);
|
| + event->end_thread_time = ConvertJavaThreadTime(end_thread_times_vector[i]);
|
| + }
|
| +}
|
| +
|
| +} // namespace android
|
| +} // namespace base
|
|
|