Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: remoting/client/jni/chromoting_jni_runtime.cc

Issue 2007403002: [Android Client] Move session-scoped native interface into JniClient (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merged with latest changes Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/client/jni/chromoting_jni_runtime.h ('k') | remoting/client/jni/jni_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/library_loader/library_loader_hooks.h" 10 #include "base/android/library_loader/library_loader_hooks.h"
11 #include "base/android/scoped_java_ref.h" 11 #include "base/android/scoped_java_ref.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/memory/singleton.h" 14 #include "base/memory/singleton.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/synchronization/waitable_event.h" 16 #include "base/synchronization/waitable_event.h"
17 #include "jni/JniInterface_jni.h" 17 #include "jni/JniInterface_jni.h"
18 #include "remoting/base/chromium_url_request.h" 18 #include "remoting/base/chromium_url_request.h"
19 #include "remoting/base/url_request_context_getter.h" 19 #include "remoting/base/url_request_context_getter.h"
20 #include "remoting/client/jni/jni_touch_event_data.h" 20 #include "remoting/client/jni/jni_touch_event_data.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;
29
30 const char kTelemetryBaseUrl[] = "https://remoting-pa.googleapis.com/v1/events"; 28 const char kTelemetryBaseUrl[] = "https://remoting-pa.googleapis.com/v1/events";
31 29
32 } // namespace 30 } // namespace
33 31
34 namespace remoting { 32 namespace remoting {
35 33
36 bool RegisterChromotingJniRuntime(JNIEnv* env) { 34 bool RegisterChromotingJniRuntime(JNIEnv* env) {
37 return remoting::RegisterNativesImpl(env); 35 return remoting::RegisterNativesImpl(env);
38 } 36 }
39 37
40 // Implementation of stubs defined in JniInterface_jni.h. These are the entry 38 // Implementation of stubs defined in JniInterface_jni.h. These are the entry
41 // points for JNI calls from Java into C++. 39 // points for JNI calls from Java into C++.
42 40
43 static void LoadNative(JNIEnv* env, const JavaParamRef<jclass>& clazz) { 41 static void LoadNative(JNIEnv* env, const JavaParamRef<jclass>& clazz) {
44 base::CommandLine::Init(0, nullptr); 42 base::CommandLine::Init(0, nullptr);
45 43
46 // Create the singleton now so that the Chromoting threads will be set up. 44 // Create the singleton now so that the Chromoting threads will be set up.
47 remoting::ChromotingJniRuntime::GetInstance(); 45 remoting::ChromotingJniRuntime::GetInstance();
48 } 46 }
49 47
50 static void Connect(JNIEnv* env,
51 const JavaParamRef<jclass>& clazz,
52 const JavaParamRef<jstring>& username,
53 const JavaParamRef<jstring>& authToken,
54 const JavaParamRef<jstring>& hostJid,
55 const JavaParamRef<jstring>& hostId,
56 const JavaParamRef<jstring>& hostPubkey,
57 const JavaParamRef<jstring>& pairId,
58 const JavaParamRef<jstring>& pairSecret,
59 const JavaParamRef<jstring>& capabilities,
60 const JavaParamRef<jstring>& flags) {
61 remoting::ChromotingJniRuntime::GetInstance()->ConnectToHost(
62 ConvertJavaStringToUTF8(env, username),
63 ConvertJavaStringToUTF8(env, authToken),
64 ConvertJavaStringToUTF8(env, hostJid),
65 ConvertJavaStringToUTF8(env, hostId),
66 ConvertJavaStringToUTF8(env, hostPubkey),
67 ConvertJavaStringToUTF8(env, pairId),
68 ConvertJavaStringToUTF8(env, pairSecret),
69 ConvertJavaStringToUTF8(env, capabilities),
70 ConvertJavaStringToUTF8(env, flags));
71 }
72
73 static void Disconnect(JNIEnv* env, const JavaParamRef<jclass>& clazz) {
74 remoting::ChromotingJniRuntime::GetInstance()->DisconnectFromHost();
75 }
76
77 static void AuthenticationResponse(JNIEnv* env,
78 const JavaParamRef<jclass>& clazz,
79 const JavaParamRef<jstring>& pin,
80 jboolean createPair,
81 const JavaParamRef<jstring>& deviceName) {
82 remoting::ChromotingJniRuntime::GetInstance()->session()->ProvideSecret(
83 ConvertJavaStringToUTF8(env, pin).c_str(), createPair,
84 ConvertJavaStringToUTF8(env, deviceName));
85 }
86
87 static void ScheduleRedraw(JNIEnv* env, const JavaParamRef<jclass>& clazz) {
88 remoting::ChromotingJniRuntime::GetInstance()->session()->RedrawDesktop();
89 }
90
91 static void SendMouseEvent(JNIEnv* env,
92 const JavaParamRef<jclass>& clazz,
93 jint x,
94 jint y,
95 jint whichButton,
96 jboolean buttonDown) {
97 // Button must be within the bounds of the MouseEvent_MouseButton enum.
98 DCHECK(whichButton >= 0 && whichButton < 5);
99
100 remoting::ChromotingJniRuntime::GetInstance()->session()->SendMouseEvent(
101 x, y,
102 static_cast<remoting::protocol::MouseEvent_MouseButton>(whichButton),
103 buttonDown);
104 }
105
106 static void SendMouseWheelEvent(JNIEnv* env,
107 const JavaParamRef<jclass>& clazz,
108 jint delta_x,
109 jint delta_y) {
110 remoting::ChromotingJniRuntime::GetInstance()->session()->SendMouseWheelEvent(
111 delta_x, delta_y);
112 }
113
114 static jboolean SendKeyEvent(JNIEnv* env,
115 const JavaParamRef<jclass>& clazz,
116 jint scanCode,
117 jint keyCode,
118 jboolean keyDown) {
119 return remoting::ChromotingJniRuntime::GetInstance()->session()->SendKeyEvent(
120 scanCode, keyCode, keyDown);
121 }
122
123 static void SendTextEvent(JNIEnv* env,
124 const JavaParamRef<jclass>& clazz,
125 const JavaParamRef<jstring>& text) {
126 remoting::ChromotingJniRuntime::GetInstance()->session()->SendTextEvent(
127 ConvertJavaStringToUTF8(env, text));
128 }
129
130 static void SendTouchEvent(
131 JNIEnv* env,
132 const JavaParamRef<jclass>& clazz,
133 jint eventType,
134 const JavaParamRef<jobjectArray>& touchEventObjectArray) {
135 protocol::TouchEvent touch_event;
136 touch_event.set_event_type(
137 static_cast<protocol::TouchEvent::TouchEventType>(eventType));
138
139 // Iterate over the elements in the object array and transfer the data from
140 // the java object to a native event object.
141 jsize length = env->GetArrayLength(touchEventObjectArray);
142 DCHECK_GE(length, 0);
143 for (jsize i = 0; i < length; ++i) {
144 protocol::TouchEventPoint* touch_point = touch_event.add_touch_points();
145
146 ScopedJavaLocalRef<jobject> java_touch_event(
147 env, env->GetObjectArrayElement(touchEventObjectArray, i));
148
149 JniTouchEventData::CopyTouchPointData(env, java_touch_event, touch_point);
150 }
151
152 remoting::ChromotingJniRuntime::GetInstance()->session()->SendTouchEvent(
153 touch_event);
154 }
155
156 static void EnableVideoChannel(JNIEnv* env,
157 const JavaParamRef<jclass>& clazz,
158 jboolean enable) {
159 remoting::ChromotingJniRuntime::GetInstance()->session()->EnableVideoChannel(
160 enable);
161 }
162
163 static void OnThirdPartyTokenFetched(
164 JNIEnv* env,
165 const JavaParamRef<jclass>& clazz,
166 const JavaParamRef<jstring>& token,
167 const JavaParamRef<jstring>& shared_secret) {
168 ChromotingJniRuntime* runtime = remoting::ChromotingJniRuntime::GetInstance();
169 runtime->network_task_runner()->PostTask(FROM_HERE, base::Bind(
170 &ChromotingJniInstance::HandleOnThirdPartyTokenFetched,
171 runtime->session(),
172 ConvertJavaStringToUTF8(env, token),
173 ConvertJavaStringToUTF8(env, shared_secret)));
174 }
175
176 static void SendExtensionMessage(JNIEnv* env,
177 const JavaParamRef<jclass>& clazz,
178 const JavaParamRef<jstring>& type,
179 const JavaParamRef<jstring>& data) {
180 remoting::ChromotingJniRuntime::GetInstance()->session()->SendClientMessage(
181 ConvertJavaStringToUTF8(env, type),
182 ConvertJavaStringToUTF8(env, data));
183 }
184
185 static void HandleAuthTokenOnNetworkThread(const std::string& token) { 48 static void HandleAuthTokenOnNetworkThread(const std::string& token) {
186 ChromotingJniRuntime* runtime = remoting::ChromotingJniRuntime::GetInstance(); 49 ChromotingJniRuntime* runtime = remoting::ChromotingJniRuntime::GetInstance();
187 DCHECK(runtime->network_task_runner()->BelongsToCurrentThread()); 50 DCHECK(runtime->network_task_runner()->BelongsToCurrentThread());
188 runtime->logger()->SetAuthToken(token); 51 runtime->logger()->SetAuthToken(token);
189 } 52 }
190 53
191 static void OnAuthTokenFetched(JNIEnv* env, 54 static void OnAuthTokenFetched(JNIEnv* env,
192 const JavaParamRef<jclass>& clazz, 55 const JavaParamRef<jclass>& clazz,
193 const JavaParamRef<jstring>& token) { 56 const JavaParamRef<jstring>& token) {
194 ChromotingJniRuntime* runtime = remoting::ChromotingJniRuntime::GetInstance(); 57 ChromotingJniRuntime* runtime = remoting::ChromotingJniRuntime::GetInstance();
(...skipping 29 matching lines...) Expand all
224 runtime_ = ChromotingClientRuntime::Create(ui_loop_.get()); 87 runtime_ = ChromotingClientRuntime::Create(ui_loop_.get());
225 network_task_runner()->PostTask( 88 network_task_runner()->PostTask(
226 FROM_HERE, base::Bind(&ChromotingJniRuntime::StartLoggerOnNetworkThread, 89 FROM_HERE, base::Bind(&ChromotingJniRuntime::StartLoggerOnNetworkThread,
227 base::Unretained(this))); 90 base::Unretained(this)));
228 } 91 }
229 92
230 ChromotingJniRuntime::~ChromotingJniRuntime() { 93 ChromotingJniRuntime::~ChromotingJniRuntime() {
231 // The singleton should only ever be destroyed on the main thread. 94 // The singleton should only ever be destroyed on the main thread.
232 DCHECK(ui_task_runner()->BelongsToCurrentThread()); 95 DCHECK(ui_task_runner()->BelongsToCurrentThread());
233 96
234 // The session must be shut down first, since it depends on our other
235 // components' still being alive.
236 DisconnectFromHost();
237
238 base::WaitableEvent done_event(false, false); 97 base::WaitableEvent done_event(false, false);
239 network_task_runner()->PostTask( 98 network_task_runner()->PostTask(
240 FROM_HERE, base::Bind(&ChromotingJniRuntime::DetachFromVmAndSignal, 99 FROM_HERE, base::Bind(&ChromotingJniRuntime::DetachFromVmAndSignal,
241 base::Unretained(this), &done_event)); 100 base::Unretained(this), &done_event));
242 done_event.Wait(); 101 done_event.Wait();
243 display_task_runner()->PostTask( 102 display_task_runner()->PostTask(
244 FROM_HERE, base::Bind(&ChromotingJniRuntime::DetachFromVmAndSignal, 103 FROM_HERE, base::Bind(&ChromotingJniRuntime::DetachFromVmAndSignal,
245 base::Unretained(this), &done_event)); 104 base::Unretained(this), &done_event));
246 done_event.Wait(); 105 done_event.Wait();
247 base::android::LibraryLoaderExitHook(); 106 base::android::LibraryLoaderExitHook();
248 base::android::DetachFromVM(); 107 base::android::DetachFromVM();
249 } 108 }
250 109
251 void ChromotingJniRuntime::ConnectToHost(const std::string& username,
252 const std::string& auth_token,
253 const std::string& host_jid,
254 const std::string& host_id,
255 const std::string& host_pubkey,
256 const std::string& pairing_id,
257 const std::string& pairing_secret,
258 const std::string& capabilities,
259 const std::string& flags) {
260 DCHECK(ui_task_runner()->BelongsToCurrentThread());
261 DCHECK(!session_.get());
262 session_ = new ChromotingJniInstance(this, username, auth_token, host_jid,
263 host_id, host_pubkey, pairing_id,
264 pairing_secret, capabilities, flags);
265 session_->Connect();
266 }
267
268 void ChromotingJniRuntime::DisconnectFromHost() {
269 DCHECK(ui_task_runner()->BelongsToCurrentThread());
270 if (session_.get()) {
271 session_->Disconnect();
272 session_ = nullptr;
273 }
274 }
275
276 void ChromotingJniRuntime::OnConnectionState(
277 protocol::ConnectionToHost::State state,
278 protocol::ErrorCode error) {
279 DCHECK(ui_task_runner()->BelongsToCurrentThread());
280
281 JNIEnv* env = base::android::AttachCurrentThread();
282 Java_JniInterface_onConnectionState(env, state, error);
283 }
284
285 void ChromotingJniRuntime::DisplayAuthenticationPrompt(bool pairing_supported) {
286 DCHECK(ui_task_runner()->BelongsToCurrentThread());
287
288 JNIEnv* env = base::android::AttachCurrentThread();
289 Java_JniInterface_displayAuthenticationPrompt(env, pairing_supported);
290 }
291
292 void ChromotingJniRuntime::CommitPairingCredentials(const std::string& host,
293 const std::string& id,
294 const std::string& secret) {
295 DCHECK(ui_task_runner()->BelongsToCurrentThread());
296
297 JNIEnv* env = base::android::AttachCurrentThread();
298 ScopedJavaLocalRef<jstring> j_host = ConvertUTF8ToJavaString(env, host);
299 ScopedJavaLocalRef<jstring> j_id = ConvertUTF8ToJavaString(env, id);
300 ScopedJavaLocalRef<jstring> j_secret = ConvertUTF8ToJavaString(env,secret);
301
302 Java_JniInterface_commitPairingCredentials(
303 env, j_host.obj(), j_id.obj(), j_secret.obj());
304 }
305
306 void ChromotingJniRuntime::FetchAuthToken() { 110 void ChromotingJniRuntime::FetchAuthToken() {
307 if (!ui_task_runner()->BelongsToCurrentThread()) { 111 if (!ui_task_runner()->BelongsToCurrentThread()) {
308 ui_task_runner()->PostTask( 112 ui_task_runner()->PostTask(
309 FROM_HERE, base::Bind(&ChromotingJniRuntime::FetchAuthToken, 113 FROM_HERE, base::Bind(&ChromotingJniRuntime::FetchAuthToken,
310 base::Unretained(this))); 114 base::Unretained(this)));
311 return; 115 return;
312 } 116 }
313 JNIEnv* env = base::android::AttachCurrentThread(); 117 JNIEnv* env = base::android::AttachCurrentThread();
314 118
315 Java_JniInterface_fetchAuthToken(env); 119 Java_JniInterface_fetchAuthToken(env);
316 } 120 }
317 121
318 void ChromotingJniRuntime::FetchThirdPartyToken(const std::string& token_url,
319 const std::string& client_id,
320 const std::string& scope) {
321 DCHECK(ui_task_runner()->BelongsToCurrentThread());
322 JNIEnv* env = base::android::AttachCurrentThread();
323
324 ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, token_url);
325 ScopedJavaLocalRef<jstring> j_client_id =
326 ConvertUTF8ToJavaString(env, client_id);
327 ScopedJavaLocalRef<jstring> j_scope = ConvertUTF8ToJavaString(env, scope);
328
329 Java_JniInterface_fetchThirdPartyToken(
330 env, j_url.obj(), j_client_id.obj(), j_scope.obj());
331 }
332
333 void ChromotingJniRuntime::SetCapabilities(const std::string& capabilities) {
334 DCHECK(ui_task_runner()->BelongsToCurrentThread());
335 JNIEnv* env = base::android::AttachCurrentThread();
336
337 ScopedJavaLocalRef<jstring> j_cap =
338 ConvertUTF8ToJavaString(env, capabilities);
339
340 Java_JniInterface_setCapabilities(env, j_cap.obj());
341 }
342
343 void ChromotingJniRuntime::HandleExtensionMessage(const std::string& type,
344 const std::string& message) {
345 DCHECK(ui_task_runner()->BelongsToCurrentThread());
346 JNIEnv* env = base::android::AttachCurrentThread();
347
348 ScopedJavaLocalRef<jstring> j_type = ConvertUTF8ToJavaString(env, type);
349 ScopedJavaLocalRef<jstring> j_message = ConvertUTF8ToJavaString(env, message);
350
351 Java_JniInterface_handleExtensionMessage(env, j_type.obj(), j_message.obj());
352 }
353
354 base::android::ScopedJavaLocalRef<jobject> ChromotingJniRuntime::NewBitmap(
355 int width, int height) {
356 JNIEnv* env = base::android::AttachCurrentThread();
357 return Java_JniInterface_newBitmap(env, width, height);
358 }
359
360 void ChromotingJniRuntime::UpdateFrameBitmap(jobject bitmap) {
361 DCHECK(display_task_runner()->BelongsToCurrentThread());
362
363 JNIEnv* env = base::android::AttachCurrentThread();
364 Java_JniInterface_setVideoFrame(env, bitmap);
365 }
366
367 void ChromotingJniRuntime::UpdateCursorShape(
368 const protocol::CursorShapeInfo& cursor_shape) {
369 DCHECK(display_task_runner()->BelongsToCurrentThread());
370
371 // const_cast<> is safe as long as the Java updateCursorShape() method copies
372 // the data out of the buffer without mutating it, and doesn't keep any
373 // reference to the buffer afterwards. Unfortunately, there seems to be no way
374 // to create a read-only ByteBuffer from a pointer-to-const.
375 char* data = string_as_array(const_cast<std::string*>(&cursor_shape.data()));
376 int cursor_total_bytes =
377 cursor_shape.width() * cursor_shape.height() * kBytesPerPixel;
378
379 JNIEnv* env = base::android::AttachCurrentThread();
380 base::android::ScopedJavaLocalRef<jobject> buffer(env,
381 env->NewDirectByteBuffer(data, cursor_total_bytes));
382 Java_JniInterface_updateCursorShape(env,
383 cursor_shape.width(),
384 cursor_shape.height(),
385 cursor_shape.hotspot_x(),
386 cursor_shape.hotspot_y(),
387 buffer.obj());
388 }
389
390 void ChromotingJniRuntime::RedrawCanvas() {
391 DCHECK(display_task_runner()->BelongsToCurrentThread());
392
393 JNIEnv* env = base::android::AttachCurrentThread();
394 Java_JniInterface_redrawGraphicsInternal(env);
395 }
396
397 void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) { 122 void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) {
398 base::android::DetachFromVM(); 123 base::android::DetachFromVM();
399 waiter->Signal(); 124 waiter->Signal();
400 } 125 }
401 126
402 void ChromotingJniRuntime::StartLoggerOnNetworkThread() { 127 void ChromotingJniRuntime::StartLoggerOnNetworkThread() {
403 DCHECK(network_task_runner()->BelongsToCurrentThread()); 128 DCHECK(network_task_runner()->BelongsToCurrentThread());
404 logger_.reset(new ClientTelemetryLogger(ChromotingEvent::Mode::ME2ME)); 129 logger_.reset(new ClientTelemetryLogger(ChromotingEvent::Mode::ME2ME));
405 logger_->Start( 130 logger_->Start(
406 base::WrapUnique( 131 base::WrapUnique(
407 new ChromiumUrlRequestFactory(runtime_->url_requester())), 132 new ChromiumUrlRequestFactory(runtime_->url_requester())),
408 kTelemetryBaseUrl); 133 kTelemetryBaseUrl);
409 logger_->SetAuthClosure( 134 logger_->SetAuthClosure(
410 base::Bind(&ChromotingJniRuntime::FetchAuthToken, 135 base::Bind(&ChromotingJniRuntime::FetchAuthToken,
411 base::Unretained(this))); 136 base::Unretained(this)));
412 } 137 }
413 138
414 } // namespace remoting 139 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/jni/chromoting_jni_runtime.h ('k') | remoting/client/jni/jni_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698