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