android_call_client.cc (10717B)
1 /* 2 * Copyright 2018 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 "examples/androidnativeapi/jni/android_call_client.h" 12 13 #include <jni.h> 14 15 #include <memory> 16 #include <string> 17 #include <utility> 18 19 #include "api/create_modular_peer_connection_factory.h" 20 #include "api/data_channel_interface.h" 21 #include "api/enable_media_with_defaults.h" 22 #include "api/jsep.h" 23 #include "api/make_ref_counted.h" 24 #include "api/media_stream_interface.h" 25 #include "api/peer_connection_interface.h" 26 #include "api/rtc_error.h" 27 #include "api/rtc_event_log/rtc_event_log_factory.h" 28 #include "api/rtp_transceiver_interface.h" 29 #include "api/scoped_refptr.h" 30 #include "api/sequence_checker.h" 31 #include "api/set_remote_description_observer_interface.h" 32 #include "api/video/video_source_interface.h" 33 #include "examples/androidnativeapi/generated_jni/CallClient_jni.h" 34 #include "media/engine/internal_decoder_factory.h" 35 #include "media/engine/internal_encoder_factory.h" 36 #include "rtc_base/checks.h" 37 #include "rtc_base/logging.h" 38 #include "rtc_base/synchronization/mutex.h" 39 #include "rtc_base/thread.h" 40 #include "sdk/android/native_api/jni/java_types.h" 41 #include "sdk/android/native_api/jni/scoped_java_ref.h" 42 #include "sdk/android/native_api/video/video_source.h" 43 #include "sdk/android/native_api/video/wrapper.h" 44 45 namespace webrtc_examples { 46 47 class AndroidCallClient::PCObserver : public webrtc::PeerConnectionObserver { 48 public: 49 explicit PCObserver(AndroidCallClient* client); 50 51 void OnSignalingChange( 52 webrtc::PeerConnectionInterface::SignalingState new_state) override; 53 void OnDataChannel(webrtc::scoped_refptr<webrtc::DataChannelInterface> 54 data_channel) override; 55 void OnRenegotiationNeeded() override; 56 void OnIceConnectionChange( 57 webrtc::PeerConnectionInterface::IceConnectionState new_state) override; 58 void OnIceGatheringChange( 59 webrtc::PeerConnectionInterface::IceGatheringState new_state) override; 60 void OnIceCandidate(const webrtc::IceCandidate* candidate) override; 61 62 private: 63 AndroidCallClient* const client_; 64 }; 65 66 namespace { 67 68 class CreateOfferObserver : public webrtc::CreateSessionDescriptionObserver { 69 public: 70 explicit CreateOfferObserver( 71 webrtc::scoped_refptr<webrtc::PeerConnectionInterface> pc); 72 73 void OnSuccess(webrtc::SessionDescriptionInterface* desc) override; 74 void OnFailure(webrtc::RTCError error) override; 75 76 private: 77 const webrtc::scoped_refptr<webrtc::PeerConnectionInterface> pc_; 78 }; 79 80 class SetRemoteSessionDescriptionObserver 81 : public webrtc::SetRemoteDescriptionObserverInterface { 82 public: 83 void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override; 84 }; 85 86 class SetLocalSessionDescriptionObserver 87 : public webrtc::SetSessionDescriptionObserver { 88 public: 89 void OnSuccess() override; 90 void OnFailure(webrtc::RTCError error) override; 91 }; 92 93 } // namespace 94 95 AndroidCallClient::AndroidCallClient() 96 : call_started_(false), pc_observer_(std::make_unique<PCObserver>(this)) { 97 thread_checker_.Detach(); 98 CreatePeerConnectionFactory(); 99 } 100 101 AndroidCallClient::~AndroidCallClient() = default; 102 103 void AndroidCallClient::Call(JNIEnv* env, 104 const webrtc::JavaRef<jobject>& local_sink, 105 const webrtc::JavaRef<jobject>& remote_sink) { 106 RTC_DCHECK_RUN_ON(&thread_checker_); 107 108 webrtc::MutexLock lock(&pc_mutex_); 109 if (call_started_) { 110 RTC_LOG(LS_WARNING) << "Call already started."; 111 return; 112 } 113 call_started_ = true; 114 115 local_sink_ = webrtc::JavaToNativeVideoSink(env, local_sink.obj()); 116 remote_sink_ = webrtc::JavaToNativeVideoSink(env, remote_sink.obj()); 117 118 video_source_ = webrtc::CreateJavaVideoSource(env, signaling_thread_.get(), 119 /* is_screencast= */ false, 120 /* align_timestamps= */ true); 121 122 CreatePeerConnection(); 123 Connect(); 124 } 125 126 void AndroidCallClient::Hangup(JNIEnv* env) { 127 RTC_DCHECK_RUN_ON(&thread_checker_); 128 129 call_started_ = false; 130 131 { 132 webrtc::MutexLock lock(&pc_mutex_); 133 if (pc_ != nullptr) { 134 pc_->Close(); 135 pc_ = nullptr; 136 } 137 } 138 139 local_sink_ = nullptr; 140 remote_sink_ = nullptr; 141 video_source_ = nullptr; 142 } 143 144 void AndroidCallClient::Delete(JNIEnv* env) { 145 RTC_DCHECK_RUN_ON(&thread_checker_); 146 147 delete this; 148 } 149 150 webrtc::ScopedJavaLocalRef<jobject> 151 AndroidCallClient::GetJavaVideoCapturerObserver(JNIEnv* env) { 152 RTC_DCHECK_RUN_ON(&thread_checker_); 153 154 return video_source_->GetJavaVideoCapturerObserver(env); 155 } 156 157 void AndroidCallClient::CreatePeerConnectionFactory() { 158 network_thread_ = webrtc::Thread::CreateWithSocketServer(); 159 network_thread_->SetName("network_thread", nullptr); 160 RTC_CHECK(network_thread_->Start()) << "Failed to start thread"; 161 162 worker_thread_ = webrtc::Thread::Create(); 163 worker_thread_->SetName("worker_thread", nullptr); 164 RTC_CHECK(worker_thread_->Start()) << "Failed to start thread"; 165 166 signaling_thread_ = webrtc::Thread::Create(); 167 signaling_thread_->SetName("signaling_thread", nullptr); 168 RTC_CHECK(signaling_thread_->Start()) << "Failed to start thread"; 169 170 webrtc::PeerConnectionFactoryDependencies pcf_deps; 171 pcf_deps.network_thread = network_thread_.get(); 172 pcf_deps.worker_thread = worker_thread_.get(); 173 pcf_deps.signaling_thread = signaling_thread_.get(); 174 pcf_deps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>(); 175 176 pcf_deps.video_encoder_factory = 177 std::make_unique<webrtc::InternalEncoderFactory>(); 178 pcf_deps.video_decoder_factory = 179 std::make_unique<webrtc::InternalDecoderFactory>(); 180 EnableMediaWithDefaults(pcf_deps); 181 182 pcf_ = CreateModularPeerConnectionFactory(std::move(pcf_deps)); 183 RTC_LOG(LS_INFO) << "PeerConnectionFactory created: " << pcf_.get(); 184 } 185 186 void AndroidCallClient::CreatePeerConnection() { 187 webrtc::MutexLock lock(&pc_mutex_); 188 webrtc::PeerConnectionInterface::RTCConfiguration config; 189 config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; 190 // Encryption has to be disabled for loopback to work. 191 webrtc::PeerConnectionFactoryInterface::Options options; 192 options.disable_encryption = true; 193 pcf_->SetOptions(options); 194 webrtc::PeerConnectionDependencies deps(pc_observer_.get()); 195 pc_ = pcf_->CreatePeerConnectionOrError(config, std::move(deps)).MoveValue(); 196 197 RTC_LOG(LS_INFO) << "PeerConnection created: " << pc_.get(); 198 199 webrtc::scoped_refptr<webrtc::VideoTrackInterface> local_video_track = 200 pcf_->CreateVideoTrack(video_source_, "video"); 201 local_video_track->AddOrUpdateSink(local_sink_.get(), 202 webrtc::VideoSinkWants()); 203 pc_->AddTransceiver(local_video_track); 204 RTC_LOG(LS_INFO) << "Local video sink set up: " << local_video_track.get(); 205 206 for (const webrtc::scoped_refptr<webrtc::RtpTransceiverInterface>& 207 tranceiver : pc_->GetTransceivers()) { 208 webrtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track = 209 tranceiver->receiver()->track(); 210 if (track && 211 track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { 212 static_cast<webrtc::VideoTrackInterface*>(track.get()) 213 ->AddOrUpdateSink(remote_sink_.get(), webrtc::VideoSinkWants()); 214 RTC_LOG(LS_INFO) << "Remote video sink set up: " << track.get(); 215 break; 216 } 217 } 218 } 219 220 void AndroidCallClient::Connect() { 221 webrtc::MutexLock lock(&pc_mutex_); 222 pc_->CreateOffer(webrtc::make_ref_counted<CreateOfferObserver>(pc_).get(), 223 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); 224 } 225 226 AndroidCallClient::PCObserver::PCObserver(AndroidCallClient* client) 227 : client_(client) {} 228 229 void AndroidCallClient::PCObserver::OnSignalingChange( 230 webrtc::PeerConnectionInterface::SignalingState new_state) { 231 RTC_LOG(LS_INFO) << "OnSignalingChange: " << new_state; 232 } 233 234 void AndroidCallClient::PCObserver::OnDataChannel( 235 webrtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) { 236 RTC_LOG(LS_INFO) << "OnDataChannel"; 237 } 238 239 void AndroidCallClient::PCObserver::OnRenegotiationNeeded() { 240 RTC_LOG(LS_INFO) << "OnRenegotiationNeeded"; 241 } 242 243 void AndroidCallClient::PCObserver::OnIceConnectionChange( 244 webrtc::PeerConnectionInterface::IceConnectionState new_state) { 245 RTC_LOG(LS_INFO) << "OnIceConnectionChange: " << new_state; 246 } 247 248 void AndroidCallClient::PCObserver::OnIceGatheringChange( 249 webrtc::PeerConnectionInterface::IceGatheringState new_state) { 250 RTC_LOG(LS_INFO) << "OnIceGatheringChange: " << new_state; 251 } 252 253 void AndroidCallClient::PCObserver::OnIceCandidate( 254 const webrtc::IceCandidate* candidate) { 255 RTC_LOG(LS_INFO) << "OnIceCandidate: " << candidate->server_url(); 256 webrtc::MutexLock lock(&client_->pc_mutex_); 257 RTC_DCHECK(client_->pc_ != nullptr); 258 client_->pc_->AddIceCandidate(candidate); 259 } 260 261 CreateOfferObserver::CreateOfferObserver( 262 webrtc::scoped_refptr<webrtc::PeerConnectionInterface> pc) 263 : pc_(pc) {} 264 265 void CreateOfferObserver::OnSuccess(webrtc::SessionDescriptionInterface* desc) { 266 std::string sdp; 267 desc->ToString(&sdp); 268 RTC_LOG(LS_INFO) << "Created offer: " << sdp; 269 270 // Ownership of desc was transferred to us, now we transfer it forward. 271 pc_->SetLocalDescription( 272 webrtc::make_ref_counted<SetLocalSessionDescriptionObserver>().get(), 273 desc); 274 275 // Generate a fake answer. 276 std::unique_ptr<webrtc::SessionDescriptionInterface> answer( 277 webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp)); 278 pc_->SetRemoteDescription( 279 std::move(answer), 280 webrtc::make_ref_counted<SetRemoteSessionDescriptionObserver>()); 281 } 282 283 void CreateOfferObserver::OnFailure(webrtc::RTCError error) { 284 RTC_LOG(LS_INFO) << "Failed to create offer: " << ToString(error.type()) 285 << ": " << error.message(); 286 } 287 288 void SetRemoteSessionDescriptionObserver::OnSetRemoteDescriptionComplete( 289 webrtc::RTCError error) { 290 RTC_LOG(LS_INFO) << "Set remote description: " << error.message(); 291 } 292 293 void SetLocalSessionDescriptionObserver::OnSuccess() { 294 RTC_LOG(LS_INFO) << "Set local description success!"; 295 } 296 297 void SetLocalSessionDescriptionObserver::OnFailure(webrtc::RTCError error) { 298 RTC_LOG(LS_INFO) << "Set local description failure: " 299 << ToString(error.type()) << ": " << error.message(); 300 } 301 302 static jlong JNI_CallClient_CreateClient(JNIEnv* env) { 303 return webrtc::NativeToJavaPointer(new webrtc_examples::AndroidCallClient()); 304 } 305 306 } // namespace webrtc_examples