Binder.java revision ce92b0d070c4967914698b4e257c203d7121c972
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; 22 23import java.io.FileDescriptor; 24import java.io.FileOutputStream; 25import java.io.IOException; 26import java.io.PrintWriter; 27import java.lang.ref.WeakReference; 28import java.lang.reflect.Modifier; 29 30/** 31 * Base class for a remotable object, the core part of a lightweight 32 * remote procedure call mechanism defined by {@link IBinder}. 33 * This class is an implementation of IBinder that provides 34 * the standard support creating a local implementation of such an object. 35 * 36 * <p>Most developers will not implement this class directly, instead using the 37 * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired 38 * interface, having it generate the appropriate Binder subclass. You can, 39 * however, derive directly from Binder to implement your own custom RPC 40 * protocol or simply instantiate a raw Binder object directly to use as a 41 * token that can be shared across processes. 42 * 43 * @see IBinder 44 */ 45public class Binder implements IBinder { 46 /* 47 * Set this flag to true to detect anonymous, local or member classes 48 * that extend this Binder class and that are not static. These kind 49 * of classes can potentially create leaks. 50 */ 51 private static final boolean FIND_POTENTIAL_LEAKS = false; 52 private static final boolean CHECK_PARCEL_SIZE = false; 53 static final String TAG = "Binder"; 54 55 /** 56 * Control whether dump() calls are allowed. 57 */ 58 private static String sDumpDisabled = null; 59 60 /* mObject is used by native code, do not remove or rename */ 61 private long mObject; 62 private IInterface mOwner; 63 private String mDescriptor; 64 65 /** 66 * Return the ID of the process that sent you the current transaction 67 * that is being processed. This pid can be used with higher-level 68 * system services to determine its identity and check permissions. 69 * If the current thread is not currently executing an incoming transaction, 70 * then its own pid is returned. 71 */ 72 public static final native int getCallingPid(); 73 74 /** 75 * Return the Linux uid assigned to the process that sent you the 76 * current transaction that is being processed. This uid can be used with 77 * higher-level system services to determine its identity and check 78 * permissions. If the current thread is not currently executing an 79 * incoming transaction, then its own uid is returned. 80 */ 81 public static final native int getCallingUid(); 82 83 /** 84 * Return the UserHandle assigned to the process that sent you the 85 * current transaction that is being processed. This is the user 86 * of the caller. It is distinct from {@link #getCallingUid()} in that a 87 * particular user will have multiple distinct apps running under it each 88 * with their own uid. If the current thread is not currently executing an 89 * incoming transaction, then its own UserHandle is returned. 90 */ 91 public static final UserHandle getCallingUserHandle() { 92 return new UserHandle(UserHandle.getUserId(getCallingUid())); 93 } 94 95 /** 96 * Reset the identity of the incoming IPC on the current thread. This can 97 * be useful if, while handling an incoming call, you will be calling 98 * on interfaces of other objects that may be local to your process and 99 * need to do permission checks on the calls coming into them (so they 100 * will check the permission of your own local process, and not whatever 101 * process originally called you). 102 * 103 * @return Returns an opaque token that can be used to restore the 104 * original calling identity by passing it to 105 * {@link #restoreCallingIdentity(long)}. 106 * 107 * @see #getCallingPid() 108 * @see #getCallingUid() 109 * @see #restoreCallingIdentity(long) 110 */ 111 public static final native long clearCallingIdentity(); 112 113 /** 114 * Restore the identity of the incoming IPC on the current thread 115 * back to a previously identity that was returned by {@link 116 * #clearCallingIdentity}. 117 * 118 * @param token The opaque token that was previously returned by 119 * {@link #clearCallingIdentity}. 120 * 121 * @see #clearCallingIdentity 122 */ 123 public static final native void restoreCallingIdentity(long token); 124 125 /** 126 * Sets the native thread-local StrictMode policy mask. 127 * 128 * <p>The StrictMode settings are kept in two places: a Java-level 129 * threadlocal for libcore/Dalvik, and a native threadlocal (set 130 * here) for propagation via Binder calls. This is a little 131 * unfortunate, but necessary to break otherwise more unfortunate 132 * dependencies either of Dalvik on Android, or Android 133 * native-only code on Dalvik. 134 * 135 * @see StrictMode 136 * @hide 137 */ 138 public static final native void setThreadStrictModePolicy(int policyMask); 139 140 /** 141 * Gets the current native thread-local StrictMode policy mask. 142 * 143 * @see #setThreadStrictModePolicy 144 * @hide 145 */ 146 public static final native int getThreadStrictModePolicy(); 147 148 /** 149 * Flush any Binder commands pending in the current thread to the kernel 150 * driver. This can be 151 * useful to call before performing an operation that may block for a long 152 * time, to ensure that any pending object references have been released 153 * in order to prevent the process from holding on to objects longer than 154 * it needs to. 155 */ 156 public static final native void flushPendingCommands(); 157 158 /** 159 * Add the calling thread to the IPC thread pool. This function does 160 * not return until the current process is exiting. 161 */ 162 public static final native void joinThreadPool(); 163 164 /** 165 * Returns true if the specified interface is a proxy. 166 * @hide 167 */ 168 public static final boolean isProxy(IInterface iface) { 169 return iface.asBinder() != iface; 170 } 171 172 /** 173 * Default constructor initializes the object. 174 */ 175 public Binder() { 176 init(); 177 178 if (FIND_POTENTIAL_LEAKS) { 179 final Class<? extends Binder> klass = getClass(); 180 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 181 (klass.getModifiers() & Modifier.STATIC) == 0) { 182 Log.w(TAG, "The following Binder class should be static or leaks might occur: " + 183 klass.getCanonicalName()); 184 } 185 } 186 } 187 188 /** 189 * Convenience method for associating a specific interface with the Binder. 190 * After calling, queryLocalInterface() will be implemented for you 191 * to return the given owner IInterface when the corresponding 192 * descriptor is requested. 193 */ 194 public void attachInterface(IInterface owner, String descriptor) { 195 mOwner = owner; 196 mDescriptor = descriptor; 197 } 198 199 /** 200 * Default implementation returns an empty interface name. 201 */ 202 public String getInterfaceDescriptor() { 203 return mDescriptor; 204 } 205 206 /** 207 * Default implementation always returns true -- if you got here, 208 * the object is alive. 209 */ 210 public boolean pingBinder() { 211 return true; 212 } 213 214 /** 215 * {@inheritDoc} 216 * 217 * Note that if you're calling on a local binder, this always returns true 218 * because your process is alive if you're calling it. 219 */ 220 public boolean isBinderAlive() { 221 return true; 222 } 223 224 /** 225 * Use information supplied to attachInterface() to return the 226 * associated IInterface if it matches the requested 227 * descriptor. 228 */ 229 public IInterface queryLocalInterface(String descriptor) { 230 if (mDescriptor.equals(descriptor)) { 231 return mOwner; 232 } 233 return null; 234 } 235 236 /** 237 * Control disabling of dump calls in this process. This is used by the system 238 * process watchdog to disable incoming dump calls while it has detecting the system 239 * is hung and is reporting that back to the activity controller. This is to 240 * prevent the controller from getting hung up on bug reports at this point. 241 * @hide 242 * 243 * @param msg The message to show instead of the dump; if null, dumps are 244 * re-enabled. 245 */ 246 public static void setDumpDisabled(String msg) { 247 synchronized (Binder.class) { 248 sDumpDisabled = msg; 249 } 250 } 251 252 /** 253 * Default implementation is a stub that returns false. You will want 254 * to override this to do the appropriate unmarshalling of transactions. 255 * 256 * <p>If you want to call this, call transact(). 257 */ 258 protected boolean onTransact(int code, Parcel data, Parcel reply, 259 int flags) throws RemoteException { 260 if (code == INTERFACE_TRANSACTION) { 261 reply.writeString(getInterfaceDescriptor()); 262 return true; 263 } else if (code == DUMP_TRANSACTION) { 264 ParcelFileDescriptor fd = data.readFileDescriptor(); 265 String[] args = data.readStringArray(); 266 if (fd != null) { 267 try { 268 dump(fd.getFileDescriptor(), args); 269 } finally { 270 try { 271 fd.close(); 272 } catch (IOException e) { 273 // swallowed, not propagated back to the caller 274 } 275 } 276 } 277 // Write the StrictMode header. 278 if (reply != null) { 279 reply.writeNoException(); 280 } else { 281 StrictMode.clearGatheredViolations(); 282 } 283 return true; 284 } 285 return false; 286 } 287 288 /** 289 * Implemented to call the more convenient version 290 * {@link #dump(FileDescriptor, PrintWriter, String[])}. 291 */ 292 public void dump(FileDescriptor fd, String[] args) { 293 FileOutputStream fout = new FileOutputStream(fd); 294 PrintWriter pw = new FastPrintWriter(fout); 295 try { 296 final String disabled; 297 synchronized (Binder.class) { 298 disabled = sDumpDisabled; 299 } 300 if (disabled == null) { 301 try { 302 dump(fd, pw, args); 303 } catch (SecurityException e) { 304 pw.println("Security exception: " + e.getMessage()); 305 throw e; 306 } catch (Throwable e) { 307 // Unlike usual calls, in this case if an exception gets thrown 308 // back to us we want to print it back in to the dump data, since 309 // that is where the caller expects all interesting information to 310 // go. 311 pw.println(); 312 pw.println("Exception occurred while dumping:"); 313 e.printStackTrace(pw); 314 } 315 } else { 316 pw.println(sDumpDisabled); 317 } 318 } finally { 319 pw.flush(); 320 } 321 } 322 323 /** 324 * Like {@link #dump(FileDescriptor, String[])}, but ensures the target 325 * executes asynchronously. 326 */ 327 public void dumpAsync(final FileDescriptor fd, final String[] args) { 328 final FileOutputStream fout = new FileOutputStream(fd); 329 final PrintWriter pw = new FastPrintWriter(fout); 330 Thread thr = new Thread("Binder.dumpAsync") { 331 public void run() { 332 try { 333 dump(fd, pw, args); 334 } finally { 335 pw.flush(); 336 } 337 } 338 }; 339 thr.start(); 340 } 341 342 /** 343 * Print the object's state into the given stream. 344 * 345 * @param fd The raw file descriptor that the dump is being sent to. 346 * @param fout The file to which you should dump your state. This will be 347 * closed for you after you return. 348 * @param args additional arguments to the dump request. 349 */ 350 protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 351 } 352 353 /** 354 * Default implementation rewinds the parcels and calls onTransact. On 355 * the remote side, transact calls into the binder to do the IPC. 356 */ 357 public final boolean transact(int code, Parcel data, Parcel reply, 358 int flags) throws RemoteException { 359 if (false) Log.v("Binder", "Transact: " + code + " to " + this); 360 if (data != null) { 361 data.setDataPosition(0); 362 } 363 boolean r = onTransact(code, data, reply, flags); 364 if (reply != null) { 365 reply.setDataPosition(0); 366 } 367 return r; 368 } 369 370 /** 371 * Local implementation is a no-op. 372 */ 373 public void linkToDeath(DeathRecipient recipient, int flags) { 374 } 375 376 /** 377 * Local implementation is a no-op. 378 */ 379 public boolean unlinkToDeath(DeathRecipient recipient, int flags) { 380 return true; 381 } 382 383 protected void finalize() throws Throwable { 384 try { 385 destroy(); 386 } finally { 387 super.finalize(); 388 } 389 } 390 391 static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) { 392 if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) { 393 // Trying to send > 800k, this is way too much 394 StringBuilder sb = new StringBuilder(); 395 sb.append(msg); 396 sb.append(": on "); 397 sb.append(obj); 398 sb.append(" calling "); 399 sb.append(code); 400 sb.append(" size "); 401 sb.append(parcel.dataSize()); 402 sb.append(" (data: "); 403 parcel.setDataPosition(0); 404 sb.append(parcel.readInt()); 405 sb.append(", "); 406 sb.append(parcel.readInt()); 407 sb.append(", "); 408 sb.append(parcel.readInt()); 409 sb.append(")"); 410 Slog.wtfStack(TAG, sb.toString()); 411 } 412 } 413 414 private native final void init(); 415 private native final void destroy(); 416 417 // Entry point from android_util_Binder.cpp's onTransact 418 private boolean execTransact(int code, long dataObj, long replyObj, 419 int flags) { 420 Parcel data = Parcel.obtain(dataObj); 421 Parcel reply = Parcel.obtain(replyObj); 422 // theoretically, we should call transact, which will call onTransact, 423 // but all that does is rewind it, and we just got these from an IPC, 424 // so we'll just call it directly. 425 boolean res; 426 // Log any exceptions as warnings, don't silently suppress them. 427 // If the call was FLAG_ONEWAY then these exceptions disappear into the ether. 428 try { 429 res = onTransact(code, data, reply, flags); 430 } catch (RemoteException e) { 431 if ((flags & FLAG_ONEWAY) != 0) { 432 Log.w(TAG, "Binder call failed.", e); 433 } else { 434 reply.setDataPosition(0); 435 reply.writeException(e); 436 } 437 res = true; 438 } catch (RuntimeException e) { 439 if ((flags & FLAG_ONEWAY) != 0) { 440 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); 441 } else { 442 reply.setDataPosition(0); 443 reply.writeException(e); 444 } 445 res = true; 446 } catch (OutOfMemoryError e) { 447 // Unconditionally log this, since this is generally unrecoverable. 448 Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e); 449 RuntimeException re = new RuntimeException("Out of memory", e); 450 reply.setDataPosition(0); 451 reply.writeException(re); 452 res = true; 453 } 454 checkParcel(this, code, reply, "Unreasonably large binder reply buffer"); 455 reply.recycle(); 456 data.recycle(); 457 458 // Just in case -- we are done with the IPC, so there should be no more strict 459 // mode violations that have gathered for this thread. Either they have been 460 // parceled and are now in transport off to the caller, or we are returning back 461 // to the main transaction loop to wait for another incoming transaction. Either 462 // way, strict mode begone! 463 StrictMode.clearGatheredViolations(); 464 465 return res; 466 } 467} 468 469final class BinderProxy implements IBinder { 470 public native boolean pingBinder(); 471 public native boolean isBinderAlive(); 472 473 public IInterface queryLocalInterface(String descriptor) { 474 return null; 475 } 476 477 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { 478 Binder.checkParcel(this, code, data, "Unreasonably large binder buffer"); 479 return transactNative(code, data, reply, flags); 480 } 481 482 public native String getInterfaceDescriptor() throws RemoteException; 483 public native boolean transactNative(int code, Parcel data, Parcel reply, 484 int flags) throws RemoteException; 485 public native void linkToDeath(DeathRecipient recipient, int flags) 486 throws RemoteException; 487 public native boolean unlinkToDeath(DeathRecipient recipient, int flags); 488 489 public void dump(FileDescriptor fd, String[] args) throws RemoteException { 490 Parcel data = Parcel.obtain(); 491 Parcel reply = Parcel.obtain(); 492 data.writeFileDescriptor(fd); 493 data.writeStringArray(args); 494 try { 495 transact(DUMP_TRANSACTION, data, reply, 0); 496 reply.readException(); 497 } finally { 498 data.recycle(); 499 reply.recycle(); 500 } 501 } 502 503 public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException { 504 Parcel data = Parcel.obtain(); 505 Parcel reply = Parcel.obtain(); 506 data.writeFileDescriptor(fd); 507 data.writeStringArray(args); 508 try { 509 transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY); 510 } finally { 511 data.recycle(); 512 reply.recycle(); 513 } 514 } 515 516 BinderProxy() { 517 mSelf = new WeakReference(this); 518 } 519 520 @Override 521 protected void finalize() throws Throwable { 522 try { 523 destroy(); 524 } finally { 525 super.finalize(); 526 } 527 } 528 529 private native final void destroy(); 530 531 private static final void sendDeathNotice(DeathRecipient recipient) { 532 if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient); 533 try { 534 recipient.binderDied(); 535 } 536 catch (RuntimeException exc) { 537 Log.w("BinderNative", "Uncaught exception from death notification", 538 exc); 539 } 540 } 541 542 final private WeakReference mSelf; 543 private long mObject; 544 private long mOrgue; 545} 546