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