ServiceWorker: Send state change events via SWProviderHost
[chromium-blink-merge.git] / mojo / android / system / core_impl.cc
blob55a374e50bcba68e1bff0ef41548c9278b2052a6
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/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "jni/CoreImpl_jni.h"
16 #include "mojo/public/c/environment/async_waiter.h"
17 #include "mojo/public/c/system/core.h"
18 #include "mojo/public/cpp/environment/environment.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 jlong GetTimeTicksNow(JNIEnv* env, jobject jcaller) {
53 return MojoGetTimeTicksNow();
56 static jint WaitMany(JNIEnv* env,
57 jobject jcaller,
58 jobject buffer,
59 jlong deadline) {
60 // |buffer| contains, in this order
61 // input: The array of N handles (MojoHandle, 4 bytes each)
62 // input: The array of N signals (MojoHandleSignals, 4 bytes each)
63 // space for output: The array of N handle states (MojoHandleSignalsState, 8
64 // bytes each)
65 // space for output: The result index (uint32_t, 4 bytes)
66 uint8_t* buffer_start =
67 static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
68 DCHECK(buffer_start);
69 DCHECK_EQ(reinterpret_cast<uintptr_t>(buffer_start) % 8, 0u);
70 // Each handle of the input array contributes 4 (MojoHandle) + 4
71 // (MojoHandleSignals) + 8 (MojoHandleSignalsState) = 16 bytes to the size of
72 // the buffer.
73 const size_t size_per_handle = 16;
74 const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
75 DCHECK_EQ((buffer_size - 4) % size_per_handle, 0u);
77 const size_t nb_handles = (buffer_size - 4) / size_per_handle;
78 const MojoHandle* handle_start =
79 reinterpret_cast<const MojoHandle*>(buffer_start);
80 const MojoHandleSignals* signals_start =
81 reinterpret_cast<const MojoHandleSignals*>(buffer_start + 4 * nb_handles);
82 MojoHandleSignalsState* states_start =
83 reinterpret_cast<MojoHandleSignalsState*>(buffer_start + 8 * nb_handles);
84 uint32_t* result_index =
85 reinterpret_cast<uint32_t*>(buffer_start + 16 * nb_handles);
86 *result_index = static_cast<uint32_t>(-1);
87 return MojoWaitMany(handle_start, signals_start, nb_handles, deadline,
88 result_index, states_start);
91 static jobject CreateMessagePipe(JNIEnv* env,
92 jobject jcaller,
93 jobject options_buffer) {
94 const MojoCreateMessagePipeOptions* options = NULL;
95 if (options_buffer) {
96 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
97 DCHECK(buffer_start);
98 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
99 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
100 DCHECK_EQ(buffer_size, sizeof(MojoCreateMessagePipeOptions));
101 options = static_cast<const MojoCreateMessagePipeOptions*>(buffer_start);
102 DCHECK_EQ(options->struct_size, buffer_size);
104 MojoHandle handle1;
105 MojoHandle handle2;
106 MojoResult result = MojoCreateMessagePipe(options, &handle1, &handle2);
107 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
108 .Release();
111 static jobject CreateDataPipe(JNIEnv* env,
112 jobject jcaller,
113 jobject options_buffer) {
114 const MojoCreateDataPipeOptions* options = NULL;
115 if (options_buffer) {
116 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
117 DCHECK(buffer_start);
118 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
119 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
120 DCHECK_EQ(buffer_size, sizeof(MojoCreateDataPipeOptions));
121 options = static_cast<const MojoCreateDataPipeOptions*>(buffer_start);
122 DCHECK_EQ(options->struct_size, buffer_size);
124 MojoHandle handle1;
125 MojoHandle handle2;
126 MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2);
127 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
128 .Release();
131 static jobject CreateSharedBuffer(JNIEnv* env,
132 jobject jcaller,
133 jobject options_buffer,
134 jlong num_bytes) {
135 const MojoCreateSharedBufferOptions* options = 0;
136 if (options_buffer) {
137 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
138 DCHECK(buffer_start);
139 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
140 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
141 DCHECK_EQ(buffer_size, sizeof(MojoCreateSharedBufferOptions));
142 options = static_cast<const MojoCreateSharedBufferOptions*>(buffer_start);
143 DCHECK_EQ(options->struct_size, buffer_size);
145 MojoHandle handle;
146 MojoResult result = MojoCreateSharedBuffer(options, num_bytes, &handle);
147 return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
148 .Release();
151 static jint Close(JNIEnv* env, jobject jcaller, jint mojo_handle) {
152 return MojoClose(mojo_handle);
155 static jint Wait(JNIEnv* env,
156 jobject jcaller,
157 jobject buffer,
158 jint mojo_handle,
159 jint signals,
160 jlong deadline) {
161 // Buffer contains space for the MojoHandleSignalsState
162 void* buffer_start = env->GetDirectBufferAddress(buffer);
163 DCHECK(buffer_start);
164 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
165 DCHECK_EQ(sizeof(struct MojoHandleSignalsState),
166 static_cast<size_t>(env->GetDirectBufferCapacity(buffer)));
167 struct MojoHandleSignalsState* signals_state =
168 static_cast<struct MojoHandleSignalsState*>(buffer_start);
169 return MojoWait(mojo_handle, signals, deadline, signals_state);
172 static jint WriteMessage(JNIEnv* env,
173 jobject jcaller,
174 jint mojo_handle,
175 jobject bytes,
176 jint num_bytes,
177 jobject handles_buffer,
178 jint flags) {
179 const void* buffer_start = 0;
180 uint32_t buffer_size = 0;
181 if (bytes) {
182 buffer_start = env->GetDirectBufferAddress(bytes);
183 DCHECK(buffer_start);
184 DCHECK(env->GetDirectBufferCapacity(bytes) >= num_bytes);
185 buffer_size = num_bytes;
187 const MojoHandle* handles = 0;
188 uint32_t num_handles = 0;
189 if (handles_buffer) {
190 handles =
191 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
192 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
194 // Java code will handle invalidating handles if the write succeeded.
195 return MojoWriteMessage(
196 mojo_handle, buffer_start, buffer_size, handles, num_handles, flags);
199 static jobject ReadMessage(JNIEnv* env,
200 jobject jcaller,
201 jint mojo_handle,
202 jobject bytes,
203 jobject handles_buffer,
204 jint flags) {
205 void* buffer_start = 0;
206 uint32_t buffer_size = 0;
207 if (bytes) {
208 buffer_start = env->GetDirectBufferAddress(bytes);
209 DCHECK(buffer_start);
210 buffer_size = env->GetDirectBufferCapacity(bytes);
212 MojoHandle* handles = 0;
213 uint32_t num_handles = 0;
214 if (handles_buffer) {
215 handles =
216 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
217 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
219 MojoResult result = MojoReadMessage(
220 mojo_handle, buffer_start, &buffer_size, handles, &num_handles, flags);
221 // Jave code will handle taking ownership of any received handle.
222 return Java_CoreImpl_newReadMessageResult(
223 env, result, buffer_size, num_handles).Release();
226 static jint ReadData(JNIEnv* env,
227 jobject jcaller,
228 jint mojo_handle,
229 jobject elements,
230 jint elements_capacity,
231 jint flags) {
232 void* buffer_start = 0;
233 uint32_t buffer_size = elements_capacity;
234 if (elements) {
235 buffer_start = env->GetDirectBufferAddress(elements);
236 DCHECK(buffer_start);
237 DCHECK(elements_capacity <= env->GetDirectBufferCapacity(elements));
239 MojoResult result =
240 MojoReadData(mojo_handle, buffer_start, &buffer_size, flags);
241 if (result < 0) {
242 return result;
244 return buffer_size;
247 static jobject BeginReadData(JNIEnv* env,
248 jobject jcaller,
249 jint mojo_handle,
250 jint num_bytes,
251 jint flags) {
252 void const* buffer = 0;
253 uint32_t buffer_size = num_bytes;
254 MojoResult result =
255 MojoBeginReadData(mojo_handle, &buffer, &buffer_size, flags);
256 jobject byte_buffer = 0;
257 if (result == MOJO_RESULT_OK) {
258 byte_buffer =
259 env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size);
261 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
262 .Release();
265 static jint EndReadData(JNIEnv* env,
266 jobject jcaller,
267 jint mojo_handle,
268 jint num_bytes_read) {
269 return MojoEndReadData(mojo_handle, num_bytes_read);
272 static jint WriteData(JNIEnv* env,
273 jobject jcaller,
274 jint mojo_handle,
275 jobject elements,
276 jint limit,
277 jint flags) {
278 void* buffer_start = env->GetDirectBufferAddress(elements);
279 DCHECK(buffer_start);
280 DCHECK(limit <= env->GetDirectBufferCapacity(elements));
281 uint32_t buffer_size = limit;
282 MojoResult result =
283 MojoWriteData(mojo_handle, buffer_start, &buffer_size, flags);
284 if (result < 0) {
285 return result;
287 return buffer_size;
290 static jobject BeginWriteData(JNIEnv* env,
291 jobject jcaller,
292 jint mojo_handle,
293 jint num_bytes,
294 jint flags) {
295 void* buffer = 0;
296 uint32_t buffer_size = num_bytes;
297 MojoResult result =
298 MojoBeginWriteData(mojo_handle, &buffer, &buffer_size, flags);
299 jobject byte_buffer = 0;
300 if (result == MOJO_RESULT_OK) {
301 byte_buffer = env->NewDirectByteBuffer(buffer, buffer_size);
303 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
304 .Release();
307 static jint EndWriteData(JNIEnv* env,
308 jobject jcaller,
309 jint mojo_handle,
310 jint num_bytes_written) {
311 return MojoEndWriteData(mojo_handle, num_bytes_written);
314 static jobject Duplicate(JNIEnv* env,
315 jobject jcaller,
316 jint mojo_handle,
317 jobject options_buffer) {
318 const MojoDuplicateBufferHandleOptions* options = 0;
319 if (options_buffer) {
320 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
321 DCHECK(buffer_start);
322 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
323 DCHECK_EQ(buffer_size, sizeof(MojoDuplicateBufferHandleOptions));
324 options =
325 static_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start);
326 DCHECK_EQ(options->struct_size, buffer_size);
328 MojoHandle handle;
329 MojoResult result = MojoDuplicateBufferHandle(mojo_handle, options, &handle);
330 return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
331 .Release();
334 static jobject Map(JNIEnv* env,
335 jobject jcaller,
336 jint mojo_handle,
337 jlong offset,
338 jlong num_bytes,
339 jint flags) {
340 void* buffer = 0;
341 MojoResult result =
342 MojoMapBuffer(mojo_handle, offset, num_bytes, &buffer, flags);
343 jobject byte_buffer = 0;
344 if (result == MOJO_RESULT_OK) {
345 byte_buffer = env->NewDirectByteBuffer(buffer, num_bytes);
347 return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
348 .Release();
351 static int Unmap(JNIEnv* env, jobject jcaller, jobject buffer) {
352 void* buffer_start = env->GetDirectBufferAddress(buffer);
353 DCHECK(buffer_start);
354 return MojoUnmapBuffer(buffer_start);
357 static jobject AsyncWait(JNIEnv* env,
358 jobject jcaller,
359 jint mojo_handle,
360 jint signals,
361 jlong deadline,
362 jobject callback) {
363 AsyncWaitCallbackData* callback_data =
364 new AsyncWaitCallbackData(env, jcaller, callback);
365 MojoAsyncWaitID cancel_id;
366 if (static_cast<MojoHandle>(mojo_handle) != MOJO_HANDLE_INVALID) {
367 cancel_id = Environment::GetDefaultAsyncWaiter()->AsyncWait(
368 mojo_handle, signals, deadline, AsyncWaitCallback, callback_data);
369 } else {
370 cancel_id = kInvalidHandleCancelID;
371 base::MessageLoop::current()->PostTask(
372 FROM_HERE,
373 base::Bind(
374 &AsyncWaitCallback, callback_data, MOJO_RESULT_INVALID_ARGUMENT));
376 base::android::ScopedJavaLocalRef<jobject> cancellable =
377 Java_CoreImpl_newAsyncWaiterCancellableImpl(
378 env, jcaller, cancel_id, reinterpret_cast<intptr_t>(callback_data));
379 callback_data->cancellable.Reset(env, cancellable.obj());
380 return cancellable.Release();
383 static void CancelAsyncWait(JNIEnv* env,
384 jobject jcaller,
385 jlong id,
386 jlong data_ptr) {
387 if (id == 0) {
388 // If |id| is |kInvalidHandleCancelID|, the async wait was done on an
389 // invalid handle, so the AsyncWaitCallback will be called and will clear
390 // the data_ptr.
391 return;
393 scoped_ptr<AsyncWaitCallbackData> deleter(
394 reinterpret_cast<AsyncWaitCallbackData*>(data_ptr));
395 Environment::GetDefaultAsyncWaiter()->CancelWait(id);
398 bool RegisterCoreImpl(JNIEnv* env) {
399 return RegisterNativesImpl(env);
402 } // namespace android
403 } // namespace mojo