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