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