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