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