1 /*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.h"
12
13 #include <string>
14 #include <vector>
15
16 #include "rtc_base/string_encode.h"
17 #include "sdk/android/generated_external_classes_jni/BigInteger_jni.h"
18 #include "sdk/android/generated_peerconnection_jni/RTCStatsCollectorCallback_jni.h"
19 #include "sdk/android/generated_peerconnection_jni/RTCStatsReport_jni.h"
20 #include "sdk/android/generated_peerconnection_jni/RTCStats_jni.h"
21 #include "sdk/android/native_api/jni/java_types.h"
22
23 namespace webrtc {
24 namespace jni {
25
26 namespace {
27
NativeToJavaBigInteger(JNIEnv * env,uint64_t u)28 ScopedJavaLocalRef<jobject> NativeToJavaBigInteger(JNIEnv* env, uint64_t u) {
29 return JNI_BigInteger::Java_BigInteger_ConstructorJMBI_JLS(
30 env, NativeToJavaString(env, rtc::ToString(u)));
31 }
32
NativeToJavaBigIntegerArray(JNIEnv * env,const std::vector<uint64_t> & container)33 ScopedJavaLocalRef<jobjectArray> NativeToJavaBigIntegerArray(
34 JNIEnv* env,
35 const std::vector<uint64_t>& container) {
36 return NativeToJavaObjectArray(
37 env, container, java_math_BigInteger_clazz(env), &NativeToJavaBigInteger);
38 }
39
MemberToJava(JNIEnv * env,const RTCStatsMemberInterface & member)40 ScopedJavaLocalRef<jobject> MemberToJava(
41 JNIEnv* env,
42 const RTCStatsMemberInterface& member) {
43 switch (member.type()) {
44 case RTCStatsMemberInterface::kBool:
45 return NativeToJavaBoolean(env, *member.cast_to<RTCStatsMember<bool>>());
46
47 case RTCStatsMemberInterface::kInt32:
48 return NativeToJavaInteger(env,
49 *member.cast_to<RTCStatsMember<int32_t>>());
50
51 case RTCStatsMemberInterface::kUint32:
52 return NativeToJavaLong(env, *member.cast_to<RTCStatsMember<uint32_t>>());
53
54 case RTCStatsMemberInterface::kInt64:
55 return NativeToJavaLong(env, *member.cast_to<RTCStatsMember<int64_t>>());
56
57 case RTCStatsMemberInterface::kUint64:
58 return NativeToJavaBigInteger(
59 env, *member.cast_to<RTCStatsMember<uint64_t>>());
60
61 case RTCStatsMemberInterface::kDouble:
62 return NativeToJavaDouble(env, *member.cast_to<RTCStatsMember<double>>());
63
64 case RTCStatsMemberInterface::kString:
65 return NativeToJavaString(env,
66 *member.cast_to<RTCStatsMember<std::string>>());
67
68 case RTCStatsMemberInterface::kSequenceBool:
69 return NativeToJavaBooleanArray(
70 env, *member.cast_to<RTCStatsMember<std::vector<bool>>>());
71
72 case RTCStatsMemberInterface::kSequenceInt32:
73 return NativeToJavaIntegerArray(
74 env, *member.cast_to<RTCStatsMember<std::vector<int32_t>>>());
75
76 case RTCStatsMemberInterface::kSequenceUint32: {
77 const std::vector<uint32_t>& v =
78 *member.cast_to<RTCStatsMember<std::vector<uint32_t>>>();
79 return NativeToJavaLongArray(env,
80 std::vector<int64_t>(v.begin(), v.end()));
81 }
82 case RTCStatsMemberInterface::kSequenceInt64:
83 return NativeToJavaLongArray(
84 env, *member.cast_to<RTCStatsMember<std::vector<int64_t>>>());
85
86 case RTCStatsMemberInterface::kSequenceUint64:
87 return NativeToJavaBigIntegerArray(
88 env, *member.cast_to<RTCStatsMember<std::vector<uint64_t>>>());
89
90 case RTCStatsMemberInterface::kSequenceDouble:
91 return NativeToJavaDoubleArray(
92 env, *member.cast_to<RTCStatsMember<std::vector<double>>>());
93
94 case RTCStatsMemberInterface::kSequenceString:
95 return NativeToJavaStringArray(
96 env, *member.cast_to<RTCStatsMember<std::vector<std::string>>>());
97 }
98 RTC_NOTREACHED();
99 return nullptr;
100 }
101
NativeToJavaRtcStats(JNIEnv * env,const RTCStats & stats)102 ScopedJavaLocalRef<jobject> NativeToJavaRtcStats(JNIEnv* env,
103 const RTCStats& stats) {
104 JavaMapBuilder builder(env);
105 for (auto* const member : stats.Members()) {
106 if (!member->is_defined())
107 continue;
108 builder.put(NativeToJavaString(env, member->name()),
109 MemberToJava(env, *member));
110 }
111 return Java_RTCStats_create(
112 env, stats.timestamp_us(), NativeToJavaString(env, stats.type()),
113 NativeToJavaString(env, stats.id()), builder.GetJavaMap());
114 }
115
NativeToJavaRtcStatsReport(JNIEnv * env,const rtc::scoped_refptr<const RTCStatsReport> & report)116 ScopedJavaLocalRef<jobject> NativeToJavaRtcStatsReport(
117 JNIEnv* env,
118 const rtc::scoped_refptr<const RTCStatsReport>& report) {
119 ScopedJavaLocalRef<jobject> j_stats_map =
120 NativeToJavaMap(env, *report, [](JNIEnv* env, const RTCStats& stats) {
121 return std::make_pair(NativeToJavaString(env, stats.id()),
122 NativeToJavaRtcStats(env, stats));
123 });
124 return Java_RTCStatsReport_create(env, report->timestamp_us(), j_stats_map);
125 }
126
127 } // namespace
128
RTCStatsCollectorCallbackWrapper(JNIEnv * jni,const JavaRef<jobject> & j_callback)129 RTCStatsCollectorCallbackWrapper::RTCStatsCollectorCallbackWrapper(
130 JNIEnv* jni,
131 const JavaRef<jobject>& j_callback)
132 : j_callback_global_(jni, j_callback) {}
133
134 RTCStatsCollectorCallbackWrapper::~RTCStatsCollectorCallbackWrapper() = default;
135
OnStatsDelivered(const rtc::scoped_refptr<const RTCStatsReport> & report)136 void RTCStatsCollectorCallbackWrapper::OnStatsDelivered(
137 const rtc::scoped_refptr<const RTCStatsReport>& report) {
138 JNIEnv* jni = AttachCurrentThreadIfNeeded();
139 Java_RTCStatsCollectorCallback_onStatsDelivered(
140 jni, j_callback_global_, NativeToJavaRtcStatsReport(jni, report));
141 }
142
143 } // namespace jni
144 } // namespace webrtc
145