1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/devtools_bridge/android/session_dependency_factory_android.h"
7 #include "base/android/jni_string.h"
8 #include "base/android/scoped_java_ref.h"
10 #include "components/devtools_bridge/abstract_data_channel.h"
11 #include "components/devtools_bridge/abstract_peer_connection.h"
12 #include "components/devtools_bridge/rtc_configuration.h"
13 #include "components/devtools_bridge/socket_tunnel_server.h"
14 #include "jni/SessionDependencyFactoryNative_jni.h"
16 using base::android::AttachCurrentThread
;
17 using base::android::ConvertJavaStringToUTF8
;
18 using base::android::ConvertUTF8ToJavaString
;
20 namespace devtools_bridge
{
26 * Wraps Java observer and adapts it to native delegate. Chromium code normally
27 * leaves local java references for automatic disposing. It doesn't happen here
28 * (because calls originated from native thread). For instance, instead of
30 * ConvertUTF8ToJavaString(env, ...).Release()
32 * please use ConvertUTF8ToJavaString(env, ...).obj() or ScopedJavaLocalFrame.
34 class PeerConnectionDelegateImpl
35 : public AbstractPeerConnection::Delegate
{
37 PeerConnectionDelegateImpl(JNIEnv
* env
, jobject java_object
) {
38 java_object_
.Reset(env
, java_object
);
42 void OnIceConnectionChange(bool connected
) override
{
43 JNIEnv
* env
= AttachCurrentThread();
44 Java_SessionDependencyFactoryNative_notifyIceConnectionChange(
45 env
, java_object_
.obj(), connected
);
48 void OnIceCandidate(const std::string
& sdp_mid
,
50 const std::string
& sdp
) override
{
51 JNIEnv
* env
= AttachCurrentThread();
52 Java_SessionDependencyFactoryNative_notifyIceCandidate(
53 env
, java_object_
.obj(),
54 ConvertUTF8ToJavaString(env
, sdp_mid
).obj(),
55 sdp_mline_index
, ConvertUTF8ToJavaString(env
, sdp
).obj());
58 void NotifyLocalOfferCreatedAndSetSet(const std::string
& description
) {
59 JNIEnv
* env
= AttachCurrentThread();
60 Java_SessionDependencyFactoryNative_notifyLocalOfferCreatedAndSetSet(
61 env
, java_object_
.obj(),
62 ConvertUTF8ToJavaString(env
, description
).obj());
65 void OnLocalOfferCreatedAndSetSet(const std::string
& description
) override
{
66 JNIEnv
* env
= AttachCurrentThread();
67 Java_SessionDependencyFactoryNative_notifyLocalOfferCreatedAndSetSet(
68 env
, java_object_
.obj(),
69 ConvertUTF8ToJavaString(env
, description
).obj());
72 void OnLocalAnswerCreatedAndSetSet(const std::string
& description
) override
{
73 JNIEnv
* env
= AttachCurrentThread();
74 Java_SessionDependencyFactoryNative_notifyLocalAnswerCreatedAndSetSet(
75 env
, java_object_
.obj(),
76 ConvertUTF8ToJavaString(env
, description
).obj());
79 void OnRemoteDescriptionSet() override
{
80 JNIEnv
* env
= AttachCurrentThread();
81 Java_SessionDependencyFactoryNative_notifyRemoteDescriptionSet(
82 env
, java_object_
.obj());
85 void OnFailure(const std::string
& description
) override
{
86 JNIEnv
* env
= AttachCurrentThread();
87 Java_SessionDependencyFactoryNative_notifyConnectionFailure(
88 env
, java_object_
.obj(),
89 ConvertUTF8ToJavaString(env
, description
).obj());
93 base::android::ScopedJavaGlobalRef
<jobject
> java_object_
;
97 class DataChannelObserverImpl
: public AbstractDataChannel::Observer
{
99 DataChannelObserverImpl(JNIEnv
* env
, jobject java_object
) {
100 java_object_
.Reset(env
, java_object
);
103 void OnOpen() override
{
104 JNIEnv
* env
= AttachCurrentThread();
105 Java_SessionDependencyFactoryNative_notifyChannelOpen(
106 env
, java_object_
.obj());
109 void OnClose() override
{
110 JNIEnv
* env
= AttachCurrentThread();
111 Java_SessionDependencyFactoryNative_notifyChannelClose(
112 env
, java_object_
.obj());
115 void OnMessage(const void* data
, size_t length
) override
{
116 JNIEnv
* env
= AttachCurrentThread();
118 ScopedJavaLocalRef
<jobject
> byte_buffer(
119 env
, env
->NewDirectByteBuffer(const_cast<void*>(data
), length
));
121 Java_SessionDependencyFactoryNative_notifyMessage(
122 env
, java_object_
.obj(), byte_buffer
.obj());
126 base::android::ScopedJavaGlobalRef
<jobject
> java_object_
;
129 static void CleanupOnSignalingThread() {
130 // Called on signaling thread when SessionDependencyFactory is destroying.
131 base::android::DetachFromVM();
136 // SessionDependencyFactoryNative
138 SessionDependencyFactoryAndroid::SessionDependencyFactoryAndroid()
139 : impl_(SessionDependencyFactory::CreateInstance(
140 base::Bind(&CleanupOnSignalingThread
))) {
143 SessionDependencyFactoryAndroid::~SessionDependencyFactoryAndroid() {
147 bool SessionDependencyFactoryAndroid::RegisterNatives(JNIEnv
* env
) {
148 return RegisterNativesImpl(env
);
151 scoped_ptr
<AbstractPeerConnection
>
152 SessionDependencyFactoryAndroid::CreatePeerConnection(
153 scoped_ptr
<RTCConfiguration
> config
,
154 scoped_ptr
<AbstractPeerConnection::Delegate
> delegate
) {
155 return impl_
->CreatePeerConnection(config
.Pass(), delegate
.Pass());
158 scoped_refptr
<base::TaskRunner
>
159 SessionDependencyFactoryAndroid::signaling_thread_task_runner() {
160 return impl_
->signaling_thread_task_runner();
163 scoped_refptr
<base::TaskRunner
>
164 SessionDependencyFactoryAndroid::io_thread_task_runner() {
165 return impl_
->io_thread_task_runner();
168 // JNI generated methods
170 static jlong
CreateFactory(JNIEnv
* env
, jclass jcaller
) {
171 return reinterpret_cast<jlong
>(new SessionDependencyFactoryAndroid());
174 static void DestroyFactory(JNIEnv
* env
, jclass jcaller
, jlong factory_ptr
) {
175 delete reinterpret_cast<SessionDependencyFactoryAndroid
*>(factory_ptr
);
178 static jlong
CreateConfig(JNIEnv
* env
, jclass jcaller
) {
179 return reinterpret_cast<jlong
>(
180 RTCConfiguration::CreateInstance().release());
183 static void AddIceServer(
184 JNIEnv
* env
, jclass jcaller
, jlong config_ptr
,
185 jstring uri
, jstring username
, jstring credential
) {
186 reinterpret_cast<RTCConfiguration
*>(config_ptr
)->AddIceServer(
187 ConvertJavaStringToUTF8(env
, uri
),
188 ConvertJavaStringToUTF8(env
, username
),
189 ConvertJavaStringToUTF8(env
, credential
));
192 static jlong
CreatePeerConnection(
193 JNIEnv
* env
, jclass jcaller
,
194 jlong factory_ptr
, jlong config_ptr
, jobject observer
) {
196 reinterpret_cast<SessionDependencyFactoryAndroid
*>(factory_ptr
);
197 auto config
= reinterpret_cast<RTCConfiguration
*>(config_ptr
);
199 auto delegate
= new PeerConnectionDelegateImpl(env
, observer
);
201 return reinterpret_cast<jlong
>(factory
->CreatePeerConnection(
202 make_scoped_ptr(config
), make_scoped_ptr(delegate
)).release());
205 static void DestroyPeerConnection(
206 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
) {
207 delete reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
);
210 static void CreateAndSetLocalOffer(
211 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
) {
212 reinterpret_cast<AbstractPeerConnection
*>(
213 connection_ptr
)->CreateAndSetLocalOffer();
216 static void CreateAndSetLocalAnswer(
217 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
) {
218 reinterpret_cast<AbstractPeerConnection
*>(
219 connection_ptr
)->CreateAndSetLocalAnswer();
222 static void SetRemoteOffer(
223 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
, jstring description
) {
224 reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
)->SetRemoteOffer(
225 ConvertJavaStringToUTF8(env
, description
));
228 static void SetRemoteAnswer(
229 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
, jstring description
) {
230 reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
)->SetRemoteAnswer(
231 ConvertJavaStringToUTF8(env
, description
));
234 static void AddIceCandidate(
235 JNIEnv
* env
, jclass jcaller
,
236 jlong connection_ptr
, jstring sdp_mid
, jint sdp_mline_index
, jstring sdp
) {
237 reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
)->AddIceCandidate(
238 ConvertJavaStringToUTF8(env
, sdp_mid
),
240 ConvertJavaStringToUTF8(env
, sdp
));
243 static jlong
CreateDataChannel(
244 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
, jint channel_id
) {
245 return reinterpret_cast<jlong
>(
246 reinterpret_cast<AbstractPeerConnection
*>(
247 connection_ptr
)->CreateDataChannel(channel_id
).release());
250 static void DestroyDataChannel(
251 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
) {
252 delete reinterpret_cast<AbstractDataChannel
*>(channel_ptr
);
255 static void RegisterDataChannelObserver(
256 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
, jobject observer
) {
257 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->RegisterObserver(
258 make_scoped_ptr(new DataChannelObserverImpl(env
, observer
)));
261 static void UnregisterDataChannelObserver(
262 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
) {
263 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->UnregisterObserver();
266 static void SendBinaryMessage(
267 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
, jobject message
,
270 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->SendBinaryMessage(
271 env
->GetDirectBufferAddress(message
), size
);
274 static void SendTextMessage(
275 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
, jobject message
,
278 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->SendTextMessage(
279 env
->GetDirectBufferAddress(message
), size
);
282 static void CloseDataChannel(JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
) {
283 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->Close();
286 static jlong
CreateSocketTunnelServer(
287 JNIEnv
* env
, jclass jcaller
, jlong factory_ptr
, jlong channel_ptr
,
288 jstring socket_name
) {
289 return reinterpret_cast<jlong
>(
290 new SocketTunnelServer(
291 reinterpret_cast<SessionDependencyFactory
*>(factory_ptr
),
292 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
),
293 ConvertJavaStringToUTF8(env
, socket_name
)));
296 static void DestroySocketTunnelServer(
297 JNIEnv
* env
, jclass jcaller
, jlong tunnel_ptr
) {
298 delete reinterpret_cast<SocketTunnelServer
*>(tunnel_ptr
);
301 } // namespace android
302 } // namespace devtools_bridge