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/logging.h"
12 #include "jni/CoreImpl_jni.h"
13 #include "mojo/embedder/embedder.h"
14 #include "mojo/public/c/system/core.h"
19 static void Constructor(JNIEnv* env, jobject jcaller) {
20 mojo::embedder::Init();
23 static jlong GetTimeTicksNow(JNIEnv* env, jobject jcaller) {
24 return MojoGetTimeTicksNow();
27 static jint WaitMany(JNIEnv* env,
31 // Buffer contains first the list of handles, then the list of flags.
32 const void* buffer_start = env->GetDirectBufferAddress(buffer);
34 const size_t record_size = 8;
35 const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
36 DCHECK_EQ(buffer_size % record_size, 0u);
38 const size_t nb_handles = buffer_size / record_size;
39 const MojoHandle* handle_start = static_cast<const MojoHandle*>(buffer_start);
40 const MojoWaitFlags* flags_start =
41 static_cast<const MojoWaitFlags*>(handle_start + nb_handles);
42 return MojoWaitMany(handle_start, flags_start, nb_handles, deadline);
45 static jobject CreateMessagePipe(JNIEnv* env, jobject jcaller) {
48 MojoResult result = MojoCreateMessagePipe(&handle1, &handle2);
49 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
53 static jobject CreateDataPipe(JNIEnv* env,
55 jobject options_buffer) {
56 const MojoCreateDataPipeOptions* options = NULL;
58 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
60 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
61 DCHECK_EQ(buffer_size, sizeof(MojoCreateDataPipeOptions));
62 options = static_cast<const MojoCreateDataPipeOptions*>(buffer_start);
63 DCHECK_EQ(options->struct_size, buffer_size);
67 MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2);
68 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
72 static jobject CreateSharedBuffer(JNIEnv* env,
74 jobject options_buffer,
76 const MojoCreateSharedBufferOptions* options = 0;
78 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
80 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
81 DCHECK_EQ(buffer_size, sizeof(MojoCreateSharedBufferOptions));
82 options = static_cast<const MojoCreateSharedBufferOptions*>(buffer_start);
83 DCHECK_EQ(options->struct_size, buffer_size);
86 MojoResult result = MojoCreateSharedBuffer(options, num_bytes, &handle);
87 return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
91 static jint Close(JNIEnv* env, jobject jcaller, jint mojo_handle) {
92 return MojoClose(mojo_handle);
95 static jint Wait(JNIEnv* env,
100 return MojoWait(mojo_handle, flags, deadline);
103 static jint WriteMessage(JNIEnv* env,
108 jobject handles_buffer,
110 const void* buffer_start = 0;
111 uint32_t buffer_size = 0;
113 buffer_start = env->GetDirectBufferAddress(bytes);
114 DCHECK(buffer_start);
115 DCHECK(env->GetDirectBufferCapacity(bytes) >= num_bytes);
116 buffer_size = num_bytes;
118 const MojoHandle* handles = 0;
119 uint32_t num_handles = 0;
120 if (handles_buffer) {
122 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
123 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
125 // Java code will handle invalidating handles if the write succeeded.
126 return MojoWriteMessage(
127 mojo_handle, buffer_start, buffer_size, handles, num_handles, flags);
130 static jobject ReadMessage(JNIEnv* env,
134 jobject handles_buffer,
136 void* buffer_start = 0;
137 uint32_t buffer_size = 0;
139 buffer_start = env->GetDirectBufferAddress(bytes);
140 DCHECK(buffer_start);
141 buffer_size = env->GetDirectBufferCapacity(bytes);
143 MojoHandle* handles = 0;
144 uint32_t num_handles = 0;
145 if (handles_buffer) {
147 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
148 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
150 MojoResult result = MojoReadMessage(
151 mojo_handle, buffer_start, &buffer_size, handles, &num_handles, flags);
152 // Jave code will handle taking ownership of any received handle.
153 return Java_CoreImpl_newNativeReadMessageResult(
154 env, result, buffer_size, num_handles).Release();
157 static jint ReadData(JNIEnv* env,
161 jint elements_capacity,
163 void* buffer_start = 0;
164 uint32_t buffer_size = elements_capacity;
166 buffer_start = env->GetDirectBufferAddress(elements);
167 DCHECK(buffer_start);
168 DCHECK(elements_capacity <= env->GetDirectBufferCapacity(elements));
171 MojoReadData(mojo_handle, buffer_start, &buffer_size, flags);
178 static jobject BeginReadData(JNIEnv* env,
183 void const* buffer = 0;
184 uint32_t buffer_size = num_bytes;
186 MojoBeginReadData(mojo_handle, &buffer, &buffer_size, flags);
187 jobject byte_buffer = 0;
188 if (result == MOJO_RESULT_OK) {
190 env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size);
192 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
196 static jint EndReadData(JNIEnv* env,
199 jint num_bytes_read) {
200 return MojoEndReadData(mojo_handle, num_bytes_read);
203 static jint WriteData(JNIEnv* env,
209 void* buffer_start = env->GetDirectBufferAddress(elements);
210 DCHECK(buffer_start);
211 DCHECK(limit <= env->GetDirectBufferCapacity(elements));
212 uint32_t buffer_size = limit;
214 MojoWriteData(mojo_handle, buffer_start, &buffer_size, flags);
221 static jobject BeginWriteData(JNIEnv* env,
227 uint32_t buffer_size = num_bytes;
229 MojoBeginWriteData(mojo_handle, &buffer, &buffer_size, flags);
230 jobject byte_buffer = 0;
231 if (result == MOJO_RESULT_OK) {
232 byte_buffer = env->NewDirectByteBuffer(buffer, buffer_size);
234 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
238 static jint EndWriteData(JNIEnv* env,
241 jint num_bytes_written) {
242 return MojoEndWriteData(mojo_handle, num_bytes_written);
245 static jobject Duplicate(JNIEnv* env,
248 jobject options_buffer) {
249 const MojoDuplicateBufferHandleOptions* options = 0;
250 if (options_buffer) {
251 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
252 DCHECK(buffer_start);
253 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
254 DCHECK_EQ(buffer_size, sizeof(MojoDuplicateBufferHandleOptions));
256 static_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start);
257 DCHECK_EQ(options->struct_size, buffer_size);
260 MojoResult result = MojoDuplicateBufferHandle(mojo_handle, options, &handle);
261 return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
265 static jobject Map(JNIEnv* env,
273 MojoMapBuffer(mojo_handle, offset, num_bytes, &buffer, flags);
274 jobject byte_buffer = 0;
275 if (result == MOJO_RESULT_OK) {
276 byte_buffer = env->NewDirectByteBuffer(buffer, num_bytes);
278 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
282 static int Unmap(JNIEnv* env, jobject jcaller, jobject buffer) {
283 void* buffer_start = env->GetDirectBufferAddress(buffer);
284 DCHECK(buffer_start);
285 return MojoUnmapBuffer(buffer_start);
288 bool RegisterCoreImpl(JNIEnv* env) {
289 return RegisterNativesImpl(env);
292 } // namespace android