Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / android / system / core_impl.cc
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.
4
5 #include "mojo/android/system/core_impl.h"
6
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"
15
16 namespace mojo {
17 namespace android {
18
19 static void Constructor(JNIEnv* env, jobject jcaller) {
20   mojo::embedder::Init();
21 }
22
23 static jlong GetTimeTicksNow(JNIEnv* env, jobject jcaller) {
24   return MojoGetTimeTicksNow();
25 }
26
27 static jint WaitMany(JNIEnv* env,
28                      jobject jcaller,
29                      jobject buffer,
30                      jlong deadline) {
31   // Buffer contains first the list of handles, then the list of flags.
32   const void* buffer_start = env->GetDirectBufferAddress(buffer);
33   DCHECK(buffer_start);
34   const size_t record_size = 8;
35   const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
36   DCHECK_EQ(buffer_size % record_size, 0u);
37
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);
43 }
44
45 static jobject CreateMessagePipe(JNIEnv* env, jobject jcaller) {
46   MojoHandle handle1;
47   MojoHandle handle2;
48   MojoResult result = MojoCreateMessagePipe(&handle1, &handle2);
49   return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
50       .Release();
51 }
52
53 static jobject CreateDataPipe(JNIEnv* env,
54                               jobject jcaller,
55                               jobject options_buffer) {
56   const MojoCreateDataPipeOptions* options = NULL;
57   if (options_buffer) {
58     const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
59     DCHECK(buffer_start);
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);
64   }
65   MojoHandle handle1;
66   MojoHandle handle2;
67   MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2);
68   return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
69       .Release();
70 }
71
72 static jobject CreateSharedBuffer(JNIEnv* env,
73                                   jobject jcaller,
74                                   jobject options_buffer,
75                                   jlong num_bytes) {
76   const MojoCreateSharedBufferOptions* options = 0;
77   if (options_buffer) {
78     const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
79     DCHECK(buffer_start);
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);
84   }
85   MojoHandle handle;
86   MojoResult result = MojoCreateSharedBuffer(options, num_bytes, &handle);
87   return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
88       .Release();
89 }
90
91 static jint Close(JNIEnv* env, jobject jcaller, jint mojo_handle) {
92   return MojoClose(mojo_handle);
93 }
94
95 static jint Wait(JNIEnv* env,
96                  jobject jcaller,
97                  jint mojo_handle,
98                  jint flags,
99                  jlong deadline) {
100   return MojoWait(mojo_handle, flags, deadline);
101 }
102
103 static jint WriteMessage(JNIEnv* env,
104                          jobject jcaller,
105                          jint mojo_handle,
106                          jobject bytes,
107                          jint num_bytes,
108                          jobject handles_buffer,
109                          jint flags) {
110   const void* buffer_start = 0;
111   uint32_t buffer_size = 0;
112   if (bytes) {
113     buffer_start = env->GetDirectBufferAddress(bytes);
114     DCHECK(buffer_start);
115     DCHECK(env->GetDirectBufferCapacity(bytes) >= num_bytes);
116     buffer_size = num_bytes;
117   }
118   const MojoHandle* handles = 0;
119   uint32_t num_handles = 0;
120   if (handles_buffer) {
121     handles =
122         static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
123     num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
124   }
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);
128 }
129
130 static jobject ReadMessage(JNIEnv* env,
131                            jobject jcaller,
132                            jint mojo_handle,
133                            jobject bytes,
134                            jobject handles_buffer,
135                            jint flags) {
136   void* buffer_start = 0;
137   uint32_t buffer_size = 0;
138   if (bytes) {
139     buffer_start = env->GetDirectBufferAddress(bytes);
140     DCHECK(buffer_start);
141     buffer_size = env->GetDirectBufferCapacity(bytes);
142   }
143   MojoHandle* handles = 0;
144   uint32_t num_handles = 0;
145   if (handles_buffer) {
146     handles =
147         static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
148     num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
149   }
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();
155 }
156
157 static jint ReadData(JNIEnv* env,
158                      jobject jcaller,
159                      jint mojo_handle,
160                      jobject elements,
161                      jint elements_capacity,
162                      jint flags) {
163   void* buffer_start = 0;
164   uint32_t buffer_size = elements_capacity;
165   if (elements) {
166     buffer_start = env->GetDirectBufferAddress(elements);
167     DCHECK(buffer_start);
168     DCHECK(elements_capacity <= env->GetDirectBufferCapacity(elements));
169   }
170   MojoResult result =
171       MojoReadData(mojo_handle, buffer_start, &buffer_size, flags);
172   if (result < 0) {
173     return result;
174   }
175   return buffer_size;
176 }
177
178 static jobject BeginReadData(JNIEnv* env,
179                              jobject jcaller,
180                              jint mojo_handle,
181                              jint num_bytes,
182                              jint flags) {
183   void const* buffer = 0;
184   uint32_t buffer_size = num_bytes;
185   MojoResult result =
186       MojoBeginReadData(mojo_handle, &buffer, &buffer_size, flags);
187   jobject byte_buffer = 0;
188   if (result == MOJO_RESULT_OK) {
189     byte_buffer =
190         env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size);
191   }
192   return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
193       .Release();
194 }
195
196 static jint EndReadData(JNIEnv* env,
197                         jobject jcaller,
198                         jint mojo_handle,
199                         jint num_bytes_read) {
200   return MojoEndReadData(mojo_handle, num_bytes_read);
201 }
202
203 static jint WriteData(JNIEnv* env,
204                       jobject jcaller,
205                       jint mojo_handle,
206                       jobject elements,
207                       jint limit,
208                       jint flags) {
209   void* buffer_start = env->GetDirectBufferAddress(elements);
210   DCHECK(buffer_start);
211   DCHECK(limit <= env->GetDirectBufferCapacity(elements));
212   uint32_t buffer_size = limit;
213   MojoResult result =
214       MojoWriteData(mojo_handle, buffer_start, &buffer_size, flags);
215   if (result < 0) {
216     return result;
217   }
218   return buffer_size;
219 }
220
221 static jobject BeginWriteData(JNIEnv* env,
222                               jobject jcaller,
223                               jint mojo_handle,
224                               jint num_bytes,
225                               jint flags) {
226   void* buffer = 0;
227   uint32_t buffer_size = num_bytes;
228   MojoResult result =
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);
233   }
234   return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
235       .Release();
236 }
237
238 static jint EndWriteData(JNIEnv* env,
239                          jobject jcaller,
240                          jint mojo_handle,
241                          jint num_bytes_written) {
242   return MojoEndWriteData(mojo_handle, num_bytes_written);
243 }
244
245 static jobject Duplicate(JNIEnv* env,
246                          jobject jcaller,
247                          jint mojo_handle,
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));
255     options =
256         static_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start);
257     DCHECK_EQ(options->struct_size, buffer_size);
258   }
259   MojoHandle handle;
260   MojoResult result = MojoDuplicateBufferHandle(mojo_handle, options, &handle);
261   return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
262       .Release();
263 }
264
265 static jobject Map(JNIEnv* env,
266                    jobject jcaller,
267                    jint mojo_handle,
268                    jlong offset,
269                    jlong num_bytes,
270                    jint flags) {
271   void* buffer = 0;
272   MojoResult result =
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);
277   }
278   return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
279       .Release();
280 }
281
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);
286 }
287
288 bool RegisterCoreImpl(JNIEnv* env) {
289   return RegisterNativesImpl(env);
290 }
291
292 }  // namespace android
293 }  // namespace mojo