• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package org.chromium.mojo.system.impl;
6 
7 import org.chromium.base.annotations.CalledByNative;
8 import org.chromium.base.annotations.JNINamespace;
9 import org.chromium.base.annotations.MainDex;
10 import org.chromium.mojo.system.AsyncWaiter;
11 import org.chromium.mojo.system.Core;
12 import org.chromium.mojo.system.DataPipe;
13 import org.chromium.mojo.system.DataPipe.ConsumerHandle;
14 import org.chromium.mojo.system.DataPipe.ProducerHandle;
15 import org.chromium.mojo.system.Handle;
16 import org.chromium.mojo.system.MessagePipeHandle;
17 import org.chromium.mojo.system.MojoException;
18 import org.chromium.mojo.system.MojoResult;
19 import org.chromium.mojo.system.Pair;
20 import org.chromium.mojo.system.ResultAnd;
21 import org.chromium.mojo.system.RunLoop;
22 import org.chromium.mojo.system.SharedBufferHandle;
23 import org.chromium.mojo.system.SharedBufferHandle.DuplicateOptions;
24 import org.chromium.mojo.system.SharedBufferHandle.MapFlags;
25 import org.chromium.mojo.system.UntypedHandle;
26 
27 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
32 
33 /**
34  * Implementation of {@link Core}.
35  */
36 @JNINamespace("mojo::android")
37 @MainDex
38 public class CoreImpl implements Core, AsyncWaiter {
39     /**
40      * Discard flag for the |MojoReadData| operation.
41      */
42     private static final int MOJO_READ_DATA_FLAG_DISCARD = 1 << 1;
43 
44     /**
45      * the size of a handle, in bytes.
46      */
47     private static final int HANDLE_SIZE = 4;
48 
49     /**
50      * the size of a flag, in bytes.
51      */
52     private static final int FLAG_SIZE = 4;
53 
54     /**
55      * The mojo handle for an invalid handle.
56      */
57     static final int INVALID_HANDLE = 0;
58 
59     private static class LazyHolder { private static final Core INSTANCE = new CoreImpl(); }
60 
61     /**
62      * The run loop for the current thread.
63      */
64     private final ThreadLocal<BaseRunLoop> mCurrentRunLoop = new ThreadLocal<BaseRunLoop>();
65 
66     /**
67      * The offset needed to get an aligned buffer.
68      */
69     private final int mByteBufferOffset;
70 
71     /**
72      * @return the instance.
73      */
getInstance()74     public static Core getInstance() {
75         return LazyHolder.INSTANCE;
76     }
77 
CoreImpl()78     private CoreImpl() {
79         // Fix for the ART runtime, before:
80         // https://android.googlesource.com/platform/libcore/+/fb6c80875a8a8d0a9628562f89c250b6a962e824%5E!/
81         // This assumes consistent allocation.
82         mByteBufferOffset = nativeGetNativeBufferOffset(ByteBuffer.allocateDirect(8), 8);
83     }
84 
85     /**
86      * @see Core#getTimeTicksNow()
87      */
88     @Override
getTimeTicksNow()89     public long getTimeTicksNow() {
90         return nativeGetTimeTicksNow();
91     }
92 
93     /**
94      * @see Core#waitMany(List, long)
95      */
96     @Override
waitMany(List<Pair<Handle, HandleSignals>> handles, long deadline)97     public WaitManyResult waitMany(List<Pair<Handle, HandleSignals>> handles, long deadline) {
98         // Allocate a direct buffer to allow native code not to reach back to java. The buffer
99         // layout will be:
100         // input: The array of handles (int, 4 bytes each)
101         // input: The array of signals (int, 4 bytes each)
102         // space for output: The array of handle states (2 ints, 8 bytes each)
103         // Space for output: The result index (int, 4 bytes)
104         // The handles and signals will be filled before calling the native method. When the native
105         // method returns, the handle states and the index will have been set.
106         ByteBuffer buffer = allocateDirectBuffer(handles.size() * 16 + 4);
107         int index = 0;
108         for (Pair<Handle, HandleSignals> handle : handles) {
109             buffer.putInt(HANDLE_SIZE * index, getMojoHandle(handle.first));
110             buffer.putInt(
111                     HANDLE_SIZE * handles.size() + FLAG_SIZE * index, handle.second.getFlags());
112             index++;
113         }
114         int code = nativeWaitMany(buffer, deadline);
115         WaitManyResult result = new WaitManyResult();
116         result.setMojoResult(filterMojoResultForWait(code));
117         result.setHandleIndex(buffer.getInt(handles.size() * 16));
118         if (result.getMojoResult() != MojoResult.INVALID_ARGUMENT
119                 && result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED) {
120             HandleSignalsState[] states = new HandleSignalsState[handles.size()];
121             for (int i = 0; i < handles.size(); ++i) {
122                 states[i] = new HandleSignalsState(
123                         new HandleSignals(buffer.getInt(8 * (handles.size() + i))),
124                         new HandleSignals(buffer.getInt(8 * (handles.size() + i) + 4)));
125             }
126             result.setSignalStates(Arrays.asList(states));
127         }
128         return result;
129     }
130 
131     /**
132      * @see Core#wait(Handle, HandleSignals, long)
133      */
134     @Override
wait(Handle handle, HandleSignals signals, long deadline)135     public WaitResult wait(Handle handle, HandleSignals signals, long deadline) {
136         // Allocate a direct buffer to allow native code not to reach back to java. Buffer will
137         // contain spaces to write the handle state.
138         ByteBuffer buffer = allocateDirectBuffer(8);
139         WaitResult result = new WaitResult();
140         result.setMojoResult(filterMojoResultForWait(
141                 nativeWait(buffer, getMojoHandle(handle), signals.getFlags(), deadline)));
142         HandleSignalsState signalsState = new HandleSignalsState(
143                 new HandleSignals(buffer.getInt(0)), new HandleSignals(buffer.getInt(4)));
144         result.setHandleSignalsState(signalsState);
145         return result;
146     }
147 
148     /**
149      * @see Core#createMessagePipe(MessagePipeHandle.CreateOptions)
150      */
151     @Override
createMessagePipe( MessagePipeHandle.CreateOptions options)152     public Pair<MessagePipeHandle, MessagePipeHandle> createMessagePipe(
153             MessagePipeHandle.CreateOptions options) {
154         ByteBuffer optionsBuffer = null;
155         if (options != null) {
156             optionsBuffer = allocateDirectBuffer(8);
157             optionsBuffer.putInt(0, 8);
158             optionsBuffer.putInt(4, options.getFlags().getFlags());
159         }
160         ResultAnd<IntegerPair> result = nativeCreateMessagePipe(optionsBuffer);
161         if (result.getMojoResult() != MojoResult.OK) {
162             throw new MojoException(result.getMojoResult());
163         }
164         return Pair.<MessagePipeHandle, MessagePipeHandle>create(
165                 new MessagePipeHandleImpl(this, result.getValue().first),
166                 new MessagePipeHandleImpl(this, result.getValue().second));
167     }
168 
169     /**
170      * @see Core#createDataPipe(DataPipe.CreateOptions)
171      */
172     @Override
createDataPipe(DataPipe.CreateOptions options)173     public Pair<ProducerHandle, ConsumerHandle> createDataPipe(DataPipe.CreateOptions options) {
174         ByteBuffer optionsBuffer = null;
175         if (options != null) {
176             optionsBuffer = allocateDirectBuffer(16);
177             optionsBuffer.putInt(0, 16);
178             optionsBuffer.putInt(4, options.getFlags().getFlags());
179             optionsBuffer.putInt(8, options.getElementNumBytes());
180             optionsBuffer.putInt(12, options.getCapacityNumBytes());
181         }
182         ResultAnd<IntegerPair> result = nativeCreateDataPipe(optionsBuffer);
183         if (result.getMojoResult() != MojoResult.OK) {
184             throw new MojoException(result.getMojoResult());
185         }
186         return Pair.<ProducerHandle, ConsumerHandle>create(
187                 new DataPipeProducerHandleImpl(this, result.getValue().first),
188                 new DataPipeConsumerHandleImpl(this, result.getValue().second));
189     }
190 
191     /**
192      * @see Core#createSharedBuffer(SharedBufferHandle.CreateOptions, long)
193      */
194     @Override
createSharedBuffer( SharedBufferHandle.CreateOptions options, long numBytes)195     public SharedBufferHandle createSharedBuffer(
196             SharedBufferHandle.CreateOptions options, long numBytes) {
197         ByteBuffer optionsBuffer = null;
198         if (options != null) {
199             optionsBuffer = allocateDirectBuffer(8);
200             optionsBuffer.putInt(0, 8);
201             optionsBuffer.putInt(4, options.getFlags().getFlags());
202         }
203         ResultAnd<Integer> result = nativeCreateSharedBuffer(optionsBuffer, numBytes);
204         if (result.getMojoResult() != MojoResult.OK) {
205             throw new MojoException(result.getMojoResult());
206         }
207         return new SharedBufferHandleImpl(this, result.getValue());
208     }
209 
210     /**
211      * @see org.chromium.mojo.system.Core#acquireNativeHandle(int)
212      */
213     @Override
acquireNativeHandle(int handle)214     public UntypedHandle acquireNativeHandle(int handle) {
215         return new UntypedHandleImpl(this, handle);
216     }
217 
218     /**
219      * @see Core#getDefaultAsyncWaiter()
220      */
221     @Override
getDefaultAsyncWaiter()222     public AsyncWaiter getDefaultAsyncWaiter() {
223         return this;
224     }
225 
226     /**
227      * @see Core#createDefaultRunLoop()
228      */
229     @Override
createDefaultRunLoop()230     public RunLoop createDefaultRunLoop() {
231         if (mCurrentRunLoop.get() != null) {
232             throw new MojoException(MojoResult.FAILED_PRECONDITION);
233         }
234         BaseRunLoop runLoop = new BaseRunLoop(this);
235         mCurrentRunLoop.set(runLoop);
236         return runLoop;
237     }
238 
239     /**
240      * @see Core#getCurrentRunLoop()
241      */
242     @Override
getCurrentRunLoop()243     public RunLoop getCurrentRunLoop() {
244         return mCurrentRunLoop.get();
245     }
246 
247     /**
248      * Remove the current run loop.
249      */
clearCurrentRunLoop()250     void clearCurrentRunLoop() {
251         mCurrentRunLoop.remove();
252     }
253 
254     /**
255      * @see AsyncWaiter#asyncWait(Handle, Core.HandleSignals, long, Callback)
256      */
257     @Override
asyncWait( Handle handle, HandleSignals signals, long deadline, Callback callback)258     public Cancellable asyncWait(
259             Handle handle, HandleSignals signals, long deadline, Callback callback) {
260         return nativeAsyncWait(getMojoHandle(handle), signals.getFlags(), deadline, callback);
261     }
262 
closeWithResult(int mojoHandle)263     int closeWithResult(int mojoHandle) {
264         return nativeClose(mojoHandle);
265     }
266 
close(int mojoHandle)267     void close(int mojoHandle) {
268         int mojoResult = nativeClose(mojoHandle);
269         if (mojoResult != MojoResult.OK) {
270             throw new MojoException(mojoResult);
271         }
272     }
273 
274     /**
275      * @see MessagePipeHandle#writeMessage(ByteBuffer, List, MessagePipeHandle.WriteFlags)
276      */
writeMessage(MessagePipeHandleImpl pipeHandle, ByteBuffer bytes, List<? extends Handle> handles, MessagePipeHandle.WriteFlags flags)277     void writeMessage(MessagePipeHandleImpl pipeHandle, ByteBuffer bytes,
278             List<? extends Handle> handles, MessagePipeHandle.WriteFlags flags) {
279         ByteBuffer handlesBuffer = null;
280         if (handles != null && !handles.isEmpty()) {
281             handlesBuffer = allocateDirectBuffer(handles.size() * HANDLE_SIZE);
282             for (Handle handle : handles) {
283                 handlesBuffer.putInt(getMojoHandle(handle));
284             }
285             handlesBuffer.position(0);
286         }
287         int mojoResult = nativeWriteMessage(pipeHandle.getMojoHandle(), bytes,
288                 bytes == null ? 0 : bytes.limit(), handlesBuffer, flags.getFlags());
289         if (mojoResult != MojoResult.OK) {
290             throw new MojoException(mojoResult);
291         }
292         // Success means the handles have been invalidated.
293         if (handles != null) {
294             for (Handle handle : handles) {
295                 if (handle.isValid()) {
296                     ((HandleBase) handle).invalidateHandle();
297                 }
298             }
299         }
300     }
301 
302     /**
303      * @see MessagePipeHandle#readMessage(ByteBuffer, int, MessagePipeHandle.ReadFlags)
304      */
readMessage(MessagePipeHandleImpl handle, ByteBuffer bytes, int maxNumberOfHandles, MessagePipeHandle.ReadFlags flags)305     ResultAnd<MessagePipeHandle.ReadMessageResult> readMessage(MessagePipeHandleImpl handle,
306             ByteBuffer bytes, int maxNumberOfHandles, MessagePipeHandle.ReadFlags flags) {
307         ByteBuffer handlesBuffer = null;
308         if (maxNumberOfHandles > 0) {
309             handlesBuffer = allocateDirectBuffer(maxNumberOfHandles * HANDLE_SIZE);
310         }
311         ResultAnd<MessagePipeHandle.ReadMessageResult> result =
312                 nativeReadMessage(handle.getMojoHandle(), bytes, handlesBuffer, flags.getFlags());
313         if (result.getMojoResult() != MojoResult.OK
314                 && result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED
315                 && result.getMojoResult() != MojoResult.SHOULD_WAIT) {
316             throw new MojoException(result.getMojoResult());
317         }
318 
319         if (result.getMojoResult() == MojoResult.OK) {
320             MessagePipeHandle.ReadMessageResult readResult = result.getValue();
321             if (bytes != null) {
322                 bytes.position(0);
323                 bytes.limit(readResult.getMessageSize());
324             }
325 
326             List<UntypedHandle> handles =
327                     new ArrayList<UntypedHandle>(readResult.getHandlesCount());
328             for (int i = 0; i < readResult.getHandlesCount(); ++i) {
329                 int mojoHandle = handlesBuffer.getInt(HANDLE_SIZE * i);
330                 handles.add(new UntypedHandleImpl(this, mojoHandle));
331             }
332             readResult.setHandles(handles);
333         }
334         return result;
335     }
336 
337     /**
338      * @see ConsumerHandle#discardData(int, DataPipe.ReadFlags)
339      */
discardData(DataPipeConsumerHandleImpl handle, int numBytes, DataPipe.ReadFlags flags)340     int discardData(DataPipeConsumerHandleImpl handle, int numBytes, DataPipe.ReadFlags flags) {
341         ResultAnd<Integer> result = nativeReadData(handle.getMojoHandle(), null, numBytes,
342                 flags.getFlags() | MOJO_READ_DATA_FLAG_DISCARD);
343         if (result.getMojoResult() != MojoResult.OK) {
344             throw new MojoException(result.getMojoResult());
345         }
346         return result.getValue();
347     }
348 
349     /**
350      * @see ConsumerHandle#readData(ByteBuffer, DataPipe.ReadFlags)
351      */
readData( DataPipeConsumerHandleImpl handle, ByteBuffer elements, DataPipe.ReadFlags flags)352     ResultAnd<Integer> readData(
353             DataPipeConsumerHandleImpl handle, ByteBuffer elements, DataPipe.ReadFlags flags) {
354         ResultAnd<Integer> result = nativeReadData(handle.getMojoHandle(), elements,
355                 elements == null ? 0 : elements.capacity(), flags.getFlags());
356         if (result.getMojoResult() != MojoResult.OK
357                 && result.getMojoResult() != MojoResult.SHOULD_WAIT) {
358             throw new MojoException(result.getMojoResult());
359         }
360         if (result.getMojoResult() == MojoResult.OK) {
361             if (elements != null) {
362                 elements.limit(result.getValue());
363             }
364         }
365         return result;
366     }
367 
368     /**
369      * @see ConsumerHandle#beginReadData(int, DataPipe.ReadFlags)
370      */
beginReadData( DataPipeConsumerHandleImpl handle, int numBytes, DataPipe.ReadFlags flags)371     ByteBuffer beginReadData(
372             DataPipeConsumerHandleImpl handle, int numBytes, DataPipe.ReadFlags flags) {
373         ResultAnd<ByteBuffer> result =
374                 nativeBeginReadData(handle.getMojoHandle(), numBytes, flags.getFlags());
375         if (result.getMojoResult() != MojoResult.OK) {
376             throw new MojoException(result.getMojoResult());
377         }
378         return result.getValue().asReadOnlyBuffer();
379     }
380 
381     /**
382      * @see ConsumerHandle#endReadData(int)
383      */
endReadData(DataPipeConsumerHandleImpl handle, int numBytesRead)384     void endReadData(DataPipeConsumerHandleImpl handle, int numBytesRead) {
385         int result = nativeEndReadData(handle.getMojoHandle(), numBytesRead);
386         if (result != MojoResult.OK) {
387             throw new MojoException(result);
388         }
389     }
390 
391     /**
392      * @see ProducerHandle#writeData(ByteBuffer, DataPipe.WriteFlags)
393      */
writeData( DataPipeProducerHandleImpl handle, ByteBuffer elements, DataPipe.WriteFlags flags)394     ResultAnd<Integer> writeData(
395             DataPipeProducerHandleImpl handle, ByteBuffer elements, DataPipe.WriteFlags flags) {
396         return nativeWriteData(
397                 handle.getMojoHandle(), elements, elements.limit(), flags.getFlags());
398     }
399 
400     /**
401      * @see ProducerHandle#beginWriteData(int, DataPipe.WriteFlags)
402      */
beginWriteData( DataPipeProducerHandleImpl handle, int numBytes, DataPipe.WriteFlags flags)403     ByteBuffer beginWriteData(
404             DataPipeProducerHandleImpl handle, int numBytes, DataPipe.WriteFlags flags) {
405         ResultAnd<ByteBuffer> result =
406                 nativeBeginWriteData(handle.getMojoHandle(), numBytes, flags.getFlags());
407         if (result.getMojoResult() != MojoResult.OK) {
408             throw new MojoException(result.getMojoResult());
409         }
410         return result.getValue();
411     }
412 
413     /**
414      * @see ProducerHandle#endWriteData(int)
415      */
endWriteData(DataPipeProducerHandleImpl handle, int numBytesWritten)416     void endWriteData(DataPipeProducerHandleImpl handle, int numBytesWritten) {
417         int result = nativeEndWriteData(handle.getMojoHandle(), numBytesWritten);
418         if (result != MojoResult.OK) {
419             throw new MojoException(result);
420         }
421     }
422 
423     /**
424      * @see SharedBufferHandle#duplicate(DuplicateOptions)
425      */
duplicate(SharedBufferHandleImpl handle, DuplicateOptions options)426     SharedBufferHandle duplicate(SharedBufferHandleImpl handle, DuplicateOptions options) {
427         ByteBuffer optionsBuffer = null;
428         if (options != null) {
429             optionsBuffer = allocateDirectBuffer(8);
430             optionsBuffer.putInt(0, 8);
431             optionsBuffer.putInt(4, options.getFlags().getFlags());
432         }
433         ResultAnd<Integer> result = nativeDuplicate(handle.getMojoHandle(), optionsBuffer);
434         if (result.getMojoResult() != MojoResult.OK) {
435             throw new MojoException(result.getMojoResult());
436         }
437         return new SharedBufferHandleImpl(this, result.getValue());
438     }
439 
440     /**
441      * @see SharedBufferHandle#map(long, long, MapFlags)
442      */
map(SharedBufferHandleImpl handle, long offset, long numBytes, MapFlags flags)443     ByteBuffer map(SharedBufferHandleImpl handle, long offset, long numBytes, MapFlags flags) {
444         ResultAnd<ByteBuffer> result =
445                 nativeMap(handle.getMojoHandle(), offset, numBytes, flags.getFlags());
446         if (result.getMojoResult() != MojoResult.OK) {
447             throw new MojoException(result.getMojoResult());
448         }
449         return result.getValue();
450     }
451 
452     /**
453      * @see SharedBufferHandle#unmap(ByteBuffer)
454      */
unmap(ByteBuffer buffer)455     void unmap(ByteBuffer buffer) {
456         int result = nativeUnmap(buffer);
457         if (result != MojoResult.OK) {
458             throw new MojoException(result);
459         }
460     }
461 
462     /**
463      * @return the mojo handle associated to the given handle, considering invalid handles.
464      */
getMojoHandle(Handle handle)465     private int getMojoHandle(Handle handle) {
466         if (handle.isValid()) {
467             return ((HandleBase) handle).getMojoHandle();
468         }
469         return 0;
470     }
471 
isUnrecoverableError(int code)472     private static boolean isUnrecoverableError(int code) {
473         switch (code) {
474             case MojoResult.OK:
475             case MojoResult.DEADLINE_EXCEEDED:
476             case MojoResult.CANCELLED:
477             case MojoResult.FAILED_PRECONDITION:
478                 return false;
479             default:
480                 return true;
481         }
482     }
483 
filterMojoResultForWait(int code)484     private static int filterMojoResultForWait(int code) {
485         if (isUnrecoverableError(code)) {
486             throw new MojoException(code);
487         }
488         return code;
489     }
490 
allocateDirectBuffer(int capacity)491     private ByteBuffer allocateDirectBuffer(int capacity) {
492         ByteBuffer buffer = ByteBuffer.allocateDirect(capacity + mByteBufferOffset);
493         if (mByteBufferOffset != 0) {
494             buffer.position(mByteBufferOffset);
495             buffer = buffer.slice();
496         }
497         return buffer.order(ByteOrder.nativeOrder());
498     }
499 
500     /**
501      * Implementation of {@link org.chromium.mojo.system.AsyncWaiter.Cancellable}.
502      */
503     private class AsyncWaiterCancellableImpl implements AsyncWaiter.Cancellable {
504         private final long mId;
505         private final long mDataPtr;
506         private boolean mActive = true;
507 
AsyncWaiterCancellableImpl(long id, long dataPtr)508         private AsyncWaiterCancellableImpl(long id, long dataPtr) {
509             this.mId = id;
510             this.mDataPtr = dataPtr;
511         }
512 
513         /**
514          * @see org.chromium.mojo.system.AsyncWaiter.Cancellable#cancel()
515          */
516         @Override
cancel()517         public void cancel() {
518             if (mActive) {
519                 mActive = false;
520                 nativeCancelAsyncWait(mId, mDataPtr);
521             }
522         }
523 
isActive()524         private boolean isActive() {
525             return mActive;
526         }
527 
deactivate()528         private void deactivate() {
529             mActive = false;
530         }
531     }
532 
533     @CalledByNative
newAsyncWaiterCancellableImpl(long id, long dataPtr)534     private AsyncWaiterCancellableImpl newAsyncWaiterCancellableImpl(long id, long dataPtr) {
535         return new AsyncWaiterCancellableImpl(id, dataPtr);
536     }
537 
538     @CalledByNative
onAsyncWaitResult( int mojoResult, AsyncWaiter.Callback callback, AsyncWaiterCancellableImpl cancellable)539     private void onAsyncWaitResult(
540             int mojoResult, AsyncWaiter.Callback callback, AsyncWaiterCancellableImpl cancellable) {
541         if (!cancellable.isActive()) {
542             // If cancellable is not active, the user cancelled the wait.
543             return;
544         }
545         cancellable.deactivate();
546         if (isUnrecoverableError(mojoResult)) {
547             callback.onError(new MojoException(mojoResult));
548             return;
549         }
550         callback.onResult(mojoResult);
551     }
552 
553     @CalledByNative
newResultAndBuffer(int mojoResult, ByteBuffer buffer)554     private static ResultAnd<ByteBuffer> newResultAndBuffer(int mojoResult, ByteBuffer buffer) {
555         return new ResultAnd<>(mojoResult, buffer);
556     }
557 
558     /**
559      * Trivial alias for Pair<Integer, Integer>. This is needed because our jni generator is unable
560      * to handle class that contains space.
561      */
562     private static final class IntegerPair extends Pair<Integer, Integer> {
IntegerPair(Integer first, Integer second)563         public IntegerPair(Integer first, Integer second) {
564             super(first, second);
565         }
566     }
567 
568     @CalledByNative
newReadMessageResult( int mojoResult, int messageSize, int handlesCount)569     private static ResultAnd<MessagePipeHandle.ReadMessageResult> newReadMessageResult(
570             int mojoResult, int messageSize, int handlesCount) {
571         MessagePipeHandle.ReadMessageResult result = new MessagePipeHandle.ReadMessageResult();
572         result.setMessageSize(messageSize);
573         result.setHandlesCount(handlesCount);
574         return new ResultAnd<>(mojoResult, result);
575     }
576 
577     @CalledByNative
newResultAndInteger(int mojoResult, int numBytesRead)578     private static ResultAnd<Integer> newResultAndInteger(int mojoResult, int numBytesRead) {
579         return new ResultAnd<>(mojoResult, numBytesRead);
580     }
581 
582     @CalledByNative
newNativeCreationResult( int mojoResult, int mojoHandle1, int mojoHandle2)583     private static ResultAnd<IntegerPair> newNativeCreationResult(
584             int mojoResult, int mojoHandle1, int mojoHandle2) {
585         return new ResultAnd<>(mojoResult, new IntegerPair(mojoHandle1, mojoHandle2));
586     }
587 
nativeGetTimeTicksNow()588     private native long nativeGetTimeTicksNow();
589 
nativeWaitMany(ByteBuffer buffer, long deadline)590     private native int nativeWaitMany(ByteBuffer buffer, long deadline);
591 
nativeCreateMessagePipe(ByteBuffer optionsBuffer)592     private native ResultAnd<IntegerPair> nativeCreateMessagePipe(ByteBuffer optionsBuffer);
593 
nativeCreateDataPipe(ByteBuffer optionsBuffer)594     private native ResultAnd<IntegerPair> nativeCreateDataPipe(ByteBuffer optionsBuffer);
595 
nativeCreateSharedBuffer( ByteBuffer optionsBuffer, long numBytes)596     private native ResultAnd<Integer> nativeCreateSharedBuffer(
597             ByteBuffer optionsBuffer, long numBytes);
598 
nativeClose(int mojoHandle)599     private native int nativeClose(int mojoHandle);
600 
nativeWait(ByteBuffer buffer, int mojoHandle, int signals, long deadline)601     private native int nativeWait(ByteBuffer buffer, int mojoHandle, int signals, long deadline);
602 
nativeWriteMessage( int mojoHandle, ByteBuffer bytes, int numBytes, ByteBuffer handlesBuffer, int flags)603     private native int nativeWriteMessage(
604             int mojoHandle, ByteBuffer bytes, int numBytes, ByteBuffer handlesBuffer, int flags);
605 
nativeReadMessage( int mojoHandle, ByteBuffer bytes, ByteBuffer handlesBuffer, int flags)606     private native ResultAnd<MessagePipeHandle.ReadMessageResult> nativeReadMessage(
607             int mojoHandle, ByteBuffer bytes, ByteBuffer handlesBuffer, int flags);
608 
nativeReadData( int mojoHandle, ByteBuffer elements, int elementsSize, int flags)609     private native ResultAnd<Integer> nativeReadData(
610             int mojoHandle, ByteBuffer elements, int elementsSize, int flags);
611 
nativeBeginReadData( int mojoHandle, int numBytes, int flags)612     private native ResultAnd<ByteBuffer> nativeBeginReadData(
613             int mojoHandle, int numBytes, int flags);
614 
nativeEndReadData(int mojoHandle, int numBytesRead)615     private native int nativeEndReadData(int mojoHandle, int numBytesRead);
616 
nativeWriteData( int mojoHandle, ByteBuffer elements, int limit, int flags)617     private native ResultAnd<Integer> nativeWriteData(
618             int mojoHandle, ByteBuffer elements, int limit, int flags);
619 
nativeBeginWriteData( int mojoHandle, int numBytes, int flags)620     private native ResultAnd<ByteBuffer> nativeBeginWriteData(
621             int mojoHandle, int numBytes, int flags);
622 
nativeEndWriteData(int mojoHandle, int numBytesWritten)623     private native int nativeEndWriteData(int mojoHandle, int numBytesWritten);
624 
nativeDuplicate(int mojoHandle, ByteBuffer optionsBuffer)625     private native ResultAnd<Integer> nativeDuplicate(int mojoHandle, ByteBuffer optionsBuffer);
626 
nativeMap( int mojoHandle, long offset, long numBytes, int flags)627     private native ResultAnd<ByteBuffer> nativeMap(
628             int mojoHandle, long offset, long numBytes, int flags);
629 
nativeUnmap(ByteBuffer buffer)630     private native int nativeUnmap(ByteBuffer buffer);
631 
nativeAsyncWait( int mojoHandle, int signals, long deadline, AsyncWaiter.Callback callback)632     private native AsyncWaiterCancellableImpl nativeAsyncWait(
633             int mojoHandle, int signals, long deadline, AsyncWaiter.Callback callback);
634 
nativeCancelAsyncWait(long mId, long dataPtr)635     private native void nativeCancelAsyncWait(long mId, long dataPtr);
636 
nativeGetNativeBufferOffset(ByteBuffer buffer, int alignment)637     private native int nativeGetNativeBufferOffset(ByteBuffer buffer, int alignment);
638 }
639