1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.util.ExceptionUtils; 22 import android.util.Log; 23 import android.util.Slog; 24 25 import com.android.internal.util.FastPrintWriter; 26 import com.android.internal.util.FunctionalUtils; 27 import com.android.internal.util.FunctionalUtils.ThrowingRunnable; 28 import com.android.internal.util.FunctionalUtils.ThrowingSupplier; 29 30 import libcore.io.IoUtils; 31 32 import java.io.FileDescriptor; 33 import java.io.FileOutputStream; 34 import java.io.PrintWriter; 35 import java.lang.ref.WeakReference; 36 import java.lang.reflect.Modifier; 37 38 /** 39 * Base class for a remotable object, the core part of a lightweight 40 * remote procedure call mechanism defined by {@link IBinder}. 41 * This class is an implementation of IBinder that provides 42 * standard local implementation of such an object. 43 * 44 * <p>Most developers will not implement this class directly, instead using the 45 * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired 46 * interface, having it generate the appropriate Binder subclass. You can, 47 * however, derive directly from Binder to implement your own custom RPC 48 * protocol or simply instantiate a raw Binder object directly to use as a 49 * token that can be shared across processes. 50 * 51 * <p>This class is just a basic IPC primitive; it has no impact on an application's 52 * lifecycle, and is valid only as long as the process that created it continues to run. 53 * To use this correctly, you must be doing so within the context of a top-level 54 * application component (a {@link android.app.Service}, {@link android.app.Activity}, 55 * or {@link android.content.ContentProvider}) that lets the system know your process 56 * should remain running.</p> 57 * 58 * <p>You must keep in mind the situations in which your process 59 * could go away, and thus require that you later re-create a new Binder and re-attach 60 * it when the process starts again. For example, if you are using this within an 61 * {@link android.app.Activity}, your activity's process may be killed any time the 62 * activity is not started; if the activity is later re-created you will need to 63 * create a new Binder and hand it back to the correct place again; you need to be 64 * aware that your process may be started for another reason (for example to receive 65 * a broadcast) that will not involve re-creating the activity and thus run its code 66 * to create a new Binder.</p> 67 * 68 * @see IBinder 69 */ 70 public class Binder implements IBinder { 71 /* 72 * Set this flag to true to detect anonymous, local or member classes 73 * that extend this Binder class and that are not static. These kind 74 * of classes can potentially create leaks. 75 */ 76 private static final boolean FIND_POTENTIAL_LEAKS = false; 77 /** @hide */ 78 public static final boolean CHECK_PARCEL_SIZE = false; 79 static final String TAG = "Binder"; 80 81 /** @hide */ 82 public static boolean LOG_RUNTIME_EXCEPTION = false; // DO NOT SUBMIT WITH TRUE 83 84 /** 85 * Control whether dump() calls are allowed. 86 */ 87 private static volatile String sDumpDisabled = null; 88 89 /** 90 * Global transaction tracker instance for this process. 91 */ 92 private static volatile TransactionTracker sTransactionTracker = null; 93 94 // Transaction tracking code. 95 96 /** 97 * Flag indicating whether we should be tracing transact calls. 98 */ 99 private static volatile boolean sTracingEnabled = false; 100 101 /** 102 * Enable Binder IPC tracing. 103 * 104 * @hide 105 */ enableTracing()106 public static void enableTracing() { 107 sTracingEnabled = true; 108 } 109 110 /** 111 * Disable Binder IPC tracing. 112 * 113 * @hide 114 */ disableTracing()115 public static void disableTracing() { 116 sTracingEnabled = false; 117 } 118 119 /** 120 * Check if binder transaction tracing is enabled. 121 * 122 * @hide 123 */ isTracingEnabled()124 public static boolean isTracingEnabled() { 125 return sTracingEnabled; 126 } 127 128 /** 129 * Get the binder transaction tracker for this process. 130 * 131 * @hide 132 */ getTransactionTracker()133 public synchronized static TransactionTracker getTransactionTracker() { 134 if (sTransactionTracker == null) 135 sTransactionTracker = new TransactionTracker(); 136 return sTransactionTracker; 137 } 138 139 /** {@hide} */ 140 static volatile boolean sWarnOnBlocking = false; 141 142 /** 143 * Warn if any blocking binder transactions are made out from this process. 144 * This is typically only useful for the system process, to prevent it from 145 * blocking on calls to external untrusted code. Instead, all outgoing calls 146 * that require a result must be sent as {@link IBinder#FLAG_ONEWAY} calls 147 * which deliver results through a callback interface. 148 * 149 * @hide 150 */ setWarnOnBlocking(boolean warnOnBlocking)151 public static void setWarnOnBlocking(boolean warnOnBlocking) { 152 sWarnOnBlocking = warnOnBlocking; 153 } 154 155 /** 156 * Allow blocking calls on the given interface, overriding the requested 157 * value of {@link #setWarnOnBlocking(boolean)}. 158 * <p> 159 * This should only be rarely called when you are <em>absolutely sure</em> 160 * the remote interface is a built-in system component that can never be 161 * upgraded. In particular, this <em>must never</em> be called for 162 * interfaces hosted by package that could be upgraded or replaced, 163 * otherwise you risk system instability if that remote interface wedges. 164 * 165 * @hide 166 */ allowBlocking(IBinder binder)167 public static IBinder allowBlocking(IBinder binder) { 168 try { 169 if (binder instanceof BinderProxy) { 170 ((BinderProxy) binder).mWarnOnBlocking = false; 171 } else if (binder != null 172 && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) { 173 Log.w(TAG, "Unable to allow blocking on interface " + binder); 174 } 175 } catch (RemoteException ignored) { 176 } 177 return binder; 178 } 179 180 /** 181 * Inherit the current {@link #allowBlocking(IBinder)} value from one given 182 * interface to another. 183 * 184 * @hide 185 */ copyAllowBlocking(IBinder fromBinder, IBinder toBinder)186 public static void copyAllowBlocking(IBinder fromBinder, IBinder toBinder) { 187 if (fromBinder instanceof BinderProxy && toBinder instanceof BinderProxy) { 188 ((BinderProxy) toBinder).mWarnOnBlocking = ((BinderProxy) fromBinder).mWarnOnBlocking; 189 } 190 } 191 192 /* mObject is used by native code, do not remove or rename */ 193 private long mObject; 194 private IInterface mOwner; 195 private String mDescriptor; 196 197 /** 198 * Return the ID of the process that sent you the current transaction 199 * that is being processed. This pid can be used with higher-level 200 * system services to determine its identity and check permissions. 201 * If the current thread is not currently executing an incoming transaction, 202 * then its own pid is returned. 203 */ getCallingPid()204 public static final native int getCallingPid(); 205 206 /** 207 * Return the Linux uid assigned to the process that sent you the 208 * current transaction that is being processed. This uid can be used with 209 * higher-level system services to determine its identity and check 210 * permissions. If the current thread is not currently executing an 211 * incoming transaction, then its own uid is returned. 212 */ getCallingUid()213 public static final native int getCallingUid(); 214 215 /** 216 * Return the UserHandle assigned to the process that sent you the 217 * current transaction that is being processed. This is the user 218 * of the caller. It is distinct from {@link #getCallingUid()} in that a 219 * particular user will have multiple distinct apps running under it each 220 * with their own uid. If the current thread is not currently executing an 221 * incoming transaction, then its own UserHandle is returned. 222 */ getCallingUserHandle()223 public static final @NonNull UserHandle getCallingUserHandle() { 224 return UserHandle.of(UserHandle.getUserId(getCallingUid())); 225 } 226 227 /** 228 * Reset the identity of the incoming IPC on the current thread. This can 229 * be useful if, while handling an incoming call, you will be calling 230 * on interfaces of other objects that may be local to your process and 231 * need to do permission checks on the calls coming into them (so they 232 * will check the permission of your own local process, and not whatever 233 * process originally called you). 234 * 235 * @return Returns an opaque token that can be used to restore the 236 * original calling identity by passing it to 237 * {@link #restoreCallingIdentity(long)}. 238 * 239 * @see #getCallingPid() 240 * @see #getCallingUid() 241 * @see #restoreCallingIdentity(long) 242 */ clearCallingIdentity()243 public static final native long clearCallingIdentity(); 244 245 /** 246 * Restore the identity of the incoming IPC on the current thread 247 * back to a previously identity that was returned by {@link 248 * #clearCallingIdentity}. 249 * 250 * @param token The opaque token that was previously returned by 251 * {@link #clearCallingIdentity}. 252 * 253 * @see #clearCallingIdentity 254 */ restoreCallingIdentity(long token)255 public static final native void restoreCallingIdentity(long token); 256 257 /** 258 * Convenience method for running the provided action enclosed in 259 * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity} 260 * 261 * Any exception thrown by the given action will be caught and rethrown after the call to 262 * {@link #restoreCallingIdentity} 263 * 264 * @hide 265 */ withCleanCallingIdentity(@onNull ThrowingRunnable action)266 public static final void withCleanCallingIdentity(@NonNull ThrowingRunnable action) { 267 long callingIdentity = clearCallingIdentity(); 268 Throwable throwableToPropagate = null; 269 try { 270 action.run(); 271 } catch (Throwable throwable) { 272 throwableToPropagate = throwable; 273 } finally { 274 restoreCallingIdentity(callingIdentity); 275 if (throwableToPropagate != null) { 276 throw ExceptionUtils.propagate(throwableToPropagate); 277 } 278 } 279 } 280 281 /** 282 * Convenience method for running the provided action enclosed in 283 * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity} returning the result 284 * 285 * Any exception thrown by the given action will be caught and rethrown after the call to 286 * {@link #restoreCallingIdentity} 287 * 288 * @hide 289 */ withCleanCallingIdentity(@onNull ThrowingSupplier<T> action)290 public static final <T> T withCleanCallingIdentity(@NonNull ThrowingSupplier<T> action) { 291 long callingIdentity = clearCallingIdentity(); 292 Throwable throwableToPropagate = null; 293 try { 294 return action.get(); 295 } catch (Throwable throwable) { 296 throwableToPropagate = throwable; 297 return null; // overridden by throwing in finally block 298 } finally { 299 restoreCallingIdentity(callingIdentity); 300 if (throwableToPropagate != null) { 301 throw ExceptionUtils.propagate(throwableToPropagate); 302 } 303 } 304 } 305 306 /** 307 * Sets the native thread-local StrictMode policy mask. 308 * 309 * <p>The StrictMode settings are kept in two places: a Java-level 310 * threadlocal for libcore/Dalvik, and a native threadlocal (set 311 * here) for propagation via Binder calls. This is a little 312 * unfortunate, but necessary to break otherwise more unfortunate 313 * dependencies either of Dalvik on Android, or Android 314 * native-only code on Dalvik. 315 * 316 * @see StrictMode 317 * @hide 318 */ setThreadStrictModePolicy(int policyMask)319 public static final native void setThreadStrictModePolicy(int policyMask); 320 321 /** 322 * Gets the current native thread-local StrictMode policy mask. 323 * 324 * @see #setThreadStrictModePolicy 325 * @hide 326 */ getThreadStrictModePolicy()327 public static final native int getThreadStrictModePolicy(); 328 329 /** 330 * Flush any Binder commands pending in the current thread to the kernel 331 * driver. This can be 332 * useful to call before performing an operation that may block for a long 333 * time, to ensure that any pending object references have been released 334 * in order to prevent the process from holding on to objects longer than 335 * it needs to. 336 */ flushPendingCommands()337 public static final native void flushPendingCommands(); 338 339 /** 340 * Add the calling thread to the IPC thread pool. This function does 341 * not return until the current process is exiting. 342 */ joinThreadPool()343 public static final native void joinThreadPool(); 344 345 /** 346 * Returns true if the specified interface is a proxy. 347 * @hide 348 */ isProxy(IInterface iface)349 public static final boolean isProxy(IInterface iface) { 350 return iface.asBinder() != iface; 351 } 352 353 /** 354 * Call blocks until the number of executing binder threads is less 355 * than the maximum number of binder threads allowed for this process. 356 * @hide 357 */ blockUntilThreadAvailable()358 public static final native void blockUntilThreadAvailable(); 359 360 /** 361 * Default constructor initializes the object. 362 */ Binder()363 public Binder() { 364 init(); 365 366 if (FIND_POTENTIAL_LEAKS) { 367 final Class<? extends Binder> klass = getClass(); 368 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 369 (klass.getModifiers() & Modifier.STATIC) == 0) { 370 Log.w(TAG, "The following Binder class should be static or leaks might occur: " + 371 klass.getCanonicalName()); 372 } 373 } 374 } 375 376 /** 377 * Convenience method for associating a specific interface with the Binder. 378 * After calling, queryLocalInterface() will be implemented for you 379 * to return the given owner IInterface when the corresponding 380 * descriptor is requested. 381 */ attachInterface(@ullable IInterface owner, @Nullable String descriptor)382 public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) { 383 mOwner = owner; 384 mDescriptor = descriptor; 385 } 386 387 /** 388 * Default implementation returns an empty interface name. 389 */ getInterfaceDescriptor()390 public @Nullable String getInterfaceDescriptor() { 391 return mDescriptor; 392 } 393 394 /** 395 * Default implementation always returns true -- if you got here, 396 * the object is alive. 397 */ pingBinder()398 public boolean pingBinder() { 399 return true; 400 } 401 402 /** 403 * {@inheritDoc} 404 * 405 * Note that if you're calling on a local binder, this always returns true 406 * because your process is alive if you're calling it. 407 */ isBinderAlive()408 public boolean isBinderAlive() { 409 return true; 410 } 411 412 /** 413 * Use information supplied to attachInterface() to return the 414 * associated IInterface if it matches the requested 415 * descriptor. 416 */ queryLocalInterface(@onNull String descriptor)417 public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) { 418 if (mDescriptor.equals(descriptor)) { 419 return mOwner; 420 } 421 return null; 422 } 423 424 /** 425 * Control disabling of dump calls in this process. This is used by the system 426 * process watchdog to disable incoming dump calls while it has detecting the system 427 * is hung and is reporting that back to the activity controller. This is to 428 * prevent the controller from getting hung up on bug reports at this point. 429 * @hide 430 * 431 * @param msg The message to show instead of the dump; if null, dumps are 432 * re-enabled. 433 */ setDumpDisabled(String msg)434 public static void setDumpDisabled(String msg) { 435 sDumpDisabled = msg; 436 } 437 438 /** 439 * Default implementation is a stub that returns false. You will want 440 * to override this to do the appropriate unmarshalling of transactions. 441 * 442 * <p>If you want to call this, call transact(). 443 * 444 * <p>Implementations that are returning a result should generally use 445 * {@link Parcel#writeNoException() Parcel.writeNoException} and 446 * {@link Parcel#writeException(Exception) Parcel.writeException} to propagate 447 * exceptions back to the caller.</p> 448 * 449 * @param code The action to perform. This should 450 * be a number between {@link #FIRST_CALL_TRANSACTION} and 451 * {@link #LAST_CALL_TRANSACTION}. 452 * @param data Marshalled data being received from the caller. 453 * @param reply If the caller is expecting a result back, it should be marshalled 454 * in to here. 455 * @param flags Additional operation flags. Either 0 for a normal 456 * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC. 457 * 458 * @return Return true on a successful call; returning false is generally used to 459 * indicate that you did not understand the transaction code. 460 */ onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)461 protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, 462 int flags) throws RemoteException { 463 if (code == INTERFACE_TRANSACTION) { 464 reply.writeString(getInterfaceDescriptor()); 465 return true; 466 } else if (code == DUMP_TRANSACTION) { 467 ParcelFileDescriptor fd = data.readFileDescriptor(); 468 String[] args = data.readStringArray(); 469 if (fd != null) { 470 try { 471 dump(fd.getFileDescriptor(), args); 472 } finally { 473 IoUtils.closeQuietly(fd); 474 } 475 } 476 // Write the StrictMode header. 477 if (reply != null) { 478 reply.writeNoException(); 479 } else { 480 StrictMode.clearGatheredViolations(); 481 } 482 return true; 483 } else if (code == SHELL_COMMAND_TRANSACTION) { 484 ParcelFileDescriptor in = data.readFileDescriptor(); 485 ParcelFileDescriptor out = data.readFileDescriptor(); 486 ParcelFileDescriptor err = data.readFileDescriptor(); 487 String[] args = data.readStringArray(); 488 ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data); 489 ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data); 490 try { 491 if (out != null) { 492 shellCommand(in != null ? in.getFileDescriptor() : null, 493 out.getFileDescriptor(), 494 err != null ? err.getFileDescriptor() : out.getFileDescriptor(), 495 args, shellCallback, resultReceiver); 496 } 497 } finally { 498 IoUtils.closeQuietly(in); 499 IoUtils.closeQuietly(out); 500 IoUtils.closeQuietly(err); 501 // Write the StrictMode header. 502 if (reply != null) { 503 reply.writeNoException(); 504 } else { 505 StrictMode.clearGatheredViolations(); 506 } 507 } 508 return true; 509 } 510 return false; 511 } 512 513 /** 514 * Implemented to call the more convenient version 515 * {@link #dump(FileDescriptor, PrintWriter, String[])}. 516 */ dump(@onNull FileDescriptor fd, @Nullable String[] args)517 public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) { 518 FileOutputStream fout = new FileOutputStream(fd); 519 PrintWriter pw = new FastPrintWriter(fout); 520 try { 521 doDump(fd, pw, args); 522 } finally { 523 pw.flush(); 524 } 525 } 526 doDump(FileDescriptor fd, PrintWriter pw, String[] args)527 void doDump(FileDescriptor fd, PrintWriter pw, String[] args) { 528 final String disabled = sDumpDisabled; 529 if (disabled == null) { 530 try { 531 dump(fd, pw, args); 532 } catch (SecurityException e) { 533 pw.println("Security exception: " + e.getMessage()); 534 throw e; 535 } catch (Throwable e) { 536 // Unlike usual calls, in this case if an exception gets thrown 537 // back to us we want to print it back in to the dump data, since 538 // that is where the caller expects all interesting information to 539 // go. 540 pw.println(); 541 pw.println("Exception occurred while dumping:"); 542 e.printStackTrace(pw); 543 } 544 } else { 545 pw.println(sDumpDisabled); 546 } 547 } 548 549 /** 550 * Like {@link #dump(FileDescriptor, String[])}, but ensures the target 551 * executes asynchronously. 552 */ dumpAsync(@onNull final FileDescriptor fd, @Nullable final String[] args)553 public void dumpAsync(@NonNull final FileDescriptor fd, @Nullable final String[] args) { 554 final FileOutputStream fout = new FileOutputStream(fd); 555 final PrintWriter pw = new FastPrintWriter(fout); 556 Thread thr = new Thread("Binder.dumpAsync") { 557 public void run() { 558 try { 559 dump(fd, pw, args); 560 } finally { 561 pw.flush(); 562 } 563 } 564 }; 565 thr.start(); 566 } 567 568 /** 569 * Print the object's state into the given stream. 570 * 571 * @param fd The raw file descriptor that the dump is being sent to. 572 * @param fout The file to which you should dump your state. This will be 573 * closed for you after you return. 574 * @param args additional arguments to the dump request. 575 */ dump(@onNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args)576 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, 577 @Nullable String[] args) { 578 } 579 580 /** 581 * @param in The raw file descriptor that an input data stream can be read from. 582 * @param out The raw file descriptor that normal command messages should be written to. 583 * @param err The raw file descriptor that command error messages should be written to. 584 * @param args Command-line arguments. 585 * @param callback Callback through which to interact with the invoking shell. 586 * @param resultReceiver Called when the command has finished executing, with the result code. 587 * @throws RemoteException 588 * @hide 589 */ shellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)590 public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, 591 @Nullable FileDescriptor err, 592 @NonNull String[] args, @Nullable ShellCallback callback, 593 @NonNull ResultReceiver resultReceiver) throws RemoteException { 594 onShellCommand(in, out, err, args, callback, resultReceiver); 595 } 596 597 /** 598 * Handle a call to {@link #shellCommand}. The default implementation simply prints 599 * an error message. Override and replace with your own. 600 * <p class="caution">Note: no permission checking is done before calling this method; you must 601 * apply any security checks as appropriate for the command being executed. 602 * Consider using {@link ShellCommand} to help in the implementation.</p> 603 * @hide 604 */ onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)605 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, 606 @Nullable FileDescriptor err, 607 @NonNull String[] args, @Nullable ShellCallback callback, 608 @NonNull ResultReceiver resultReceiver) throws RemoteException { 609 FileOutputStream fout = new FileOutputStream(err != null ? err : out); 610 PrintWriter pw = new FastPrintWriter(fout); 611 pw.println("No shell command implementation."); 612 pw.flush(); 613 resultReceiver.send(0, null); 614 } 615 616 /** 617 * Default implementation rewinds the parcels and calls onTransact. On 618 * the remote side, transact calls into the binder to do the IPC. 619 */ transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)620 public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, 621 int flags) throws RemoteException { 622 if (false) Log.v("Binder", "Transact: " + code + " to " + this); 623 624 if (data != null) { 625 data.setDataPosition(0); 626 } 627 boolean r = onTransact(code, data, reply, flags); 628 if (reply != null) { 629 reply.setDataPosition(0); 630 } 631 return r; 632 } 633 634 /** 635 * Local implementation is a no-op. 636 */ linkToDeath(@onNull DeathRecipient recipient, int flags)637 public void linkToDeath(@NonNull DeathRecipient recipient, int flags) { 638 } 639 640 /** 641 * Local implementation is a no-op. 642 */ unlinkToDeath(@onNull DeathRecipient recipient, int flags)643 public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) { 644 return true; 645 } 646 finalize()647 protected void finalize() throws Throwable { 648 try { 649 destroyBinder(); 650 } finally { 651 super.finalize(); 652 } 653 } 654 checkParcel(IBinder obj, int code, Parcel parcel, String msg)655 static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) { 656 if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) { 657 // Trying to send > 800k, this is way too much 658 StringBuilder sb = new StringBuilder(); 659 sb.append(msg); 660 sb.append(": on "); 661 sb.append(obj); 662 sb.append(" calling "); 663 sb.append(code); 664 sb.append(" size "); 665 sb.append(parcel.dataSize()); 666 sb.append(" (data: "); 667 parcel.setDataPosition(0); 668 sb.append(parcel.readInt()); 669 sb.append(", "); 670 sb.append(parcel.readInt()); 671 sb.append(", "); 672 sb.append(parcel.readInt()); 673 sb.append(")"); 674 Slog.wtfStack(TAG, sb.toString()); 675 } 676 } 677 init()678 private native final void init(); destroyBinder()679 private native final void destroyBinder(); 680 681 // Entry point from android_util_Binder.cpp's onTransact execTransact(int code, long dataObj, long replyObj, int flags)682 private boolean execTransact(int code, long dataObj, long replyObj, 683 int flags) { 684 Parcel data = Parcel.obtain(dataObj); 685 Parcel reply = Parcel.obtain(replyObj); 686 // theoretically, we should call transact, which will call onTransact, 687 // but all that does is rewind it, and we just got these from an IPC, 688 // so we'll just call it directly. 689 boolean res; 690 // Log any exceptions as warnings, don't silently suppress them. 691 // If the call was FLAG_ONEWAY then these exceptions disappear into the ether. 692 final boolean tracingEnabled = Binder.isTracingEnabled(); 693 try { 694 if (tracingEnabled) { 695 Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code); 696 } 697 res = onTransact(code, data, reply, flags); 698 } catch (RemoteException|RuntimeException e) { 699 if (LOG_RUNTIME_EXCEPTION) { 700 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); 701 } 702 if ((flags & FLAG_ONEWAY) != 0) { 703 if (e instanceof RemoteException) { 704 Log.w(TAG, "Binder call failed.", e); 705 } else { 706 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); 707 } 708 } else { 709 // Clear the parcel before writing the exception 710 reply.setDataSize(0); 711 reply.setDataPosition(0); 712 reply.writeException(e); 713 } 714 res = true; 715 } finally { 716 if (tracingEnabled) { 717 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS); 718 } 719 } 720 checkParcel(this, code, reply, "Unreasonably large binder reply buffer"); 721 reply.recycle(); 722 data.recycle(); 723 724 // Just in case -- we are done with the IPC, so there should be no more strict 725 // mode violations that have gathered for this thread. Either they have been 726 // parceled and are now in transport off to the caller, or we are returning back 727 // to the main transaction loop to wait for another incoming transaction. Either 728 // way, strict mode begone! 729 StrictMode.clearGatheredViolations(); 730 731 return res; 732 } 733 } 734 735 final class BinderProxy implements IBinder { 736 // Assume the process-wide default value when created 737 volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking; 738 pingBinder()739 public native boolean pingBinder(); isBinderAlive()740 public native boolean isBinderAlive(); 741 queryLocalInterface(String descriptor)742 public IInterface queryLocalInterface(String descriptor) { 743 return null; 744 } 745 transact(int code, Parcel data, Parcel reply, int flags)746 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { 747 Binder.checkParcel(this, code, data, "Unreasonably large binder buffer"); 748 749 if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) { 750 // For now, avoid spamming the log by disabling after we've logged 751 // about this interface at least once 752 mWarnOnBlocking = false; 753 Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY", 754 new Throwable()); 755 } 756 757 final boolean tracingEnabled = Binder.isTracingEnabled(); 758 if (tracingEnabled) { 759 final Throwable tr = new Throwable(); 760 Binder.getTransactionTracker().addTrace(tr); 761 StackTraceElement stackTraceElement = tr.getStackTrace()[1]; 762 Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, 763 stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName()); 764 } 765 try { 766 return transactNative(code, data, reply, flags); 767 } finally { 768 if (tracingEnabled) { 769 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS); 770 } 771 } 772 } 773 getInterfaceDescriptor()774 public native String getInterfaceDescriptor() throws RemoteException; transactNative(int code, Parcel data, Parcel reply, int flags)775 public native boolean transactNative(int code, Parcel data, Parcel reply, 776 int flags) throws RemoteException; linkToDeath(DeathRecipient recipient, int flags)777 public native void linkToDeath(DeathRecipient recipient, int flags) 778 throws RemoteException; unlinkToDeath(DeathRecipient recipient, int flags)779 public native boolean unlinkToDeath(DeathRecipient recipient, int flags); 780 dump(FileDescriptor fd, String[] args)781 public void dump(FileDescriptor fd, String[] args) throws RemoteException { 782 Parcel data = Parcel.obtain(); 783 Parcel reply = Parcel.obtain(); 784 data.writeFileDescriptor(fd); 785 data.writeStringArray(args); 786 try { 787 transact(DUMP_TRANSACTION, data, reply, 0); 788 reply.readException(); 789 } finally { 790 data.recycle(); 791 reply.recycle(); 792 } 793 } 794 dumpAsync(FileDescriptor fd, String[] args)795 public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException { 796 Parcel data = Parcel.obtain(); 797 Parcel reply = Parcel.obtain(); 798 data.writeFileDescriptor(fd); 799 data.writeStringArray(args); 800 try { 801 transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY); 802 } finally { 803 data.recycle(); 804 reply.recycle(); 805 } 806 } 807 shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)808 public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 809 String[] args, ShellCallback callback, 810 ResultReceiver resultReceiver) throws RemoteException { 811 Parcel data = Parcel.obtain(); 812 Parcel reply = Parcel.obtain(); 813 data.writeFileDescriptor(in); 814 data.writeFileDescriptor(out); 815 data.writeFileDescriptor(err); 816 data.writeStringArray(args); 817 ShellCallback.writeToParcel(callback, data); 818 resultReceiver.writeToParcel(data, 0); 819 try { 820 transact(SHELL_COMMAND_TRANSACTION, data, reply, 0); 821 reply.readException(); 822 } finally { 823 data.recycle(); 824 reply.recycle(); 825 } 826 } 827 BinderProxy()828 BinderProxy() { 829 mSelf = new WeakReference(this); 830 } 831 832 @Override finalize()833 protected void finalize() throws Throwable { 834 try { 835 destroy(); 836 } finally { 837 super.finalize(); 838 } 839 } 840 destroy()841 private native final void destroy(); 842 sendDeathNotice(DeathRecipient recipient)843 private static final void sendDeathNotice(DeathRecipient recipient) { 844 if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient); 845 try { 846 recipient.binderDied(); 847 } 848 catch (RuntimeException exc) { 849 Log.w("BinderNative", "Uncaught exception from death notification", 850 exc); 851 } 852 } 853 854 final private WeakReference mSelf; 855 private long mObject; 856 private long mOrgue; 857 } 858