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 import android.util.Slog;
     21 import com.android.internal.util.FastPrintWriter;
     22 
     23 import java.io.FileDescriptor;
     24 import java.io.FileOutputStream;
     25 import java.io.IOException;
     26 import java.io.PrintWriter;
     27 import java.lang.ref.WeakReference;
     28 import java.lang.reflect.Modifier;
     29 
     30 /**
     31  * Base class for a remotable object, the core part of a lightweight
     32  * remote procedure call mechanism defined by {@link IBinder}.
     33  * This class is an implementation of IBinder that provides
     34  * standard local implementation of such an object.
     35  *
     36  * <p>Most developers will not implement this class directly, instead using the
     37  * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
     38  * interface, having it generate the appropriate Binder subclass.  You can,
     39  * however, derive directly from Binder to implement your own custom RPC
     40  * protocol or simply instantiate a raw Binder object directly to use as a
     41  * token that can be shared across processes.
     42  *
     43  * <p>This class is just a basic IPC primitive; it has no impact on an application's
     44  * lifecycle, and is valid only as long as the process that created it continues to run.
     45  * To use this correctly, you must be doing so within the context of a top-level
     46  * application component (a {@link android.app.Service}, {@link android.app.Activity},
     47  * or {@link android.content.ContentProvider}) that lets the system know your process
     48  * should remain running.</p>
     49  *
     50  * <p>You must keep in mind the situations in which your process
     51  * could go away, and thus require that you later re-create a new Binder and re-attach
     52  * it when the process starts again.  For example, if you are using this within an
     53  * {@link android.app.Activity}, your activity's process may be killed any time the
     54  * activity is not started; if the activity is later re-created you will need to
     55  * create a new Binder and hand it back to the correct place again; you need to be
     56  * aware that your process may be started for another reason (for example to receive
     57  * a broadcast) that will not involve re-creating the activity and thus run its code
     58  * to create a new Binder.</p>
     59  *
     60  * @see IBinder
     61  */
     62 public class Binder implements IBinder {
     63     /*
     64      * Set this flag to true to detect anonymous, local or member classes
     65      * that extend this Binder class and that are not static. These kind
     66      * of classes can potentially create leaks.
     67      */
     68     private static final boolean FIND_POTENTIAL_LEAKS = false;
     69     private static final boolean CHECK_PARCEL_SIZE = false;
     70     static final String TAG = "Binder";
     71 
     72     /**
     73      * Control whether dump() calls are allowed.
     74      */
     75     private static String sDumpDisabled = null;
     76 
     77     /* mObject is used by native code, do not remove or rename */
     78     private long mObject;
     79     private IInterface mOwner;
     80     private String mDescriptor;
     81 
     82     /**
     83      * Return the ID of the process that sent you the current transaction
     84      * that is being processed.  This pid can be used with higher-level
     85      * system services to determine its identity and check permissions.
     86      * If the current thread is not currently executing an incoming transaction,
     87      * then its own pid is returned.
     88      */
     89     public static final native int getCallingPid();
     90 
     91     /**
     92      * Return the Linux uid assigned to the process that sent you the
     93      * current transaction that is being processed.  This uid can be used with
     94      * higher-level system services to determine its identity and check
     95      * permissions.  If the current thread is not currently executing an
     96      * incoming transaction, then its own uid is returned.
     97      */
     98     public static final native int getCallingUid();
     99 
    100     /**
    101      * Return the UserHandle assigned to the process that sent you the
    102      * current transaction that is being processed.  This is the user
    103      * of the caller.  It is distinct from {@link #getCallingUid()} in that a
    104      * particular user will have multiple distinct apps running under it each
    105      * with their own uid.  If the current thread is not currently executing an
    106      * incoming transaction, then its own UserHandle is returned.
    107      */
    108     public static final UserHandle getCallingUserHandle() {
    109         return new UserHandle(UserHandle.getUserId(getCallingUid()));
    110     }
    111 
    112     /**
    113      * Reset the identity of the incoming IPC on the current thread.  This can
    114      * be useful if, while handling an incoming call, you will be calling
    115      * on interfaces of other objects that may be local to your process and
    116      * need to do permission checks on the calls coming into them (so they
    117      * will check the permission of your own local process, and not whatever
    118      * process originally called you).
    119      *
    120      * @return Returns an opaque token that can be used to restore the
    121      * original calling identity by passing it to
    122      * {@link #restoreCallingIdentity(long)}.
    123      *
    124      * @see #getCallingPid()
    125      * @see #getCallingUid()
    126      * @see #restoreCallingIdentity(long)
    127      */
    128     public static final native long clearCallingIdentity();
    129 
    130     /**
    131      * Restore the identity of the incoming IPC on the current thread
    132      * back to a previously identity that was returned by {@link
    133      * #clearCallingIdentity}.
    134      *
    135      * @param token The opaque token that was previously returned by
    136      * {@link #clearCallingIdentity}.
    137      *
    138      * @see #clearCallingIdentity
    139      */
    140     public static final native void restoreCallingIdentity(long token);
    141 
    142     /**
    143      * Sets the native thread-local StrictMode policy mask.
    144      *
    145      * <p>The StrictMode settings are kept in two places: a Java-level
    146      * threadlocal for libcore/Dalvik, and a native threadlocal (set
    147      * here) for propagation via Binder calls.  This is a little
    148      * unfortunate, but necessary to break otherwise more unfortunate
    149      * dependencies either of Dalvik on Android, or Android
    150      * native-only code on Dalvik.
    151      *
    152      * @see StrictMode
    153      * @hide
    154      */
    155     public static final native void setThreadStrictModePolicy(int policyMask);
    156 
    157     /**
    158      * Gets the current native thread-local StrictMode policy mask.
    159      *
    160      * @see #setThreadStrictModePolicy
    161      * @hide
    162      */
    163     public static final native int getThreadStrictModePolicy();
    164 
    165     /**
    166      * Flush any Binder commands pending in the current thread to the kernel
    167      * driver.  This can be
    168      * useful to call before performing an operation that may block for a long
    169      * time, to ensure that any pending object references have been released
    170      * in order to prevent the process from holding on to objects longer than
    171      * it needs to.
    172      */
    173     public static final native void flushPendingCommands();
    174 
    175     /**
    176      * Add the calling thread to the IPC thread pool.  This function does
    177      * not return until the current process is exiting.
    178      */
    179     public static final native void joinThreadPool();
    180 
    181     /**
    182      * Returns true if the specified interface is a proxy.
    183      * @hide
    184      */
    185     public static final boolean isProxy(IInterface iface) {
    186         return iface.asBinder() != iface;
    187     }
    188 
    189     /**
    190      * Call blocks until the number of executing binder threads is less
    191      * than the maximum number of binder threads allowed for this process.
    192      * @hide
    193      */
    194     public static final native void blockUntilThreadAvailable();
    195 
    196     /**
    197      * Default constructor initializes the object.
    198      */
    199     public Binder() {
    200         init();
    201 
    202         if (FIND_POTENTIAL_LEAKS) {
    203             final Class<? extends Binder> klass = getClass();
    204             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
    205                     (klass.getModifiers() & Modifier.STATIC) == 0) {
    206                 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
    207                     klass.getCanonicalName());
    208             }
    209         }
    210     }
    211 
    212     /**
    213      * Convenience method for associating a specific interface with the Binder.
    214      * After calling, queryLocalInterface() will be implemented for you
    215      * to return the given owner IInterface when the corresponding
    216      * descriptor is requested.
    217      */
    218     public void attachInterface(IInterface owner, String descriptor) {
    219         mOwner = owner;
    220         mDescriptor = descriptor;
    221     }
    222 
    223     /**
    224      * Default implementation returns an empty interface name.
    225      */
    226     public String getInterfaceDescriptor() {
    227         return mDescriptor;
    228     }
    229 
    230     /**
    231      * Default implementation always returns true -- if you got here,
    232      * the object is alive.
    233      */
    234     public boolean pingBinder() {
    235         return true;
    236     }
    237 
    238     /**
    239      * {@inheritDoc}
    240      *
    241      * Note that if you're calling on a local binder, this always returns true
    242      * because your process is alive if you're calling it.
    243      */
    244     public boolean isBinderAlive() {
    245         return true;
    246     }
    247 
    248     /**
    249      * Use information supplied to attachInterface() to return the
    250      * associated IInterface if it matches the requested
    251      * descriptor.
    252      */
    253     public IInterface queryLocalInterface(String descriptor) {
    254         if (mDescriptor.equals(descriptor)) {
    255             return mOwner;
    256         }
    257         return null;
    258     }
    259 
    260     /**
    261      * Control disabling of dump calls in this process.  This is used by the system
    262      * process watchdog to disable incoming dump calls while it has detecting the system
    263      * is hung and is reporting that back to the activity controller.  This is to
    264      * prevent the controller from getting hung up on bug reports at this point.
    265      * @hide
    266      *
    267      * @param msg The message to show instead of the dump; if null, dumps are
    268      * re-enabled.
    269      */
    270     public static void setDumpDisabled(String msg) {
    271         synchronized (Binder.class) {
    272             sDumpDisabled = msg;
    273         }
    274     }
    275 
    276     /**
    277      * Default implementation is a stub that returns false.  You will want
    278      * to override this to do the appropriate unmarshalling of transactions.
    279      *
    280      * <p>If you want to call this, call transact().
    281      */
    282     protected boolean onTransact(int code, Parcel data, Parcel reply,
    283             int flags) throws RemoteException {
    284         if (code == INTERFACE_TRANSACTION) {
    285             reply.writeString(getInterfaceDescriptor());
    286             return true;
    287         } else if (code == DUMP_TRANSACTION) {
    288             ParcelFileDescriptor fd = data.readFileDescriptor();
    289             String[] args = data.readStringArray();
    290             if (fd != null) {
    291                 try {
    292                     dump(fd.getFileDescriptor(), args);
    293                 } finally {
    294                     try {
    295                         fd.close();
    296                     } catch (IOException e) {
    297                         // swallowed, not propagated back to the caller
    298                     }
    299                 }
    300             }
    301             // Write the StrictMode header.
    302             if (reply != null) {
    303                 reply.writeNoException();
    304             } else {
    305                 StrictMode.clearGatheredViolations();
    306             }
    307             return true;
    308         }
    309         return false;
    310     }
    311 
    312     /**
    313      * Implemented to call the more convenient version
    314      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
    315      */
    316     public void dump(FileDescriptor fd, String[] args) {
    317         FileOutputStream fout = new FileOutputStream(fd);
    318         PrintWriter pw = new FastPrintWriter(fout);
    319         try {
    320             final String disabled;
    321             synchronized (Binder.class) {
    322                 disabled = sDumpDisabled;
    323             }
    324             if (disabled == null) {
    325                 try {
    326                     dump(fd, pw, args);
    327                 } catch (SecurityException e) {
    328                     pw.println("Security exception: " + e.getMessage());
    329                     throw e;
    330                 } catch (Throwable e) {
    331                     // Unlike usual calls, in this case if an exception gets thrown
    332                     // back to us we want to print it back in to the dump data, since
    333                     // that is where the caller expects all interesting information to
    334                     // go.
    335                     pw.println();
    336                     pw.println("Exception occurred while dumping:");
    337                     e.printStackTrace(pw);
    338                 }
    339             } else {
    340                 pw.println(sDumpDisabled);
    341             }
    342         } finally {
    343             pw.flush();
    344         }
    345     }
    346 
    347     /**
    348      * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
    349      * executes asynchronously.
    350      */
    351     public void dumpAsync(final FileDescriptor fd, final String[] args) {
    352         final FileOutputStream fout = new FileOutputStream(fd);
    353         final PrintWriter pw = new FastPrintWriter(fout);
    354         Thread thr = new Thread("Binder.dumpAsync") {
    355             public void run() {
    356                 try {
    357                     dump(fd, pw, args);
    358                 } finally {
    359                     pw.flush();
    360                 }
    361             }
    362         };
    363         thr.start();
    364     }
    365 
    366     /**
    367      * Print the object's state into the given stream.
    368      *
    369      * @param fd The raw file descriptor that the dump is being sent to.
    370      * @param fout The file to which you should dump your state.  This will be
    371      * closed for you after you return.
    372      * @param args additional arguments to the dump request.
    373      */
    374     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
    375     }
    376 
    377     /**
    378      * Default implementation rewinds the parcels and calls onTransact.  On
    379      * the remote side, transact calls into the binder to do the IPC.
    380      */
    381     public final boolean transact(int code, Parcel data, Parcel reply,
    382             int flags) throws RemoteException {
    383         if (false) Log.v("Binder", "Transact: " + code + " to " + this);
    384         if (data != null) {
    385             data.setDataPosition(0);
    386         }
    387         boolean r = onTransact(code, data, reply, flags);
    388         if (reply != null) {
    389             reply.setDataPosition(0);
    390         }
    391         return r;
    392     }
    393 
    394     /**
    395      * Local implementation is a no-op.
    396      */
    397     public void linkToDeath(DeathRecipient recipient, int flags) {
    398     }
    399 
    400     /**
    401      * Local implementation is a no-op.
    402      */
    403     public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
    404         return true;
    405     }
    406 
    407     protected void finalize() throws Throwable {
    408         try {
    409             destroy();
    410         } finally {
    411             super.finalize();
    412         }
    413     }
    414 
    415     static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
    416         if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
    417             // Trying to send > 800k, this is way too much
    418             StringBuilder sb = new StringBuilder();
    419             sb.append(msg);
    420             sb.append(": on ");
    421             sb.append(obj);
    422             sb.append(" calling ");
    423             sb.append(code);
    424             sb.append(" size ");
    425             sb.append(parcel.dataSize());
    426             sb.append(" (data: ");
    427             parcel.setDataPosition(0);
    428             sb.append(parcel.readInt());
    429             sb.append(", ");
    430             sb.append(parcel.readInt());
    431             sb.append(", ");
    432             sb.append(parcel.readInt());
    433             sb.append(")");
    434             Slog.wtfStack(TAG, sb.toString());
    435         }
    436     }
    437 
    438     private native final void init();
    439     private native final void destroy();
    440 
    441     // Entry point from android_util_Binder.cpp's onTransact
    442     private boolean execTransact(int code, long dataObj, long replyObj,
    443             int flags) {
    444         Parcel data = Parcel.obtain(dataObj);
    445         Parcel reply = Parcel.obtain(replyObj);
    446         // theoretically, we should call transact, which will call onTransact,
    447         // but all that does is rewind it, and we just got these from an IPC,
    448         // so we'll just call it directly.
    449         boolean res;
    450         // Log any exceptions as warnings, don't silently suppress them.
    451         // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
    452         try {
    453             res = onTransact(code, data, reply, flags);
    454         } catch (RemoteException e) {
    455             if ((flags & FLAG_ONEWAY) != 0) {
    456                 Log.w(TAG, "Binder call failed.", e);
    457             } else {
    458                 reply.setDataPosition(0);
    459                 reply.writeException(e);
    460             }
    461             res = true;
    462         } catch (RuntimeException e) {
    463             if ((flags & FLAG_ONEWAY) != 0) {
    464                 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
    465             } else {
    466                 reply.setDataPosition(0);
    467                 reply.writeException(e);
    468             }
    469             res = true;
    470         } catch (OutOfMemoryError e) {
    471             // Unconditionally log this, since this is generally unrecoverable.
    472             Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
    473             RuntimeException re = new RuntimeException("Out of memory", e);
    474             reply.setDataPosition(0);
    475             reply.writeException(re);
    476             res = true;
    477         }
    478         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
    479         reply.recycle();
    480         data.recycle();
    481 
    482         // Just in case -- we are done with the IPC, so there should be no more strict
    483         // mode violations that have gathered for this thread.  Either they have been
    484         // parceled and are now in transport off to the caller, or we are returning back
    485         // to the main transaction loop to wait for another incoming transaction.  Either
    486         // way, strict mode begone!
    487         StrictMode.clearGatheredViolations();
    488 
    489         return res;
    490     }
    491 }
    492 
    493 final class BinderProxy implements IBinder {
    494     public native boolean pingBinder();
    495     public native boolean isBinderAlive();
    496 
    497     public IInterface queryLocalInterface(String descriptor) {
    498         return null;
    499     }
    500 
    501     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    502         Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
    503         return transactNative(code, data, reply, flags);
    504     }
    505 
    506     public native String getInterfaceDescriptor() throws RemoteException;
    507     public native boolean transactNative(int code, Parcel data, Parcel reply,
    508             int flags) throws RemoteException;
    509     public native void linkToDeath(DeathRecipient recipient, int flags)
    510             throws RemoteException;
    511     public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
    512 
    513     public void dump(FileDescriptor fd, String[] args) throws RemoteException {
    514         Parcel data = Parcel.obtain();
    515         Parcel reply = Parcel.obtain();
    516         data.writeFileDescriptor(fd);
    517         data.writeStringArray(args);
    518         try {
    519             transact(DUMP_TRANSACTION, data, reply, 0);
    520             reply.readException();
    521         } finally {
    522             data.recycle();
    523             reply.recycle();
    524         }
    525     }
    526 
    527     public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
    528         Parcel data = Parcel.obtain();
    529         Parcel reply = Parcel.obtain();
    530         data.writeFileDescriptor(fd);
    531         data.writeStringArray(args);
    532         try {
    533             transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
    534         } finally {
    535             data.recycle();
    536             reply.recycle();
    537         }
    538     }
    539 
    540     BinderProxy() {
    541         mSelf = new WeakReference(this);
    542     }
    543 
    544     @Override
    545     protected void finalize() throws Throwable {
    546         try {
    547             destroy();
    548         } finally {
    549             super.finalize();
    550         }
    551     }
    552 
    553     private native final void destroy();
    554 
    555     private static final void sendDeathNotice(DeathRecipient recipient) {
    556         if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
    557         try {
    558             recipient.binderDied();
    559         }
    560         catch (RuntimeException exc) {
    561             Log.w("BinderNative", "Uncaught exception from death notification",
    562                     exc);
    563         }
    564     }
    565 
    566     final private WeakReference mSelf;
    567     private long mObject;
    568     private long mOrgue;
    569 }
    570