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