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