Load the default favicon as a native image, rather than as a Skia image.
[chromium-blink-merge.git] / mojo / android / system / core_impl.cc
blob1d7f87925acef56119e26a939e0f9318952cf7bf
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 "mojo/android/system/core_impl.h"
7 #include "base/android/base_jni_registrar.h"
8 #include "base/android/jni_android.h"
9 #include "base/android/jni_registrar.h"
10 #include "base/android/library_loader/library_loader_hooks.h"
11 #include "base/android/scoped_java_ref.h"
12 #include "base/bind.h"
13 #include "base/message_loop/message_loop.h"
14 #include "jni/CoreImpl_jni.h"
15 #include "mojo/embedder/embedder.h"
16 #include "mojo/public/c/environment/async_waiter.h"
17 #include "mojo/public/c/system/core.h"
18 #include "mojo/public/cpp/environment/default_async_waiter.h"
20 namespace {
22 // |AsyncWait| is guaranteed never to return 0.
23 const MojoAsyncWaitID kInvalidHandleCancelID = 0;
25 struct AsyncWaitCallbackData {
26 base::android::ScopedJavaGlobalRef<jobject> core_impl;
27 base::android::ScopedJavaGlobalRef<jobject> callback;
28 base::android::ScopedJavaGlobalRef<jobject> cancellable;
30 AsyncWaitCallbackData(JNIEnv* env, jobject core_impl, jobject callback) {
31 this->core_impl.Reset(env, core_impl);
32 this->callback.Reset(env, callback);
36 void AsyncWaitCallback(void* data, MojoResult result) {
37 scoped_ptr<AsyncWaitCallbackData> callback_data(
38 static_cast<AsyncWaitCallbackData*>(data));
39 mojo::android::Java_CoreImpl_onAsyncWaitResult(
40 base::android::AttachCurrentThread(),
41 callback_data->core_impl.obj(),
42 result,
43 callback_data->callback.obj(),
44 callback_data->cancellable.obj());
47 } // namespace
49 namespace mojo {
50 namespace android {
52 static void Constructor(JNIEnv* env, jobject jcaller) {
53 mojo::embedder::Init();
56 static jlong GetTimeTicksNow(JNIEnv* env, jobject jcaller) {
57 return MojoGetTimeTicksNow();
60 static jint WaitMany(JNIEnv* env,
61 jobject jcaller,
62 jobject buffer,
63 jlong deadline) {
64 // Buffer contains first the list of handles, then the list of flags.
65 const void* buffer_start = env->GetDirectBufferAddress(buffer);
66 DCHECK(buffer_start);
67 const size_t record_size = 8;
68 const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
69 DCHECK_EQ(buffer_size % record_size, 0u);
71 const size_t nb_handles = buffer_size / record_size;
72 const MojoHandle* handle_start = static_cast<const MojoHandle*>(buffer_start);
73 const MojoWaitFlags* flags_start =
74 static_cast<const MojoWaitFlags*>(handle_start + nb_handles);
75 return MojoWaitMany(handle_start, flags_start, nb_handles, deadline);
78 static jobject CreateMessagePipe(JNIEnv* env, jobject jcaller) {
79 MojoHandle handle1;
80 MojoHandle handle2;
81 // TODO(vtl): Add support for the options struct.
82 MojoResult result = MojoCreateMessagePipe(NULL, &handle1, &handle2);
83 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
84 .Release();
87 static jobject CreateDataPipe(JNIEnv* env,
88 jobject jcaller,
89 jobject options_buffer) {
90 const MojoCreateDataPipeOptions* options = NULL;
91 if (options_buffer) {
92 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
93 DCHECK(buffer_start);
94 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
95 DCHECK_EQ(buffer_size, sizeof(MojoCreateDataPipeOptions));
96 options = static_cast<const MojoCreateDataPipeOptions*>(buffer_start);
97 DCHECK_EQ(options->struct_size, buffer_size);
99 MojoHandle handle1;
100 MojoHandle handle2;
101 MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2);
102 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
103 .Release();
106 static jobject CreateSharedBuffer(JNIEnv* env,
107 jobject jcaller,
108 jobject options_buffer,
109 jlong num_bytes) {
110 const MojoCreateSharedBufferOptions* options = 0;
111 if (options_buffer) {
112 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
113 DCHECK(buffer_start);
114 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
115 DCHECK_EQ(buffer_size, sizeof(MojoCreateSharedBufferOptions));
116 options = static_cast<const MojoCreateSharedBufferOptions*>(buffer_start);
117 DCHECK_EQ(options->struct_size, buffer_size);
119 MojoHandle handle;
120 MojoResult result = MojoCreateSharedBuffer(options, num_bytes, &handle);
121 return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
122 .Release();
125 static jint Close(JNIEnv* env, jobject jcaller, jint mojo_handle) {
126 return MojoClose(mojo_handle);
129 static jint Wait(JNIEnv* env,
130 jobject jcaller,
131 jint mojo_handle,
132 jint flags,
133 jlong deadline) {
134 return MojoWait(mojo_handle, flags, deadline);
137 static jint WriteMessage(JNIEnv* env,
138 jobject jcaller,
139 jint mojo_handle,
140 jobject bytes,
141 jint num_bytes,
142 jobject handles_buffer,
143 jint flags) {
144 const void* buffer_start = 0;
145 uint32_t buffer_size = 0;
146 if (bytes) {
147 buffer_start = env->GetDirectBufferAddress(bytes);
148 DCHECK(buffer_start);
149 DCHECK(env->GetDirectBufferCapacity(bytes) >= num_bytes);
150 buffer_size = num_bytes;
152 const MojoHandle* handles = 0;
153 uint32_t num_handles = 0;
154 if (handles_buffer) {
155 handles =
156 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
157 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
159 // Java code will handle invalidating handles if the write succeeded.
160 return MojoWriteMessage(
161 mojo_handle, buffer_start, buffer_size, handles, num_handles, flags);
164 static jobject ReadMessage(JNIEnv* env,
165 jobject jcaller,
166 jint mojo_handle,
167 jobject bytes,
168 jobject handles_buffer,
169 jint flags) {
170 void* buffer_start = 0;
171 uint32_t buffer_size = 0;
172 if (bytes) {
173 buffer_start = env->GetDirectBufferAddress(bytes);
174 DCHECK(buffer_start);
175 buffer_size = env->GetDirectBufferCapacity(bytes);
177 MojoHandle* handles = 0;
178 uint32_t num_handles = 0;
179 if (handles_buffer) {
180 handles =
181 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
182 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
184 MojoResult result = MojoReadMessage(
185 mojo_handle, buffer_start, &buffer_size, handles, &num_handles, flags);
186 // Jave code will handle taking ownership of any received handle.
187 return Java_CoreImpl_newReadMessageResult(
188 env, result, buffer_size, num_handles).Release();
191 static jint ReadData(JNIEnv* env,
192 jobject jcaller,
193 jint mojo_handle,
194 jobject elements,
195 jint elements_capacity,
196 jint flags) {
197 void* buffer_start = 0;
198 uint32_t buffer_size = elements_capacity;
199 if (elements) {
200 buffer_start = env->GetDirectBufferAddress(elements);
201 DCHECK(buffer_start);
202 DCHECK(elements_capacity <= env->GetDirectBufferCapacity(elements));
204 MojoResult result =
205 MojoReadData(mojo_handle, buffer_start, &buffer_size, flags);
206 if (result < 0) {
207 return result;
209 return buffer_size;
212 static jobject BeginReadData(JNIEnv* env,
213 jobject jcaller,
214 jint mojo_handle,
215 jint num_bytes,
216 jint flags) {
217 void const* buffer = 0;
218 uint32_t buffer_size = num_bytes;
219 MojoResult result =
220 MojoBeginReadData(mojo_handle, &buffer, &buffer_size, flags);
221 jobject byte_buffer = 0;
222 if (result == MOJO_RESULT_OK) {
223 byte_buffer =
224 env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size);
226 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
227 .Release();
230 static jint EndReadData(JNIEnv* env,
231 jobject jcaller,
232 jint mojo_handle,
233 jint num_bytes_read) {
234 return MojoEndReadData(mojo_handle, num_bytes_read);
237 static jint WriteData(JNIEnv* env,
238 jobject jcaller,
239 jint mojo_handle,
240 jobject elements,
241 jint limit,
242 jint flags) {
243 void* buffer_start = env->GetDirectBufferAddress(elements);
244 DCHECK(buffer_start);
245 DCHECK(limit <= env->GetDirectBufferCapacity(elements));
246 uint32_t buffer_size = limit;
247 MojoResult result =
248 MojoWriteData(mojo_handle, buffer_start, &buffer_size, flags);
249 if (result < 0) {
250 return result;
252 return buffer_size;
255 static jobject BeginWriteData(JNIEnv* env,
256 jobject jcaller,
257 jint mojo_handle,
258 jint num_bytes,
259 jint flags) {
260 void* buffer = 0;
261 uint32_t buffer_size = num_bytes;
262 MojoResult result =
263 MojoBeginWriteData(mojo_handle, &buffer, &buffer_size, flags);
264 jobject byte_buffer = 0;
265 if (result == MOJO_RESULT_OK) {
266 byte_buffer = env->NewDirectByteBuffer(buffer, buffer_size);
268 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
269 .Release();
272 static jint EndWriteData(JNIEnv* env,
273 jobject jcaller,
274 jint mojo_handle,
275 jint num_bytes_written) {
276 return MojoEndWriteData(mojo_handle, num_bytes_written);
279 static jobject Duplicate(JNIEnv* env,
280 jobject jcaller,
281 jint mojo_handle,
282 jobject options_buffer) {
283 const MojoDuplicateBufferHandleOptions* options = 0;
284 if (options_buffer) {
285 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
286 DCHECK(buffer_start);
287 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
288 DCHECK_EQ(buffer_size, sizeof(MojoDuplicateBufferHandleOptions));
289 options =
290 static_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start);
291 DCHECK_EQ(options->struct_size, buffer_size);
293 MojoHandle handle;
294 MojoResult result = MojoDuplicateBufferHandle(mojo_handle, options, &handle);
295 return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
296 .Release();
299 static jobject Map(JNIEnv* env,
300 jobject jcaller,
301 jint mojo_handle,
302 jlong offset,
303 jlong num_bytes,
304 jint flags) {
305 void* buffer = 0;
306 MojoResult result =
307 MojoMapBuffer(mojo_handle, offset, num_bytes, &buffer, flags);
308 jobject byte_buffer = 0;
309 if (result == MOJO_RESULT_OK) {
310 byte_buffer = env->NewDirectByteBuffer(buffer, num_bytes);
312 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
313 .Release();
316 static int Unmap(JNIEnv* env, jobject jcaller, jobject buffer) {
317 void* buffer_start = env->GetDirectBufferAddress(buffer);
318 DCHECK(buffer_start);
319 return MojoUnmapBuffer(buffer_start);
322 static jobject AsyncWait(JNIEnv* env,
323 jobject jcaller,
324 jint mojo_handle,
325 jint flags,
326 jlong deadline,
327 jobject callback) {
328 AsyncWaitCallbackData* callback_data =
329 new AsyncWaitCallbackData(env, jcaller, callback);
330 MojoAsyncWaitID cancel_id;
331 if (static_cast<MojoHandle>(mojo_handle) != MOJO_HANDLE_INVALID) {
332 MojoAsyncWaiter* async_waiter = mojo::GetDefaultAsyncWaiter();
333 cancel_id = async_waiter->AsyncWait(async_waiter,
334 mojo_handle,
335 flags,
336 deadline,
337 AsyncWaitCallback,
338 callback_data);
339 } else {
340 cancel_id = kInvalidHandleCancelID;
341 base::MessageLoop::current()->PostTask(
342 FROM_HERE,
343 base::Bind(
344 &AsyncWaitCallback, callback_data, MOJO_RESULT_INVALID_ARGUMENT));
346 base::android::ScopedJavaLocalRef<jobject> cancellable =
347 Java_CoreImpl_newAsyncWaiterCancellableImpl(
348 env, jcaller, cancel_id, reinterpret_cast<intptr_t>(callback_data));
349 callback_data->cancellable.Reset(env, cancellable.obj());
350 return cancellable.Release();
353 static void CancelAsyncWait(JNIEnv* env,
354 jobject jcaller,
355 jlong id,
356 jlong data_ptr) {
357 if (id == 0) {
358 // If |id| is |kInvalidHandleCancelID|, the async wait was done on an
359 // invalid handle, so the AsyncWaitCallback will be called and will clear
360 // the data_ptr.
361 return;
363 scoped_ptr<AsyncWaitCallbackData> deleter(
364 reinterpret_cast<AsyncWaitCallbackData*>(data_ptr));
365 MojoAsyncWaiter* async_waiter = mojo::GetDefaultAsyncWaiter();
366 async_waiter->CancelWait(async_waiter, id);
369 bool RegisterCoreImpl(JNIEnv* env) {
370 return RegisterNativesImpl(env);
373 } // namespace android
374 } // namespace mojo