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