Delete historical data usage from store when user clears data usage.
[chromium-blink-merge.git] / mojo / android / system / core_impl.cc
blob21589876b4897a2b13f94f73c1e58b9da6dda849
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,
53 const JavaParamRef<jobject>& jcaller) {
54 return MojoGetTimeTicksNow();
57 static jint WaitMany(JNIEnv* env,
58 const JavaParamRef<jobject>& jcaller,
59 const JavaParamRef<jobject>& buffer,
60 jlong deadline) {
61 // |buffer| contains, in this order
62 // input: The array of N handles (MojoHandle, 4 bytes each)
63 // input: The array of N signals (MojoHandleSignals, 4 bytes each)
64 // space for output: The array of N handle states (MojoHandleSignalsState, 8
65 // bytes each)
66 // space for output: The result index (uint32_t, 4 bytes)
67 uint8_t* buffer_start =
68 static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
69 DCHECK(buffer_start);
70 DCHECK_EQ(reinterpret_cast<uintptr_t>(buffer_start) % 8, 0u);
71 // Each handle of the input array contributes 4 (MojoHandle) + 4
72 // (MojoHandleSignals) + 8 (MojoHandleSignalsState) = 16 bytes to the size of
73 // the buffer.
74 const size_t size_per_handle = 16;
75 const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
76 DCHECK_EQ((buffer_size - 4) % size_per_handle, 0u);
78 const size_t nb_handles = (buffer_size - 4) / size_per_handle;
79 const MojoHandle* handle_start =
80 reinterpret_cast<const MojoHandle*>(buffer_start);
81 const MojoHandleSignals* signals_start =
82 reinterpret_cast<const MojoHandleSignals*>(buffer_start + 4 * nb_handles);
83 MojoHandleSignalsState* states_start =
84 reinterpret_cast<MojoHandleSignalsState*>(buffer_start + 8 * nb_handles);
85 uint32_t* result_index =
86 reinterpret_cast<uint32_t*>(buffer_start + 16 * nb_handles);
87 *result_index = static_cast<uint32_t>(-1);
88 return MojoWaitMany(handle_start, signals_start, nb_handles, deadline,
89 result_index, states_start);
92 static ScopedJavaLocalRef<jobject> CreateMessagePipe(
93 JNIEnv* env,
94 const JavaParamRef<jobject>& jcaller,
95 const JavaParamRef<jobject>& options_buffer) {
96 const MojoCreateMessagePipeOptions* options = NULL;
97 if (options_buffer) {
98 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
99 DCHECK(buffer_start);
100 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
101 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
102 DCHECK_EQ(buffer_size, sizeof(MojoCreateMessagePipeOptions));
103 options = static_cast<const MojoCreateMessagePipeOptions*>(buffer_start);
104 DCHECK_EQ(options->struct_size, buffer_size);
106 MojoHandle handle1;
107 MojoHandle handle2;
108 MojoResult result = MojoCreateMessagePipe(options, &handle1, &handle2);
109 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2);
112 static ScopedJavaLocalRef<jobject> CreateDataPipe(
113 JNIEnv* env,
114 const JavaParamRef<jobject>& jcaller,
115 const JavaParamRef<jobject>& options_buffer) {
116 const MojoCreateDataPipeOptions* options = NULL;
117 if (options_buffer) {
118 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
119 DCHECK(buffer_start);
120 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
121 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
122 DCHECK_EQ(buffer_size, sizeof(MojoCreateDataPipeOptions));
123 options = static_cast<const MojoCreateDataPipeOptions*>(buffer_start);
124 DCHECK_EQ(options->struct_size, buffer_size);
126 MojoHandle handle1;
127 MojoHandle handle2;
128 MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2);
129 return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2);
132 static ScopedJavaLocalRef<jobject> CreateSharedBuffer(
133 JNIEnv* env,
134 const JavaParamRef<jobject>& jcaller,
135 const JavaParamRef<jobject>& options_buffer,
136 jlong num_bytes) {
137 const MojoCreateSharedBufferOptions* options = 0;
138 if (options_buffer) {
139 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
140 DCHECK(buffer_start);
141 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
142 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
143 DCHECK_EQ(buffer_size, sizeof(MojoCreateSharedBufferOptions));
144 options = static_cast<const MojoCreateSharedBufferOptions*>(buffer_start);
145 DCHECK_EQ(options->struct_size, buffer_size);
147 MojoHandle handle;
148 MojoResult result = MojoCreateSharedBuffer(options, num_bytes, &handle);
149 return Java_CoreImpl_newResultAndInteger(env, result, handle);
152 static jint Close(JNIEnv* env,
153 const JavaParamRef<jobject>& jcaller,
154 jint mojo_handle) {
155 return MojoClose(mojo_handle);
158 static jint Wait(JNIEnv* env,
159 const JavaParamRef<jobject>& jcaller,
160 const JavaParamRef<jobject>& buffer,
161 jint mojo_handle,
162 jint signals,
163 jlong deadline) {
164 // Buffer contains space for the MojoHandleSignalsState
165 void* buffer_start = env->GetDirectBufferAddress(buffer);
166 DCHECK(buffer_start);
167 DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
168 DCHECK_EQ(sizeof(struct MojoHandleSignalsState),
169 static_cast<size_t>(env->GetDirectBufferCapacity(buffer)));
170 struct MojoHandleSignalsState* signals_state =
171 static_cast<struct MojoHandleSignalsState*>(buffer_start);
172 return MojoWait(mojo_handle, signals, deadline, signals_state);
175 static jint WriteMessage(JNIEnv* env,
176 const JavaParamRef<jobject>& jcaller,
177 jint mojo_handle,
178 const JavaParamRef<jobject>& bytes,
179 jint num_bytes,
180 const JavaParamRef<jobject>& handles_buffer,
181 jint flags) {
182 const void* buffer_start = 0;
183 uint32_t buffer_size = 0;
184 if (bytes) {
185 buffer_start = env->GetDirectBufferAddress(bytes);
186 DCHECK(buffer_start);
187 DCHECK(env->GetDirectBufferCapacity(bytes) >= num_bytes);
188 buffer_size = num_bytes;
190 const MojoHandle* handles = 0;
191 uint32_t num_handles = 0;
192 if (handles_buffer) {
193 handles =
194 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
195 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
197 // Java code will handle invalidating handles if the write succeeded.
198 return MojoWriteMessage(
199 mojo_handle, buffer_start, buffer_size, handles, num_handles, flags);
202 static ScopedJavaLocalRef<jobject> ReadMessage(
203 JNIEnv* env,
204 const JavaParamRef<jobject>& jcaller,
205 jint mojo_handle,
206 const JavaParamRef<jobject>& bytes,
207 const JavaParamRef<jobject>& handles_buffer,
208 jint flags) {
209 void* buffer_start = 0;
210 uint32_t buffer_size = 0;
211 if (bytes) {
212 buffer_start = env->GetDirectBufferAddress(bytes);
213 DCHECK(buffer_start);
214 buffer_size = env->GetDirectBufferCapacity(bytes);
216 MojoHandle* handles = 0;
217 uint32_t num_handles = 0;
218 if (handles_buffer) {
219 handles =
220 static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
221 num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
223 MojoResult result = MojoReadMessage(
224 mojo_handle, buffer_start, &buffer_size, handles, &num_handles, flags);
225 // Jave code will handle taking ownership of any received handle.
226 return Java_CoreImpl_newReadMessageResult(env, result, buffer_size,
227 num_handles);
230 static ScopedJavaLocalRef<jobject> ReadData(
231 JNIEnv* env,
232 const JavaParamRef<jobject>& jcaller,
233 jint mojo_handle,
234 const JavaParamRef<jobject>& elements,
235 jint elements_capacity,
236 jint flags) {
237 void* buffer_start = 0;
238 uint32_t buffer_size = elements_capacity;
239 if (elements) {
240 buffer_start = env->GetDirectBufferAddress(elements);
241 DCHECK(buffer_start);
242 DCHECK(elements_capacity <= env->GetDirectBufferCapacity(elements));
244 MojoResult result =
245 MojoReadData(mojo_handle, buffer_start, &buffer_size, flags);
246 return Java_CoreImpl_newResultAndInteger(
247 env, result, (result == MOJO_RESULT_OK) ? buffer_size : 0);
250 static ScopedJavaLocalRef<jobject> BeginReadData(
251 JNIEnv* env,
252 const JavaParamRef<jobject>& jcaller,
253 jint mojo_handle,
254 jint num_bytes,
255 jint flags) {
256 void const* buffer = 0;
257 uint32_t buffer_size = num_bytes;
258 MojoResult result =
259 MojoBeginReadData(mojo_handle, &buffer, &buffer_size, flags);
260 jobject byte_buffer = 0;
261 if (result == MOJO_RESULT_OK) {
262 byte_buffer =
263 env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size);
265 return Java_CoreImpl_newResultAndBuffer(env, result, byte_buffer);
268 static jint EndReadData(JNIEnv* env,
269 const JavaParamRef<jobject>& jcaller,
270 jint mojo_handle,
271 jint num_bytes_read) {
272 return MojoEndReadData(mojo_handle, num_bytes_read);
275 static ScopedJavaLocalRef<jobject> WriteData(
276 JNIEnv* env,
277 const JavaParamRef<jobject>& jcaller,
278 jint mojo_handle,
279 const JavaParamRef<jobject>& elements,
280 jint limit,
281 jint flags) {
282 void* buffer_start = env->GetDirectBufferAddress(elements);
283 DCHECK(buffer_start);
284 DCHECK(limit <= env->GetDirectBufferCapacity(elements));
285 uint32_t buffer_size = limit;
286 MojoResult result =
287 MojoWriteData(mojo_handle, buffer_start, &buffer_size, flags);
288 return Java_CoreImpl_newResultAndInteger(
289 env, result, (result == MOJO_RESULT_OK) ? buffer_size : 0);
292 static ScopedJavaLocalRef<jobject> BeginWriteData(
293 JNIEnv* env,
294 const JavaParamRef<jobject>& jcaller,
295 jint mojo_handle,
296 jint num_bytes,
297 jint flags) {
298 void* buffer = 0;
299 uint32_t buffer_size = num_bytes;
300 MojoResult result =
301 MojoBeginWriteData(mojo_handle, &buffer, &buffer_size, flags);
302 jobject byte_buffer = 0;
303 if (result == MOJO_RESULT_OK) {
304 byte_buffer = env->NewDirectByteBuffer(buffer, buffer_size);
306 return Java_CoreImpl_newResultAndBuffer(env, result, byte_buffer);
309 static jint EndWriteData(JNIEnv* env,
310 const JavaParamRef<jobject>& jcaller,
311 jint mojo_handle,
312 jint num_bytes_written) {
313 return MojoEndWriteData(mojo_handle, num_bytes_written);
316 static ScopedJavaLocalRef<jobject> Duplicate(
317 JNIEnv* env,
318 const JavaParamRef<jobject>& jcaller,
319 jint mojo_handle,
320 const JavaParamRef<jobject>& options_buffer) {
321 const MojoDuplicateBufferHandleOptions* options = 0;
322 if (options_buffer) {
323 const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
324 DCHECK(buffer_start);
325 const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
326 DCHECK_EQ(buffer_size, sizeof(MojoDuplicateBufferHandleOptions));
327 options =
328 static_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start);
329 DCHECK_EQ(options->struct_size, buffer_size);
331 MojoHandle handle;
332 MojoResult result = MojoDuplicateBufferHandle(mojo_handle, options, &handle);
333 return Java_CoreImpl_newResultAndInteger(env, result, handle);
336 static ScopedJavaLocalRef<jobject> Map(JNIEnv* env,
337 const JavaParamRef<jobject>& jcaller,
338 jint mojo_handle,
339 jlong offset,
340 jlong num_bytes,
341 jint flags) {
342 void* buffer = 0;
343 MojoResult result =
344 MojoMapBuffer(mojo_handle, offset, num_bytes, &buffer, flags);
345 jobject byte_buffer = 0;
346 if (result == MOJO_RESULT_OK) {
347 byte_buffer = env->NewDirectByteBuffer(buffer, num_bytes);
349 return Java_CoreImpl_newResultAndBuffer(env, result, byte_buffer);
352 static int Unmap(JNIEnv* env,
353 const JavaParamRef<jobject>& jcaller,
354 const JavaParamRef<jobject>& buffer) {
355 void* buffer_start = env->GetDirectBufferAddress(buffer);
356 DCHECK(buffer_start);
357 return MojoUnmapBuffer(buffer_start);
360 static ScopedJavaLocalRef<jobject> AsyncWait(
361 JNIEnv* env,
362 const JavaParamRef<jobject>& jcaller,
363 jint mojo_handle,
364 jint signals,
365 jlong deadline,
366 const JavaParamRef<jobject>& callback) {
367 AsyncWaitCallbackData* callback_data =
368 new AsyncWaitCallbackData(env, jcaller, callback);
369 MojoAsyncWaitID cancel_id;
370 if (static_cast<MojoHandle>(mojo_handle) != MOJO_HANDLE_INVALID) {
371 cancel_id = Environment::GetDefaultAsyncWaiter()->AsyncWait(
372 mojo_handle, signals, deadline, AsyncWaitCallback, callback_data);
373 } else {
374 cancel_id = kInvalidHandleCancelID;
375 base::MessageLoop::current()->PostTask(
376 FROM_HERE,
377 base::Bind(
378 &AsyncWaitCallback, callback_data, MOJO_RESULT_INVALID_ARGUMENT));
380 base::android::ScopedJavaLocalRef<jobject> cancellable =
381 Java_CoreImpl_newAsyncWaiterCancellableImpl(
382 env, jcaller, cancel_id, reinterpret_cast<intptr_t>(callback_data));
383 callback_data->cancellable.Reset(env, cancellable.obj());
384 return cancellable;
387 static void CancelAsyncWait(JNIEnv* env,
388 const JavaParamRef<jobject>& jcaller,
389 jlong id,
390 jlong data_ptr) {
391 if (id == 0) {
392 // If |id| is |kInvalidHandleCancelID|, the async wait was done on an
393 // invalid handle, so the AsyncWaitCallback will be called and will clear
394 // the data_ptr.
395 return;
397 scoped_ptr<AsyncWaitCallbackData> deleter(
398 reinterpret_cast<AsyncWaitCallbackData*>(data_ptr));
399 Environment::GetDefaultAsyncWaiter()->CancelWait(id);
402 static jint GetNativeBufferOffset(JNIEnv* env,
403 const JavaParamRef<jobject>& jcaller,
404 const JavaParamRef<jobject>& buffer,
405 jint alignment) {
406 jint offset =
407 reinterpret_cast<uintptr_t>(env->GetDirectBufferAddress(buffer)) %
408 alignment;
409 if (offset == 0)
410 return 0;
411 return alignment - offset;
414 bool RegisterCoreImpl(JNIEnv* env) {
415 return RegisterNativesImpl(env);
418 } // namespace android
419 } // namespace mojo