Chromium Code Reviews| 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 |