OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 "base/android/early_trace_event.h" |
| 6 |
| 7 #include <jni.h> |
| 8 |
| 9 #include <string> |
| 10 #include <vector> |
| 11 |
| 12 #include "base/android/jni_array.h" |
| 13 #include "base/basictypes.h" |
| 14 #include "base/time/time.h" |
| 15 #include "base/trace_event/trace_event.h" |
| 16 #include "jni/EarlyTraceEvent_jni.h" |
| 17 |
| 18 namespace base { |
| 19 namespace android { |
| 20 namespace { |
| 21 |
| 22 int64_t MillisecondsToMicroseconds(int64_t value) { |
| 23 return value * 1000; |
| 24 } |
| 25 |
| 26 // Converts events recorded on the Java side in milliseconds (since boot time) |
| 27 // to microsecond-precision TimeTicks (as TraceLog expects). |
| 28 TimeTicks ConvertJavaTimeSinceBoot(int64_t time_since_boot_msec, |
| 29 int64_t time_offset_msec) { |
| 30 return TimeTicks::FromInternalValue( |
| 31 MillisecondsToMicroseconds(time_since_boot_msec - time_offset_msec)); |
| 32 } |
| 33 |
| 34 TimeTicks ConvertJavaThreadTime(int64_t time_msec) { |
| 35 return TimeTicks::FromInternalValue(MillisecondsToMicroseconds(time_msec)); |
| 36 } |
| 37 |
| 38 } // namespace |
| 39 |
| 40 bool RegisterEarlyTraceEvent(JNIEnv* env) { |
| 41 return RegisterNativesImpl(env); |
| 42 } |
| 43 |
| 44 EarlyTraceEvent::EarlyTraceEvent() {} |
| 45 |
| 46 EarlyTraceEvent::~EarlyTraceEvent() {} |
| 47 |
| 48 void GetAllEarlyTraceEvents(std::vector<EarlyTraceEvent>* trace_events) { |
| 49 JNIEnv* const env = AttachCurrentThread(); |
| 50 const ScopedJavaLocalRef<jobject> early_events_reader = |
| 51 Java_EarlyTraceEvent_getAll(env); |
| 52 |
| 53 // Convert the name string array. |
| 54 std::vector<std::string> names_vector; |
| 55 |
| 56 const ScopedJavaLocalRef<jobjectArray> jni_event_names = |
| 57 Java_EarlyTraceEventsNativeReader_readNames( |
| 58 env, early_events_reader.obj()); |
| 59 AppendJavaStringArrayToStringVector( |
| 60 env, jni_event_names.obj(), &names_vector); |
| 61 |
| 62 // Convert all the long arrays. |
| 63 std::vector<int64_t> thread_ids_vector; |
| 64 std::vector<int64_t> begin_times_since_boot_vector; |
| 65 std::vector<int64_t> begin_thread_times_vector; |
| 66 std::vector<int64_t> end_times_since_boot_vector; |
| 67 std::vector<int64_t> end_thread_times_vector; |
| 68 |
| 69 static const struct { |
| 70 ScopedJavaLocalRef<jlongArray> (* const jni_function)(JNIEnv*, jobject); |
| 71 std::vector<int64_t>* const output_vector; |
| 72 } long_array_descriptors[] = { |
| 73 { Java_EarlyTraceEventsNativeReader_readThreadIds, &thread_ids_vector }, |
| 74 { Java_EarlyTraceEventsNativeReader_readBeginTimesSinceBootMsec, |
| 75 &begin_times_since_boot_vector }, |
| 76 { Java_EarlyTraceEventsNativeReader_readBeginThreadTimesMsec, |
| 77 &begin_thread_times_vector }, |
| 78 { Java_EarlyTraceEventsNativeReader_readEndTimesSinceBootMsec, |
| 79 &end_times_since_boot_vector }, |
| 80 { Java_EarlyTraceEventsNativeReader_readEndThreadTimesMsec, |
| 81 &end_thread_times_vector }, |
| 82 }; |
| 83 |
| 84 for (size_t i = 0; |
| 85 i < sizeof(long_array_descriptors) / sizeof(long_array_descriptors[0]); |
| 86 ++i) { |
| 87 const android::ScopedJavaLocalRef<jlongArray> jni_array = |
| 88 long_array_descriptors[i].jni_function(env, early_events_reader.obj()); |
| 89 AppendJavaLongArrayToLongVector( |
| 90 env, jni_array.obj(), long_array_descriptors[i].output_vector); |
| 91 } |
| 92 |
| 93 // The Java side uses times since boot whereas TraceLog uses |
| 94 // TimeTicks::NowFromSystemTraceTime(). The difference between those two time |
| 95 // systems must be propagated to all the early trace events that were |
| 96 // recorded. |
| 97 const int64_t time_offset_msec = |
| 98 Java_EarlyTraceEvent_getMsecTimeSinceBoot(env) - |
| 99 TimeTicks::NowFromSystemTraceTime().ToInternalValue() / 1000; |
| 100 |
| 101 const size_t events_count = names_vector.size(); |
| 102 trace_events->reserve(events_count); |
| 103 |
| 104 for (size_t i = 0; i < events_count; ++i) { |
| 105 trace_events->push_back(EarlyTraceEvent()); |
| 106 EarlyTraceEvent* const event = &trace_events->back(); |
| 107 |
| 108 event->name.swap(names_vector[i]); |
| 109 event->thread_id = thread_ids_vector[i]; |
| 110 |
| 111 event->begin_timestamp = ConvertJavaTimeSinceBoot( |
| 112 begin_times_since_boot_vector[i], time_offset_msec); |
| 113 event->end_timestamp = ConvertJavaTimeSinceBoot( |
| 114 end_times_since_boot_vector[i], time_offset_msec); |
| 115 |
| 116 event->begin_thread_time = ConvertJavaThreadTime( |
| 117 begin_thread_times_vector[i]); |
| 118 event->end_thread_time = ConvertJavaThreadTime(end_thread_times_vector[i]); |
| 119 } |
| 120 } |
| 121 |
| 122 } // namespace android |
| 123 } // namespace base |
OLD | NEW |