• 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.annotation.SystemApi;
22 import android.app.AppOpsManager;
23 import android.compat.annotation.UnsupportedAppUsage;
24 import android.ravenwood.annotation.RavenwoodClassLoadHook;
25 import android.ravenwood.annotation.RavenwoodKeepWholeClass;
26 import android.util.ExceptionUtils;
27 import android.util.Log;
28 import android.util.Slog;
29 
30 import com.android.internal.annotations.VisibleForTesting;
31 import com.android.internal.os.BinderCallHeavyHitterWatcher;
32 import com.android.internal.os.BinderCallHeavyHitterWatcher.BinderCallHeavyHitterListener;
33 import com.android.internal.os.BinderInternal;
34 import com.android.internal.os.BinderInternal.CallSession;
35 import com.android.internal.util.FastPrintWriter;
36 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
37 import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
38 
39 import dalvik.annotation.optimization.CriticalNative;
40 
41 import libcore.io.IoUtils;
42 import libcore.util.NativeAllocationRegistry;
43 
44 import java.io.FileDescriptor;
45 import java.io.FileInputStream;
46 import java.io.FileOutputStream;
47 import java.io.IOException;
48 import java.io.PrintWriter;
49 import java.lang.reflect.Modifier;
50 import java.util.concurrent.atomic.AtomicReferenceArray;
51 
52 /**
53  * Base class for a remotable object, the core part of a lightweight
54  * remote procedure call mechanism defined by {@link IBinder}.
55  * This class is an implementation of IBinder that provides
56  * standard local implementation of such an object.
57  *
58  * <p>Most developers will not implement this class directly, instead using the
59  * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
60  * interface, having it generate the appropriate Binder subclass. You can,
61  * however, derive directly from Binder to implement your own custom RPC
62  * protocol or simply instantiate a raw Binder object directly to use as a
63  * token that can be shared across processes.
64  *
65  * <p>This class is just a basic IPC primitive; it has no impact on an application's
66  * lifecycle, and is valid only as long as the process that created it continues to run.
67  * To use this correctly, you must be doing so within the context of a top-level
68  * application component (a {@link android.app.Service}, {@link android.app.Activity},
69  * or {@link android.content.ContentProvider}) that lets the system know your process
70  * should remain running.
71  *
72  * <p>You must keep in mind the situations in which your process
73  * could go away, and thus require that you later re-create a new Binder and re-attach
74  * it when the process starts again. For example, if you are using this within an
75  * {@link android.app.Activity}, your activity's process may be killed any time the
76  * activity is not started; if the activity is later re-created you will need to
77  * create a new Binder and hand it back to the correct place again; you need to be
78  * aware that your process may be started for another reason (for example to receive
79  * a broadcast) that will not involve re-creating the activity and thus run its code
80  * to create a new Binder.
81  *
82  * @see IBinder
83  */
84 @RavenwoodKeepWholeClass
85 @RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK)
86 public class Binder implements IBinder {
87     /*
88      * Set this flag to true to detect anonymous, local or member classes
89      * that extend this Binder class and that are not static. These kind
90      * of classes can potentially create leaks.
91      */
92     private static final boolean FIND_POTENTIAL_LEAKS = false;
93     /** @hide */
94     public static final boolean CHECK_PARCEL_SIZE = false;
95     static final String TAG = "Binder";
96 
97     /** @hide */
98     public static boolean LOG_RUNTIME_EXCEPTION = false; // DO NOT SUBMIT WITH TRUE
99 
100     /**
101      * Value to represents that a calling work source is not set.
102      *
103      * <p>This constant needs to be kept in sync with IPCThreadState::kUnsetWorkSource.
104      *
105      * @hide
106      */
107     public static final int UNSET_WORKSOURCE = -1;
108 
109     /**
110      * Control whether {@link #dump(FileDescriptor, PrintWriter, String[]) dump()}
111      * calls are allowed.
112      */
113     private static volatile String sDumpDisabled = null;
114 
115     /**
116      * Global transaction tracker instance for this process.
117      */
118     private static volatile TransactionTracker sTransactionTracker = null;
119 
120     /**
121      * Global observer for this process.
122      */
123     private static BinderInternal.Observer sObserver = null;
124 
125     /**
126      * Guestimate of native memory associated with a Binder.
127      */
128     private static final int NATIVE_ALLOCATION_SIZE = 500;
129 
getNativeFinalizer()130     private static native long getNativeFinalizer();
131 
132     // Use a Holder to allow static initialization of Binder in the boot image, and
133     // possibly to avoid some initialization ordering issues.
134     private static class NoImagePreloadHolder {
135         public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
136                 Binder.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
137     }
138 
139     /**
140      * The watcher to monitor the heavy hitter from incoming transactions
141      */
142     private static volatile BinderCallHeavyHitterWatcher sHeavyHitterWatcher = null;
143 
144     // Transaction tracking code.
145 
146     /**
147      * Flag indicating whether we should be tracing transact calls.
148      */
149     private static volatile boolean sStackTrackingEnabled = false;
150 
151     /**
152      * The extension binder object
153      */
154     private IBinder mExtension = null;
155 
156     /**
157      * Enable Binder IPC stack tracking. If enabled, every binder transaction will be logged to
158      * {@link TransactionTracker}.
159      *
160      * @hide
161      */
enableStackTracking()162     public static void enableStackTracking() {
163         sStackTrackingEnabled = true;
164     }
165 
166     /**
167      * Disable Binder IPC stack tracking.
168      *
169      * @hide
170      */
disableStackTracking()171     public static void disableStackTracking() {
172         sStackTrackingEnabled = false;
173     }
174 
175     /**
176      * Check if binder transaction stack tracking is enabled.
177      *
178      * @hide
179      */
isStackTrackingEnabled()180     public static boolean isStackTrackingEnabled() {
181         return sStackTrackingEnabled;
182     }
183 
184     /**
185      * Get the binder transaction tracker for this process.
186      *
187      * @hide
188      */
getTransactionTracker()189     public synchronized static TransactionTracker getTransactionTracker() {
190         if (sTransactionTracker == null)
191             sTransactionTracker = new TransactionTracker();
192         return sTransactionTracker;
193     }
194 
195     /**
196      * Get the binder transaction observer for this process.
197      *
198      * TODO(b/299356196): only applies to Java code, not C++/Rust
199      *
200      * @hide
201      */
setObserver(@ullable BinderInternal.Observer observer)202     public static void setObserver(@Nullable BinderInternal.Observer observer) {
203         sObserver = observer;
204     }
205 
206     /** @hide */
207     static volatile boolean sWarnOnBlocking = false;
208 
209     /**
210      * Warn if any blocking binder transactions are made out from this process.
211      * This is typically only useful for the system process, to prevent it from
212      * blocking on calls to external untrusted code. Instead, all outgoing calls
213      * that require a result must be sent as {@link IBinder#FLAG_ONEWAY} calls
214      * which deliver results through a callback interface.
215      *
216      * TODO(b/299355525): only applies to Java code, not C++/Rust
217      *
218      * @hide
219      */
setWarnOnBlocking(boolean warnOnBlocking)220     public static void setWarnOnBlocking(boolean warnOnBlocking) {
221         sWarnOnBlocking = warnOnBlocking;
222     }
223 
224     /**
225      * Allow blocking calls on the given interface, overriding the requested
226      * value of {@link #setWarnOnBlocking(boolean)}.
227      *
228      * <p>This should only be rarely called when you are <em>absolutely sure</em>
229      * the remote interface is a built-in system component that can never be
230      * upgraded. In particular, this <em>must never</em> be called for
231      * interfaces hosted by package that could be upgraded or replaced,
232      * otherwise you risk system instability if that remote interface wedges.
233      *
234      * TODO(b/299355525): only applies to Java code, not C++/Rust
235      *
236      * @hide
237      */
allowBlocking(IBinder binder)238     public static IBinder allowBlocking(IBinder binder) {
239         try {
240             if (binder instanceof BinderProxy) {
241                 ((BinderProxy) binder).mWarnOnBlocking = false;
242             } else if (binder != null && binder.getInterfaceDescriptor() != null
243                     && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
244                 Log.w(TAG, "Unable to allow blocking on interface " + binder);
245             }
246         } catch (RemoteException ignored) {
247         }
248         return binder;
249     }
250 
251     /**
252      * Reset the given interface back to the default blocking behavior,
253      * reverting any changes made by {@link #allowBlocking(IBinder)}.
254      *
255      * @hide
256      */
defaultBlocking(IBinder binder)257     public static IBinder defaultBlocking(IBinder binder) {
258         if (binder instanceof BinderProxy) {
259             ((BinderProxy) binder).mWarnOnBlocking = sWarnOnBlocking;
260         }
261         return binder;
262     }
263 
264     /**
265      * Inherit the current {@link #allowBlocking(IBinder)} value from one given
266      * interface to another.
267      *
268      * @hide
269      */
copyAllowBlocking(IBinder fromBinder, IBinder toBinder)270     public static void copyAllowBlocking(IBinder fromBinder, IBinder toBinder) {
271         if (fromBinder instanceof BinderProxy && toBinder instanceof BinderProxy) {
272             ((BinderProxy) toBinder).mWarnOnBlocking = ((BinderProxy) fromBinder).mWarnOnBlocking;
273         }
274     }
275 
276     static ThreadLocal<Boolean> sWarnOnBlockingOnCurrentThread =
277             ThreadLocal.withInitial(() -> sWarnOnBlocking);
278 
279     /**
280      * Allow blocking calls for the current thread.
281      *
282      * @see {@link #allowBlocking}.
283      *
284      * @hide
285      */
allowBlockingForCurrentThread()286     public static void allowBlockingForCurrentThread() {
287         sWarnOnBlockingOnCurrentThread.set(false);
288     }
289 
290     /**
291      * Reset the current thread to the default blocking behavior.
292      *
293      * @see {@link #defaultBlocking}.
294      *
295      * @hide
296      */
defaultBlockingForCurrentThread()297     public static void defaultBlockingForCurrentThread() {
298         sWarnOnBlockingOnCurrentThread.set(sWarnOnBlocking);
299     }
300 
301     /**
302      * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
303      */
304     @UnsupportedAppUsage
305     private final long mObject;
306 
307     private IInterface mOwner;
308     @Nullable
309     private String mDescriptor;
310     private volatile AtomicReferenceArray<String> mTransactionTraceNames = null;
311     private volatile String mSimpleDescriptor = null;
312     private static final int TRANSACTION_TRACE_NAME_ID_LIMIT = 1024;
313 
314     /**
315      * Return the ID of the process that sent you the current transaction
316      * that is being processed. This PID can be used with higher-level
317      * system services to determine its identity and check permissions.
318      * If the current thread is not currently executing an incoming transaction,
319      * then its own PID is returned.
320      *
321      * Warning do not use this as a security identifier! PID is unreliable
322      * as it may be re-used. This should mostly be used for debugging.
323      *
324      * oneway transactions do not receive PID. Even if you expect
325      * a transaction to be synchronous, a misbehaving client could send it
326      * as a asynchronous call and result in a 0 PID here. Additionally, if
327      * there is a race and the calling process dies, the PID may still be
328      * 0 for a synchronous call.
329      */
330     @CriticalNative
getCallingPid()331     public static final native int getCallingPid();
332 
333     /**
334      * Return the Linux UID assigned to the process that sent you the
335      * current transaction that is being processed. This UID can be used with
336      * higher-level system services to determine its identity and check
337      * permissions. If the current thread is not currently executing an
338      * incoming transaction, then its own UID is returned.
339      */
340     @CriticalNative
getCallingUid()341     public static final native int getCallingUid();
342 
343     /**
344      * Returns {@code true} if the current thread is currently executing an
345      * incoming transaction.
346      *
347      * @hide
348      */
349     @CriticalNative
isDirectlyHandlingTransactionNative()350     public static final native boolean isDirectlyHandlingTransactionNative();
351 
352     private static boolean sIsHandlingBinderTransaction = false;
353 
354     /**
355      * @hide
356      */
isDirectlyHandlingTransaction()357     public static final boolean isDirectlyHandlingTransaction() {
358         return sIsHandlingBinderTransaction || isDirectlyHandlingTransactionNative();
359     }
360 
361     /**
362      * This is Test API which will be used to override output of isDirectlyHandlingTransactionNative
363      * @hide
364      */
setIsDirectlyHandlingTransactionOverride(boolean isInTransaction)365     public static void setIsDirectlyHandlingTransactionOverride(boolean isInTransaction) {
366         sIsHandlingBinderTransaction = isInTransaction;
367     }
368 
369     /**
370     * Returns {@code true} if the current thread has had its identity
371     * set explicitly via {@link #clearCallingIdentity()}
372     *
373     * @hide
374     */
375     @CriticalNative
hasExplicitIdentity()376     private static native boolean hasExplicitIdentity();
377 
378     /**
379      * Return the Linux UID assigned to the process that sent the transaction
380      * currently being processed.
381      *
382      * @throws IllegalStateException if the current thread is not currently
383      * executing an incoming transaction and the calling identity has not been
384      * explicitly set with {@link #clearCallingIdentity()}
385      */
getCallingUidOrThrow()386     public static final int getCallingUidOrThrow() {
387         if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
388             throw new IllegalStateException(
389                   "Thread is not in a binder transaction, "
390                   + "and the calling identity has not been "
391                   + "explicitly set with clearCallingIdentity");
392         }
393         return getCallingUid();
394     }
395 
396     /**
397      * Return the Linux UID assigned to the process that sent the transaction
398      * currently being processed.
399      *
400      * Slog.wtf if the current thread is not currently
401      * executing an incoming transaction and the calling identity has not been
402      * explicitly set with {@link #clearCallingIdentity()}
403      *
404      * @hide
405      */
getCallingUidOrWtf(String message)406     public static final int getCallingUidOrWtf(String message) {
407         if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
408             Slog.wtf(TAG,
409                     message + ": Thread is not in a binder transaction, "
410                             + "and the calling identity has not been "
411                             + "explicitly set with clearCallingIdentity");
412         }
413         return getCallingUid();
414     }
415 
416     /**
417      * Return the UserHandle assigned to the process that sent you the
418      * current transaction that is being processed. This is the user
419      * of the caller. It is distinct from {@link #getCallingUid()} in that a
420      * particular user will have multiple distinct apps running under it each
421      * with their own UID. If the current thread is not currently executing an
422      * incoming transaction, then its own UserHandle is returned.
423      *
424      * @see UserHandle
425      */
getCallingUserHandle()426     public static final @NonNull UserHandle getCallingUserHandle() {
427         return UserHandle.of(UserHandle.getUserId(getCallingUid()));
428     }
429 
430     /**
431      * Reset the identity of the incoming IPC on the current thread. This can
432      * be useful if, while handling an incoming call, you will be calling
433      * on interfaces of other objects that may be local to your process and
434      * need to do permission checks on the calls coming into them (so they
435      * will check the permission of your own local process, and not whatever
436      * process originally called you).
437      *
438      * @return Returns an opaque token that can be used to restore the
439      * original calling identity by passing it to
440      * {@link #restoreCallingIdentity(long)}.
441      *
442      * @see #getCallingPid()
443      * @see #getCallingUid()
444      * @see #restoreCallingIdentity(long)
445      */
446     @CriticalNative
clearCallingIdentity()447     public static final native long clearCallingIdentity();
448 
449     /**
450      * Restore the identity of the incoming IPC on the current thread
451      * back to a previously identity that was returned by {@link
452      * #clearCallingIdentity}.
453      *
454      * @param token The opaque token that was previously returned by
455      * {@link #clearCallingIdentity}.
456      *
457      * @see #clearCallingIdentity
458      */
459     @CriticalNative
restoreCallingIdentity(long token)460     public static final native void restoreCallingIdentity(long token);
461 
462     /**
463      * Convenience method for running the provided action enclosed in
464      * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity}.
465      *
466      * <p>Any exception thrown by the given action will be caught and
467      * rethrown after the call to {@link #restoreCallingIdentity}.
468      *
469      * @hide
470      */
withCleanCallingIdentity(@onNull ThrowingRunnable action)471     public static final void withCleanCallingIdentity(@NonNull ThrowingRunnable action) {
472         Throwable throwableToPropagate = null;
473         final long callingIdentity = clearCallingIdentity();
474         try {
475             action.runOrThrow();
476         } catch (Throwable throwable) {
477             throwableToPropagate = throwable;
478         } finally {
479             restoreCallingIdentity(callingIdentity);
480             if (throwableToPropagate != null) {
481                 throw ExceptionUtils.propagate(throwableToPropagate);
482             }
483         }
484     }
485 
486     /**
487      * Convenience method for running the provided action enclosed in
488      * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity} returning the result.
489      *
490      * <p>Any exception thrown by the given action will be caught and rethrown after
491      * the call to {@link #restoreCallingIdentity}.
492      *
493      * @hide
494      */
withCleanCallingIdentity(@onNull ThrowingSupplier<T> action)495     public static final <T> T withCleanCallingIdentity(@NonNull ThrowingSupplier<T> action) {
496         Throwable throwableToPropagate = null;
497         final long callingIdentity = clearCallingIdentity();
498         try {
499             return action.getOrThrow();
500         } catch (Throwable throwable) {
501             throwableToPropagate = throwable;
502             return null; // overridden by throwing in finally block
503         } finally {
504             restoreCallingIdentity(callingIdentity);
505             if (throwableToPropagate != null) {
506                 throw ExceptionUtils.propagate(throwableToPropagate);
507             }
508         }
509     }
510 
511     /**
512      * Sets the native thread-local StrictMode policy mask.
513      *
514      * <p>The StrictMode settings are kept in two places: a Java-level
515      * threadlocal for libcore/Dalvik, and a native threadlocal (set
516      * here) for propagation via Binder calls. This is a little
517      * unfortunate, but necessary to break otherwise more unfortunate
518      * dependencies either of Dalvik on Android, or Android
519      * native-only code on Dalvik.
520      *
521      * @see StrictMode
522      *
523      * @hide
524      */
525     @CriticalNative
setThreadStrictModePolicy(int policyMask)526     public static final native void setThreadStrictModePolicy(int policyMask);
527 
528     /**
529      * Gets the current native thread-local StrictMode policy mask.
530      *
531      * @see #setThreadStrictModePolicy
532      *
533      * @hide
534      */
535     @CriticalNative
getThreadStrictModePolicy()536     public static final native int getThreadStrictModePolicy();
537 
538     /**
539      * Sets the work source for this thread.
540      *
541      * <p>All the following binder calls on this thread will use the provided work source. If this
542      * is called during an on-going binder transaction, all the following binder calls will use the
543      * work source until the end of the transaction.
544      *
545      * <p>The concept of worksource is similar to {@link WorkSource}. However, for performance
546      * reasons, we only support one UID. This UID represents the original user responsible for the
547      * binder calls.
548      *
549      * <p>{@link #restoreCallingWorkSource(long)} must always be called after setting the
550      * worksource.
551      *
552      * <p>A typical use case would be
553      * <pre>
554      * long token = Binder.setCallingWorkSourceUid(uid);
555      * try {
556      *   // Call an API.
557      * } finally {
558      *   Binder.restoreCallingWorkSource(token);
559      * }
560      * </pre>
561      *
562      * <p>The work source will be propagated for future outgoing binder transactions
563      * executed on this thread.
564      *
565      * @param workSource The original UID responsible for the binder call.
566      * @return token to restore original work source.
567      */
568     @CriticalNative
setCallingWorkSourceUid(int workSource)569     public static final native long setCallingWorkSourceUid(int workSource);
570 
571     /**
572      * Returns the work source set by the caller.
573      *
574      * <p>Unlike {@link #getCallingUid()}, this result of this method cannot be trusted. The
575      * caller can set the value to whatever they want. Only use this value if you trust the calling
576      * UID.
577      *
578      * @return The original UID responsible for the binder transaction.
579      */
580     @CriticalNative
getCallingWorkSourceUid()581     public static final native int getCallingWorkSourceUid();
582 
583     /**
584      * Clears the work source on this thread.
585      *
586      * <p>The work source will be propagated for future outgoing binder transactions
587      * executed on this thread.
588      *
589      * <p>{@link #restoreCallingWorkSource(long)} must always be called after clearing the
590      * worksource.
591      *
592      * <p>A typical use case would be
593      * <pre>
594      * long token = Binder.clearCallingWorkSource();
595      * try {
596      *   // Call an API.
597      * } finally {
598      *   Binder.restoreCallingWorkSource(token);
599      * }
600      * </pre>
601      *
602      * @return token to restore original work source.
603      */
604     @CriticalNative
clearCallingWorkSource()605     public static final native long clearCallingWorkSource();
606 
607     /**
608      * Restores the work source on this thread using a token returned by
609      * {@link #setCallingWorkSourceUid(int)} or {@link #clearCallingWorkSource()}.
610      *
611      * <p>A typical use case would be
612      * <pre>
613      * long token = Binder.setCallingWorkSourceUid(uid);
614      * try {
615      *   // Call an API.
616      * } finally {
617      *   Binder.restoreCallingWorkSource(token);
618      * }
619      * </pre>
620      */
621     @CriticalNative
restoreCallingWorkSource(long token)622     public static final native void restoreCallingWorkSource(long token);
623 
624     /**
625      * Mark as being built with VINTF-level stability promise. This API should
626      * only ever be invoked by generated code from the aidl compiler. It means
627      * that the interface represented by this binder is guaranteed to be kept
628      * stable for several years, according to the VINTF compatibility lifecycle,
629      * and the build system also keeps snapshots of these APIs and invokes the
630      * AIDL compiler to make sure that these snapshots are backwards compatible.
631      * Instead of using this API, use the @VintfStability annotation on your
632      * AIDL interface.
633      *
634      * @hide
635      */
636     @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
markVintfStability()637     public final native void markVintfStability();
638 
639     /**
640      * Use a VINTF-stability binder w/o VINTF requirements. Should be called
641      * on a binder before it is sent out of process.
642      *
643      * <p>This must be called before the object is sent to another process.
644      *
645      * @hide
646      */
forceDowngradeToSystemStability()647     public final native void forceDowngradeToSystemStability();
648 
649     /**
650      * Flush any Binder commands pending in the current thread to the kernel
651      * driver. This can be
652      * useful to call before performing an operation that may block for a long
653      * time, to ensure that any pending object references have been released
654      * in order to prevent the process from holding on to objects longer than
655      * it needs to.
656      */
flushPendingCommands()657     public static final native void flushPendingCommands();
658 
659     /**
660      * Add the calling thread to the IPC thread pool. This function does
661      * not return until the current process is exiting.
662      */
joinThreadPool()663     public static final void joinThreadPool() {
664         BinderInternal.joinThreadPool();
665     }
666 
667     /**
668      * Returns true if the specified interface is a proxy.
669      *
670      * @hide
671      */
isProxy(IInterface iface)672     public static final boolean isProxy(IInterface iface) {
673         return iface.asBinder() != iface;
674     }
675 
676     /**
677      * Call blocks until the number of executing binder threads is less
678      * than the maximum number of binder threads allowed for this process.
679      *
680      * @hide
681      */
blockUntilThreadAvailable()682     public static final native void blockUntilThreadAvailable();
683 
684 
685     /**
686      * TODO (b/308179628): Move this to libbinder for non-Java usages.
687      */
688     private static IBinderCallback sBinderCallback = null;
689 
690     /**
691      * Set callback function for unexpected binder transaction errors.
692      *
693      * @hide
694      */
setTransactionCallback(IBinderCallback callback)695     public static final void setTransactionCallback(IBinderCallback callback) {
696         sBinderCallback = callback;
697     }
698 
699     /**
700      * Execute the callback function if it's already set.
701      *
702      * @hide
703      */
transactionCallback(int pid, int code, int flags, int err)704     public static final void transactionCallback(int pid, int code, int flags, int err) {
705         if (sBinderCallback != null) {
706             sBinderCallback.onTransactionError(pid, code, flags, err);
707         }
708     }
709 
710     /**
711      * Default constructor just initializes the object.
712      *
713      * <p>If you're creating a Binder token (a Binder object without an attached interface),
714      * you should use {@link #Binder(String)} instead.
715      */
Binder()716     public Binder() {
717         this(null);
718     }
719 
720     /**
721      * Constructor for creating a raw Binder object (token) along with a descriptor.
722      *
723      * <p>The descriptor of binder objects usually specifies the interface they are implementing.
724      * In case of binder tokens, no interface is implemented, and the descriptor can be used
725      * as a sort of tag to help identify the binder token. This will help identify remote
726      * references to these objects more easily when debugging.
727      *
728      * @param descriptor Used to identify the creator of this token, for example the class name.
729      * Instead of creating multiple tokens with the same descriptor, consider adding a suffix to
730      * help identify them.
731      */
Binder(@ullable String descriptor)732     public Binder(@Nullable String descriptor) {
733         mObject = getNativeBBinderHolder();
734         NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
735 
736         if (FIND_POTENTIAL_LEAKS) {
737             final Class<? extends Binder> klass = getClass();
738             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
739                     (klass.getModifiers() & Modifier.STATIC) == 0) {
740                 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
741                     klass.getCanonicalName());
742             }
743         }
744         mDescriptor = descriptor;
745     }
746 
747     /**
748      * Convenience method for associating a specific interface with the Binder.
749      * After calling, {@link #queryLocalInterface(String) queryLocalInterface()}
750      * will be implemented for you to return the given owner IInterface when
751      * the corresponding descriptor is requested.
752      */
attachInterface(@ullable IInterface owner, @Nullable String descriptor)753     public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
754         mOwner = owner;
755         mDescriptor = descriptor;
756     }
757 
758     /**
759      * Default implementation returns an empty interface name.
760      */
getInterfaceDescriptor()761     public @Nullable String getInterfaceDescriptor() {
762         return mDescriptor;
763     }
764 
765     /**
766      * Default implementation always returns true -- if you got here,
767      * the object is alive.
768      */
pingBinder()769     public boolean pingBinder() {
770         return true;
771     }
772 
773     /**
774      * {@inheritDoc}
775      *
776      * Note that if you're calling on a local binder, this always returns true
777      * because your process is alive if you're calling it.
778      */
isBinderAlive()779     public boolean isBinderAlive() {
780         return true;
781     }
782 
783     /**
784      * Use information supplied to {@link #attachInterface attachInterface()}
785      * to return the associated {@link IInterface} if it matches the requested
786      * descriptor.
787      */
queryLocalInterface(@onNull String descriptor)788     public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
789         if (mDescriptor != null && mDescriptor.equals(descriptor)) {
790             return mOwner;
791         }
792         return null;
793     }
794 
795     /**
796      * Control disabling of dump calls in this process. This is used by the system
797      * process watchdog to disable incoming dump calls while it has detecting the system
798      * is hung and is reporting that back to the activity controller. This is to
799      * prevent the controller from getting hung up on bug reports at this point.
800      *
801      * @param msg The message to show instead of the dump; if null, dumps are
802      * re-enabled.
803      *
804      * @hide
805      */
setDumpDisabled(String msg)806     public static void setDumpDisabled(String msg) {
807         sDumpDisabled = msg;
808     }
809 
810     /**
811      * Listener to be notified about each proxy-side binder call.
812      *
813      * @see {@link #setProxyTransactListener}.
814      *
815      * @hide
816      */
817     @SystemApi
818     public interface ProxyTransactListener {
819         /**
820          * Called before onTransact.
821          *
822          * @return an object that will be passed back to {@link #onTransactEnded} (or null).,
823          *
824          * @hide
825          */
826         @Nullable
onTransactStarted(@onNull IBinder binder, int transactionCode, int flags)827         default Object onTransactStarted(@NonNull IBinder binder, int transactionCode, int flags) {
828             return onTransactStarted(binder, transactionCode);
829         }
830 
831         /**
832          * Called before onTransact.
833          *
834          * @return an object that will be passed back to {@link #onTransactEnded} (or null).
835          */
836         @Nullable
onTransactStarted(@onNull IBinder binder, int transactionCode)837         Object onTransactStarted(@NonNull IBinder binder, int transactionCode);
838 
839         /**
840          * Called after onTransact (even when an exception is thrown).
841          *
842          * @param session The object return by {@link #onTransactStarted}.
843          */
onTransactEnded(@ullable Object session)844         void onTransactEnded(@Nullable Object session);
845     }
846 
847     /**
848      * Propagates the work source to binder calls executed by the system server.
849      *
850      * <li>By default, this listener will propagate the worksource if the outgoing call happens on
851      * the same thread as the incoming binder call.
852      * <li>Custom attribution can be done by calling {@link ThreadLocalWorkSource#setUid(int)}.
853      *
854      * @hide
855      */
856     public static class PropagateWorkSourceTransactListener implements ProxyTransactListener {
857         @Override
onTransactStarted(IBinder binder, int transactionCode)858         public Object onTransactStarted(IBinder binder, int transactionCode) {
859             // Note that {@link #getCallingUid()} is already set to the UID of the current
860             // process when this method is called.
861             //
862             // We use {@link ThreadLocalWorkSource} instead. It also allows feature owners to set
863             // {@link ThreadLocalWorkSource#set(int)} manually to attribute resources to a UID.
864             int uid = ThreadLocalWorkSource.getUid();
865             if (uid != ThreadLocalWorkSource.UID_NONE) {
866                 return Binder.setCallingWorkSourceUid(uid);
867             }
868             return null;
869         }
870 
871         @Override
onTransactEnded(Object session)872         public void onTransactEnded(Object session) {
873             if (session != null) {
874                 long token = (long) session;
875                 Binder.restoreCallingWorkSource(token);
876             }
877         }
878     }
879 
880     /**
881      * Sets a listener for the transact method on the proxy-side.
882      *
883      * <li>The listener is global. Only fast operations should be done to avoid thread
884      * contentions.
885      * <li>The listener implementation needs to handle synchronization if needed. The methods on the
886      * listener can be called concurrently.
887      * <li>Listener set will be used for new transactions. On-going transaction will still use the
888      * previous listener (if already set).
889      * <li>The listener is called on the critical path of the binder transaction so be careful about
890      * performance.
891      * <li>Never execute another binder transaction inside the listener.
892      *
893      * @hide
894      */
895     @SystemApi
setProxyTransactListener(@ullable ProxyTransactListener listener)896     public static void setProxyTransactListener(@Nullable ProxyTransactListener listener) {
897         BinderProxy.setTransactListener(listener);
898     }
899 
900     /**
901      * Default implementation is a stub that returns false. You will want
902      * to override this to do the appropriate unmarshalling of transactions.
903      *
904      * <p>If you want to call this, call transact().
905      *
906      * <p>Implementations that are returning a result should generally use
907      * {@link Parcel#writeNoException() Parcel.writeNoException} and
908      * {@link Parcel#writeException(Exception) Parcel.writeException} to propagate
909      * exceptions back to the caller.
910      *
911      * @param code The action to perform. This should be a number between
912      * {@link #FIRST_CALL_TRANSACTION} and {@link #LAST_CALL_TRANSACTION}.
913      * @param data Marshalled data being received from the caller.
914      * @param reply If the caller is expecting a result back, it should be marshalled
915      * in to here.
916      * @param flags Additional operation flags. Either 0 for a normal
917      * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
918      *
919      * @return Return true on a successful call; returning false is generally used to
920      * indicate that you did not understand the transaction code.
921      */
onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)922     protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
923             int flags) throws RemoteException {
924         if (code == INTERFACE_TRANSACTION) {
925             reply.writeString(getInterfaceDescriptor());
926             return true;
927         } else if (code == DUMP_TRANSACTION) {
928             ParcelFileDescriptor fd = data.readFileDescriptor();
929             String[] args = data.readStringArray();
930             if (fd != null) {
931                 try {
932                     dump(fd.getFileDescriptor(), args);
933                 } finally {
934                     IoUtils.closeQuietly(fd);
935                 }
936             }
937             // Write the StrictMode header.
938             if (reply != null) {
939                 reply.writeNoException();
940             } else {
941                 StrictMode.clearGatheredViolations();
942             }
943             return true;
944         } else if (code == SHELL_COMMAND_TRANSACTION) {
945             ParcelFileDescriptor in = data.readFileDescriptor();
946             ParcelFileDescriptor out = data.readFileDescriptor();
947             ParcelFileDescriptor err = data.readFileDescriptor();
948             String[] args = data.readStringArray();
949             ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
950             ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
951             try {
952                 if (out != null) {
953                     shellCommand(in != null ? in.getFileDescriptor() : null,
954                             out.getFileDescriptor(),
955                             err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
956                             args, shellCallback, resultReceiver);
957                 }
958             } finally {
959                 IoUtils.closeQuietly(in);
960                 IoUtils.closeQuietly(out);
961                 IoUtils.closeQuietly(err);
962                 // Write the StrictMode header.
963                 if (reply != null) {
964                     reply.writeNoException();
965                 } else {
966                     StrictMode.clearGatheredViolations();
967                 }
968             }
969             return true;
970         }
971         return false;
972     }
973 
974     /**
975      * Resolves a transaction code to a human readable name.
976      *
977      * <p>Default implementation is a stub that returns null.
978      *
979      * <p>AIDL generated code will return the original method name.
980      *
981      * @param transactionCode The code to resolve.
982      * @return A human readable name.
983      *
984      * @hide
985      */
getTransactionName(int transactionCode)986     public @Nullable String getTransactionName(int transactionCode) {
987         return null;
988     }
989 
990     /**
991      * @hide
992      */
993     @VisibleForTesting
getTransactionTraceName(int transactionCode)994     public final @Nullable String getTransactionTraceName(int transactionCode) {
995         final boolean isInterfaceUserDefined = getMaxTransactionId() == 0;
996         if (mTransactionTraceNames == null) {
997             final int highestId = isInterfaceUserDefined ? TRANSACTION_TRACE_NAME_ID_LIMIT
998                     : Math.min(getMaxTransactionId(), TRANSACTION_TRACE_NAME_ID_LIMIT);
999             mSimpleDescriptor = getSimpleDescriptor();
1000             mTransactionTraceNames = new AtomicReferenceArray(highestId + 1);
1001         }
1002 
1003         final int index = isInterfaceUserDefined
1004                 ? transactionCode : transactionCode - FIRST_CALL_TRANSACTION;
1005         if (index >= mTransactionTraceNames.length() || index < 0) {
1006             return null;
1007         }
1008 
1009         String transactionTraceName = mTransactionTraceNames.getAcquire(index);
1010         if (transactionTraceName == null) {
1011             final String transactionName = getTransactionName(transactionCode);
1012             final StringBuffer buf = new StringBuffer();
1013 
1014             // Keep trace name consistent with cpp trace name in:
1015             // system/tools/aidl/generate_cpp.cpp
1016             buf.append("AIDL::java::");
1017             if (transactionName != null) {
1018                 buf.append(mSimpleDescriptor).append("::").append(transactionName);
1019             } else {
1020                 buf.append(mSimpleDescriptor).append("::#").append(transactionCode);
1021             }
1022             buf.append("::server");
1023 
1024             transactionTraceName = buf.toString();
1025             mTransactionTraceNames.setRelease(index, transactionTraceName);
1026         }
1027 
1028         return transactionTraceName;
1029     }
1030 
getSimpleDescriptor()1031     private @NonNull String getSimpleDescriptor() {
1032         String descriptor = mDescriptor;
1033         if (descriptor == null) {
1034             // Just "Binder" to avoid null checks in transaction name tracing.
1035             return "Binder";
1036         }
1037 
1038         final int dot = descriptor.lastIndexOf(".");
1039         if (dot > 0) {
1040             // Strip the package name
1041             return descriptor.substring(dot + 1);
1042         }
1043         return descriptor;
1044     }
1045 
1046     /**
1047      * @return The highest user-defined transaction id of all transactions.
1048      * @hide
1049      */
getMaxTransactionId()1050     public int getMaxTransactionId() {
1051         return 0;
1052     }
1053 
1054     /**
1055      * Implemented to call the more convenient version
1056      * {@link #dump(FileDescriptor, PrintWriter, String[])}.
1057      */
dump(@onNull FileDescriptor fd, @Nullable String[] args)1058     public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) {
1059         FileOutputStream fout = new FileOutputStream(fd);
1060         PrintWriter pw = new FastPrintWriter(fout);
1061         try {
1062             doDump(fd, pw, args);
1063         } finally {
1064             pw.flush();
1065         }
1066     }
1067 
doDump(FileDescriptor fd, PrintWriter pw, String[] args)1068     void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
1069         final String disabled = sDumpDisabled;
1070         if (disabled == null) {
1071             try {
1072                 dump(fd, pw, args);
1073             } catch (SecurityException e) {
1074                 pw.println("Security exception: " + e.getMessage());
1075                 throw e;
1076             } catch (Throwable e) {
1077                 // Unlike usual calls, in this case if an exception gets thrown
1078                 // back to us we want to print it back in to the dump data, since
1079                 // that is where the caller expects all interesting information to
1080                 // go.
1081                 pw.println();
1082                 pw.println("Exception occurred while dumping:");
1083                 e.printStackTrace(pw);
1084             }
1085         } else {
1086             pw.println(sDumpDisabled);
1087         }
1088     }
1089 
1090     /**
1091      * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
1092      * executes asynchronously.
1093      */
dumpAsync(@onNull final FileDescriptor fd, @Nullable final String[] args)1094     public void dumpAsync(@NonNull final FileDescriptor fd, @Nullable final String[] args) {
1095         final FileOutputStream fout = new FileOutputStream(fd);
1096         final PrintWriter pw = new FastPrintWriter(fout);
1097         Thread thr = new Thread("Binder.dumpAsync") {
1098             public void run() {
1099                 try {
1100                     dump(fd, pw, args);
1101                 } finally {
1102                     pw.flush();
1103                 }
1104             }
1105         };
1106         thr.start();
1107     }
1108 
1109     /**
1110      * Print the object's state into the given stream.
1111      *
1112      * @param fd The raw file descriptor that the dump is being sent to.
1113      * @param fout The file to which you should dump your state. This will be
1114      * closed for you after you return.
1115      * @param args additional arguments to the dump request.
1116      */
dump(@onNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args)1117     protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
1118             @Nullable String[] args) {
1119     }
1120 
1121     /**
1122      * Called whenever the stub implementation throws an exception which isn't propagated to the
1123      * remote caller by the binder. If this method isn't overridden, this exception is swallowed,
1124      * and some default return values are propagated to the caller.
1125      *
1126      * <br> <b> This should not throw. </b> Doing so would defeat the purpose of this handler, and
1127      * suppress the exception it is handling.
1128      *
1129      * @param code The transaction code being handled
1130      * @param e The exception which was thrown.
1131      * @hide
1132      */
onUnhandledException(int code, int flags, Exception e)1133     protected void onUnhandledException(int code, int flags, Exception e) {
1134     }
1135 
1136     /**
1137      * @param in The raw file descriptor that an input data stream can be read from.
1138      * @param out The raw file descriptor that normal command messages should be written to.
1139      * @param err The raw file descriptor that command error messages should be written to.
1140      * @param args Command-line arguments.
1141      * @param callback Callback through which to interact with the invoking shell.
1142      * @param resultReceiver Called when the command has finished executing, with the result code.
1143      * @throws RemoteException
1144      *
1145      * @hide
1146      */
shellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)1147     public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
1148             @Nullable FileDescriptor err,
1149             @NonNull String[] args, @Nullable ShellCallback callback,
1150             @NonNull ResultReceiver resultReceiver) throws RemoteException {
1151         onShellCommand(in, out, err, args, callback, resultReceiver);
1152     }
1153 
1154     /**
1155      * Handle a call to {@link #shellCommand}.
1156      *
1157      * <p>The default implementation performs a caller check to make sure the caller UID is of
1158      * SHELL or ROOT, and then call {@link #handleShellCommand}.
1159      *
1160      * <p class="caution">Note: no permission checking is done before calling this method; you must
1161      * apply any security checks as appropriate for the command being executed.
1162      * Consider using {@link ShellCommand} to help in the implementation.
1163      *
1164      * @hide
1165      */
onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)1166     public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
1167             @Nullable FileDescriptor err,
1168             @NonNull String[] args, @Nullable ShellCallback callback,
1169             @NonNull ResultReceiver resultReceiver) throws RemoteException {
1170 
1171         final int callingUid = Binder.getCallingUid();
1172         if (callingUid != Process.ROOT_UID && callingUid != Process.SHELL_UID) {
1173             resultReceiver.send(-1, null);
1174             throw new SecurityException("Shell commands are only callable by ADB");
1175         }
1176 
1177         // First, convert in, out and err to @NonNull, by redirecting any that's null to /dev/null.
1178         try {
1179             if (in == null) {
1180                 in = new FileInputStream("/dev/null").getFD();
1181             }
1182             if (out == null) {
1183                 out = new FileOutputStream("/dev/null").getFD();
1184             }
1185             if (err == null) {
1186                 err = out;
1187             }
1188         } catch (IOException e) {
1189             PrintWriter pw = new FastPrintWriter(new FileOutputStream(err != null ? err : out));
1190             pw.println("Failed to open /dev/null: " + e.getMessage());
1191             pw.flush();
1192             resultReceiver.send(-1, null);
1193             return;
1194         }
1195         // Also make args @NonNull.
1196         if (args == null) {
1197             args = new String[0];
1198         }
1199 
1200         int result = -1;
1201         try (ParcelFileDescriptor inPfd = ParcelFileDescriptor.dup(in);
1202                 ParcelFileDescriptor outPfd = ParcelFileDescriptor.dup(out);
1203                 ParcelFileDescriptor errPfd = ParcelFileDescriptor.dup(err)) {
1204             result = handleShellCommand(inPfd, outPfd, errPfd, args);
1205         } catch (IOException e) {
1206             PrintWriter pw = new FastPrintWriter(new FileOutputStream(err));
1207             pw.println("dup() failed: " + e.getMessage());
1208             pw.flush();
1209         } finally {
1210             resultReceiver.send(result, null);
1211         }
1212     }
1213 
1214     /**
1215      * System services can implement this method to implement ADB shell commands.
1216      *
1217      * <p>A system binder service can implement it to handle shell commands on ADB. For example,
1218      * the Job Scheduler service implements it to handle {@code adb shell cmd jobscheduler}.
1219      *
1220      * <p>Commands are only executable by ADB shell; i.e. only {@link Process#SHELL_UID} and
1221      * {@link Process#ROOT_UID} can call them.
1222      *
1223      * @param in standard input
1224      * @param out standard output
1225      * @param err standard error
1226      * @param args arguments passed to the command. Can be empty. The first argument is typically
1227      * a subcommand, such as {@code run} for {@code adb shell cmd jobscheduler run}.
1228      * @return the status code returned from the {@code cmd} command.
1229      *
1230      * @hide
1231      */
1232     @SystemApi
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)1233     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
1234             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
1235             @NonNull String[] args) {
1236         FileOutputStream ferr = new FileOutputStream(err.getFileDescriptor());
1237         PrintWriter pw = new FastPrintWriter(ferr);
1238         pw.println("No shell command implementation.");
1239         pw.flush();
1240         return 0;
1241     }
1242 
1243     /** @hide */
1244     @Override
getExtension()1245     public final @Nullable IBinder getExtension() {
1246         return mExtension;
1247     }
1248 
1249     /**
1250      * Set the binder extension.
1251      * This should be called immediately when the object is created.
1252      *
1253      * @hide
1254      */
setExtension(@ullable IBinder extension)1255     public final void setExtension(@Nullable IBinder extension) {
1256         mExtension = extension;
1257         setExtensionNative(extension);
1258     }
1259 
setExtensionNative(@ullable IBinder extension)1260     private final native void setExtensionNative(@Nullable IBinder extension);
1261 
1262     /**
1263      * Default implementation rewinds the parcels and calls onTransact. On
1264      * the remote side, transact calls into the binder to do the IPC.
1265      */
transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)1266     public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
1267             int flags) throws RemoteException {
1268         if (false) Log.v("Binder", "Transact: " + code + " to " + this);
1269 
1270         if (data != null) {
1271             data.setDataPosition(0);
1272         }
1273         boolean r = onTransact(code, data, reply, flags);
1274         if (reply != null) {
1275             reply.setDataPosition(0);
1276         }
1277         return r;
1278     }
1279 
1280     /**
1281      * Local implementation is a no-op.
1282      */
linkToDeath(@onNull DeathRecipient recipient, int flags)1283     public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
1284     }
1285 
1286     /**
1287      * Local implementation is a no-op.
1288      */
unlinkToDeath(@onNull DeathRecipient recipient, int flags)1289     public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
1290         return true;
1291     }
1292 
checkParcel(IBinder obj, int code, Parcel parcel, String msg)1293     static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
1294         if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
1295             // Trying to send > 800k, this is way too much.
1296             StringBuilder sb = new StringBuilder();
1297             sb.append(msg);
1298             sb.append(": on ");
1299             sb.append(obj);
1300             sb.append(" calling ");
1301             sb.append(code);
1302             sb.append(" size ");
1303             sb.append(parcel.dataSize());
1304             sb.append(" (data: ");
1305             parcel.setDataPosition(0);
1306             sb.append(parcel.readInt());
1307             sb.append(", ");
1308             sb.append(parcel.readInt());
1309             sb.append(", ");
1310             sb.append(parcel.readInt());
1311             sb.append(")");
1312             Slog.wtfStack(TAG, sb.toString());
1313         }
1314     }
1315 
getNativeBBinderHolder()1316     private static native long getNativeBBinderHolder();
1317 
1318     /**
1319      * By default, we use the calling UID since we can always trust it.
1320      */
1321     private static volatile BinderInternal.WorkSourceProvider sWorkSourceProvider =
1322             (x) -> Binder.getCallingUid();
1323 
1324     /**
1325      * Sets the work source provider.
1326      *
1327      * <li>The callback is global. Only fast operations should be done to avoid thread
1328      * contentions.
1329      * <li>The callback implementation needs to handle synchronization if needed. The methods on the
1330      * callback can be called concurrently.
1331      * <li>The callback is called on the critical path of the binder transaction so be careful about
1332      * performance.
1333      * <li>Never execute another binder transaction inside the callback.
1334      *
1335      * @hide
1336      */
setWorkSourceProvider(BinderInternal.WorkSourceProvider workSourceProvider)1337     public static void setWorkSourceProvider(BinderInternal.WorkSourceProvider workSourceProvider) {
1338         if (workSourceProvider == null) {
1339             throw new IllegalArgumentException("workSourceProvider cannot be null");
1340         }
1341         sWorkSourceProvider = workSourceProvider;
1342     }
1343 
1344     // Entry point from android_util_Binder.cpp's onTransact.
1345     @UnsupportedAppUsage
execTransact(int code, long dataObj, long replyObj, int flags)1346     private boolean execTransact(int code, long dataObj, long replyObj,
1347             int flags) {
1348 
1349         Parcel data = Parcel.obtain(dataObj);
1350         Parcel reply = Parcel.obtain(replyObj);
1351 
1352         // At that point, the parcel request headers haven't been parsed so we do not know what
1353         // {@link WorkSource} the caller has set. Use calling UID as the default.
1354         //
1355         // TODO: this is wrong - we should attribute along the entire call route
1356         // also this attribution logic should move to native code - it only works
1357         // for Java now
1358         //
1359         // This attribution support is not generic and therefore not support in RPC mode
1360         final int callingUid = data.isForRpc() ? -1 : Binder.getCallingUid();
1361         final long origWorkSource = callingUid == -1
1362                 ? -1 : ThreadLocalWorkSource.setUid(callingUid);
1363 
1364         try {
1365             return execTransactInternal(code, data, reply, flags, callingUid);
1366         } finally {
1367             reply.recycle();
1368             data.recycle();
1369 
1370             if (callingUid != -1) {
1371                 ThreadLocalWorkSource.restore(origWorkSource);
1372             }
1373         }
1374     }
1375 
execTransactInternal(int code, Parcel data, Parcel reply, int flags, int callingUid)1376     private boolean execTransactInternal(int code, Parcel data, Parcel reply, int flags,
1377             int callingUid) {
1378         // Make sure the observer won't change while processing a transaction.
1379         final BinderInternal.Observer observer = sObserver;
1380 
1381         // TODO(b/299356196): observer should also observe transactions in native code
1382         final CallSession callSession =
1383                 observer != null ? observer.callStarted(this, code, UNSET_WORKSOURCE) : null;
1384         // Theoretically, we should call transact, which will call onTransact,
1385         // but all that does is rewind it, and we just got these from an IPC,
1386         // so we'll just call it directly.
1387         boolean res;
1388         // Log any exceptions as warnings, don't silently suppress them.
1389         // If the call was {@link IBinder#FLAG_ONEWAY} then these exceptions
1390         // disappear into the ether.
1391         final boolean tagEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_AIDL);
1392         final boolean hasFullyQualifiedName = getMaxTransactionId() > 0;
1393         final String transactionTraceName;
1394 
1395         if (tagEnabled) {
1396             // If tracing enabled and we have a fully qualified name, fetch the name
1397             transactionTraceName = getTransactionTraceName(code);
1398         } else {
1399             transactionTraceName = null;
1400         }
1401 
1402         final boolean tracingEnabled = tagEnabled && transactionTraceName != null;
1403         try {
1404             // TODO(b/299356201) - this logic should not be in Java - it should be in native
1405             // code in libbinder so that it works for all binder users.
1406             final BinderCallHeavyHitterWatcher heavyHitterWatcher = sHeavyHitterWatcher;
1407             if (heavyHitterWatcher != null && callingUid != -1) {
1408                 // Notify the heavy hitter watcher, if it's enabled.
1409                 heavyHitterWatcher.onTransaction(callingUid, getClass(), code);
1410             }
1411             if (tracingEnabled) {
1412                 Trace.traceBegin(Trace.TRACE_TAG_AIDL, transactionTraceName);
1413             }
1414 
1415             // TODO(b/299353919) - this logic should not be in Java - it should be
1416             // in native code in libbinder so that it works for all binder users.
1417             // Further, this should not re-use flags.
1418             if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0 && callingUid != -1) {
1419                 AppOpsManager.startNotedAppOpsCollection(callingUid);
1420                 try {
1421                     res = onTransact(code, data, reply, flags);
1422                 } finally {
1423                     AppOpsManager.finishNotedAppOpsCollection();
1424                 }
1425             } else {
1426                 res = onTransact(code, data, reply, flags);
1427             }
1428         } catch (RemoteException|RuntimeException e) {
1429             if (observer != null) {
1430                 observer.callThrewException(callSession, e);
1431             }
1432             if (LOG_RUNTIME_EXCEPTION) {
1433                 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
1434             }
1435             if ((flags & FLAG_ONEWAY) != 0) {
1436                 if (e instanceof RemoteException) {
1437                     Log.w(TAG, "Binder call failed.", e);
1438                 } else {
1439                     Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
1440                 }
1441                 onUnhandledException(code, flags, e);
1442             } else {
1443                 // Clear the parcel before writing the exception.
1444                 reply.setDataSize(0);
1445                 reply.setDataPosition(0);
1446                 // The writeException below won't do anything useful if this is the case.
1447                 if (Parcel.getExceptionCode(e) == 0) {
1448                     onUnhandledException(code, flags, e);
1449                 }
1450                 reply.writeException(e);
1451             }
1452             res = true;
1453         } finally {
1454             if (tracingEnabled) {
1455                 Trace.traceEnd(Trace.TRACE_TAG_AIDL);
1456             }
1457             if (observer != null) {
1458                 // The parcel RPC headers have been called during onTransact so we can now access
1459                 // the worksource UID from the parcel.
1460                 final int workSourceUid = sWorkSourceProvider.resolveWorkSourceUid(
1461                         data.readCallingWorkSourceUid());
1462                 observer.callEnded(callSession, data.dataSize(), reply.dataSize(), workSourceUid);
1463             }
1464 
1465             checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
1466         }
1467 
1468         // Just in case -- we are done with the IPC, so there should be no more strict
1469         // mode violations that have gathered for this thread. Either they have been
1470         // parceled and are now in transport off to the caller, or we are returning back
1471         // to the main transaction loop to wait for another incoming transaction. Either
1472         // way, strict mode begone!
1473         StrictMode.clearGatheredViolations();
1474         return res;
1475     }
1476 
1477     /**
1478      * Set the configuration for the heavy hitter watcher.
1479      *
1480      * @hide
1481      */
setHeavyHitterWatcherConfig(final boolean enabled, final int batchSize, final float threshold, @Nullable final BinderCallHeavyHitterListener listener)1482     public static synchronized void setHeavyHitterWatcherConfig(final boolean enabled,
1483             final int batchSize, final float threshold,
1484             @Nullable final BinderCallHeavyHitterListener listener) {
1485         Slog.i(TAG, "Setting heavy hitter watcher config: "
1486                 + enabled + ", " + batchSize + ", " + threshold);
1487         BinderCallHeavyHitterWatcher watcher = sHeavyHitterWatcher;
1488         if (enabled) {
1489             if (listener == null) {
1490                 throw new IllegalArgumentException();
1491             }
1492             boolean newWatcher = false;
1493             if (watcher == null) {
1494                 watcher = BinderCallHeavyHitterWatcher.getInstance();
1495                 newWatcher = true;
1496             }
1497             watcher.setConfig(true, batchSize, threshold, listener);
1498             if (newWatcher) {
1499                 sHeavyHitterWatcher = watcher;
1500             }
1501         } else if (watcher != null) {
1502             watcher.setConfig(false, 0, 0.0f, null);
1503         }
1504     }
1505 }
1506