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