Index: mojo/system/android/core_impl.cc |
diff --git a/mojo/system/android/core_impl.cc b/mojo/system/android/core_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3532fc69eb40426cfee0ad7005db0b38391e2099 |
--- /dev/null |
+++ b/mojo/system/android/core_impl.cc |
@@ -0,0 +1,290 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "mojo/system/android/core_impl.h" |
+ |
+#include "base/android/base_jni_registrar.h" |
+#include "base/android/jni_android.h" |
+#include "base/android/jni_registrar.h" |
+#include "base/android/library_loader/library_loader_hooks.h" |
+#include "base/logging.h" |
+#include "jni/CoreImpl_jni.h" |
+#include "mojo/embedder/embedder.h" |
+#include "mojo/public/c/system/core.h" |
+ |
+namespace mojo { |
+ |
+static void Constructor(JNIEnv* env, jobject jcaller) { |
+ mojo::embedder::Init(); |
+} |
+ |
+static jlong GetTimeTicksNow(JNIEnv* env, jobject jcaller) { |
+ return MojoGetTimeTicksNow(); |
+} |
+ |
+static jint WaitMany(JNIEnv* env, |
+ jobject jcaller, |
+ jobject buffer, |
+ jlong deadline) { |
+ // Buffer contains first the list of handles, then the list of flags. |
+ const void* buffer_start = env->GetDirectBufferAddress(buffer); |
+ DCHECK(buffer_start); |
bulach
2014/04/14 17:39:56
probably best as CHECK ?
qsr
2014/04/15 08:37:37
We do create and provide this buffer in java world
|
+ const size_t record_size = 8; |
+ const size_t buffer_size = env->GetDirectBufferCapacity(buffer); |
+ DCHECK_EQ(buffer_size % record_size, 0u); |
+ |
+ const size_t nb_handles = buffer_size / record_size; |
+ const MojoHandle* handleStart = |
bulach
2014/04/14 17:39:56
nit: handle_start
qsr
2014/04/15 08:37:37
Done.
|
+ reinterpret_cast<const MojoHandle*>(buffer_start); |
viettrungluu
2014/04/14 18:02:50
nit (here and everywhere else): (const) void* -> (
qsr
2014/04/15 08:37:37
Done.
|
+ const MojoWaitFlags* flagsStart = |
+ reinterpret_cast<const MojoWaitFlags*>(handleStart + nb_handles); |
+ return MojoWaitMany(handleStart, flagsStart, nb_handles, deadline); |
+} |
+ |
+static jobject CreateMessagePipe(JNIEnv* env, jobject jcaller) { |
+ MojoHandle handle1, handle2; |
bulach
2014/04/14 17:39:56
nit: one per line. also, perhaps input / output?
qsr
2014/04/15 08:37:37
message pipe are bidi, there is no input output he
|
+ MojoResult result = MojoCreateMessagePipe(&handle1, &handle2); |
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2) |
+ .Release(); |
+} |
+ |
+static jobject CreateDataPipe(JNIEnv* env, |
+ jobject jcaller, |
+ jobject optionsBuffer) { |
bulach
2014/04/14 17:39:56
nit: s/sBuffer/s_buffer/
qsr
2014/04/15 08:37:37
Done.
|
+ const MojoCreateDataPipeOptions* options = NULL; |
+ if (optionsBuffer) { |
+ const void* buffer_start = env->GetDirectBufferAddress(optionsBuffer); |
+ DCHECK(buffer_start); |
+ const size_t buffer_size = env->GetDirectBufferCapacity(optionsBuffer); |
+ DCHECK_EQ(buffer_size, sizeof(MojoCreateDataPipeOptions)); |
bulach
2014/04/14 17:39:56
CHECKs ?
viettrungluu
2014/04/14 18:02:50
Note that the various Mojo...Options structures ar
qsr
2014/04/15 08:37:37
Well, they are extensible in a C++ word, where the
qsr
2014/04/15 08:37:37
Same as above. This is completely on our control.
|
+ options = reinterpret_cast<const MojoCreateDataPipeOptions*>(buffer_start); |
+ DCHECK_EQ(options->struct_size, buffer_size); |
viettrungluu
2014/04/14 18:02:50
Depending on the amount of safety we want to enfor
qsr
2014/04/15 08:37:37
The buffer creation is done in the java code, tran
|
+ } |
+ MojoHandle handle1, handle2; |
+ MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2); |
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2) |
+ .Release(); |
+} |
+ |
+static jobject CreateSharedBuffer(JNIEnv* env, |
+ jobject jcaller, |
+ jobject optionsBuffer, |
+ jlong numBytes) { |
bulach
2014/04/14 17:39:56
nit: s/mBytes/m_bytes/, s/sBuffer/s_buffer/
qsr
2014/04/15 08:37:37
Done.
|
+ const MojoCreateSharedBufferOptions* options = 0; |
+ if (optionsBuffer) { |
+ const void* buffer_start = env->GetDirectBufferAddress(optionsBuffer); |
+ DCHECK(buffer_start); |
+ const size_t buffer_size = env->GetDirectBufferCapacity(optionsBuffer); |
+ DCHECK_EQ(buffer_size, sizeof(MojoCreateSharedBufferOptions)); |
+ options = |
+ reinterpret_cast<const MojoCreateSharedBufferOptions*>(buffer_start); |
+ DCHECK_EQ(options->struct_size, buffer_size); |
+ } |
+ MojoHandle handle; |
+ MojoResult result = MojoCreateSharedBuffer(options, numBytes, &handle); |
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0) |
+ .Release(); |
+} |
+ |
+static jint Close(JNIEnv* env, jobject jcaller, jint mojoHandle) { |
+ return MojoClose(mojoHandle); |
+} |
+ |
+static jint Wait(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jint flags, |
+ jlong deadline) { |
+ return MojoWait(mojoHandle, flags, deadline); |
+} |
+ |
+static jint WriteMessage(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jobject bytes, |
+ jint numBytes, |
+ jobject handlesBuffer, |
+ jint flags) { |
+ const void* buffer_start = 0; |
+ uint32_t buffer_size = 0; |
+ if (bytes) { |
+ buffer_start = env->GetDirectBufferAddress(bytes); |
+ DCHECK(buffer_start); |
+ DCHECK(env->GetDirectBufferCapacity(bytes) >= numBytes); |
+ buffer_size = numBytes; |
+ } |
+ const MojoHandle* handles = 0; |
+ uint32_t num_handles = 0; |
+ if (handlesBuffer) { |
+ handles = reinterpret_cast<MojoHandle*>( |
+ env->GetDirectBufferAddress(handlesBuffer)); |
+ num_handles = env->GetDirectBufferCapacity(handlesBuffer) / 4; |
+ } |
+ // Java code will handle invalidating handles if the write succeeded. |
+ return MojoWriteMessage( |
+ mojoHandle, buffer_start, buffer_size, handles, num_handles, flags); |
+} |
+ |
+static jobject ReadMessage(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jobject bytes, |
+ jobject handlesBuffer, |
+ jint flags) { |
+ void* buffer_start = 0; |
+ uint32_t buffer_size = 0; |
+ if (bytes) { |
+ buffer_start = env->GetDirectBufferAddress(bytes); |
+ DCHECK(buffer_start); |
+ buffer_size = env->GetDirectBufferCapacity(bytes); |
bulach
2014/04/14 17:39:56
I'd create a simple java wrapper and use our own J
qsr
2014/04/15 08:37:37
I'm sorry, but I do not understand what you mean.
|
+ } |
+ MojoHandle* handles = 0; |
+ uint32_t num_handles = 0; |
+ if (handlesBuffer) { |
+ handles = reinterpret_cast<MojoHandle*>( |
+ env->GetDirectBufferAddress(handlesBuffer)); |
+ num_handles = env->GetDirectBufferCapacity(handlesBuffer) / 4; |
+ } |
+ MojoResult result = MojoReadMessage( |
+ mojoHandle, buffer_start, &buffer_size, handles, &num_handles, flags); |
+ // Jave code will handle taking ownership of any received handle. |
+ return Java_CoreImpl_newNativeReadMessageResult( |
+ env, result, buffer_size, num_handles).Release(); |
+} |
+ |
+static jint ReadData(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jobject elements, |
+ jint flags) { |
+ void* buffer_start = 0; |
+ uint32_t buffer_size = 0; |
+ if (elements) { |
+ buffer_start = env->GetDirectBufferAddress(elements); |
+ DCHECK(buffer_start); |
+ buffer_size = env->GetDirectBufferCapacity(elements); |
+ } |
+ MojoResult result = |
+ MojoReadData(mojoHandle, buffer_start, &buffer_size, flags); |
+ if (result < 0) { |
+ return result; |
+ } |
+ return buffer_size; |
+} |
+ |
+static jobject BeginReadData(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jint numBytes, |
+ jint flags) { |
+ void const* buffer = 0; |
+ uint32_t buffer_size = numBytes; |
+ MojoResult result = |
+ MojoBeginReadData(mojoHandle, &buffer, &buffer_size, flags); |
+ jobject byte_buffer = 0; |
+ if (result == MOJO_RESULT_OK) { |
+ byte_buffer = |
+ env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size); |
+ } |
+ return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer) |
+ .Release(); |
+} |
+ |
+static jint EndReadData(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jint numBytesRead) { |
+ return MojoEndReadData(mojoHandle, numBytesRead); |
+} |
+ |
+static jint WriteData(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jobject elements, |
+ jint limit, |
+ jint flags) { |
+ void* buffer_start = env->GetDirectBufferAddress(elements); |
+ DCHECK(buffer_start); |
+ DCHECK(limit <= env->GetDirectBufferCapacity(elements)); |
+ uint32_t buffer_size = limit; |
+ MojoResult result = |
+ MojoWriteData(mojoHandle, buffer_start, &buffer_size, flags); |
+ if (result < 0) { |
+ return result; |
+ } |
+ return buffer_size; |
+} |
+ |
+static jobject BeginWriteData(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jint numBytes, |
+ jint flags) { |
+ void* buffer = 0; |
+ uint32_t buffer_size = numBytes; |
+ MojoResult result = |
+ MojoBeginWriteData(mojoHandle, &buffer, &buffer_size, flags); |
+ jobject byte_buffer = 0; |
+ if (result == MOJO_RESULT_OK) { |
+ byte_buffer = env->NewDirectByteBuffer(buffer, buffer_size); |
+ } |
+ return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer) |
+ .Release(); |
+} |
+ |
+static jint EndWriteData(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jint numBytesWritten) { |
bulach
2014/04/14 17:39:56
s/mBytesW/m_bytes_w/ (similarly for other paramete
qsr
2014/04/15 08:37:37
Done.
|
+ return MojoEndWriteData(mojoHandle, numBytesWritten); |
+} |
+ |
+static jobject Duplicate(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jobject optionsBuffer) { |
+ const MojoDuplicateBufferHandleOptions* options = 0; |
+ if (optionsBuffer) { |
+ const void* buffer_start = env->GetDirectBufferAddress(optionsBuffer); |
+ DCHECK(buffer_start); |
+ const size_t buffer_size = env->GetDirectBufferCapacity(optionsBuffer); |
+ DCHECK_EQ(buffer_size, sizeof(MojoDuplicateBufferHandleOptions)); |
+ options = |
+ reinterpret_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start); |
+ DCHECK_EQ(options->struct_size, buffer_size); |
+ } |
+ MojoHandle handle; |
+ MojoResult result = MojoDuplicateBufferHandle(mojoHandle, options, &handle); |
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0) |
+ .Release(); |
+} |
+ |
+static jobject Map(JNIEnv* env, |
+ jobject jcaller, |
+ jint mojoHandle, |
+ jlong offset, |
+ jlong numBytes, |
+ jint flags) { |
+ void* buffer = 0; |
+ MojoResult result = |
+ MojoMapBuffer(mojoHandle, offset, numBytes, &buffer, flags); |
+ jobject byte_buffer = 0; |
+ if (result == MOJO_RESULT_OK) { |
+ byte_buffer = env->NewDirectByteBuffer(buffer, numBytes); |
+ } |
+ return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer) |
+ .Release(); |
+} |
+ |
+static int Unmap(JNIEnv* env, jobject jcaller, jobject buffer) { |
+ void* buffer_start = env->GetDirectBufferAddress(buffer); |
+ DCHECK(buffer_start); |
+ return MojoUnmapBuffer(buffer_start); |
+} |
+ |
+bool RegisterCoreImpl(JNIEnv* env) { |
+ return RegisterNativesImpl(env); |
+} |
+ |
+} // namespace mojo |