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 virtual void OnIceConnectionChange(bool connected
) override
{
43 JNIEnv
* env
= AttachCurrentThread();
44 Java_SessionDependencyFactoryNative_notifyIceConnectionChange(
45 env
, java_object_
.obj(), connected
);
48 virtual void OnIceCandidate(
49 const std::string
& sdp_mid
, int sdp_mline_index
, const std::string
& sdp
)
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 virtual void OnLocalOfferCreatedAndSetSet(const std::string
& description
)
67 JNIEnv
* env
= AttachCurrentThread();
68 Java_SessionDependencyFactoryNative_notifyLocalOfferCreatedAndSetSet(
69 env
, java_object_
.obj(),
70 ConvertUTF8ToJavaString(env
, description
).obj());
73 virtual void OnLocalAnswerCreatedAndSetSet(const std::string
& description
)
75 JNIEnv
* env
= AttachCurrentThread();
76 Java_SessionDependencyFactoryNative_notifyLocalAnswerCreatedAndSetSet(
77 env
, java_object_
.obj(),
78 ConvertUTF8ToJavaString(env
, description
).obj());
81 virtual void OnRemoteDescriptionSet() override
{
82 JNIEnv
* env
= AttachCurrentThread();
83 Java_SessionDependencyFactoryNative_notifyRemoteDescriptionSet(
84 env
, java_object_
.obj());
87 virtual void OnFailure(const std::string
& description
) override
{
88 JNIEnv
* env
= AttachCurrentThread();
89 Java_SessionDependencyFactoryNative_notifyConnectionFailure(
90 env
, java_object_
.obj(),
91 ConvertUTF8ToJavaString(env
, description
).obj());
95 base::android::ScopedJavaGlobalRef
<jobject
> java_object_
;
99 class DataChannelObserverImpl
: public AbstractDataChannel::Observer
{
101 DataChannelObserverImpl(JNIEnv
* env
, jobject java_object
) {
102 java_object_
.Reset(env
, java_object
);
105 virtual void OnOpen() override
{
106 JNIEnv
* env
= AttachCurrentThread();
107 Java_SessionDependencyFactoryNative_notifyChannelOpen(
108 env
, java_object_
.obj());
111 virtual void OnClose() override
{
112 JNIEnv
* env
= AttachCurrentThread();
113 Java_SessionDependencyFactoryNative_notifyChannelClose(
114 env
, java_object_
.obj());
117 virtual void OnMessage(const void* data
, size_t length
) override
{
118 JNIEnv
* env
= AttachCurrentThread();
120 ScopedJavaLocalRef
<jobject
> byte_buffer(
121 env
, env
->NewDirectByteBuffer(const_cast<void*>(data
), length
));
123 Java_SessionDependencyFactoryNative_notifyMessage(
124 env
, java_object_
.obj(), byte_buffer
.obj());
128 base::android::ScopedJavaGlobalRef
<jobject
> java_object_
;
131 static void CleanupOnSignalingThread() {
132 // Called on signaling thread when SessionDependencyFactory is destroying.
133 base::android::DetachFromVM();
138 // SessionDependencyFactoryNative
140 SessionDependencyFactoryAndroid::SessionDependencyFactoryAndroid()
141 : impl_(SessionDependencyFactory::CreateInstance(
142 base::Bind(&CleanupOnSignalingThread
))) {
145 SessionDependencyFactoryAndroid::~SessionDependencyFactoryAndroid() {
149 bool SessionDependencyFactoryAndroid::RegisterNatives(JNIEnv
* env
) {
150 return RegisterNativesImpl(env
);
153 scoped_ptr
<AbstractPeerConnection
>
154 SessionDependencyFactoryAndroid::CreatePeerConnection(
155 scoped_ptr
<RTCConfiguration
> config
,
156 scoped_ptr
<AbstractPeerConnection::Delegate
> delegate
) {
157 return impl_
->CreatePeerConnection(config
.Pass(), delegate
.Pass());
160 scoped_refptr
<base::TaskRunner
>
161 SessionDependencyFactoryAndroid::signaling_thread_task_runner() {
162 return impl_
->signaling_thread_task_runner();
165 scoped_refptr
<base::TaskRunner
>
166 SessionDependencyFactoryAndroid::io_thread_task_runner() {
167 return impl_
->io_thread_task_runner();
170 // JNI generated methods
172 static jlong
CreateFactory(JNIEnv
* env
, jclass jcaller
) {
173 return reinterpret_cast<jlong
>(new SessionDependencyFactoryAndroid());
176 static void DestroyFactory(JNIEnv
* env
, jclass jcaller
, jlong factory_ptr
) {
177 delete reinterpret_cast<SessionDependencyFactoryAndroid
*>(factory_ptr
);
180 static jlong
CreateConfig(JNIEnv
* env
, jclass jcaller
) {
181 return reinterpret_cast<jlong
>(
182 RTCConfiguration::CreateInstance().release());
185 static void AddIceServer(
186 JNIEnv
* env
, jclass jcaller
, jlong config_ptr
,
187 jstring uri
, jstring username
, jstring credential
) {
188 reinterpret_cast<RTCConfiguration
*>(config_ptr
)->AddIceServer(
189 ConvertJavaStringToUTF8(env
, uri
),
190 ConvertJavaStringToUTF8(env
, username
),
191 ConvertJavaStringToUTF8(env
, credential
));
194 static jlong
CreatePeerConnection(
195 JNIEnv
* env
, jclass jcaller
,
196 jlong factory_ptr
, jlong config_ptr
, jobject observer
) {
198 reinterpret_cast<SessionDependencyFactoryAndroid
*>(factory_ptr
);
199 auto config
= reinterpret_cast<RTCConfiguration
*>(config_ptr
);
201 auto delegate
= new PeerConnectionDelegateImpl(env
, observer
);
203 return reinterpret_cast<jlong
>(factory
->CreatePeerConnection(
204 make_scoped_ptr(config
), make_scoped_ptr(delegate
)).release());
207 static void DestroyPeerConnection(
208 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
) {
209 delete reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
);
212 static void CreateAndSetLocalOffer(
213 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
) {
214 reinterpret_cast<AbstractPeerConnection
*>(
215 connection_ptr
)->CreateAndSetLocalOffer();
218 static void CreateAndSetLocalAnswer(
219 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
) {
220 reinterpret_cast<AbstractPeerConnection
*>(
221 connection_ptr
)->CreateAndSetLocalAnswer();
224 static void SetRemoteOffer(
225 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
, jstring description
) {
226 reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
)->SetRemoteOffer(
227 ConvertJavaStringToUTF8(env
, description
));
230 static void SetRemoteAnswer(
231 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
, jstring description
) {
232 reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
)->SetRemoteAnswer(
233 ConvertJavaStringToUTF8(env
, description
));
236 static void AddIceCandidate(
237 JNIEnv
* env
, jclass jcaller
,
238 jlong connection_ptr
, jstring sdp_mid
, jint sdp_mline_index
, jstring sdp
) {
239 reinterpret_cast<AbstractPeerConnection
*>(connection_ptr
)->AddIceCandidate(
240 ConvertJavaStringToUTF8(env
, sdp_mid
),
242 ConvertJavaStringToUTF8(env
, sdp
));
245 static jlong
CreateDataChannel(
246 JNIEnv
* env
, jclass jcaller
, jlong connection_ptr
, jint channel_id
) {
247 return reinterpret_cast<jlong
>(
248 reinterpret_cast<AbstractPeerConnection
*>(
249 connection_ptr
)->CreateDataChannel(channel_id
).release());
252 static void DestroyDataChannel(
253 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
) {
254 delete reinterpret_cast<AbstractDataChannel
*>(channel_ptr
);
257 static void RegisterDataChannelObserver(
258 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
, jobject observer
) {
259 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->RegisterObserver(
260 make_scoped_ptr(new DataChannelObserverImpl(env
, observer
)));
263 static void UnregisterDataChannelObserver(
264 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
) {
265 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->UnregisterObserver();
268 static void SendBinaryMessage(
269 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
, jobject message
,
272 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->SendBinaryMessage(
273 env
->GetDirectBufferAddress(message
), size
);
276 static void SendTextMessage(
277 JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
, jobject message
,
280 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->SendTextMessage(
281 env
->GetDirectBufferAddress(message
), size
);
284 static void CloseDataChannel(JNIEnv
* env
, jclass jcaller
, jlong channel_ptr
) {
285 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
)->Close();
288 static jlong
CreateSocketTunnelServer(
289 JNIEnv
* env
, jclass jcaller
, jlong factory_ptr
, jlong channel_ptr
,
290 jstring socket_name
) {
291 return reinterpret_cast<jlong
>(
292 new SocketTunnelServer(
293 reinterpret_cast<SessionDependencyFactory
*>(factory_ptr
),
294 reinterpret_cast<AbstractDataChannel
*>(channel_ptr
),
295 ConvertJavaStringToUTF8(env
, socket_name
)));
298 static void DestroySocketTunnelServer(
299 JNIEnv
* env
, jclass jcaller
, jlong tunnel_ptr
) {
300 delete reinterpret_cast<SocketTunnelServer
*>(tunnel_ptr
);
303 } // namespace android
304 } // namespace devtools_bridge