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