Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: webrtc/api/android/jni/peerconnection_jni.cc

Issue 2513723002: Created a java wrapper for the callback OnAddTrack to PeerConnection.Observer (Closed)
Patch Set: Address the CR comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2013 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
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // the below methods and we only override one of them. 166 // the below methods and we only override one of them.
167 // TODO(deadbeef): Remove once there's only one version of the methods. 167 // TODO(deadbeef): Remove once there's only one version of the methods.
168 using PeerConnectionObserver::OnAddStream; 168 using PeerConnectionObserver::OnAddStream;
169 using PeerConnectionObserver::OnRemoveStream; 169 using PeerConnectionObserver::OnRemoveStream;
170 using PeerConnectionObserver::OnDataChannel; 170 using PeerConnectionObserver::OnDataChannel;
171 171
172 PCOJava(JNIEnv* jni, jobject j_observer) 172 PCOJava(JNIEnv* jni, jobject j_observer)
173 : j_observer_global_(jni, j_observer), 173 : j_observer_global_(jni, j_observer),
174 j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)), 174 j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)),
175 j_media_stream_class_(jni, FindClass(jni, "org/webrtc/MediaStream")), 175 j_media_stream_class_(jni, FindClass(jni, "org/webrtc/MediaStream")),
176 j_media_stream_ctor_(GetMethodID( 176 j_media_stream_ctor_(
177 jni, *j_media_stream_class_, "<init>", "(J)V")), 177 GetMethodID(jni, *j_media_stream_class_, "<init>", "(J)V")),
178 j_audio_track_class_(jni, FindClass(jni, "org/webrtc/AudioTrack")), 178 j_audio_track_class_(jni, FindClass(jni, "org/webrtc/AudioTrack")),
179 j_audio_track_ctor_(GetMethodID( 179 j_audio_track_ctor_(
180 jni, *j_audio_track_class_, "<init>", "(J)V")), 180 GetMethodID(jni, *j_audio_track_class_, "<init>", "(J)V")),
181 j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")), 181 j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")),
182 j_video_track_ctor_(GetMethodID( 182 j_video_track_ctor_(
183 jni, *j_video_track_class_, "<init>", "(J)V")), 183 GetMethodID(jni, *j_video_track_class_, "<init>", "(J)V")),
184 j_data_channel_class_(jni, FindClass(jni, "org/webrtc/DataChannel")), 184 j_data_channel_class_(jni, FindClass(jni, "org/webrtc/DataChannel")),
185 j_data_channel_ctor_(GetMethodID( 185 j_data_channel_ctor_(
186 jni, *j_data_channel_class_, "<init>", "(J)V")) { 186 GetMethodID(jni, *j_data_channel_class_, "<init>", "(J)V")),
187 } 187 j_rtp_receiver_class_(jni, FindClass(jni, "org/webrtc/RtpReceiver")),
188 j_rtp_receiver_ctor_(
189 GetMethodID(jni, *j_rtp_receiver_class_, "<init>", "(J)V")) {}
188 190
189 virtual ~PCOJava() { 191 virtual ~PCOJava() {
190 ScopedLocalRefFrame local_ref_frame(jni()); 192 ScopedLocalRefFrame local_ref_frame(jni());
191 while (!remote_streams_.empty()) 193 while (!remote_streams_.empty())
192 DisposeRemoteStream(remote_streams_.begin()); 194 DisposeRemoteStream(remote_streams_.begin());
195 while (!rtp_receivers_.empty())
196 DisposeRtpReceiver(rtp_receivers_.begin());
193 } 197 }
194 198
195 void OnIceCandidate(const IceCandidateInterface* candidate) override { 199 void OnIceCandidate(const IceCandidateInterface* candidate) override {
196 ScopedLocalRefFrame local_ref_frame(jni()); 200 ScopedLocalRefFrame local_ref_frame(jni());
197 std::string sdp; 201 std::string sdp;
198 RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; 202 RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp;
199 jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate"); 203 jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate");
200 jmethodID ctor = GetMethodID(jni(), candidate_class, 204 jmethodID ctor = GetMethodID(jni(), candidate_class,
201 "<init>", "(Ljava/lang/String;ILjava/lang/String;)V"); 205 "<init>", "(Ljava/lang/String;ILjava/lang/String;)V");
202 jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid()); 206 jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 jni(), *j_observer_class_, "onIceGatheringChange", 264 jni(), *j_observer_class_, "onIceGatheringChange",
261 "(Lorg/webrtc/PeerConnection$IceGatheringState;)V"); 265 "(Lorg/webrtc/PeerConnection$IceGatheringState;)V");
262 jobject new_state_enum = JavaEnumFromIndex( 266 jobject new_state_enum = JavaEnumFromIndex(
263 jni(), "PeerConnection$IceGatheringState", new_state); 267 jni(), "PeerConnection$IceGatheringState", new_state);
264 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); 268 jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
265 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; 269 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
266 } 270 }
267 271
268 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override { 272 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
269 ScopedLocalRefFrame local_ref_frame(jni()); 273 ScopedLocalRefFrame local_ref_frame(jni());
270 // Java MediaStream holds one reference. Corresponding Release() is in 274 // The stream could be added into the remote_streams_ map when calling
271 // MediaStream_free, triggered by MediaStream.dispose(). 275 // OnAddTrack.
272 stream->AddRef(); 276 jobject j_stream = GetOrCreateJavaStream(stream);
273 jobject j_stream =
274 jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_,
275 reinterpret_cast<jlong>(stream.get()));
276 CHECK_EXCEPTION(jni()) << "error during NewObject";
277 277
278 for (const auto& track : stream->GetAudioTracks()) { 278 for (const auto& track : stream->GetAudioTracks()) {
279 jstring id = JavaStringFromStdString(jni(), track->id()); 279 jstring id = JavaStringFromStdString(jni(), track->id());
280 // Java AudioTrack holds one reference. Corresponding Release() is in 280 // Java AudioTrack holds one reference. Corresponding Release() is in
281 // MediaStreamTrack_free, triggered by AudioTrack.dispose(). 281 // MediaStreamTrack_free, triggered by AudioTrack.dispose().
282 track->AddRef(); 282 track->AddRef();
283 jobject j_track = 283 jobject j_track =
284 jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_, 284 jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_,
285 reinterpret_cast<jlong>(track.get()), id); 285 reinterpret_cast<jlong>(track.get()), id);
286 CHECK_EXCEPTION(jni()) << "error during NewObject"; 286 CHECK_EXCEPTION(jni()) << "error during NewObject";
(...skipping 26 matching lines...) Expand all
313 "Ljava/util/LinkedList;"); 313 "Ljava/util/LinkedList;");
314 jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id); 314 jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
315 jmethodID add = GetMethodID(jni(), 315 jmethodID add = GetMethodID(jni(),
316 GetObjectClass(jni(), video_tracks), 316 GetObjectClass(jni(), video_tracks),
317 "add", 317 "add",
318 "(Ljava/lang/Object;)Z"); 318 "(Ljava/lang/Object;)Z");
319 jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track); 319 jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track);
320 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; 320 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
321 RTC_CHECK(added); 321 RTC_CHECK(added);
322 } 322 }
323 remote_streams_[stream] = NewGlobalRef(jni(), j_stream);
324 323
325 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream", 324 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream",
326 "(Lorg/webrtc/MediaStream;)V"); 325 "(Lorg/webrtc/MediaStream;)V");
327 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); 326 jni()->CallVoidMethod(*j_observer_global_, m, j_stream);
328 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; 327 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
329 } 328 }
330 329
331 void OnRemoveStream( 330 void OnRemoveStream(
332 rtc::scoped_refptr<MediaStreamInterface> stream) override { 331 rtc::scoped_refptr<MediaStreamInterface> stream) override {
333 ScopedLocalRefFrame local_ref_frame(jni()); 332 ScopedLocalRefFrame local_ref_frame(jni());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 } 366 }
368 367
369 void OnRenegotiationNeeded() override { 368 void OnRenegotiationNeeded() override {
370 ScopedLocalRefFrame local_ref_frame(jni()); 369 ScopedLocalRefFrame local_ref_frame(jni());
371 jmethodID m = 370 jmethodID m =
372 GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V"); 371 GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V");
373 jni()->CallVoidMethod(*j_observer_global_, m); 372 jni()->CallVoidMethod(*j_observer_global_, m);
374 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; 373 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
375 } 374 }
376 375
376 void OnAddTrack(
377 rtc::scoped_refptr<RtpReceiverInterface> receiver,
378 std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams) override {
magjed_webrtc 2016/12/02 12:19:46 this should be const-ref.
Zhi Huang 2016/12/03 00:03:02 Oh this is my fault. Hopefully it's not too late t
379 ScopedLocalRefFrame local_ref_frame(jni());
380 jobject j_rtp_receiver = jni()->NewObject(
381 *j_rtp_receiver_class_, j_rtp_receiver_ctor_, (jlong)receiver.get());
magjed_webrtc 2016/12/02 12:19:46 It's dangerous to cast the pointer to a jlong that
Zhi Huang 2016/12/03 00:03:03 Done. There are many places, besides this CL, usi
382 CHECK_EXCEPTION(jni()) << "error during NewObject";
383 receiver->AddRef();
384 rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver);
385
386 jobjectArray j_stream_array = ToJavaMediaStreamArray(jni(), streams);
387 jmethodID m =
388 GetMethodID(jni(), *j_observer_class_, "onAddTrack",
389 "(Lorg/webrtc/RtpReceiver;[Lorg/webrtc/MediaStream;)V");
390 jni()->CallVoidMethod(*j_observer_global_, m, j_rtp_receiver,
391 j_stream_array);
392 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
393 }
394
377 void SetConstraints(ConstraintsWrapper* constraints) { 395 void SetConstraints(ConstraintsWrapper* constraints) {
378 RTC_CHECK(!constraints_.get()) << "constraints already set!"; 396 RTC_CHECK(!constraints_.get()) << "constraints already set!";
379 constraints_.reset(constraints); 397 constraints_.reset(constraints);
380 } 398 }
381 399
382 const ConstraintsWrapper* constraints() { return constraints_.get(); } 400 const ConstraintsWrapper* constraints() { return constraints_.get(); }
383 401
384 private: 402 private:
385 typedef std::map<MediaStreamInterface*, jobject> NativeToJavaStreamsMap; 403 typedef std::map<MediaStreamInterface*, jobject> NativeToJavaStreamsMap;
404 typedef std::map<RtpReceiverInterface*, jobject> NativeToJavaRtpReceiverMap;
386 405
387 void DisposeRemoteStream(const NativeToJavaStreamsMap::iterator& it) { 406 void DisposeRemoteStream(const NativeToJavaStreamsMap::iterator& it) {
388 jobject j_stream = it->second; 407 jobject j_stream = it->second;
389 remote_streams_.erase(it); 408 remote_streams_.erase(it);
390 jni()->CallVoidMethod( 409 jni()->CallVoidMethod(
391 j_stream, GetMethodID(jni(), *j_media_stream_class_, "dispose", "()V")); 410 j_stream, GetMethodID(jni(), *j_media_stream_class_, "dispose", "()V"));
392 CHECK_EXCEPTION(jni()) << "error during MediaStream.dispose()"; 411 CHECK_EXCEPTION(jni()) << "error during MediaStream.dispose()";
393 DeleteGlobalRef(jni(), j_stream); 412 DeleteGlobalRef(jni(), j_stream);
394 } 413 }
395 414
415 void DisposeRtpReceiver(const NativeToJavaRtpReceiverMap::iterator& it) {
416 jobject j_rtp_receiver = it->second;
417 rtp_receivers_.erase(it);
418 jni()->CallVoidMethod(
419 j_rtp_receiver,
420 GetMethodID(jni(), *j_rtp_receiver_class_, "dispose", "()V"));
skvlad 2016/11/28 21:35:42 Calling dispose() from Java will call Release() on
Taylor Brandstetter 2016/11/28 23:15:12 That's possible before this CL, though. I agree it
421 CHECK_EXCEPTION(jni()) << "error during RtpReceiver.dispose()";
422 DeleteGlobalRef(jni(), j_rtp_receiver);
skvlad 2016/11/28 21:35:42 You could just store ScopedGlobalRefs in the map a
423 }
424
396 jobject ToJavaCandidate(JNIEnv* jni, 425 jobject ToJavaCandidate(JNIEnv* jni,
397 jclass* candidate_class, 426 jclass* candidate_class,
398 const cricket::Candidate& candidate) { 427 const cricket::Candidate& candidate) {
399 std::string sdp = webrtc::SdpSerializeCandidate(candidate); 428 std::string sdp = webrtc::SdpSerializeCandidate(candidate);
400 RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate"; 429 RTC_CHECK(!sdp.empty()) << "got an empty ICE candidate";
401 jmethodID ctor = GetMethodID(jni, *candidate_class, "<init>", 430 jmethodID ctor = GetMethodID(jni, *candidate_class, "<init>",
402 "(Ljava/lang/String;ILjava/lang/String;)V"); 431 "(Ljava/lang/String;ILjava/lang/String;)V");
403 jstring j_mid = JavaStringFromStdString(jni, candidate.transport_name()); 432 jstring j_mid = JavaStringFromStdString(jni, candidate.transport_name());
404 jstring j_sdp = JavaStringFromStdString(jni, sdp); 433 jstring j_sdp = JavaStringFromStdString(jni, sdp);
405 // sdp_mline_index is not used, pass an invalid value -1. 434 // sdp_mline_index is not used, pass an invalid value -1.
(...skipping 10 matching lines...) Expand all
416 jobjectArray java_candidates = 445 jobjectArray java_candidates =
417 jni->NewObjectArray(candidates.size(), candidate_class, NULL); 446 jni->NewObjectArray(candidates.size(), candidate_class, NULL);
418 int i = 0; 447 int i = 0;
419 for (const cricket::Candidate& candidate : candidates) { 448 for (const cricket::Candidate& candidate : candidates) {
420 jobject j_candidate = ToJavaCandidate(jni, &candidate_class, candidate); 449 jobject j_candidate = ToJavaCandidate(jni, &candidate_class, candidate);
421 jni->SetObjectArrayElement(java_candidates, i++, j_candidate); 450 jni->SetObjectArrayElement(java_candidates, i++, j_candidate);
422 } 451 }
423 return java_candidates; 452 return java_candidates;
424 } 453 }
425 454
455 jobjectArray ToJavaMediaStreamArray(
456 JNIEnv* jni,
457 std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams) {
magjed_webrtc 2016/12/02 12:19:46 const-ref
Zhi Huang 2016/12/03 00:03:02 Done.
458 jobjectArray java_streams =
459 jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr);
460 CHECK_EXCEPTION(jni) << "error during NewObjectArray";
461 int i = 0;
462 for (rtc::scoped_refptr<MediaStreamInterface> stream : streams) {
magjed_webrtc 2016/12/02 12:19:47 I think it would be cleaner with: for (size_t i =
Zhi Huang 2016/12/03 00:03:02 Done.
463 jobject j_stream = GetOrCreateJavaStream(stream);
464 jni->SetObjectArrayElement(java_streams, i++, j_stream);
465 }
466 return java_streams;
467 }
468
469 // If the NativeToJavaStreamsMap contains the stream, return it.
470 // Otherwise, create a new Java MediaStream.
471 jobject GetOrCreateJavaStream(
472 rtc::scoped_refptr<MediaStreamInterface> stream) {
magjed_webrtc 2016/12/02 12:19:46 Use const-ref, or raw MediaStreamInterface*, I'm n
Zhi Huang 2016/12/03 00:03:02 Done.
473 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
474 if (it != remote_streams_.end()) {
475 return it->second;
476 }
477
478 // Java MediaStream holds one reference. Corresponding Release() is in
479 // MediaStream_free, triggered by MediaStream.dispose().
480 stream->AddRef();
481 jobject j_stream =
482 jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_,
483 reinterpret_cast<jlong>(stream.get()));
484 CHECK_EXCEPTION(jni()) << "error during NewObject";
485
486 remote_streams_[stream] = NewGlobalRef(jni(), j_stream);
487 return j_stream;
488 }
489
426 JNIEnv* jni() { 490 JNIEnv* jni() {
427 return AttachCurrentThreadIfNeeded(); 491 return AttachCurrentThreadIfNeeded();
428 } 492 }
429 493
430 const ScopedGlobalRef<jobject> j_observer_global_; 494 const ScopedGlobalRef<jobject> j_observer_global_;
431 const ScopedGlobalRef<jclass> j_observer_class_; 495 const ScopedGlobalRef<jclass> j_observer_class_;
432 const ScopedGlobalRef<jclass> j_media_stream_class_; 496 const ScopedGlobalRef<jclass> j_media_stream_class_;
433 const jmethodID j_media_stream_ctor_; 497 const jmethodID j_media_stream_ctor_;
434 const ScopedGlobalRef<jclass> j_audio_track_class_; 498 const ScopedGlobalRef<jclass> j_audio_track_class_;
435 const jmethodID j_audio_track_ctor_; 499 const jmethodID j_audio_track_ctor_;
436 const ScopedGlobalRef<jclass> j_video_track_class_; 500 const ScopedGlobalRef<jclass> j_video_track_class_;
437 const jmethodID j_video_track_ctor_; 501 const jmethodID j_video_track_ctor_;
438 const ScopedGlobalRef<jclass> j_data_channel_class_; 502 const ScopedGlobalRef<jclass> j_data_channel_class_;
439 const jmethodID j_data_channel_ctor_; 503 const jmethodID j_data_channel_ctor_;
504 const ScopedGlobalRef<jclass> j_rtp_receiver_class_;
505 const jmethodID j_rtp_receiver_ctor_;
440 // C++ -> Java remote streams. The stored jobects are global refs and must be 506 // C++ -> Java remote streams. The stored jobects are global refs and must be
441 // manually deleted upon removal. Use DisposeRemoteStream(). 507 // manually deleted upon removal. Use DisposeRemoteStream().
442 NativeToJavaStreamsMap remote_streams_; 508 NativeToJavaStreamsMap remote_streams_;
509 NativeToJavaRtpReceiverMap rtp_receivers_;
443 std::unique_ptr<ConstraintsWrapper> constraints_; 510 std::unique_ptr<ConstraintsWrapper> constraints_;
444 }; 511 };
445 512
446 // Wrapper for a Java MediaConstraints object. Copies all needed data so when 513 // Wrapper for a Java MediaConstraints object. Copies all needed data so when
447 // the constructor returns the Java object is no longer needed. 514 // the constructor returns the Java object is no longer needed.
448 class ConstraintsWrapper : public MediaConstraintsInterface { 515 class ConstraintsWrapper : public MediaConstraintsInterface {
449 public: 516 public:
450 ConstraintsWrapper(JNIEnv* jni, jobject j_constraints) { 517 ConstraintsWrapper(JNIEnv* jni, jobject j_constraints) {
451 PopulateConstraintsFromJavaPairList( 518 PopulateConstraintsFromJavaPairList(
452 jni, j_constraints, "mandatory", &mandatory_); 519 jni, j_constraints, "mandatory", &mandatory_);
(...skipping 1952 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 return JavaStringFromStdString( 2472 return JavaStringFromStdString(
2406 jni, 2473 jni,
2407 reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)->id()); 2474 reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)->id());
2408 } 2475 }
2409 2476
2410 JOW(void, RtpReceiver_free)(JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer) { 2477 JOW(void, RtpReceiver_free)(JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer) {
2411 reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)->Release(); 2478 reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)->Release();
2412 } 2479 }
2413 2480
2414 } // namespace webrtc_jni 2481 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698