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

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

Issue 29583003: Use jni_generator in Chromoting Android client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed Created 7 years, 2 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_interface.cc » ('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/base_jni_registrar.h"
8 #include "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h" 9 #include "base/android/scoped_java_ref.h"
10 #include "base/basictypes.h"
11 #include "base/command_line.h"
10 #include "base/memory/singleton.h" 12 #include "base/memory/singleton.h"
11 #include "base/stl_util.h" 13 #include "base/stl_util.h"
12 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "google_apis/google_api_keys.h"
16 #include "jni/JniInterface_jni.h"
13 #include "media/base/yuv_convert.h" 17 #include "media/base/yuv_convert.h"
14 #include "net/android/net_jni_registrar.h"
15 #include "remoting/base/url_request_context.h" 18 #include "remoting/base/url_request_context.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 19 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
17 20
21 using base::android::ConvertJavaStringToUTF8;
22
18 namespace { 23 namespace {
19 24
20 // Class and package name of the Java class supporting the methods we call.
21 const char* const kJavaClass = "org/chromium/chromoting/jni/JniInterface";
22
23 const int kBytesPerPixel = 4; 25 const int kBytesPerPixel = 4;
24 26
25 } // namespace 27 } // namespace
26 28
27 namespace remoting { 29 namespace remoting {
28 30
31 bool RegisterJni(JNIEnv* env) {
32 return remoting::RegisterNativesImpl(env);
33 }
34
35 // Implementation of stubs defined in JniInterface_jni.h. These are the entry
36 // points for JNI calls from Java into C++.
37
38 static void LoadNative(JNIEnv* env, jclass clazz, jobject context) {
39 base::android::ScopedJavaLocalRef<jobject> context_activity(env, context);
40 base::android::InitApplicationContext(context_activity);
41
42 // The google_apis functions check the command-line arguments to make sure no
43 // runtime API keys have been specified by the environment. Unfortunately, we
44 // neither launch Chromium nor have a command line, so we need to prevent
45 // them from DCHECKing out when they go looking.
46 CommandLine::Init(0, NULL);
47
48 // Create the singleton now so that the Chromoting threads will be set up.
49 remoting::ChromotingJniRuntime::GetInstance();
50 }
51
52 static jstring GetApiKey(JNIEnv* env, jclass clazz) {
53 return env->NewStringUTF(google_apis::GetAPIKey().c_str());
54 }
55
56 static jstring GetClientId(JNIEnv* env, jclass clazz) {
57 return env->NewStringUTF(
58 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING).c_str());
59 }
60
61 static jstring GetClientSecret(JNIEnv* env, jclass clazz) {
62 return env->NewStringUTF(
63 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING).c_str());
64 }
65
66 static void Connect(JNIEnv* env,
67 jclass clazz,
68 jstring username,
69 jstring authToken,
70 jstring hostJid,
71 jstring hostId,
72 jstring hostPubkey,
73 jstring pairId,
74 jstring pairSecret) {
75 remoting::ChromotingJniRuntime::GetInstance()->ConnectToHost(
76 ConvertJavaStringToUTF8(env, username).c_str(),
77 ConvertJavaStringToUTF8(env, authToken).c_str(),
78 ConvertJavaStringToUTF8(env, hostJid).c_str(),
79 ConvertJavaStringToUTF8(env, hostId).c_str(),
80 ConvertJavaStringToUTF8(env, hostPubkey).c_str(),
81 ConvertJavaStringToUTF8(env, pairId).c_str(),
82 ConvertJavaStringToUTF8(env, pairSecret).c_str());
83 }
84
85 static void Disconnect(JNIEnv* env, jclass clazz) {
86 remoting::ChromotingJniRuntime::GetInstance()->DisconnectFromHost();
87 }
88
89 static void AuthenticationResponse(JNIEnv* env,
90 jclass clazz,
91 jstring pin,
92 jboolean createPair) {
93 remoting::ChromotingJniRuntime::GetInstance()->session()->ProvideSecret(
94 ConvertJavaStringToUTF8(env, pin).c_str(), createPair);
95 }
96
97 static void ScheduleRedraw(JNIEnv* env, jclass clazz) {
98 remoting::ChromotingJniRuntime::GetInstance()->session()->RedrawDesktop();
99 }
100
101 static void MouseAction(JNIEnv* env,
102 jclass clazz,
103 jint x,
104 jint y,
105 jint whichButton,
106 jboolean buttonDown) {
107 // Button must be within the bounds of the MouseEvent_MouseButton enum.
108 DCHECK(whichButton >= 0 && whichButton < 5);
109
110 remoting::ChromotingJniRuntime::GetInstance()->session()->PerformMouseAction(
111 x,
112 y,
113 static_cast<remoting::protocol::MouseEvent_MouseButton>(whichButton),
114 buttonDown);
115 }
116
117 static void KeyboardAction(JNIEnv* env,
118 jclass clazz,
119 jint keyCode,
120 jboolean keyDown) {
121 remoting::ChromotingJniRuntime::GetInstance()
122 ->session()
123 ->PerformKeyboardAction(keyCode, keyDown);
124 }
125
126 // ChromotingJniRuntime implementation.
127
29 // static 128 // static
30 ChromotingJniRuntime* ChromotingJniRuntime::GetInstance() { 129 ChromotingJniRuntime* ChromotingJniRuntime::GetInstance() {
31 return Singleton<ChromotingJniRuntime>::get(); 130 return Singleton<ChromotingJniRuntime>::get();
32 } 131 }
33 132
34 ChromotingJniRuntime::ChromotingJniRuntime() { 133 ChromotingJniRuntime::ChromotingJniRuntime() {
35 // Obtain a reference to the Java environment. (Future calls to this function
36 // made from the same thread return the same stored reference instead of
37 // repeating the work of attaching to the JVM.)
38 JNIEnv* env = base::android::AttachCurrentThread();
39
40 // The base and networks stacks must be registered with JNI in order to work
41 // on Android. An AtExitManager cleans this up at process exit.
42 at_exit_manager_.reset(new base::AtExitManager()); 134 at_exit_manager_.reset(new base::AtExitManager());
43 base::android::RegisterJni(env);
44 net::android::RegisterJni(env);
45 135
46 // On Android, the UI thread is managed by Java, so we need to attach and 136 // On Android, the UI thread is managed by Java, so we need to attach and
47 // start a special type of message loop to allow Chromium code to run tasks. 137 // start a special type of message loop to allow Chromium code to run tasks.
48 LOG(INFO) << "Starting main message loop"; 138 LOG(INFO) << "Starting main message loop";
49 ui_loop_.reset(new base::MessageLoopForUI()); 139 ui_loop_.reset(new base::MessageLoopForUI());
50 ui_loop_->Start(); 140 ui_loop_->Start();
51 141
52 LOG(INFO) << "Spawning additional threads"; 142 LOG(INFO) << "Spawning additional threads";
53 // TODO(solb) Stop pretending to control the managed UI thread's lifetime. 143 // TODO(solb) Stop pretending to control the managed UI thread's lifetime.
54 ui_task_runner_ = new AutoThreadTaskRunner(ui_loop_->message_loop_proxy(), 144 ui_task_runner_ = new AutoThreadTaskRunner(ui_loop_->message_loop_proxy(),
55 base::MessageLoop::QuitClosure()); 145 base::MessageLoop::QuitClosure());
56 network_task_runner_ = AutoThread::CreateWithType("native_net", 146 network_task_runner_ = AutoThread::CreateWithType("native_net",
57 ui_task_runner_, 147 ui_task_runner_,
58 base::MessageLoop::TYPE_IO); 148 base::MessageLoop::TYPE_IO);
59 display_task_runner_ = AutoThread::Create("native_disp", 149 display_task_runner_ = AutoThread::Create("native_disp",
60 ui_task_runner_); 150 ui_task_runner_);
61 151
62 url_requester_ = new URLRequestContextGetter(network_task_runner_); 152 url_requester_ = new URLRequestContextGetter(network_task_runner_);
63 153
64 // Allows later decoding of video frames. 154 // Allows later decoding of video frames.
65 media::InitializeCPUSpecificYUVConversions(); 155 media::InitializeCPUSpecificYUVConversions();
66
67 class_ = static_cast<jclass>(env->NewGlobalRef(env->FindClass(kJavaClass)));
68 } 156 }
69 157
70 ChromotingJniRuntime::~ChromotingJniRuntime() { 158 ChromotingJniRuntime::~ChromotingJniRuntime() {
71 // The singleton should only ever be destroyed on the main thread. 159 // The singleton should only ever be destroyed on the main thread.
72 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 160 DCHECK(ui_task_runner_->BelongsToCurrentThread());
73 161
74 // The session must be shut down first, since it depends on our other 162 // The session must be shut down first, since it depends on our other
75 // components' still being alive. 163 // components' still being alive.
76 DisconnectFromHost(); 164 DisconnectFromHost();
77 165
78 JNIEnv* env = base::android::AttachCurrentThread();
79 env->DeleteGlobalRef(class_);
80
81 base::WaitableEvent done_event(false, false); 166 base::WaitableEvent done_event(false, false);
82 network_task_runner_->PostTask(FROM_HERE, base::Bind( 167 network_task_runner_->PostTask(FROM_HERE, base::Bind(
83 &ChromotingJniRuntime::DetachFromVmAndSignal, 168 &ChromotingJniRuntime::DetachFromVmAndSignal,
84 base::Unretained(this), 169 base::Unretained(this),
85 &done_event)); 170 &done_event));
86 done_event.Wait(); 171 done_event.Wait();
87 display_task_runner_->PostTask(FROM_HERE, base::Bind( 172 display_task_runner_->PostTask(FROM_HERE, base::Bind(
88 &ChromotingJniRuntime::DetachFromVmAndSignal, 173 &ChromotingJniRuntime::DetachFromVmAndSignal,
89 base::Unretained(this), 174 base::Unretained(this),
90 &done_event)); 175 &done_event));
(...skipping 27 matching lines...) Expand all
118 session_ = NULL; 203 session_ = NULL;
119 } 204 }
120 } 205 }
121 206
122 void ChromotingJniRuntime::ReportConnectionStatus( 207 void ChromotingJniRuntime::ReportConnectionStatus(
123 protocol::ConnectionToHost::State state, 208 protocol::ConnectionToHost::State state,
124 protocol::ErrorCode error) { 209 protocol::ErrorCode error) {
125 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 210 DCHECK(ui_task_runner_->BelongsToCurrentThread());
126 211
127 JNIEnv* env = base::android::AttachCurrentThread(); 212 JNIEnv* env = base::android::AttachCurrentThread();
128 env->CallStaticVoidMethod( 213 Java_JniInterface_reportConnectionStatus(env, state, error);
129 class_,
130 env->GetStaticMethodID(class_, "reportConnectionStatus", "(II)V"),
131 state,
132 error);
133 } 214 }
134 215
135 void ChromotingJniRuntime::DisplayAuthenticationPrompt(bool pairing_supported) { 216 void ChromotingJniRuntime::DisplayAuthenticationPrompt(bool pairing_supported) {
136 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 217 DCHECK(ui_task_runner_->BelongsToCurrentThread());
137 218
138 JNIEnv* env = base::android::AttachCurrentThread(); 219 JNIEnv* env = base::android::AttachCurrentThread();
139 env->CallStaticVoidMethod( 220 Java_JniInterface_displayAuthenticationPrompt(env, pairing_supported);
140 class_,
141 env->GetStaticMethodID(class_, "displayAuthenticationPrompt", "(Z)V"),
142 pairing_supported);
143 } 221 }
144 222
145 void ChromotingJniRuntime::CommitPairingCredentials(const std::string& host, 223 void ChromotingJniRuntime::CommitPairingCredentials(const std::string& host,
146 const std::string& id, 224 const std::string& id,
147 const std::string& secret) { 225 const std::string& secret) {
148 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 226 DCHECK(ui_task_runner_->BelongsToCurrentThread());
149 227
150 JNIEnv* env = base::android::AttachCurrentThread(); 228 JNIEnv* env = base::android::AttachCurrentThread();
151 jstring host_jstr = env->NewStringUTF(host.c_str()); 229 jstring host_jstr = env->NewStringUTF(host.c_str());
152 jbyteArray id_arr = env->NewByteArray(id.size()); 230 jbyteArray id_arr = env->NewByteArray(id.size());
153 env->SetByteArrayRegion(id_arr, 0, id.size(), 231 env->SetByteArrayRegion(id_arr, 0, id.size(),
154 reinterpret_cast<const jbyte*>(id.c_str())); 232 reinterpret_cast<const jbyte*>(id.c_str()));
155 jbyteArray secret_arr = env->NewByteArray(secret.size()); 233 jbyteArray secret_arr = env->NewByteArray(secret.size());
156 env->SetByteArrayRegion(secret_arr, 0, secret.size(), 234 env->SetByteArrayRegion(secret_arr, 0, secret.size(),
157 reinterpret_cast<const jbyte*>(secret.c_str())); 235 reinterpret_cast<const jbyte*>(secret.c_str()));
158 236
159 env->CallStaticVoidMethod( 237 Java_JniInterface_commitPairingCredentials(env, host_jstr, id_arr,
160 class_, 238 secret_arr);
161 env->GetStaticMethodID(
162 class_,
163 "commitPairingCredentials",
164 "(Ljava/lang/String;[B[B)V"),
165 host_jstr,
166 id_arr,
167 secret_arr);
168 239
169 // Because we passed them as arguments, their corresponding Java objects were 240 // Because we passed them as arguments, their corresponding Java objects were
170 // GCd as soon as the managed method returned, so we mustn't release it here. 241 // GCd as soon as the managed method returned, so we mustn't release it here.
171 } 242 }
172 243
173 base::android::ScopedJavaLocalRef<jobject> ChromotingJniRuntime::NewBitmap( 244 base::android::ScopedJavaLocalRef<jobject> ChromotingJniRuntime::NewBitmap(
174 webrtc::DesktopSize size) { 245 webrtc::DesktopSize size) {
175 JNIEnv* env = base::android::AttachCurrentThread(); 246 JNIEnv* env = base::android::AttachCurrentThread();
176 247 return Java_JniInterface_newBitmap(env, size.width(), size.height());
177 jobject bitmap = env->CallStaticObjectMethod(
178 class_,
179 env->GetStaticMethodID(
180 class_,
181 "newBitmap",
182 "(II)Landroid/graphics/Bitmap;"),
183 size.width(),
184 size.height());
185 return base::android::ScopedJavaLocalRef<jobject>(env, bitmap);
186 } 248 }
187 249
188 void ChromotingJniRuntime::UpdateFrameBitmap(jobject bitmap) { 250 void ChromotingJniRuntime::UpdateFrameBitmap(jobject bitmap) {
189 DCHECK(display_task_runner_->BelongsToCurrentThread()); 251 DCHECK(display_task_runner_->BelongsToCurrentThread());
190 252
191 JNIEnv* env = base::android::AttachCurrentThread(); 253 JNIEnv* env = base::android::AttachCurrentThread();
192 254 Java_JniInterface_setVideoFrame(env, bitmap);
193 env->CallStaticVoidMethod(
194 class_,
195 env->GetStaticMethodID(
196 class_,
197 "setVideoFrame",
198 "(Landroid/graphics/Bitmap;)V"),
199 bitmap);
200 } 255 }
201 256
202 void ChromotingJniRuntime::UpdateCursorShape( 257 void ChromotingJniRuntime::UpdateCursorShape(
203 const protocol::CursorShapeInfo& cursor_shape) { 258 const protocol::CursorShapeInfo& cursor_shape) {
204 DCHECK(display_task_runner_->BelongsToCurrentThread()); 259 DCHECK(display_task_runner_->BelongsToCurrentThread());
205 260
206 // const_cast<> is safe as long as the Java updateCursorShape() method copies 261 // const_cast<> is safe as long as the Java updateCursorShape() method copies
207 // the data out of the buffer without mutating it, and doesn't keep any 262 // the data out of the buffer without mutating it, and doesn't keep any
208 // reference to the buffer afterwards. Unfortunately, there seems to be no way 263 // reference to the buffer afterwards. Unfortunately, there seems to be no way
209 // to create a read-only ByteBuffer from a pointer-to-const. 264 // to create a read-only ByteBuffer from a pointer-to-const.
210 char* data = string_as_array(const_cast<std::string*>(&cursor_shape.data())); 265 char* data = string_as_array(const_cast<std::string*>(&cursor_shape.data()));
211 int cursor_total_bytes = 266 int cursor_total_bytes =
212 cursor_shape.width() * cursor_shape.height() * kBytesPerPixel; 267 cursor_shape.width() * cursor_shape.height() * kBytesPerPixel;
213 268
214 JNIEnv* env = base::android::AttachCurrentThread(); 269 JNIEnv* env = base::android::AttachCurrentThread();
215 base::android::ScopedJavaLocalRef<jobject> buffer(env, 270 base::android::ScopedJavaLocalRef<jobject> buffer(env,
216 env->NewDirectByteBuffer(data, cursor_total_bytes)); 271 env->NewDirectByteBuffer(data, cursor_total_bytes));
217 env->CallStaticVoidMethod( 272 Java_JniInterface_updateCursorShape(env,
218 class_, 273 cursor_shape.width(),
219 env->GetStaticMethodID( 274 cursor_shape.height(),
220 class_, 275 cursor_shape.hotspot_x(),
221 "updateCursorShape", 276 cursor_shape.hotspot_y(),
222 "(IIIILjava/nio/ByteBuffer;)V"), 277 buffer.obj());
223 cursor_shape.width(),
224 cursor_shape.height(),
225 cursor_shape.hotspot_x(),
226 cursor_shape.hotspot_y(),
227 buffer.obj());
228 } 278 }
229 279
230 void ChromotingJniRuntime::RedrawCanvas() { 280 void ChromotingJniRuntime::RedrawCanvas() {
231 DCHECK(display_task_runner_->BelongsToCurrentThread()); 281 DCHECK(display_task_runner_->BelongsToCurrentThread());
232 282
233 JNIEnv* env = base::android::AttachCurrentThread(); 283 JNIEnv* env = base::android::AttachCurrentThread();
234 env->CallStaticVoidMethod( 284 Java_JniInterface_redrawGraphicsInternal(env);
235 class_,
236 env->GetStaticMethodID(class_, "redrawGraphicsInternal", "()V"));
237 } 285 }
238 286
239 void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) { 287 void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) {
240 base::android::DetachFromVM(); 288 base::android::DetachFromVM();
241 waiter->Signal(); 289 waiter->Signal();
242 } 290 }
243 291
244 } // namespace remoting 292 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/jni/chromoting_jni_runtime.h ('k') | remoting/client/jni/jni_interface.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698