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