• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
enableTracing()106     public static void enableTracing() {
107         sTracingEnabled = true;
108     }
109 
110     /**
111      * Disable Binder IPC tracing.
112      *
113      * @hide
114      */
disableTracing()115     public static void disableTracing() {
116         sTracingEnabled = false;
117     }
118 
119     /**
120      * Check if binder transaction tracing is enabled.
121      *
122      * @hide
123      */
isTracingEnabled()124     public static boolean isTracingEnabled() {
125         return sTracingEnabled;
126     }
127 
128     /**
129      * Get the binder transaction tracker for this process.
130      *
131      * @hide
132      */
getTransactionTracker()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      */
setWarnOnBlocking(boolean warnOnBlocking)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      */
allowBlocking(IBinder binder)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      */
copyAllowBlocking(IBinder fromBinder, IBinder toBinder)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      */
getCallingPid()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      */
getCallingUid()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      */
getCallingUserHandle()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      */
clearCallingIdentity()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      */
restoreCallingIdentity(long token)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      */
withCleanCallingIdentity(@onNull ThrowingRunnable action)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      */
withCleanCallingIdentity(@onNull ThrowingSupplier<T> action)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      */
setThreadStrictModePolicy(int policyMask)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      */
getThreadStrictModePolicy()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      */
flushPendingCommands()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      */
joinThreadPool()343     public static final native void joinThreadPool();
344 
345     /**
346      * Returns true if the specified interface is a proxy.
347      * @hide
348      */
isProxy(IInterface iface)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      */
blockUntilThreadAvailable()358     public static final native void blockUntilThreadAvailable();
359 
360     /**
361      * Default constructor initializes the object.
362      */
Binder()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      */
attachInterface(@ullable IInterface owner, @Nullable String descriptor)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      */
getInterfaceDescriptor()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      */
pingBinder()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      */
isBinderAlive()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      */
queryLocalInterface(@onNull String descriptor)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      */
setDumpDisabled(String msg)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      */
onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)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      */
dump(@onNull FileDescriptor fd, @Nullable String[] args)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 
doDump(FileDescriptor fd, PrintWriter pw, String[] args)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      */
dumpAsync(@onNull final FileDescriptor fd, @Nullable final String[] args)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      */
dump(@onNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args)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      */
shellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)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      */
onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)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      */
transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)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      */
linkToDeath(@onNull DeathRecipient recipient, int flags)637     public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
638     }
639 
640     /**
641      * Local implementation is a no-op.
642      */
unlinkToDeath(@onNull DeathRecipient recipient, int flags)643     public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
644         return true;
645     }
646 
finalize()647     protected void finalize() throws Throwable {
648         try {
649             destroyBinder();
650         } finally {
651             super.finalize();
652         }
653     }
654 
checkParcel(IBinder obj, int code, Parcel parcel, String msg)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 
init()678     private native final void init();
destroyBinder()679     private native final void destroyBinder();
680 
681     // Entry point from android_util_Binder.cpp's onTransact
execTransact(int code, long dataObj, long replyObj, int flags)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                 // Clear the parcel before writing the exception
710                 reply.setDataSize(0);
711                 reply.setDataPosition(0);
712                 reply.writeException(e);
713             }
714             res = true;
715         } finally {
716             if (tracingEnabled) {
717                 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
718             }
719         }
720         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
721         reply.recycle();
722         data.recycle();
723 
724         // Just in case -- we are done with the IPC, so there should be no more strict
725         // mode violations that have gathered for this thread.  Either they have been
726         // parceled and are now in transport off to the caller, or we are returning back
727         // to the main transaction loop to wait for another incoming transaction.  Either
728         // way, strict mode begone!
729         StrictMode.clearGatheredViolations();
730 
731         return res;
732     }
733 }
734 
735 final class BinderProxy implements IBinder {
736     // Assume the process-wide default value when created
737     volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking;
738 
pingBinder()739     public native boolean pingBinder();
isBinderAlive()740     public native boolean isBinderAlive();
741 
queryLocalInterface(String descriptor)742     public IInterface queryLocalInterface(String descriptor) {
743         return null;
744     }
745 
transact(int code, Parcel data, Parcel reply, int flags)746     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
747         Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
748 
749         if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
750             // For now, avoid spamming the log by disabling after we've logged
751             // about this interface at least once
752             mWarnOnBlocking = false;
753             Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
754                     new Throwable());
755         }
756 
757         final boolean tracingEnabled = Binder.isTracingEnabled();
758         if (tracingEnabled) {
759             final Throwable tr = new Throwable();
760             Binder.getTransactionTracker().addTrace(tr);
761             StackTraceElement stackTraceElement = tr.getStackTrace()[1];
762             Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
763                     stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
764         }
765         try {
766             return transactNative(code, data, reply, flags);
767         } finally {
768             if (tracingEnabled) {
769                 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
770             }
771         }
772     }
773 
getInterfaceDescriptor()774     public native String getInterfaceDescriptor() throws RemoteException;
transactNative(int code, Parcel data, Parcel reply, int flags)775     public native boolean transactNative(int code, Parcel data, Parcel reply,
776             int flags) throws RemoteException;
linkToDeath(DeathRecipient recipient, int flags)777     public native void linkToDeath(DeathRecipient recipient, int flags)
778             throws RemoteException;
unlinkToDeath(DeathRecipient recipient, int flags)779     public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
780 
dump(FileDescriptor fd, String[] args)781     public void dump(FileDescriptor fd, String[] args) throws RemoteException {
782         Parcel data = Parcel.obtain();
783         Parcel reply = Parcel.obtain();
784         data.writeFileDescriptor(fd);
785         data.writeStringArray(args);
786         try {
787             transact(DUMP_TRANSACTION, data, reply, 0);
788             reply.readException();
789         } finally {
790             data.recycle();
791             reply.recycle();
792         }
793     }
794 
dumpAsync(FileDescriptor fd, String[] args)795     public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
796         Parcel data = Parcel.obtain();
797         Parcel reply = Parcel.obtain();
798         data.writeFileDescriptor(fd);
799         data.writeStringArray(args);
800         try {
801             transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
802         } finally {
803             data.recycle();
804             reply.recycle();
805         }
806     }
807 
shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)808     public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
809             String[] args, ShellCallback callback,
810             ResultReceiver resultReceiver) throws RemoteException {
811         Parcel data = Parcel.obtain();
812         Parcel reply = Parcel.obtain();
813         data.writeFileDescriptor(in);
814         data.writeFileDescriptor(out);
815         data.writeFileDescriptor(err);
816         data.writeStringArray(args);
817         ShellCallback.writeToParcel(callback, data);
818         resultReceiver.writeToParcel(data, 0);
819         try {
820             transact(SHELL_COMMAND_TRANSACTION, data, reply, 0);
821             reply.readException();
822         } finally {
823             data.recycle();
824             reply.recycle();
825         }
826     }
827 
BinderProxy()828     BinderProxy() {
829         mSelf = new WeakReference(this);
830     }
831 
832     @Override
finalize()833     protected void finalize() throws Throwable {
834         try {
835             destroy();
836         } finally {
837             super.finalize();
838         }
839     }
840 
destroy()841     private native final void destroy();
842 
sendDeathNotice(DeathRecipient recipient)843     private static final void sendDeathNotice(DeathRecipient recipient) {
844         if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
845         try {
846             recipient.binderDied();
847         }
848         catch (RuntimeException exc) {
849             Log.w("BinderNative", "Uncaught exception from death notification",
850                     exc);
851         }
852     }
853 
854     final private WeakReference mSelf;
855     private long mObject;
856     private long mOrgue;
857 }
858