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