Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/client/jni/chromoting_jni_runtime.h" | 5 #include "remoting/client/jni/chromoting_jni_runtime.h" |
| 6 | 6 |
| 7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
| 8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
| 9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
| 10 #include "base/android/scoped_java_ref.h" | 10 #include "base/android/scoped_java_ref.h" |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
| 16 #include "google_apis/google_api_keys.h" | 16 #include "google_apis/google_api_keys.h" |
| 17 #include "jni/JniInterface_jni.h" | 17 #include "jni/JniInterface_jni.h" |
| 18 #include "media/base/yuv_convert.h" | 18 #include "media/base/yuv_convert.h" |
| 19 #include "remoting/base/url_request_context_getter.h" | 19 #include "remoting/base/url_request_context_getter.h" |
| 20 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 20 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 21 | 21 |
| 22 using base::android::ConvertJavaStringToUTF8; | 22 using base::android::ConvertJavaStringToUTF8; |
| 23 using base::android::ConvertUTF8ToJavaString; | 23 using base::android::ConvertUTF8ToJavaString; |
| 24 using base::android::ToJavaByteArray; | 24 using base::android::ToJavaByteArray; |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 const int kBytesPerPixel = 4; | 28 const int kBytesPerPixel = 4; |
| 29 | 29 |
| 30 remoting::ChromotingJniInstance* GetSession() { | |
|
Sergey Ulanov
2014/07/24 02:47:02
nit: Move this inside the remoting namespace below
Lambros
2014/07/26 00:42:35
Removed.
| |
| 31 return remoting::ChromotingJniRuntime::GetInstance()->session(); | |
| 32 } | |
| 33 | |
| 30 } // namespace | 34 } // namespace |
| 31 | 35 |
| 32 namespace remoting { | 36 namespace remoting { |
| 33 | 37 |
| 34 bool RegisterJni(JNIEnv* env) { | 38 bool RegisterJni(JNIEnv* env) { |
| 35 return remoting::RegisterNativesImpl(env); | 39 return remoting::RegisterNativesImpl(env); |
| 36 } | 40 } |
| 37 | 41 |
| 38 // Implementation of stubs defined in JniInterface_jni.h. These are the entry | 42 // Implementation of stubs defined in JniInterface_jni.h. These are the entry |
| 39 // points for JNI calls from Java into C++. | 43 // points for JNI calls from Java into C++. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 | 94 |
| 91 static void Disconnect(JNIEnv* env, jclass clazz) { | 95 static void Disconnect(JNIEnv* env, jclass clazz) { |
| 92 remoting::ChromotingJniRuntime::GetInstance()->DisconnectFromHost(); | 96 remoting::ChromotingJniRuntime::GetInstance()->DisconnectFromHost(); |
| 93 } | 97 } |
| 94 | 98 |
| 95 static void AuthenticationResponse(JNIEnv* env, | 99 static void AuthenticationResponse(JNIEnv* env, |
| 96 jclass clazz, | 100 jclass clazz, |
| 97 jstring pin, | 101 jstring pin, |
| 98 jboolean createPair, | 102 jboolean createPair, |
| 99 jstring deviceName) { | 103 jstring deviceName) { |
| 100 remoting::ChromotingJniRuntime::GetInstance()->session()->ProvideSecret( | 104 if (GetSession()) { |
|
Sergey Ulanov
2014/07/24 02:47:02
I think it's better to check that the session in J
Lambros
2014/07/26 00:42:35
Done.
| |
| 101 ConvertJavaStringToUTF8(env, pin).c_str(), createPair, | 105 GetSession()->ProvideSecret( |
| 102 ConvertJavaStringToUTF8(env, deviceName)); | 106 ConvertJavaStringToUTF8(env, pin).c_str(), createPair, |
| 107 ConvertJavaStringToUTF8(env, deviceName)); | |
| 108 } | |
| 103 } | 109 } |
| 104 | 110 |
| 105 static void ScheduleRedraw(JNIEnv* env, jclass clazz) { | 111 static void ScheduleRedraw(JNIEnv* env, jclass clazz) { |
| 106 remoting::ChromotingJniRuntime::GetInstance()->session()->RedrawDesktop(); | 112 if (GetSession()) { |
| 113 GetSession()->RedrawDesktop(); | |
| 114 } | |
| 107 } | 115 } |
| 108 | 116 |
| 109 static void SendMouseEvent(JNIEnv* env, | 117 static void SendMouseEvent(JNIEnv* env, |
| 110 jclass clazz, | 118 jclass clazz, |
| 111 jint x, | 119 jint x, |
| 112 jint y, | 120 jint y, |
| 113 jint whichButton, | 121 jint whichButton, |
| 114 jboolean buttonDown) { | 122 jboolean buttonDown) { |
| 115 // Button must be within the bounds of the MouseEvent_MouseButton enum. | 123 // Button must be within the bounds of the MouseEvent_MouseButton enum. |
| 116 DCHECK(whichButton >= 0 && whichButton < 5); | 124 DCHECK(whichButton >= 0 && whichButton < 5); |
| 117 | 125 |
| 118 remoting::ChromotingJniRuntime::GetInstance()->session()->SendMouseEvent( | 126 if (GetSession()) { |
| 119 x, y, | 127 GetSession()->SendMouseEvent( |
| 120 static_cast<remoting::protocol::MouseEvent_MouseButton>(whichButton), | 128 x, y, |
| 121 buttonDown); | 129 static_cast<remoting::protocol::MouseEvent_MouseButton>(whichButton), |
| 130 buttonDown); | |
| 131 } | |
| 122 } | 132 } |
| 123 | 133 |
| 124 static void SendMouseWheelEvent(JNIEnv* env, | 134 static void SendMouseWheelEvent(JNIEnv* env, |
| 125 jclass clazz, | 135 jclass clazz, |
| 126 jint delta_x, | 136 jint delta_x, |
| 127 jint delta_y) { | 137 jint delta_y) { |
| 128 remoting::ChromotingJniRuntime::GetInstance()->session()->SendMouseWheelEvent( | 138 if (GetSession()) { |
| 129 delta_x, delta_y); | 139 GetSession()->SendMouseWheelEvent(delta_x, delta_y); |
| 140 } | |
| 130 } | 141 } |
| 131 | 142 |
| 132 static jboolean SendKeyEvent(JNIEnv* env, | 143 static jboolean SendKeyEvent(JNIEnv* env, |
| 133 jclass clazz, | 144 jclass clazz, |
| 134 jint keyCode, | 145 jint keyCode, |
| 135 jboolean keyDown) { | 146 jboolean keyDown) { |
| 136 return remoting::ChromotingJniRuntime::GetInstance()->session()->SendKeyEvent( | 147 if (GetSession()) { |
| 137 keyCode, keyDown); | 148 return GetSession()->SendKeyEvent(keyCode, keyDown); |
| 149 } else { | |
| 150 return false; | |
| 151 } | |
| 138 } | 152 } |
| 139 | 153 |
| 140 static void SendTextEvent(JNIEnv* env, | 154 static void SendTextEvent(JNIEnv* env, |
| 141 jclass clazz, | 155 jclass clazz, |
| 142 jstring text) { | 156 jstring text) { |
| 143 remoting::ChromotingJniRuntime::GetInstance()->session()->SendTextEvent( | 157 if (GetSession()) { |
| 144 ConvertJavaStringToUTF8(env, text)); | 158 GetSession()->SendTextEvent(ConvertJavaStringToUTF8(env, text)); |
| 159 } | |
| 145 } | 160 } |
| 146 | 161 |
| 147 static void OnThirdPartyTokenFetched(JNIEnv* env, | 162 static void OnThirdPartyTokenFetched(JNIEnv* env, |
| 148 jclass clazz, | 163 jclass clazz, |
| 149 jstring token, | 164 jstring token, |
| 150 jstring shared_secret) { | 165 jstring shared_secret) { |
| 151 ChromotingJniRuntime* runtime = remoting::ChromotingJniRuntime::GetInstance(); | 166 if (GetSession()) { |
| 152 runtime->network_task_runner()->PostTask(FROM_HERE, base::Bind( | 167 ChromotingJniRuntime* runtime = |
| 153 &ChromotingJniInstance::HandleOnThirdPartyTokenFetched, | 168 remoting::ChromotingJniRuntime::GetInstance(); |
| 154 runtime->session(), | 169 runtime->network_task_runner()->PostTask(FROM_HERE, base::Bind( |
| 155 ConvertJavaStringToUTF8(env, token), | 170 &ChromotingJniInstance::HandleOnThirdPartyTokenFetched, |
| 156 ConvertJavaStringToUTF8(env, shared_secret))); | 171 runtime->session(), |
| 172 ConvertJavaStringToUTF8(env, token), | |
| 173 ConvertJavaStringToUTF8(env, shared_secret))); | |
| 174 } | |
| 157 } | 175 } |
| 158 | 176 |
| 159 // ChromotingJniRuntime implementation. | 177 // ChromotingJniRuntime implementation. |
| 160 | 178 |
| 161 // static | 179 // static |
| 162 ChromotingJniRuntime* ChromotingJniRuntime::GetInstance() { | 180 ChromotingJniRuntime* ChromotingJniRuntime::GetInstance() { |
| 163 return Singleton<ChromotingJniRuntime>::get(); | 181 return Singleton<ChromotingJniRuntime>::get(); |
| 164 } | 182 } |
| 165 | 183 |
| 166 ChromotingJniRuntime::ChromotingJniRuntime() { | 184 ChromotingJniRuntime::ChromotingJniRuntime() { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 done_event.Wait(); | 220 done_event.Wait(); |
| 203 display_task_runner_->PostTask(FROM_HERE, base::Bind( | 221 display_task_runner_->PostTask(FROM_HERE, base::Bind( |
| 204 &ChromotingJniRuntime::DetachFromVmAndSignal, | 222 &ChromotingJniRuntime::DetachFromVmAndSignal, |
| 205 base::Unretained(this), | 223 base::Unretained(this), |
| 206 &done_event)); | 224 &done_event)); |
| 207 done_event.Wait(); | 225 done_event.Wait(); |
| 208 base::android::DetachFromVM(); | 226 base::android::DetachFromVM(); |
| 209 } | 227 } |
| 210 | 228 |
| 211 void ChromotingJniRuntime::ConnectToHost(const char* username, | 229 void ChromotingJniRuntime::ConnectToHost(const char* username, |
| 212 const char* auth_token, | 230 const char* auth_token, |
| 213 const char* host_jid, | 231 const char* host_jid, |
| 214 const char* host_id, | 232 const char* host_id, |
| 215 const char* host_pubkey, | 233 const char* host_pubkey, |
| 216 const char* pairing_id, | 234 const char* pairing_id, |
| 217 const char* pairing_secret) { | 235 const char* pairing_secret) { |
| 218 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 236 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 219 DCHECK(!session_); | 237 DCHECK(!session_); |
| 220 session_ = new ChromotingJniInstance(this, | 238 session_ = new ChromotingJniInstance(this, |
| 221 username, | 239 username, |
| 222 auth_token, | 240 auth_token, |
| 223 host_jid, | 241 host_jid, |
| 224 host_id, | 242 host_id, |
| 225 host_pubkey, | 243 host_pubkey, |
| 226 pairing_id, | 244 pairing_id, |
| 227 pairing_secret); | 245 pairing_secret); |
| 228 } | 246 } |
| 229 | 247 |
| 230 void ChromotingJniRuntime::DisconnectFromHost() { | 248 void ChromotingJniRuntime::DisconnectFromHost() { |
| 231 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 249 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 232 if (session_) { | 250 if (session_) { |
| 233 session_->Disconnect(); | 251 session_->Disconnect(); |
| 234 session_ = NULL; | 252 session_ = NULL; |
| 235 } | 253 } |
| 236 } | 254 } |
| 237 | 255 |
| 238 void ChromotingJniRuntime::ReportConnectionStatus( | 256 void ChromotingJniRuntime::ReportConnectionStatus( |
| 239 protocol::ConnectionToHost::State state, | 257 protocol::ConnectionToHost::State state, |
| 240 protocol::ErrorCode error) { | 258 protocol::ErrorCode error) { |
| 241 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 259 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 242 | 260 |
| 261 switch (state) { | |
| 262 case protocol::ConnectionToHost::CLOSED: | |
| 263 case protocol::ConnectionToHost::FAILED: | |
| 264 // If the session has become disconnected, ensure that |session_| gets | |
| 265 // cleaned up. | |
| 266 DisconnectFromHost(); | |
|
Sergey Ulanov
2014/07/24 02:47:02
Can the Java layer call Disconnect() when the host
Lambros
2014/07/26 00:42:35
Done.
| |
| 267 break; | |
| 268 default: | |
| 269 break; | |
| 270 } | |
| 243 JNIEnv* env = base::android::AttachCurrentThread(); | 271 JNIEnv* env = base::android::AttachCurrentThread(); |
| 244 Java_JniInterface_reportConnectionStatus(env, state, error); | 272 Java_JniInterface_reportConnectionStatus(env, state, error); |
| 245 } | 273 } |
| 246 | 274 |
| 247 void ChromotingJniRuntime::DisplayAuthenticationPrompt(bool pairing_supported) { | 275 void ChromotingJniRuntime::DisplayAuthenticationPrompt(bool pairing_supported) { |
| 248 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 276 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 249 | 277 |
| 250 JNIEnv* env = base::android::AttachCurrentThread(); | 278 JNIEnv* env = base::android::AttachCurrentThread(); |
| 251 Java_JniInterface_displayAuthenticationPrompt(env, pairing_supported); | 279 Java_JniInterface_displayAuthenticationPrompt(env, pairing_supported); |
| 252 } | 280 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 | 350 |
| 323 JNIEnv* env = base::android::AttachCurrentThread(); | 351 JNIEnv* env = base::android::AttachCurrentThread(); |
| 324 Java_JniInterface_redrawGraphicsInternal(env); | 352 Java_JniInterface_redrawGraphicsInternal(env); |
| 325 } | 353 } |
| 326 | 354 |
| 327 void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) { | 355 void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) { |
| 328 base::android::DetachFromVM(); | 356 base::android::DetachFromVM(); |
| 329 waiter->Signal(); | 357 waiter->Signal(); |
| 330 } | 358 } |
| 331 } // namespace remoting | 359 } // namespace remoting |
| OLD | NEW |