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      * Default constructor initializes the object.
    191      */
    192     public Binder() {
    193         init();
    194 
    195         if (FIND_POTENTIAL_LEAKS) {
    196             final Class<? extends Binder> klass = getClass();
    197             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
    198                     (klass.getModifiers() & Modifier.STATIC) == 0) {
    199                 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
    200                     klass.getCanonicalName());
    201             }
    202         }
    203     }
    204 
    205     /**
    206      * Convenience method for associating a specific interface with the Binder.
    207      * After calling, queryLocalInterface() will be implemented for you
    208      * to return the given owner IInterface when the corresponding
    209      * descriptor is requested.
    210      */
    211     public void attachInterface(IInterface owner, String descriptor) {
    212         mOwner = owner;
    213         mDescriptor = descriptor;
    214     }
    215 
    216     /**
    217      * Default implementation returns an empty interface name.
    218      */
    219     public String getInterfaceDescriptor() {
    220         return mDescriptor;
    221     }
    222 
    223     /**
    224      * Default implementation always returns true -- if you got here,
    225      * the object is alive.
    226      */
    227     public boolean pingBinder() {
    228         return true;
    229     }
    230 
    231     /**
    232      * {@inheritDoc}
    233      *
    234      * Note that if you're calling on a local binder, this always returns true
    235      * because your process is alive if you're calling it.
    236      */
    237     public boolean isBinderAlive() {
    238         return true;
    239     }
    240 
    241     /**
    242      * Use information supplied to attachInterface() to return the
    243      * associated IInterface if it matches the requested
    244      * descriptor.
    245      */
    246     public IInterface queryLocalInterface(String descriptor) {
    247         if (mDescriptor.equals(descriptor)) {
    248             return mOwner;
    249         }
    250         return null;
    251     }
    252 
    253     /**
    254      * Control disabling of dump calls in this process.  This is used by the system
    255      * process watchdog to disable incoming dump calls while it has detecting the system
    256      * is hung and is reporting that back to the activity controller.  This is to
    257      * prevent the controller from getting hung up on bug reports at this point.
    258      * @hide
    259      *
    260      * @param msg The message to show instead of the dump; if null, dumps are
    261      * re-enabled.
    262      */
    263     public static void setDumpDisabled(String msg) {
    264         synchronized (Binder.class) {
    265             sDumpDisabled = msg;
    266         }
    267     }
    268 
    269     /**
    270      * Default implementation is a stub that returns false.  You will want
    271      * to override this to do the appropriate unmarshalling of transactions.
    272      *
    273      * <p>If you want to call this, call transact().
    274      */
    275     protected boolean onTransact(int code, Parcel data, Parcel reply,
    276             int flags) throws RemoteException {
    277         if (code == INTERFACE_TRANSACTION) {
    278             reply.writeString(getInterfaceDescriptor());
    279             return true;
    280         } else if (code == DUMP_TRANSACTION) {
    281             ParcelFileDescriptor fd = data.readFileDescriptor();
    282             String[] args = data.readStringArray();
    283             if (fd != null) {
    284                 try {
    285                     dump(fd.getFileDescriptor(), args);
    286                 } finally {
    287                     try {
    288                         fd.close();
    289                     } catch (IOException e) {
    290                         // swallowed, not propagated back to the caller
    291                     }
    292                 }
    293             }
    294             // Write the StrictMode header.
    295             if (reply != null) {
    296                 reply.writeNoException();
    297             } else {
    298                 StrictMode.clearGatheredViolations();
    299             }
    300             return true;
    301         }
    302         return false;
    303     }
    304 
    305     /**
    306      * Implemented to call the more convenient version
    307      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
    308      */
    309     public void dump(FileDescriptor fd, String[] args) {
    310         FileOutputStream fout = new FileOutputStream(fd);
    311         PrintWriter pw = new FastPrintWriter(fout);
    312         try {
    313             final String disabled;
    314             synchronized (Binder.class) {
    315                 disabled = sDumpDisabled;
    316             }
    317             if (disabled == null) {
    318                 try {
    319                     dump(fd, pw, args);
    320                 } catch (SecurityException e) {
    321                     pw.println("Security exception: " + e.getMessage());
    322                     throw e;
    323                 } catch (Throwable e) {
    324                     // Unlike usual calls, in this case if an exception gets thrown
    325                     // back to us we want to print it back in to the dump data, since
    326                     // that is where the caller expects all interesting information to
    327                     // go.
    328                     pw.println();
    329                     pw.println("Exception occurred while dumping:");
    330                     e.printStackTrace(pw);
    331                 }
    332             } else {
    333                 pw.println(sDumpDisabled);
    334             }
    335         } finally {
    336             pw.flush();
    337         }
    338     }
    339 
    340     /**
    341      * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
    342      * executes asynchronously.
    343      */
    344     public void dumpAsync(final FileDescriptor fd, final String[] args) {
    345         final FileOutputStream fout = new FileOutputStream(fd);
    346         final PrintWriter pw = new FastPrintWriter(fout);
    347         Thread thr = new Thread("Binder.dumpAsync") {
    348             public void run() {
    349                 try {
    350                     dump(fd, pw, args);
    351                 } finally {
    352                     pw.flush();
    353                 }
    354             }
    355         };
    356         thr.start();
    357     }
    358 
    359     /**
    360      * Print the object's state into the given stream.
    361      *
    362      * @param fd The raw file descriptor that the dump is being sent to.
    363      * @param fout The file to which you should dump your state.  This will be
    364      * closed for you after you return.
    365      * @param args additional arguments to the dump request.
    366      */
    367     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
    368     }
    369 
    370     /**
    371      * Default implementation rewinds the parcels and calls onTransact.  On
    372      * the remote side, transact calls into the binder to do the IPC.
    373      */
    374     public final boolean transact(int code, Parcel data, Parcel reply,
    375             int flags) throws RemoteException {
    376         if (false) Log.v("Binder", "Transact: " + code + " to " + this);
    377         if (data != null) {
    378             data.setDataPosition(0);
    379         }
    380         boolean r = onTransact(code, data, reply, flags);
    381         if (reply != null) {
    382             reply.setDataPosition(0);
    383         }
    384         return r;
    385     }
    386 
    387     /**
    388      * Local implementation is a no-op.
    389      */
    390     public void linkToDeath(DeathRecipient recipient, int flags) {
    391     }
    392 
    393     /**
    394      * Local implementation is a no-op.
    395      */
    396     public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
    397         return true;
    398     }
    399 
    400     protected void finalize() throws Throwable {
    401         try {
    402             destroy();
    403         } finally {
    404             super.finalize();
    405         }
    406     }
    407 
    408     static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
    409         if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
    410             // Trying to send > 800k, this is way too much
    411             StringBuilder sb = new StringBuilder();
    412             sb.append(msg);
    413             sb.append(": on ");
    414             sb.append(obj);
    415             sb.append(" calling ");
    416             sb.append(code);
    417             sb.append(" size ");
    418             sb.append(parcel.dataSize());
    419             sb.append(" (data: ");
    420             parcel.setDataPosition(0);
    421             sb.append(parcel.readInt());
    422             sb.append(", ");
    423             sb.append(parcel.readInt());
    424             sb.append(", ");
    425             sb.append(parcel.readInt());
    426             sb.append(")");
    427             Slog.wtfStack(TAG, sb.toString());
    428         }
    429     }
    430 
    431     private native final void init();
    432     private native final void destroy();
    433 
    434     // Entry point from android_util_Binder.cpp's onTransact
    435     private boolean execTransact(int code, long dataObj, long replyObj,
    436             int flags) {
    437         Parcel data = Parcel.obtain(dataObj);
    438         Parcel reply = Parcel.obtain(replyObj);
    439         // theoretically, we should call transact, which will call onTransact,
    440         // but all that does is rewind it, and we just got these from an IPC,
    441         // so we'll just call it directly.
    442         boolean res;
    443         // Log any exceptions as warnings, don't silently suppress them.
    444         // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
    445         try {
    446             res = onTransact(code, data, reply, flags);
    447         } catch (RemoteException e) {
    448             if ((flags & FLAG_ONEWAY) != 0) {
    449                 Log.w(TAG, "Binder call failed.", e);
    450             } else {
    451                 reply.setDataPosition(0);
    452                 reply.writeException(e);
    453             }
    454             res = true;
    455         } catch (RuntimeException e) {
    456             if ((flags & FLAG_ONEWAY) != 0) {
    457                 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
    458             } else {
    459                 reply.setDataPosition(0);
    460                 reply.writeException(e);
    461             }
    462             res = true;
    463         } catch (OutOfMemoryError e) {
    464             // Unconditionally log this, since this is generally unrecoverable.
    465             Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
    466             RuntimeException re = new RuntimeException("Out of memory", e);
    467             reply.setDataPosition(0);
    468             reply.writeException(re);
    469             res = true;
    470         }
    471         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
    472         reply.recycle();
    473         data.recycle();
    474 
    475         // Just in case -- we are done with the IPC, so there should be no more strict
    476         // mode violations that have gathered for this thread.  Either they have been
    477         // parceled and are now in transport off to the caller, or we are returning back
    478         // to the main transaction loop to wait for another incoming transaction.  Either
    479         // way, strict mode begone!
    480         StrictMode.clearGatheredViolations();
    481 
    482         return res;
    483     }
    484 }
    485 
    486 final class BinderProxy implements IBinder {
    487     public native boolean pingBinder();
    488     public native boolean isBinderAlive();
    489 
    490     public IInterface queryLocalInterface(String descriptor) {
    491         return null;
    492     }
    493 
    494     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    495         Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
    496         return transactNative(code, data, reply, flags);
    497     }
    498 
    499     public native String getInterfaceDescriptor() throws RemoteException;
    500     public native boolean transactNative(int code, Parcel data, Parcel reply,
    501             int flags) throws RemoteException;
    502     public native void linkToDeath(DeathRecipient recipient, int flags)
    503             throws RemoteException;
    504     public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
    505 
    506     public void dump(FileDescriptor fd, String[] args) throws RemoteException {
    507         Parcel data = Parcel.obtain();
    508         Parcel reply = Parcel.obtain();
    509         data.writeFileDescriptor(fd);
    510         data.writeStringArray(args);
    511         try {
    512             transact(DUMP_TRANSACTION, data, reply, 0);
    513             reply.readException();
    514         } finally {
    515             data.recycle();
    516             reply.recycle();
    517         }
    518     }
    519 
    520     public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
    521         Parcel data = Parcel.obtain();
    522         Parcel reply = Parcel.obtain();
    523         data.writeFileDescriptor(fd);
    524         data.writeStringArray(args);
    525         try {
    526             transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
    527         } finally {
    528             data.recycle();
    529             reply.recycle();
    530         }
    531     }
    532 
    533     BinderProxy() {
    534         mSelf = new WeakReference(this);
    535     }
    536 
    537     @Override
    538     protected void finalize() throws Throwable {
    539         try {
    540             destroy();
    541         } finally {
    542             super.finalize();
    543         }
    544     }
    545 
    546     private native final void destroy();
    547 
    548     private static final void sendDeathNotice(DeathRecipient recipient) {
    549         if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
    550         try {
    551             recipient.binderDied();
    552         }
    553         catch (RuntimeException exc) {
    554             Log.w("BinderNative", "Uncaught exception from death notification",
    555                     exc);
    556         }
    557     }
    558 
    559     final private WeakReference mSelf;
    560     private long mObject;
    561     private long mOrgue;
    562 }
    563