jni_client.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // Copyright 2016 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.
  4. #include "remoting/client/jni/jni_client.h"
  5. #include <memory>
  6. #include "base/android/jni_android.h"
  7. #include "base/android/jni_string.h"
  8. #include "base/check_op.h"
  9. #include "remoting/android/jni_headers/Client_jni.h"
  10. #include "remoting/client/audio/audio_player_android.h"
  11. #include "remoting/client/chromoting_client_runtime.h"
  12. #include "remoting/client/chromoting_session.h"
  13. #include "remoting/client/connect_to_host_info.h"
  14. #include "remoting/client/jni/jni_gl_display_handler.h"
  15. #include "remoting/client/jni/jni_runtime_delegate.h"
  16. #include "remoting/client/jni/jni_touch_event_data.h"
  17. #include "remoting/protocol/video_renderer.h"
  18. using base::android::ConvertJavaStringToUTF8;
  19. using base::android::ConvertUTF8ToJavaString;
  20. using base::android::JavaObjectArrayReader;
  21. using base::android::JavaParamRef;
  22. using base::android::ScopedJavaLocalRef;
  23. namespace remoting {
  24. JniClient::JniClient(base::android::ScopedJavaGlobalRef<jobject> java_client)
  25. : java_client_(java_client) {
  26. runtime_ = ChromotingClientRuntime::GetInstance();
  27. weak_ptr_ = weak_factory_.GetWeakPtr();
  28. }
  29. JniClient::~JniClient() {
  30. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  31. // The session must be shut down first, since it depends on our other
  32. // components' still being alive.
  33. DisconnectFromHost();
  34. }
  35. void JniClient::ConnectToHost(const ConnectToHostInfo& info) {
  36. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  37. DCHECK(!display_handler_);
  38. DCHECK(!session_);
  39. host_id_ = info.host_id;
  40. display_handler_ = std::make_unique<JniGlDisplayHandler>(java_client_);
  41. session_ = std::make_unique<ChromotingSession>(
  42. weak_ptr_, display_handler_->CreateCursorShapeStub(),
  43. display_handler_->CreateVideoRenderer(),
  44. std::make_unique<AudioPlayerAndroid>(), info);
  45. }
  46. void JniClient::DisconnectFromHost() {
  47. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  48. session_.reset();
  49. display_handler_.reset();
  50. }
  51. void JniClient::OnConnectionState(protocol::ConnectionToHost::State state,
  52. protocol::ErrorCode error) {
  53. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  54. JNIEnv* env = base::android::AttachCurrentThread();
  55. Java_Client_onConnectionState(env, java_client_, state, error);
  56. }
  57. void JniClient::DisplayAuthenticationPrompt(bool pairing_supported) {
  58. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  59. JNIEnv* env = base::android::AttachCurrentThread();
  60. Java_Client_displayAuthenticationPrompt(env, java_client_, pairing_supported);
  61. }
  62. void JniClient::CommitPairingCredentials(const std::string& host,
  63. const std::string& id,
  64. const std::string& secret) {
  65. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  66. JNIEnv* env = base::android::AttachCurrentThread();
  67. ScopedJavaLocalRef<jstring> j_host = ConvertUTF8ToJavaString(env, host);
  68. ScopedJavaLocalRef<jstring> j_id = ConvertUTF8ToJavaString(env, id);
  69. ScopedJavaLocalRef<jstring> j_secret = ConvertUTF8ToJavaString(env, secret);
  70. Java_Client_commitPairingCredentials(env, java_client_, j_host, j_id,
  71. j_secret);
  72. }
  73. void JniClient::FetchSecret(
  74. bool pairing_supported,
  75. const protocol::SecretFetchedCallback& secret_fetched_callback) {
  76. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  77. DCHECK(!secret_fetched_callback_);
  78. secret_fetched_callback_ = secret_fetched_callback;
  79. // Delete pairing credentials if they exist.
  80. CommitPairingCredentials(host_id_, std::string(), std::string());
  81. DisplayAuthenticationPrompt(pairing_supported);
  82. }
  83. void JniClient::FetchThirdPartyToken(
  84. const std::string& token_url,
  85. const std::string& client_id,
  86. const std::string& scopes,
  87. const protocol::ThirdPartyTokenFetchedCallback& callback) {
  88. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  89. DCHECK(!third_party_token_fetched_callback_);
  90. third_party_token_fetched_callback_ = callback;
  91. JNIEnv* env = base::android::AttachCurrentThread();
  92. ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, token_url);
  93. ScopedJavaLocalRef<jstring> j_client_id =
  94. ConvertUTF8ToJavaString(env, client_id);
  95. ScopedJavaLocalRef<jstring> j_scopes = ConvertUTF8ToJavaString(env, scopes);
  96. Java_Client_fetchThirdPartyToken(env, java_client_, j_url, j_client_id,
  97. j_scopes);
  98. }
  99. void JniClient::SetCapabilities(const std::string& capabilities) {
  100. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  101. JNIEnv* env = base::android::AttachCurrentThread();
  102. ScopedJavaLocalRef<jstring> j_cap =
  103. ConvertUTF8ToJavaString(env, capabilities);
  104. Java_Client_setCapabilities(env, java_client_, j_cap);
  105. }
  106. void JniClient::HandleExtensionMessage(const std::string& type,
  107. const std::string& message) {
  108. DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
  109. JNIEnv* env = base::android::AttachCurrentThread();
  110. ScopedJavaLocalRef<jstring> j_type = ConvertUTF8ToJavaString(env, type);
  111. ScopedJavaLocalRef<jstring> j_message = ConvertUTF8ToJavaString(env, message);
  112. Java_Client_handleExtensionMessage(env, java_client_, j_type, j_message);
  113. }
  114. void JniClient::Connect(
  115. JNIEnv* env,
  116. const base::android::JavaParamRef<jobject>& caller,
  117. const base::android::JavaParamRef<jstring>& username,
  118. const base::android::JavaParamRef<jstring>& auth_token,
  119. const base::android::JavaParamRef<jstring>& host_jid,
  120. const base::android::JavaParamRef<jstring>& host_ftl_id,
  121. const base::android::JavaParamRef<jstring>& host_id,
  122. const base::android::JavaParamRef<jstring>& host_pubkey,
  123. const base::android::JavaParamRef<jstring>& pair_id,
  124. const base::android::JavaParamRef<jstring>& pair_secret,
  125. const base::android::JavaParamRef<jstring>& capabilities,
  126. const base::android::JavaParamRef<jstring>& flags,
  127. const base::android::JavaParamRef<jstring>& host_version,
  128. const base::android::JavaParamRef<jstring>& host_os,
  129. const base::android::JavaParamRef<jstring>& host_os_version) {
  130. ConnectToHostInfo info;
  131. info.username = ConvertJavaStringToUTF8(env, username);
  132. info.auth_token = ConvertJavaStringToUTF8(env, auth_token);
  133. info.host_jid = ConvertJavaStringToUTF8(env, host_jid);
  134. info.host_ftl_id = ConvertJavaStringToUTF8(env, host_ftl_id);
  135. info.host_id = ConvertJavaStringToUTF8(env, host_id);
  136. info.host_pubkey = ConvertJavaStringToUTF8(env, host_pubkey);
  137. info.pairing_id = ConvertJavaStringToUTF8(env, pair_id);
  138. info.pairing_secret = ConvertJavaStringToUTF8(env, pair_secret);
  139. info.capabilities = ConvertJavaStringToUTF8(env, capabilities);
  140. info.flags = ConvertJavaStringToUTF8(env, flags);
  141. info.host_version = ConvertJavaStringToUTF8(env, host_version);
  142. info.host_os = ConvertJavaStringToUTF8(env, host_os);
  143. info.host_os_version = ConvertJavaStringToUTF8(env, host_os_version);
  144. ConnectToHost(info);
  145. }
  146. void JniClient::Disconnect(JNIEnv* env,
  147. const base::android::JavaParamRef<jobject>& caller) {
  148. DisconnectFromHost();
  149. }
  150. void JniClient::AuthenticationResponse(
  151. JNIEnv* env,
  152. const JavaParamRef<jobject>& caller,
  153. const JavaParamRef<jstring>& pin,
  154. jboolean createPair,
  155. const JavaParamRef<jstring>& deviceName) {
  156. if (session_ && createPair) {
  157. session_->RequestPairing(ConvertJavaStringToUTF8(env, deviceName));
  158. }
  159. if (secret_fetched_callback_) {
  160. std::move(secret_fetched_callback_).Run(ConvertJavaStringToUTF8(env, pin));
  161. }
  162. }
  163. void JniClient::SendMouseEvent(
  164. JNIEnv* env,
  165. const base::android::JavaParamRef<jobject>& caller,
  166. jint x,
  167. jint y,
  168. jint whichButton,
  169. jboolean buttonDown) {
  170. // Button must be within the bounds of the MouseEvent_MouseButton enum.
  171. DCHECK(whichButton >= 0 && whichButton < 5);
  172. session_->SendMouseEvent(
  173. x, y,
  174. static_cast<remoting::protocol::MouseEvent_MouseButton>(whichButton),
  175. buttonDown);
  176. }
  177. void JniClient::SendMouseWheelEvent(
  178. JNIEnv* env,
  179. const base::android::JavaParamRef<jobject>& caller,
  180. jint delta_x,
  181. jint delta_y) {
  182. session_->SendMouseWheelEvent(delta_x, delta_y);
  183. }
  184. jboolean JniClient::SendKeyEvent(
  185. JNIEnv* env,
  186. const base::android::JavaParamRef<jobject>& caller,
  187. jint scanCode,
  188. jint keyCode,
  189. jboolean keyDown) {
  190. return session_->SendKeyEvent(scanCode, keyCode, keyDown);
  191. }
  192. void JniClient::SendTextEvent(
  193. JNIEnv* env,
  194. const base::android::JavaParamRef<jobject>& caller,
  195. const JavaParamRef<jstring>& text) {
  196. session_->SendTextEvent(ConvertJavaStringToUTF8(env, text));
  197. }
  198. void JniClient::SendTouchEvent(
  199. JNIEnv* env,
  200. const base::android::JavaParamRef<jobject>& caller,
  201. jint eventType,
  202. const JavaParamRef<jobjectArray>& touchEventObjectArray) {
  203. protocol::TouchEvent touch_event;
  204. touch_event.set_event_type(
  205. static_cast<protocol::TouchEvent::TouchEventType>(eventType));
  206. // Iterate over the elements in the object array and transfer the data from
  207. // the java object to a native event object.
  208. JavaObjectArrayReader<jobject> java_touch_events(touchEventObjectArray);
  209. DCHECK_GE(java_touch_events.size(), 0);
  210. for (auto java_touch_event : java_touch_events) {
  211. protocol::TouchEventPoint* touch_point = touch_event.add_touch_points();
  212. JniTouchEventData::CopyTouchPointData(env, java_touch_event, touch_point);
  213. }
  214. session_->SendTouchEvent(touch_event);
  215. }
  216. void JniClient::EnableVideoChannel(
  217. JNIEnv* env,
  218. const base::android::JavaParamRef<jobject>& caller,
  219. jboolean enable) {
  220. session_->EnableVideoChannel(enable);
  221. }
  222. void JniClient::OnThirdPartyTokenFetched(
  223. JNIEnv* env,
  224. const base::android::JavaParamRef<jobject>& caller,
  225. const JavaParamRef<jstring>& token,
  226. const JavaParamRef<jstring>& shared_secret) {
  227. if (third_party_token_fetched_callback_) {
  228. std::move(third_party_token_fetched_callback_)
  229. .Run(ConvertJavaStringToUTF8(env, token),
  230. ConvertJavaStringToUTF8(env, shared_secret));
  231. }
  232. }
  233. void JniClient::SendExtensionMessage(
  234. JNIEnv* env,
  235. const base::android::JavaParamRef<jobject>& caller,
  236. const JavaParamRef<jstring>& type,
  237. const JavaParamRef<jstring>& data) {
  238. session_->SendClientMessage(ConvertJavaStringToUTF8(env, type),
  239. ConvertJavaStringToUTF8(env, data));
  240. }
  241. void JniClient::SendClientResolution(
  242. JNIEnv* env,
  243. const base::android::JavaParamRef<jobject>& caller,
  244. jint dips_width,
  245. jint dips_height,
  246. jfloat scale) {
  247. session_->SendClientResolution(dips_width, dips_height, scale);
  248. }
  249. void JniClient::Destroy(JNIEnv* env, const JavaParamRef<jobject>& caller) {
  250. delete this;
  251. }
  252. base::WeakPtr<JniClient> JniClient::GetWeakPtr() {
  253. return weak_ptr_;
  254. }
  255. static jlong JNI_Client_Init(JNIEnv* env, const JavaParamRef<jobject>& caller) {
  256. return reinterpret_cast<intptr_t>(
  257. new JniClient(base::android::ScopedJavaGlobalRef<jobject>(env, caller)));
  258. }
  259. } // namespace remoting