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.Config; 20 import android.util.Log; 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/developing/tools/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 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 * Reset the identity of the incoming IPC to the local process. 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 */ clearCallingIdentity()91 public static final native long clearCallingIdentity(); 92 93 /** 94 * Restore the identity of the incoming IPC back to a previously identity 95 * that was returned by {@link #clearCallingIdentity}. 96 * 97 * @param token The opaque token that was previously returned by 98 * {@link #clearCallingIdentity}. 99 * 100 * @see #clearCallingIdentity 101 */ restoreCallingIdentity(long token)102 public static final native void restoreCallingIdentity(long token); 103 104 /** 105 * Flush any Binder commands pending in the current thread to the kernel 106 * driver. This can be 107 * useful to call before performing an operation that may block for a long 108 * time, to ensure that any pending object references have been released 109 * in order to prevent the process from holding on to objects longer than 110 * it needs to. 111 */ flushPendingCommands()112 public static final native void flushPendingCommands(); 113 114 /** 115 * Add the calling thread to the IPC thread pool. This function does 116 * not return until the current process is exiting. 117 */ joinThreadPool()118 public static final native void joinThreadPool(); 119 120 /** 121 * Default constructor initializes the object. 122 */ Binder()123 public Binder() { 124 init(); 125 126 if (FIND_POTENTIAL_LEAKS) { 127 final Class<? extends Binder> klass = getClass(); 128 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 129 (klass.getModifiers() & Modifier.STATIC) == 0) { 130 Log.w(TAG, "The following Binder class should be static or leaks might occur: " + 131 klass.getCanonicalName()); 132 } 133 } 134 } 135 136 /** 137 * Convenience method for associating a specific interface with the Binder. 138 * After calling, queryLocalInterface() will be implemented for you 139 * to return the given owner IInterface when the corresponding 140 * descriptor is requested. 141 */ attachInterface(IInterface owner, String descriptor)142 public void attachInterface(IInterface owner, String descriptor) { 143 mOwner = owner; 144 mDescriptor = descriptor; 145 } 146 147 /** 148 * Default implementation returns an empty interface name. 149 */ getInterfaceDescriptor()150 public String getInterfaceDescriptor() { 151 return mDescriptor; 152 } 153 154 /** 155 * Default implementation always returns true -- if you got here, 156 * the object is alive. 157 */ pingBinder()158 public boolean pingBinder() { 159 return true; 160 } 161 162 /** 163 * {@inheritDoc} 164 * 165 * Note that if you're calling on a local binder, this always returns true 166 * because your process is alive if you're calling it. 167 */ isBinderAlive()168 public boolean isBinderAlive() { 169 return true; 170 } 171 172 /** 173 * Use information supplied to attachInterface() to return the 174 * associated IInterface if it matches the requested 175 * descriptor. 176 */ queryLocalInterface(String descriptor)177 public IInterface queryLocalInterface(String descriptor) { 178 if (mDescriptor.equals(descriptor)) { 179 return mOwner; 180 } 181 return null; 182 } 183 184 /** 185 * Default implementation is a stub that returns false. You will want 186 * to override this to do the appropriate unmarshalling of transactions. 187 * 188 * <p>If you want to call this, call transact(). 189 */ onTransact(int code, Parcel data, Parcel reply, int flags)190 protected boolean onTransact(int code, Parcel data, Parcel reply, 191 int flags) throws RemoteException { 192 if (code == INTERFACE_TRANSACTION) { 193 reply.writeString(getInterfaceDescriptor()); 194 return true; 195 } else if (code == DUMP_TRANSACTION) { 196 ParcelFileDescriptor fd = data.readFileDescriptor(); 197 String[] args = data.readStringArray(); 198 if (fd != null) { 199 try { 200 dump(fd.getFileDescriptor(), args); 201 } finally { 202 try { 203 fd.close(); 204 } catch (IOException e) { 205 } 206 } 207 } 208 return true; 209 } 210 return false; 211 } 212 213 /** 214 * Implemented to call the more convenient version 215 * {@link #dump(FileDescriptor, PrintWriter, String[])}. 216 */ dump(FileDescriptor fd, String[] args)217 public void dump(FileDescriptor fd, String[] args) { 218 FileOutputStream fout = new FileOutputStream(fd); 219 PrintWriter pw = new PrintWriter(fout); 220 try { 221 dump(fd, pw, args); 222 } finally { 223 pw.flush(); 224 } 225 } 226 227 /** 228 * Print the object's state into the given stream. 229 * 230 * @param fd The raw file descriptor that the dump is being sent to. 231 * @param fout The file to which you should dump your state. This will be 232 * closed for you after you return. 233 * @param args additional arguments to the dump request. 234 */ dump(FileDescriptor fd, PrintWriter fout, String[] args)235 protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 236 } 237 238 /** 239 * Default implementation rewinds the parcels and calls onTransact. On 240 * the remote side, transact calls into the binder to do the IPC. 241 */ transact(int code, Parcel data, Parcel reply, int flags)242 public final boolean transact(int code, Parcel data, Parcel reply, 243 int flags) throws RemoteException { 244 if (Config.LOGV) Log.v("Binder", "Transact: " + code + " to " + this); 245 if (data != null) { 246 data.setDataPosition(0); 247 } 248 boolean r = onTransact(code, data, reply, flags); 249 if (reply != null) { 250 reply.setDataPosition(0); 251 } 252 return r; 253 } 254 255 /** 256 * Local implementation is a no-op. 257 */ linkToDeath(DeathRecipient recipient, int flags)258 public void linkToDeath(DeathRecipient recipient, int flags) { 259 } 260 261 /** 262 * Local implementation is a no-op. 263 */ unlinkToDeath(DeathRecipient recipient, int flags)264 public boolean unlinkToDeath(DeathRecipient recipient, int flags) { 265 return true; 266 } 267 finalize()268 protected void finalize() throws Throwable { 269 try { 270 destroy(); 271 } finally { 272 super.finalize(); 273 } 274 } 275 init()276 private native final void init(); destroy()277 private native final void destroy(); execTransact(int code, int dataObj, int replyObj, int flags)278 private boolean execTransact(int code, int dataObj, int replyObj, 279 int flags) { 280 Parcel data = Parcel.obtain(dataObj); 281 Parcel reply = Parcel.obtain(replyObj); 282 // theoretically, we should call transact, which will call onTransact, 283 // but all that does is rewind it, and we just got these from an IPC, 284 // so we'll just call it directly. 285 boolean res; 286 try { 287 res = onTransact(code, data, reply, flags); 288 } catch (RemoteException e) { 289 reply.writeException(e); 290 res = true; 291 } catch (RuntimeException e) { 292 reply.writeException(e); 293 res = true; 294 } 295 reply.recycle(); 296 data.recycle(); 297 return res; 298 } 299 } 300 301 final class BinderProxy implements IBinder { pingBinder()302 public native boolean pingBinder(); isBinderAlive()303 public native boolean isBinderAlive(); 304 queryLocalInterface(String descriptor)305 public IInterface queryLocalInterface(String descriptor) { 306 return null; 307 } 308 getInterfaceDescriptor()309 public native String getInterfaceDescriptor() throws RemoteException; transact(int code, Parcel data, Parcel reply, int flags)310 public native boolean transact(int code, Parcel data, Parcel reply, 311 int flags) throws RemoteException; linkToDeath(DeathRecipient recipient, int flags)312 public native void linkToDeath(DeathRecipient recipient, int flags) 313 throws RemoteException; unlinkToDeath(DeathRecipient recipient, int flags)314 public native boolean unlinkToDeath(DeathRecipient recipient, int flags); 315 dump(FileDescriptor fd, String[] args)316 public void dump(FileDescriptor fd, String[] args) throws RemoteException { 317 Parcel data = Parcel.obtain(); 318 data.writeFileDescriptor(fd); 319 data.writeStringArray(args); 320 try { 321 transact(DUMP_TRANSACTION, data, null, 0); 322 } finally { 323 data.recycle(); 324 } 325 } 326 BinderProxy()327 BinderProxy() { 328 mSelf = new WeakReference(this); 329 } 330 331 @Override finalize()332 protected void finalize() throws Throwable { 333 try { 334 destroy(); 335 } finally { 336 super.finalize(); 337 } 338 } 339 destroy()340 private native final void destroy(); 341 sendDeathNotice(DeathRecipient recipient)342 private static final void sendDeathNotice(DeathRecipient recipient) { 343 if (Config.LOGV) Log.v("JavaBinder", "sendDeathNotice to " + recipient); 344 try { 345 recipient.binderDied(); 346 } 347 catch (RuntimeException exc) { 348 Log.w("BinderNative", "Uncaught exception from death notification", 349 exc); 350 } 351 } 352 353 final private WeakReference mSelf; 354 private int mObject; 355 } 356