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