OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h" | 11 #include "webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h" |
12 | 12 |
13 #include <string> | 13 #include <string> |
14 | 14 |
15 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" | 15 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
16 #include "webrtc/sdk/android/src/jni/pc/java_native_conversion.h" | 16 #include "webrtc/sdk/android/src/jni/pc/java_native_conversion.h" |
17 | 17 |
18 namespace webrtc_jni { | 18 namespace webrtc { |
| 19 namespace jni { |
19 | 20 |
20 // Convenience, used since callbacks occur on the signaling thread, which may | 21 // Convenience, used since callbacks occur on the signaling thread, which may |
21 // be a non-Java thread. | 22 // be a non-Java thread. |
22 static JNIEnv* jni() { | 23 static JNIEnv* jni() { |
23 return AttachCurrentThreadIfNeeded(); | 24 return AttachCurrentThreadIfNeeded(); |
24 } | 25 } |
25 | 26 |
26 PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni, | 27 PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni, |
27 jobject j_observer) | 28 jobject j_observer) |
28 : j_observer_global_(jni, j_observer), | 29 : j_observer_global_(jni, j_observer), |
(...skipping 16 matching lines...) Expand all Loading... |
45 | 46 |
46 PeerConnectionObserverJni::~PeerConnectionObserverJni() { | 47 PeerConnectionObserverJni::~PeerConnectionObserverJni() { |
47 ScopedLocalRefFrame local_ref_frame(jni()); | 48 ScopedLocalRefFrame local_ref_frame(jni()); |
48 while (!remote_streams_.empty()) | 49 while (!remote_streams_.empty()) |
49 DisposeRemoteStream(remote_streams_.begin()); | 50 DisposeRemoteStream(remote_streams_.begin()); |
50 while (!rtp_receivers_.empty()) | 51 while (!rtp_receivers_.empty()) |
51 DisposeRtpReceiver(rtp_receivers_.begin()); | 52 DisposeRtpReceiver(rtp_receivers_.begin()); |
52 } | 53 } |
53 | 54 |
54 void PeerConnectionObserverJni::OnIceCandidate( | 55 void PeerConnectionObserverJni::OnIceCandidate( |
55 const webrtc::IceCandidateInterface* candidate) { | 56 const IceCandidateInterface* candidate) { |
56 ScopedLocalRefFrame local_ref_frame(jni()); | 57 ScopedLocalRefFrame local_ref_frame(jni()); |
57 std::string sdp; | 58 std::string sdp; |
58 RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; | 59 RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; |
59 jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate"); | 60 jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate"); |
60 jmethodID ctor = | 61 jmethodID ctor = |
61 GetMethodID(jni(), candidate_class, "<init>", | 62 GetMethodID(jni(), candidate_class, "<init>", |
62 "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"); | 63 "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"); |
63 jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid()); | 64 jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid()); |
64 jstring j_sdp = JavaStringFromStdString(jni(), sdp); | 65 jstring j_sdp = JavaStringFromStdString(jni(), sdp); |
65 jstring j_url = JavaStringFromStdString(jni(), candidate->candidate().url()); | 66 jstring j_url = JavaStringFromStdString(jni(), candidate->candidate().url()); |
(...skipping 10 matching lines...) Expand all Loading... |
76 const std::vector<cricket::Candidate>& candidates) { | 77 const std::vector<cricket::Candidate>& candidates) { |
77 ScopedLocalRefFrame local_ref_frame(jni()); | 78 ScopedLocalRefFrame local_ref_frame(jni()); |
78 jobjectArray candidates_array = NativeToJavaCandidateArray(jni(), candidates); | 79 jobjectArray candidates_array = NativeToJavaCandidateArray(jni(), candidates); |
79 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceCandidatesRemoved", | 80 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceCandidatesRemoved", |
80 "([Lorg/webrtc/IceCandidate;)V"); | 81 "([Lorg/webrtc/IceCandidate;)V"); |
81 jni()->CallVoidMethod(*j_observer_global_, m, candidates_array); | 82 jni()->CallVoidMethod(*j_observer_global_, m, candidates_array); |
82 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; | 83 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; |
83 } | 84 } |
84 | 85 |
85 void PeerConnectionObserverJni::OnSignalingChange( | 86 void PeerConnectionObserverJni::OnSignalingChange( |
86 webrtc::PeerConnectionInterface::SignalingState new_state) { | 87 PeerConnectionInterface::SignalingState new_state) { |
87 ScopedLocalRefFrame local_ref_frame(jni()); | 88 ScopedLocalRefFrame local_ref_frame(jni()); |
88 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSignalingChange", | 89 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSignalingChange", |
89 "(Lorg/webrtc/PeerConnection$SignalingState;)V"); | 90 "(Lorg/webrtc/PeerConnection$SignalingState;)V"); |
90 jobject new_state_enum = JavaEnumFromIndexAndClassName( | 91 jobject new_state_enum = JavaEnumFromIndexAndClassName( |
91 jni(), "PeerConnection$SignalingState", new_state); | 92 jni(), "PeerConnection$SignalingState", new_state); |
92 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); | 93 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); |
93 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 94 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
94 } | 95 } |
95 | 96 |
96 void PeerConnectionObserverJni::OnIceConnectionChange( | 97 void PeerConnectionObserverJni::OnIceConnectionChange( |
97 webrtc::PeerConnectionInterface::IceConnectionState new_state) { | 98 PeerConnectionInterface::IceConnectionState new_state) { |
98 ScopedLocalRefFrame local_ref_frame(jni()); | 99 ScopedLocalRefFrame local_ref_frame(jni()); |
99 jmethodID m = | 100 jmethodID m = |
100 GetMethodID(jni(), *j_observer_class_, "onIceConnectionChange", | 101 GetMethodID(jni(), *j_observer_class_, "onIceConnectionChange", |
101 "(Lorg/webrtc/PeerConnection$IceConnectionState;)V"); | 102 "(Lorg/webrtc/PeerConnection$IceConnectionState;)V"); |
102 jobject new_state_enum = JavaEnumFromIndexAndClassName( | 103 jobject new_state_enum = JavaEnumFromIndexAndClassName( |
103 jni(), "PeerConnection$IceConnectionState", new_state); | 104 jni(), "PeerConnection$IceConnectionState", new_state); |
104 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); | 105 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); |
105 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 106 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
106 } | 107 } |
107 | 108 |
108 void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) { | 109 void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) { |
109 ScopedLocalRefFrame local_ref_frame(jni()); | 110 ScopedLocalRefFrame local_ref_frame(jni()); |
110 jmethodID m = GetMethodID(jni(), *j_observer_class_, | 111 jmethodID m = GetMethodID(jni(), *j_observer_class_, |
111 "onIceConnectionReceivingChange", "(Z)V"); | 112 "onIceConnectionReceivingChange", "(Z)V"); |
112 jni()->CallVoidMethod(*j_observer_global_, m, receiving); | 113 jni()->CallVoidMethod(*j_observer_global_, m, receiving); |
113 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 114 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
114 } | 115 } |
115 | 116 |
116 void PeerConnectionObserverJni::OnIceGatheringChange( | 117 void PeerConnectionObserverJni::OnIceGatheringChange( |
117 webrtc::PeerConnectionInterface::IceGatheringState new_state) { | 118 PeerConnectionInterface::IceGatheringState new_state) { |
118 ScopedLocalRefFrame local_ref_frame(jni()); | 119 ScopedLocalRefFrame local_ref_frame(jni()); |
119 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceGatheringChange", | 120 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceGatheringChange", |
120 "(Lorg/webrtc/PeerConnection$IceGatheringState;)V"); | 121 "(Lorg/webrtc/PeerConnection$IceGatheringState;)V"); |
121 jobject new_state_enum = JavaEnumFromIndexAndClassName( | 122 jobject new_state_enum = JavaEnumFromIndexAndClassName( |
122 jni(), "PeerConnection$IceGatheringState", new_state); | 123 jni(), "PeerConnection$IceGatheringState", new_state); |
123 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); | 124 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); |
124 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 125 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
125 } | 126 } |
126 | 127 |
127 void PeerConnectionObserverJni::OnAddStream( | 128 void PeerConnectionObserverJni::OnAddStream( |
128 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { | 129 rtc::scoped_refptr<MediaStreamInterface> stream) { |
129 ScopedLocalRefFrame local_ref_frame(jni()); | 130 ScopedLocalRefFrame local_ref_frame(jni()); |
130 // The stream could be added into the remote_streams_ map when calling | 131 // The stream could be added into the remote_streams_ map when calling |
131 // OnAddTrack. | 132 // OnAddTrack. |
132 jobject j_stream = GetOrCreateJavaStream(stream); | 133 jobject j_stream = GetOrCreateJavaStream(stream); |
133 | 134 |
134 for (const auto& track : stream->GetAudioTracks()) { | 135 for (const auto& track : stream->GetAudioTracks()) { |
135 jstring id = JavaStringFromStdString(jni(), track->id()); | 136 jstring id = JavaStringFromStdString(jni(), track->id()); |
136 // Java AudioTrack holds one reference. Corresponding Release() is in | 137 // Java AudioTrack holds one reference. Corresponding Release() is in |
137 // MediaStreamTrack_free, triggered by AudioTrack.dispose(). | 138 // MediaStreamTrack_free, triggered by AudioTrack.dispose(). |
138 track->AddRef(); | 139 track->AddRef(); |
(...skipping 30 matching lines...) Expand all Loading... |
169 RTC_CHECK(added); | 170 RTC_CHECK(added); |
170 } | 171 } |
171 | 172 |
172 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream", | 173 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream", |
173 "(Lorg/webrtc/MediaStream;)V"); | 174 "(Lorg/webrtc/MediaStream;)V"); |
174 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); | 175 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); |
175 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 176 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
176 } | 177 } |
177 | 178 |
178 void PeerConnectionObserverJni::OnRemoveStream( | 179 void PeerConnectionObserverJni::OnRemoveStream( |
179 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { | 180 rtc::scoped_refptr<MediaStreamInterface> stream) { |
180 ScopedLocalRefFrame local_ref_frame(jni()); | 181 ScopedLocalRefFrame local_ref_frame(jni()); |
181 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); | 182 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); |
182 RTC_CHECK(it != remote_streams_.end()) | 183 RTC_CHECK(it != remote_streams_.end()) |
183 << "unexpected stream: " << std::hex << stream; | 184 << "unexpected stream: " << std::hex << stream; |
184 jobject j_stream = it->second; | 185 jobject j_stream = it->second; |
185 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onRemoveStream", | 186 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onRemoveStream", |
186 "(Lorg/webrtc/MediaStream;)V"); | 187 "(Lorg/webrtc/MediaStream;)V"); |
187 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); | 188 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); |
188 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 189 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
189 // Release the refptr reference so that DisposeRemoteStream can assert | 190 // Release the refptr reference so that DisposeRemoteStream can assert |
190 // it removes the final reference. | 191 // it removes the final reference. |
191 stream = nullptr; | 192 stream = nullptr; |
192 DisposeRemoteStream(it); | 193 DisposeRemoteStream(it); |
193 } | 194 } |
194 | 195 |
195 void PeerConnectionObserverJni::OnDataChannel( | 196 void PeerConnectionObserverJni::OnDataChannel( |
196 rtc::scoped_refptr<webrtc::DataChannelInterface> channel) { | 197 rtc::scoped_refptr<DataChannelInterface> channel) { |
197 ScopedLocalRefFrame local_ref_frame(jni()); | 198 ScopedLocalRefFrame local_ref_frame(jni()); |
198 jobject j_channel = | 199 jobject j_channel = |
199 jni()->NewObject(*j_data_channel_class_, j_data_channel_ctor_, | 200 jni()->NewObject(*j_data_channel_class_, j_data_channel_ctor_, |
200 jlongFromPointer(channel.get())); | 201 jlongFromPointer(channel.get())); |
201 CHECK_EXCEPTION(jni()) << "error during NewObject"; | 202 CHECK_EXCEPTION(jni()) << "error during NewObject"; |
202 | 203 |
203 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onDataChannel", | 204 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onDataChannel", |
204 "(Lorg/webrtc/DataChannel;)V"); | 205 "(Lorg/webrtc/DataChannel;)V"); |
205 jni()->CallVoidMethod(*j_observer_global_, m, j_channel); | 206 jni()->CallVoidMethod(*j_observer_global_, m, j_channel); |
206 | 207 |
207 // Channel is now owned by Java object, and will be freed from | 208 // Channel is now owned by Java object, and will be freed from |
208 // DataChannel.dispose(). Important that this be done _after_ the | 209 // DataChannel.dispose(). Important that this be done _after_ the |
209 // CallVoidMethod above as Java code might call back into native code and be | 210 // CallVoidMethod above as Java code might call back into native code and be |
210 // surprised to see a refcount of 2. | 211 // surprised to see a refcount of 2. |
211 int bumped_count = channel->AddRef(); | 212 int bumped_count = channel->AddRef(); |
212 RTC_CHECK(bumped_count == 2) << "Unexpected refcount OnDataChannel"; | 213 RTC_CHECK(bumped_count == 2) << "Unexpected refcount OnDataChannel"; |
213 | 214 |
214 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 215 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
215 } | 216 } |
216 | 217 |
217 void PeerConnectionObserverJni::OnRenegotiationNeeded() { | 218 void PeerConnectionObserverJni::OnRenegotiationNeeded() { |
218 ScopedLocalRefFrame local_ref_frame(jni()); | 219 ScopedLocalRefFrame local_ref_frame(jni()); |
219 jmethodID m = | 220 jmethodID m = |
220 GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V"); | 221 GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V"); |
221 jni()->CallVoidMethod(*j_observer_global_, m); | 222 jni()->CallVoidMethod(*j_observer_global_, m); |
222 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 223 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
223 } | 224 } |
224 | 225 |
225 void PeerConnectionObserverJni::OnAddTrack( | 226 void PeerConnectionObserverJni::OnAddTrack( |
226 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, | 227 rtc::scoped_refptr<RtpReceiverInterface> receiver, |
227 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& | 228 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) { |
228 streams) { | |
229 ScopedLocalRefFrame local_ref_frame(jni()); | 229 ScopedLocalRefFrame local_ref_frame(jni()); |
230 jobject j_rtp_receiver = | 230 jobject j_rtp_receiver = |
231 jni()->NewObject(*j_rtp_receiver_class_, j_rtp_receiver_ctor_, | 231 jni()->NewObject(*j_rtp_receiver_class_, j_rtp_receiver_ctor_, |
232 jlongFromPointer(receiver.get())); | 232 jlongFromPointer(receiver.get())); |
233 CHECK_EXCEPTION(jni()) << "error during NewObject"; | 233 CHECK_EXCEPTION(jni()) << "error during NewObject"; |
234 receiver->AddRef(); | 234 receiver->AddRef(); |
235 rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver); | 235 rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver); |
236 | 236 |
237 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); | 237 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); |
238 jmethodID m = | 238 jmethodID m = |
(...skipping 26 matching lines...) Expand all Loading... |
265 jni()->CallVoidMethod( | 265 jni()->CallVoidMethod( |
266 j_rtp_receiver, | 266 j_rtp_receiver, |
267 GetMethodID(jni(), *j_rtp_receiver_class_, "dispose", "()V")); | 267 GetMethodID(jni(), *j_rtp_receiver_class_, "dispose", "()V")); |
268 CHECK_EXCEPTION(jni()) << "error during RtpReceiver.dispose()"; | 268 CHECK_EXCEPTION(jni()) << "error during RtpReceiver.dispose()"; |
269 DeleteGlobalRef(jni(), j_rtp_receiver); | 269 DeleteGlobalRef(jni(), j_rtp_receiver); |
270 } | 270 } |
271 | 271 |
272 // If the NativeToJavaStreamsMap contains the stream, return it. | 272 // If the NativeToJavaStreamsMap contains the stream, return it. |
273 // Otherwise, create a new Java MediaStream. | 273 // Otherwise, create a new Java MediaStream. |
274 jobject PeerConnectionObserverJni::GetOrCreateJavaStream( | 274 jobject PeerConnectionObserverJni::GetOrCreateJavaStream( |
275 const rtc::scoped_refptr<webrtc::MediaStreamInterface>& stream) { | 275 const rtc::scoped_refptr<MediaStreamInterface>& stream) { |
276 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); | 276 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); |
277 if (it != remote_streams_.end()) { | 277 if (it != remote_streams_.end()) { |
278 return it->second; | 278 return it->second; |
279 } | 279 } |
280 | 280 |
281 // Java MediaStream holds one reference. Corresponding Release() is in | 281 // Java MediaStream holds one reference. Corresponding Release() is in |
282 // MediaStream_free, triggered by MediaStream.dispose(). | 282 // MediaStream_free, triggered by MediaStream.dispose(). |
283 stream->AddRef(); | 283 stream->AddRef(); |
284 jobject j_stream = | 284 jobject j_stream = |
285 jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_, | 285 jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_, |
286 reinterpret_cast<jlong>(stream.get())); | 286 reinterpret_cast<jlong>(stream.get())); |
287 CHECK_EXCEPTION(jni()) << "error during NewObject"; | 287 CHECK_EXCEPTION(jni()) << "error during NewObject"; |
288 | 288 |
289 remote_streams_[stream] = NewGlobalRef(jni(), j_stream); | 289 remote_streams_[stream] = NewGlobalRef(jni(), j_stream); |
290 return j_stream; | 290 return j_stream; |
291 } | 291 } |
292 | 292 |
293 jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray( | 293 jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray( |
294 JNIEnv* jni, | 294 JNIEnv* jni, |
295 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& | 295 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) { |
296 streams) { | |
297 jobjectArray java_streams = | 296 jobjectArray java_streams = |
298 jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr); | 297 jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr); |
299 CHECK_EXCEPTION(jni) << "error during NewObjectArray"; | 298 CHECK_EXCEPTION(jni) << "error during NewObjectArray"; |
300 for (size_t i = 0; i < streams.size(); ++i) { | 299 for (size_t i = 0; i < streams.size(); ++i) { |
301 jobject j_stream = GetOrCreateJavaStream(streams[i]); | 300 jobject j_stream = GetOrCreateJavaStream(streams[i]); |
302 jni->SetObjectArrayElement(java_streams, i, j_stream); | 301 jni->SetObjectArrayElement(java_streams, i, j_stream); |
303 } | 302 } |
304 return java_streams; | 303 return java_streams; |
305 } | 304 } |
306 | 305 |
307 } // namespace webrtc_jni | 306 } // namespace jni |
| 307 } // namespace webrtc |
OLD | NEW |