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