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.ExceptionUtils;
     20 import android.util.Log;
     21 import android.util.Slog;
     22 
     23 import com.android.internal.util.FastPrintWriter;
     24 import com.android.internal.util.FunctionalUtils;
     25 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
     26 import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
     27 
     28 import libcore.io.IoUtils;
     29 
     30 import java.io.FileDescriptor;
     31 import java.io.FileOutputStream;
     32 import java.io.PrintWriter;
     33 import java.lang.ref.WeakReference;
     34 import java.lang.reflect.Modifier;
     35 
     36 /**
     37  * Base class for a remotable object, the core part of a lightweight
     38  * remote procedure call mechanism defined by {@link IBinder}.
     39  * This class is an implementation of IBinder that provides
     40  * standard local implementation of such an object.
     41  *
     42  * <p>Most developers will not implement this class directly, instead using the
     43  * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
     44  * interface, having it generate the appropriate Binder subclass.  You can,
     45  * however, derive directly from Binder to implement your own custom RPC
     46  * protocol or simply instantiate a raw Binder object directly to use as a
     47  * token that can be shared across processes.
     48  *
     49  * <p>This class is just a basic IPC primitive; it has no impact on an application's
     50  * lifecycle, and is valid only as long as the process that created it continues to run.
     51  * To use this correctly, you must be doing so within the context of a top-level
     52  * application component (a {@link android.app.Service}, {@link android.app.Activity},
     53  * or {@link android.content.ContentProvider}) that lets the system know your process
     54  * should remain running.</p>
     55  *
     56  * <p>You must keep in mind the situations in which your process
     57  * could go away, and thus require that you later re-create a new Binder and re-attach
     58  * it when the process starts again.  For example, if you are using this within an
     59  * {@link android.app.Activity}, your activity's process may be killed any time the
     60  * activity is not started; if the activity is later re-created you will need to
     61  * create a new Binder and hand it back to the correct place again; you need to be
     62  * aware that your process may be started for another reason (for example to receive
     63  * a broadcast) that will not involve re-creating the activity and thus run its code
     64  * to create a new Binder.</p>
     65  *
     66  * @see IBinder
     67  */
     68 public class Binder implements IBinder {
     69     /*
     70      * Set this flag to true to detect anonymous, local or member classes
     71      * that extend this Binder class and that are not static. These kind
     72      * of classes can potentially create leaks.
     73      */
     74     private static final boolean FIND_POTENTIAL_LEAKS = false;
     75     /** @hide */
     76     public static final boolean CHECK_PARCEL_SIZE = false;
     77     static final String TAG = "Binder";
     78 
     79     /** @hide */
     80     public static boolean LOG_RUNTIME_EXCEPTION = false; // DO NOT SUBMIT WITH TRUE
     81 
     82     /**
     83      * Control whether dump() calls are allowed.
     84      */
     85     private static volatile String sDumpDisabled = null;
     86 
     87     /**
     88      * Global transaction tracker instance for this process.
     89      */
     90     private static volatile TransactionTracker sTransactionTracker = null;
     91 
     92     // Transaction tracking code.
     93 
     94     /**
     95      * Flag indicating whether we should be tracing transact calls.
     96      */
     97     private static volatile boolean sTracingEnabled = false;
     98 
     99     /**
    100      * Enable Binder IPC tracing.
    101      *
    102      * @hide
    103      */
    104     public static void enableTracing() {
    105         sTracingEnabled = true;
    106     }
    107 
    108     /**
    109      * Disable Binder IPC tracing.
    110      *
    111      * @hide
    112      */
    113     public static void disableTracing() {
    114         sTracingEnabled = false;
    115     }
    116 
    117     /**
    118      * Check if binder transaction tracing is enabled.
    119      *
    120      * @hide
    121      */
    122     public static boolean isTracingEnabled() {
    123         return sTracingEnabled;
    124     }
    125 
    126     /**
    127      * Get the binder transaction tracker for this process.
    128      *
    129      * @hide
    130      */
    131     public synchronized static TransactionTracker getTransactionTracker() {
    132         if (sTransactionTracker == null)
    133             sTransactionTracker = new TransactionTracker();
    134         return sTransactionTracker;
    135     }
    136 
    137     /** {@hide} */
    138     static volatile boolean sWarnOnBlocking = false;
    139 
    140     /**
    141      * Warn if any blocking binder transactions are made out from this process.
    142      * This is typically only useful for the system process, to prevent it from
    143      * blocking on calls to external untrusted code. Instead, all outgoing calls
    144      * that require a result must be sent as {@link IBinder#FLAG_ONEWAY} calls
    145      * which deliver results through a callback interface.
    146      *
    147      * @hide
    148      */
    149     public static void setWarnOnBlocking(boolean warnOnBlocking) {
    150         sWarnOnBlocking = warnOnBlocking;
    151     }
    152 
    153     /**
    154      * Allow blocking calls on the given interface, overriding the requested
    155      * value of {@link #setWarnOnBlocking(boolean)}.
    156      * <p>
    157      * This should only be rarely called when you are <em>absolutely sure</em>
    158      * the remote interface is a built-in system component that can never be
    159      * upgraded. In particular, this <em>must never</em> be called for
    160      * interfaces hosted by package that could be upgraded or replaced,
    161      * otherwise you risk system instability if that remote interface wedges.
    162      *
    163      * @hide
    164      */
    165     public static IBinder allowBlocking(IBinder binder) {
    166         try {
    167             if (binder instanceof BinderProxy) {
    168                 ((BinderProxy) binder).mWarnOnBlocking = false;
    169             } else if (binder != null
    170                     && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
    171                 Log.w(TAG, "Unable to allow blocking on interface " + binder);
    172             }
    173         } catch (RemoteException ignored) {
    174         }
    175         return binder;
    176     }
    177 
    178     /**
    179      * Inherit the current {@link #allowBlocking(IBinder)} value from one given
    180      * interface to another.
    181      *
    182      * @hide
    183      */
    184     public static void copyAllowBlocking(IBinder fromBinder, IBinder toBinder) {
    185         if (fromBinder instanceof BinderProxy && toBinder instanceof BinderProxy) {
    186             ((BinderProxy) toBinder).mWarnOnBlocking = ((BinderProxy) fromBinder).mWarnOnBlocking;
    187         }
    188     }
    189 
    190     /* mObject is used by native code, do not remove or rename */
    191     private long mObject;
    192     private IInterface mOwner;
    193     private String mDescriptor;
    194 
    195     /**
    196      * Return the ID of the process that sent you the current transaction
    197      * that is being processed.  This pid can be used with higher-level
    198      * system services to determine its identity and check permissions.
    199      * If the current thread is not currently executing an incoming transaction,
    200      * then its own pid is returned.
    201      */
    202     public static final native int getCallingPid();
    203 
    204     /**
    205      * Return the Linux uid assigned to the process that sent you the
    206      * current transaction that is being processed.  This uid can be used with
    207      * higher-level system services to determine its identity and check
    208      * permissions.  If the current thread is not currently executing an
    209      * incoming transaction, then its own uid is returned.
    210      */
    211     public static final native int getCallingUid();
    212 
    213     /**
    214      * Return the UserHandle assigned to the process that sent you the
    215      * current transaction that is being processed.  This is the user
    216      * of the caller.  It is distinct from {@link #getCallingUid()} in that a
    217      * particular user will have multiple distinct apps running under it each
    218      * with their own uid.  If the current thread is not currently executing an
    219      * incoming transaction, then its own UserHandle is returned.
    220      */
    221     public static final UserHandle getCallingUserHandle() {
    222         return UserHandle.of(UserHandle.getUserId(getCallingUid()));
    223     }
    224 
    225     /**
    226      * Reset the identity of the incoming IPC on the current thread.  This can
    227      * be useful if, while handling an incoming call, you will be calling
    228      * on interfaces of other objects that may be local to your process and
    229      * need to do permission checks on the calls coming into them (so they
    230      * will check the permission of your own local process, and not whatever
    231      * process originally called you).
    232      *
    233      * @return Returns an opaque token that can be used to restore the
    234      * original calling identity by passing it to
    235      * {@link #restoreCallingIdentity(long)}.
    236      *
    237      * @see #getCallingPid()
    238      * @see #getCallingUid()
    239      * @see #restoreCallingIdentity(long)
    240      */
    241     public static final native long clearCallingIdentity();
    242 
    243     /**
    244      * Restore the identity of the incoming IPC on the current thread
    245      * back to a previously identity that was returned by {@link
    246      * #clearCallingIdentity}.
    247      *
    248      * @param token The opaque token that was previously returned by
    249      * {@link #clearCallingIdentity}.
    250      *
    251      * @see #clearCallingIdentity
    252      */
    253     public static final native void restoreCallingIdentity(long token);
    254 
    255     /**
    256      * Convenience method for running the provided action enclosed in
    257      * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity}
    258      *
    259      * Any exception thrown by the given action will be caught and rethrown after the call to
    260      * {@link #restoreCallingIdentity}
    261      *
    262      * @hide
    263      */
    264     public static final void withCleanCallingIdentity(ThrowingRunnable action) {
    265         long callingIdentity = clearCallingIdentity();
    266         Throwable throwableToPropagate = null;
    267         try {
    268             action.run();
    269         } catch (Throwable throwable) {
    270             throwableToPropagate = throwable;
    271         } finally {
    272             restoreCallingIdentity(callingIdentity);
    273             if (throwableToPropagate != null) {
    274                 throw ExceptionUtils.propagate(throwableToPropagate);
    275             }
    276         }
    277     }
    278 
    279     /**
    280      * Convenience method for running the provided action enclosed in
    281      * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity} returning the result
    282      *
    283      * Any exception thrown by the given action will be caught and rethrown after the call to
    284      * {@link #restoreCallingIdentity}
    285      *
    286      * @hide
    287      */
    288     public static final <T> T withCleanCallingIdentity(ThrowingSupplier<T> action) {
    289         long callingIdentity = clearCallingIdentity();
    290         Throwable throwableToPropagate = null;
    291         try {
    292             return action.get();
    293         } catch (Throwable throwable) {
    294             throwableToPropagate = throwable;
    295             return null; // overridden by throwing in finally block
    296         } finally {
    297             restoreCallingIdentity(callingIdentity);
    298             if (throwableToPropagate != null) {
    299                 throw ExceptionUtils.propagate(throwableToPropagate);
    300             }
    301         }
    302     }
    303 
    304     /**
    305      * Sets the native thread-local StrictMode policy mask.
    306      *
    307      * <p>The StrictMode settings are kept in two places: a Java-level
    308      * threadlocal for libcore/Dalvik, and a native threadlocal (set
    309      * here) for propagation via Binder calls.  This is a little
    310      * unfortunate, but necessary to break otherwise more unfortunate
    311      * dependencies either of Dalvik on Android, or Android
    312      * native-only code on Dalvik.
    313      *
    314      * @see StrictMode
    315      * @hide
    316      */
    317     public static final native void setThreadStrictModePolicy(int policyMask);
    318 
    319     /**
    320      * Gets the current native thread-local StrictMode policy mask.
    321      *
    322      * @see #setThreadStrictModePolicy
    323      * @hide
    324      */
    325     public static final native int getThreadStrictModePolicy();
    326 
    327     /**
    328      * Flush any Binder commands pending in the current thread to the kernel
    329      * driver.  This can be
    330      * useful to call before performing an operation that may block for a long
    331      * time, to ensure that any pending object references have been released
    332      * in order to prevent the process from holding on to objects longer than
    333      * it needs to.
    334      */
    335     public static final native void flushPendingCommands();
    336 
    337     /**
    338      * Add the calling thread to the IPC thread pool.  This function does
    339      * not return until the current process is exiting.
    340      */
    341     public static final native void joinThreadPool();
    342 
    343     /**
    344      * Returns true if the specified interface is a proxy.
    345      * @hide
    346      */
    347     public static final boolean isProxy(IInterface iface) {
    348         return iface.asBinder() != iface;
    349     }
    350 
    351     /**
    352      * Call blocks until the number of executing binder threads is less
    353      * than the maximum number of binder threads allowed for this process.
    354      * @hide
    355      */
    356     public static final native void blockUntilThreadAvailable();
    357 
    358     /**
    359      * Default constructor initializes the object.
    360      */
    361     public Binder() {
    362         init();
    363 
    364         if (FIND_POTENTIAL_LEAKS) {
    365             final Class<? extends Binder> klass = getClass();
    366             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
    367                     (klass.getModifiers() & Modifier.STATIC) == 0) {
    368                 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
    369                     klass.getCanonicalName());
    370             }
    371         }
    372     }
    373 
    374     /**
    375      * Convenience method for associating a specific interface with the Binder.
    376      * After calling, queryLocalInterface() will be implemented for you
    377      * to return the given owner IInterface when the corresponding
    378      * descriptor is requested.
    379      */
    380     public void attachInterface(IInterface owner, String descriptor) {
    381         mOwner = owner;
    382         mDescriptor = descriptor;
    383     }
    384 
    385     /**
    386      * Default implementation returns an empty interface name.
    387      */
    388     public String getInterfaceDescriptor() {
    389         return mDescriptor;
    390     }
    391 
    392     /**
    393      * Default implementation always returns true -- if you got here,
    394      * the object is alive.
    395      */
    396     public boolean pingBinder() {
    397         return true;
    398     }
    399 
    400     /**
    401      * {@inheritDoc}
    402      *
    403      * Note that if you're calling on a local binder, this always returns true
    404      * because your process is alive if you're calling it.
    405      */
    406     public boolean isBinderAlive() {
    407         return true;
    408     }
    409 
    410     /**
    411      * Use information supplied to attachInterface() to return the
    412      * associated IInterface if it matches the requested
    413      * descriptor.
    414      */
    415     public IInterface queryLocalInterface(String descriptor) {
    416         if (mDescriptor.equals(descriptor)) {
    417             return mOwner;
    418         }
    419         return null;
    420     }
    421 
    422     /**
    423      * Control disabling of dump calls in this process.  This is used by the system
    424      * process watchdog to disable incoming dump calls while it has detecting the system
    425      * is hung and is reporting that back to the activity controller.  This is to
    426      * prevent the controller from getting hung up on bug reports at this point.
    427      * @hide
    428      *
    429      * @param msg The message to show instead of the dump; if null, dumps are
    430      * re-enabled.
    431      */
    432     public static void setDumpDisabled(String msg) {
    433         sDumpDisabled = msg;
    434     }
    435 
    436     /**
    437      * Default implementation is a stub that returns false.  You will want
    438      * to override this to do the appropriate unmarshalling of transactions.
    439      *
    440      * <p>If you want to call this, call transact().
    441      */
    442     protected boolean onTransact(int code, Parcel data, Parcel reply,
    443             int flags) throws RemoteException {
    444         if (code == INTERFACE_TRANSACTION) {
    445             reply.writeString(getInterfaceDescriptor());
    446             return true;
    447         } else if (code == DUMP_TRANSACTION) {
    448             ParcelFileDescriptor fd = data.readFileDescriptor();
    449             String[] args = data.readStringArray();
    450             if (fd != null) {
    451                 try {
    452                     dump(fd.getFileDescriptor(), args);
    453                 } finally {
    454                     IoUtils.closeQuietly(fd);
    455                 }
    456             }
    457             // Write the StrictMode header.
    458             if (reply != null) {
    459                 reply.writeNoException();
    460             } else {
    461                 StrictMode.clearGatheredViolations();
    462             }
    463             return true;
    464         } else if (code == SHELL_COMMAND_TRANSACTION) {
    465             ParcelFileDescriptor in = data.readFileDescriptor();
    466             ParcelFileDescriptor out = data.readFileDescriptor();
    467             ParcelFileDescriptor err = data.readFileDescriptor();
    468             String[] args = data.readStringArray();
    469             ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
    470             ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
    471             try {
    472                 if (out != null) {
    473                     shellCommand(in != null ? in.getFileDescriptor() : null,
    474                             out.getFileDescriptor(),
    475                             err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
    476                             args, shellCallback, resultReceiver);
    477                 }
    478             } finally {
    479                 IoUtils.closeQuietly(in);
    480                 IoUtils.closeQuietly(out);
    481                 IoUtils.closeQuietly(err);
    482                 // Write the StrictMode header.
    483                 if (reply != null) {
    484                     reply.writeNoException();
    485                 } else {
    486                     StrictMode.clearGatheredViolations();
    487                 }
    488             }
    489             return true;
    490         }
    491         return false;
    492     }
    493 
    494     /**
    495      * Implemented to call the more convenient version
    496      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
    497      */
    498     public void dump(FileDescriptor fd, String[] args) {
    499         FileOutputStream fout = new FileOutputStream(fd);
    500         PrintWriter pw = new FastPrintWriter(fout);
    501         try {
    502             doDump(fd, pw, args);
    503         } finally {
    504             pw.flush();
    505         }
    506     }
    507 
    508     void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
    509         final String disabled = sDumpDisabled;
    510         if (disabled == null) {
    511             try {
    512                 dump(fd, pw, args);
    513             } catch (SecurityException e) {
    514                 pw.println("Security exception: " + e.getMessage());
    515                 throw e;
    516             } catch (Throwable e) {
    517                 // Unlike usual calls, in this case if an exception gets thrown
    518                 // back to us we want to print it back in to the dump data, since
    519                 // that is where the caller expects all interesting information to
    520                 // go.
    521                 pw.println();
    522                 pw.println("Exception occurred while dumping:");
    523                 e.printStackTrace(pw);
    524             }
    525         } else {
    526             pw.println(sDumpDisabled);
    527         }
    528     }
    529 
    530     /**
    531      * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
    532      * executes asynchronously.
    533      */
    534     public void dumpAsync(final FileDescriptor fd, final String[] args) {
    535         final FileOutputStream fout = new FileOutputStream(fd);
    536         final PrintWriter pw = new FastPrintWriter(fout);
    537         Thread thr = new Thread("Binder.dumpAsync") {
    538             public void run() {
    539                 try {
    540                     dump(fd, pw, args);
    541                 } finally {
    542                     pw.flush();
    543                 }
    544             }
    545         };
    546         thr.start();
    547     }
    548 
    549     /**
    550      * Print the object's state into the given stream.
    551      *
    552      * @param fd The raw file descriptor that the dump is being sent to.
    553      * @param fout The file to which you should dump your state.  This will be
    554      * closed for you after you return.
    555      * @param args additional arguments to the dump request.
    556      */
    557     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
    558     }
    559 
    560     /**
    561      * @param in The raw file descriptor that an input data stream can be read from.
    562      * @param out The raw file descriptor that normal command messages should be written to.
    563      * @param err The raw file descriptor that command error messages should be written to.
    564      * @param args Command-line arguments.
    565      * @param callback Callback through which to interact with the invoking shell.
    566      * @param resultReceiver Called when the command has finished executing, with the result code.
    567      * @throws RemoteException
    568      * @hide
    569      */
    570     public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
    571             String[] args, ShellCallback callback,
    572             ResultReceiver resultReceiver) throws RemoteException {
    573         onShellCommand(in, out, err, args, callback, resultReceiver);
    574     }
    575 
    576     /**
    577      * Handle a call to {@link #shellCommand}.  The default implementation simply prints
    578      * an error message.  Override and replace with your own.
    579      * <p class="caution">Note: no permission checking is done before calling this method; you must
    580      * apply any security checks as appropriate for the command being executed.
    581      * Consider using {@link ShellCommand} to help in the implementation.</p>
    582      * @hide
    583      */
    584     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
    585             String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException {
    586         FileOutputStream fout = new FileOutputStream(err != null ? err : out);
    587         PrintWriter pw = new FastPrintWriter(fout);
    588         pw.println("No shell command implementation.");
    589         pw.flush();
    590         resultReceiver.send(0, null);
    591     }
    592 
    593     /**
    594      * Default implementation rewinds the parcels and calls onTransact.  On
    595      * the remote side, transact calls into the binder to do the IPC.
    596      */
    597     public final boolean transact(int code, Parcel data, Parcel reply,
    598             int flags) throws RemoteException {
    599         if (false) Log.v("Binder", "Transact: " + code + " to " + this);
    600 
    601         if (data != null) {
    602             data.setDataPosition(0);
    603         }
    604         boolean r = onTransact(code, data, reply, flags);
    605         if (reply != null) {
    606             reply.setDataPosition(0);
    607         }
    608         return r;
    609     }
    610 
    611     /**
    612      * Local implementation is a no-op.
    613      */
    614     public void linkToDeath(DeathRecipient recipient, int flags) {
    615     }
    616 
    617     /**
    618      * Local implementation is a no-op.
    619      */
    620     public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
    621         return true;
    622     }
    623 
    624     protected void finalize() throws Throwable {
    625         try {
    626             destroy();
    627         } finally {
    628             super.finalize();
    629         }
    630     }
    631 
    632     static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
    633         if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
    634             // Trying to send > 800k, this is way too much
    635             StringBuilder sb = new StringBuilder();
    636             sb.append(msg);
    637             sb.append(": on ");
    638             sb.append(obj);
    639             sb.append(" calling ");
    640             sb.append(code);
    641             sb.append(" size ");
    642             sb.append(parcel.dataSize());
    643             sb.append(" (data: ");
    644             parcel.setDataPosition(0);
    645             sb.append(parcel.readInt());
    646             sb.append(", ");
    647             sb.append(parcel.readInt());
    648             sb.append(", ");
    649             sb.append(parcel.readInt());
    650             sb.append(")");
    651             Slog.wtfStack(TAG, sb.toString());
    652         }
    653     }
    654 
    655     private native final void init();
    656     private native final void destroy();
    657 
    658     // Entry point from android_util_Binder.cpp's onTransact
    659     private boolean execTransact(int code, long dataObj, long replyObj,
    660             int flags) {
    661         Parcel data = Parcel.obtain(dataObj);
    662         Parcel reply = Parcel.obtain(replyObj);
    663         // theoretically, we should call transact, which will call onTransact,
    664         // but all that does is rewind it, and we just got these from an IPC,
    665         // so we'll just call it directly.
    666         boolean res;
    667         // Log any exceptions as warnings, don't silently suppress them.
    668         // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
    669         final boolean tracingEnabled = Binder.isTracingEnabled();
    670         try {
    671             if (tracingEnabled) {
    672                 Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
    673             }
    674             res = onTransact(code, data, reply, flags);
    675         } catch (RemoteException|RuntimeException e) {
    676             if (LOG_RUNTIME_EXCEPTION) {
    677                 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
    678             }
    679             if ((flags & FLAG_ONEWAY) != 0) {
    680                 if (e instanceof RemoteException) {
    681                     Log.w(TAG, "Binder call failed.", e);
    682                 } else {
    683                     Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
    684                 }
    685             } else {
    686                 reply.setDataPosition(0);
    687                 reply.writeException(e);
    688             }
    689             res = true;
    690         } catch (OutOfMemoryError e) {
    691             // Unconditionally log this, since this is generally unrecoverable.
    692             Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
    693             RuntimeException re = new RuntimeException("Out of memory", e);
    694             reply.setDataPosition(0);
    695             reply.writeException(re);
    696             res = true;
    697         } finally {
    698             if (tracingEnabled) {
    699                 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
    700             }
    701         }
    702         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
    703         reply.recycle();
    704         data.recycle();
    705 
    706         // Just in case -- we are done with the IPC, so there should be no more strict
    707         // mode violations that have gathered for this thread.  Either they have been
    708         // parceled and are now in transport off to the caller, or we are returning back
    709         // to the main transaction loop to wait for another incoming transaction.  Either
    710         // way, strict mode begone!
    711         StrictMode.clearGatheredViolations();
    712 
    713         return res;
    714     }
    715 }
    716 
    717 final class BinderProxy implements IBinder {
    718     // Assume the process-wide default value when created
    719     volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking;
    720 
    721     public native boolean pingBinder();
    722     public native boolean isBinderAlive();
    723 
    724     public IInterface queryLocalInterface(String descriptor) {
    725         return null;
    726     }
    727 
    728     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    729         Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
    730 
    731         if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
    732             // For now, avoid spamming the log by disabling after we've logged
    733             // about this interface at least once
    734             mWarnOnBlocking = false;
    735             Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
    736                     new Throwable());
    737         }
    738 
    739         final boolean tracingEnabled = Binder.isTracingEnabled();
    740         if (tracingEnabled) {
    741             final Throwable tr = new Throwable();
    742             Binder.getTransactionTracker().addTrace(tr);
    743             StackTraceElement stackTraceElement = tr.getStackTrace()[1];
    744             Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
    745                     stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
    746         }
    747         try {
    748             return transactNative(code, data, reply, flags);
    749         } finally {
    750             if (tracingEnabled) {
    751                 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
    752             }
    753         }
    754     }
    755 
    756     public native String getInterfaceDescriptor() throws RemoteException;
    757     public native boolean transactNative(int code, Parcel data, Parcel reply,
    758             int flags) throws RemoteException;
    759     public native void linkToDeath(DeathRecipient recipient, int flags)
    760             throws RemoteException;
    761     public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
    762 
    763     public void dump(FileDescriptor fd, String[] args) throws RemoteException {
    764         Parcel data = Parcel.obtain();
    765         Parcel reply = Parcel.obtain();
    766         data.writeFileDescriptor(fd);
    767         data.writeStringArray(args);
    768         try {
    769             transact(DUMP_TRANSACTION, data, reply, 0);
    770             reply.readException();
    771         } finally {
    772             data.recycle();
    773             reply.recycle();
    774         }
    775     }
    776 
    777     public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
    778         Parcel data = Parcel.obtain();
    779         Parcel reply = Parcel.obtain();
    780         data.writeFileDescriptor(fd);
    781         data.writeStringArray(args);
    782         try {
    783             transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
    784         } finally {
    785             data.recycle();
    786             reply.recycle();
    787         }
    788     }
    789 
    790     public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
    791             String[] args, ShellCallback callback,
    792             ResultReceiver resultReceiver) throws RemoteException {
    793         Parcel data = Parcel.obtain();
    794         Parcel reply = Parcel.obtain();
    795         data.writeFileDescriptor(in);
    796         data.writeFileDescriptor(out);
    797         data.writeFileDescriptor(err);
    798         data.writeStringArray(args);
    799         ShellCallback.writeToParcel(callback, data);
    800         resultReceiver.writeToParcel(data, 0);
    801         try {
    802             transact(SHELL_COMMAND_TRANSACTION, data, reply, 0);
    803             reply.readException();
    804         } finally {
    805             data.recycle();
    806             reply.recycle();
    807         }
    808     }
    809 
    810     BinderProxy() {
    811         mSelf = new WeakReference(this);
    812     }
    813 
    814     @Override
    815     protected void finalize() throws Throwable {
    816         try {
    817             destroy();
    818         } finally {
    819             super.finalize();
    820         }
    821     }
    822 
    823     private native final void destroy();
    824 
    825     private static final void sendDeathNotice(DeathRecipient recipient) {
    826         if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
    827         try {
    828             recipient.binderDied();
    829         }
    830         catch (RuntimeException exc) {
    831             Log.w("BinderNative", "Uncaught exception from death notification",
    832                     exc);
    833         }
    834     }
    835 
    836     final private WeakReference mSelf;
    837     private long mObject;
    838     private long mOrgue;
    839 }
    840