Home | History | Annotate | Download | only in os
      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