blob: eb264d6d308cf013e60ebd38ff8ad0f2be80faa4 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.os;
18
Dianne Hackborn4cd650c2017-07-31 17:38:53 -070019import android.annotation.NonNull;
20import android.annotation.Nullable;
Eugene Suslacf00ade2017-04-10 11:51:58 -070021import android.util.ExceptionUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.util.Log;
Dianne Hackborn017c6a22014-09-25 17:41:34 -070023import android.util.Slog;
Eugene Suslacf00ade2017-04-10 11:51:58 -070024
Dianne Hackborndb4e33f2013-04-01 17:28:16 -070025import com.android.internal.util.FastPrintWriter;
Eugene Suslacf00ade2017-04-10 11:51:58 -070026import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
27import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
28
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070029import libcore.io.IoUtils;
Hans Boehm5e5b13f2017-09-28 18:16:50 -070030import libcore.util.NativeAllocationRegistry;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
32import java.io.FileDescriptor;
33import java.io.FileOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import java.io.PrintWriter;
35import java.lang.ref.WeakReference;
36import java.lang.reflect.Modifier;
Hans Boehm29f388f2017-10-03 18:01:20 -070037import java.util.ArrayList;
Andreas Gampe3fc030f2017-12-27 09:30:45 -080038import java.util.Arrays;
39import java.util.HashMap;
40import java.util.Map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
42/**
43 * Base class for a remotable object, the core part of a lightweight
44 * remote procedure call mechanism defined by {@link IBinder}.
45 * This class is an implementation of IBinder that provides
Dianne Hackbornab4a81b2014-10-09 17:59:38 -070046 * standard local implementation of such an object.
47 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 * <p>Most developers will not implement this class directly, instead using the
Scott Main40eee612012-08-06 17:48:37 -070049 * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 * interface, having it generate the appropriate Binder subclass. You can,
51 * however, derive directly from Binder to implement your own custom RPC
52 * protocol or simply instantiate a raw Binder object directly to use as a
53 * token that can be shared across processes.
Dianne Hackbornab4a81b2014-10-09 17:59:38 -070054 *
55 * <p>This class is just a basic IPC primitive; it has no impact on an application's
56 * lifecycle, and is valid only as long as the process that created it continues to run.
57 * To use this correctly, you must be doing so within the context of a top-level
58 * application component (a {@link android.app.Service}, {@link android.app.Activity},
59 * or {@link android.content.ContentProvider}) that lets the system know your process
60 * should remain running.</p>
61 *
62 * <p>You must keep in mind the situations in which your process
63 * could go away, and thus require that you later re-create a new Binder and re-attach
64 * it when the process starts again. For example, if you are using this within an
65 * {@link android.app.Activity}, your activity's process may be killed any time the
66 * activity is not started; if the activity is later re-created you will need to
67 * create a new Binder and hand it back to the correct place again; you need to be
68 * aware that your process may be started for another reason (for example to receive
69 * a broadcast) that will not involve re-creating the activity and thus run its code
70 * to create a new Binder.</p>
71 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 * @see IBinder
73 */
74public class Binder implements IBinder {
75 /*
76 * Set this flag to true to detect anonymous, local or member classes
77 * that extend this Binder class and that are not static. These kind
78 * of classes can potentially create leaks.
79 */
80 private static final boolean FIND_POTENTIAL_LEAKS = false;
Jeff Sharkeyf5299f12017-03-17 10:25:07 -060081 /** @hide */
82 public static final boolean CHECK_PARCEL_SIZE = false;
Dianne Hackborn017c6a22014-09-25 17:41:34 -070083 static final String TAG = "Binder";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084
Makoto Onukif9b941f2016-03-10 17:19:08 -080085 /** @hide */
86 public static boolean LOG_RUNTIME_EXCEPTION = false; // DO NOT SUBMIT WITH TRUE
87
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -070088 /**
89 * Control whether dump() calls are allowed.
90 */
Jeff Sharkey0a17db12016-11-04 11:23:46 -060091 private static volatile String sDumpDisabled = null;
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -070092
Rahul Chaturvedi52613f92015-06-17 23:54:08 -040093 /**
94 * Global transaction tracker instance for this process.
95 */
Jeff Sharkey0a17db12016-11-04 11:23:46 -060096 private static volatile TransactionTracker sTransactionTracker = null;
Rahul Chaturvedi52613f92015-06-17 23:54:08 -040097
Hans Boehm5e5b13f2017-09-28 18:16:50 -070098 /**
99 * Guestimate of native memory associated with a Binder.
100 */
101 private static final int NATIVE_ALLOCATION_SIZE = 500;
102
103 private static native long getNativeFinalizer();
104
105 // Use a Holder to allow static initialization of Binder in the boot image, and
106 // possibly to avoid some initialization ordering issues.
107 private static class NoImagePreloadHolder {
108 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
109 Binder.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
110 }
111
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400112 // Transaction tracking code.
113
114 /**
115 * Flag indicating whether we should be tracing transact calls.
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400116 */
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600117 private static volatile boolean sTracingEnabled = false;
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400118
119 /**
120 * Enable Binder IPC tracing.
121 *
122 * @hide
123 */
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600124 public static void enableTracing() {
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400125 sTracingEnabled = true;
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600126 }
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400127
128 /**
129 * Disable Binder IPC tracing.
130 *
131 * @hide
132 */
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600133 public static void disableTracing() {
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400134 sTracingEnabled = false;
135 }
136
137 /**
138 * Check if binder transaction tracing is enabled.
139 *
140 * @hide
141 */
142 public static boolean isTracingEnabled() {
143 return sTracingEnabled;
144 }
145
146 /**
147 * Get the binder transaction tracker for this process.
148 *
149 * @hide
150 */
151 public synchronized static TransactionTracker getTransactionTracker() {
152 if (sTransactionTracker == null)
153 sTransactionTracker = new TransactionTracker();
154 return sTransactionTracker;
155 }
156
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600157 /** {@hide} */
158 static volatile boolean sWarnOnBlocking = false;
159
160 /**
161 * Warn if any blocking binder transactions are made out from this process.
162 * This is typically only useful for the system process, to prevent it from
163 * blocking on calls to external untrusted code. Instead, all outgoing calls
164 * that require a result must be sent as {@link IBinder#FLAG_ONEWAY} calls
165 * which deliver results through a callback interface.
166 *
167 * @hide
168 */
169 public static void setWarnOnBlocking(boolean warnOnBlocking) {
170 sWarnOnBlocking = warnOnBlocking;
171 }
172
173 /**
174 * Allow blocking calls on the given interface, overriding the requested
175 * value of {@link #setWarnOnBlocking(boolean)}.
176 * <p>
177 * This should only be rarely called when you are <em>absolutely sure</em>
178 * the remote interface is a built-in system component that can never be
179 * upgraded. In particular, this <em>must never</em> be called for
180 * interfaces hosted by package that could be upgraded or replaced,
181 * otherwise you risk system instability if that remote interface wedges.
182 *
183 * @hide
184 */
185 public static IBinder allowBlocking(IBinder binder) {
186 try {
187 if (binder instanceof BinderProxy) {
188 ((BinderProxy) binder).mWarnOnBlocking = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700189 } else if (binder != null && binder.getInterfaceDescriptor() != null
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600190 && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
191 Log.w(TAG, "Unable to allow blocking on interface " + binder);
192 }
193 } catch (RemoteException ignored) {
194 }
195 return binder;
196 }
197
198 /**
Jeff Sharkey59189482017-11-09 18:13:43 -0700199 * Reset the given interface back to the default blocking behavior,
200 * reverting any changes made by {@link #allowBlocking(IBinder)}.
201 *
202 * @hide
203 */
204 public static IBinder defaultBlocking(IBinder binder) {
205 if (binder instanceof BinderProxy) {
206 ((BinderProxy) binder).mWarnOnBlocking = sWarnOnBlocking;
207 }
208 return binder;
209 }
210
211 /**
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600212 * Inherit the current {@link #allowBlocking(IBinder)} value from one given
213 * interface to another.
214 *
215 * @hide
216 */
217 public static void copyAllowBlocking(IBinder fromBinder, IBinder toBinder) {
218 if (fromBinder instanceof BinderProxy && toBinder instanceof BinderProxy) {
219 ((BinderProxy) toBinder).mWarnOnBlocking = ((BinderProxy) fromBinder).mWarnOnBlocking;
220 }
221 }
222
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700223 /**
224 * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
225 */
226 private final long mObject;
227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 private IInterface mOwner;
229 private String mDescriptor;
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 /**
232 * Return the ID of the process that sent you the current transaction
233 * that is being processed. This pid can be used with higher-level
234 * system services to determine its identity and check permissions.
235 * If the current thread is not currently executing an incoming transaction,
236 * then its own pid is returned.
237 */
238 public static final native int getCallingPid();
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 /**
Dianne Hackborn74ee8652012-09-07 18:33:18 -0700241 * Return the Linux uid assigned to the process that sent you the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 * current transaction that is being processed. This uid can be used with
243 * higher-level system services to determine its identity and check
244 * permissions. If the current thread is not currently executing an
245 * incoming transaction, then its own uid is returned.
246 */
247 public static final native int getCallingUid();
Amith Yamasani742a6712011-05-04 14:49:28 -0700248
249 /**
Dianne Hackborn74ee8652012-09-07 18:33:18 -0700250 * Return the UserHandle assigned to the process that sent you the
251 * current transaction that is being processed. This is the user
252 * of the caller. It is distinct from {@link #getCallingUid()} in that a
253 * particular user will have multiple distinct apps running under it each
254 * with their own uid. If the current thread is not currently executing an
255 * incoming transaction, then its own UserHandle is returned.
256 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700257 public static final @NonNull UserHandle getCallingUserHandle() {
Fyodor Kupolov02cb6e72015-09-18 18:20:55 -0700258 return UserHandle.of(UserHandle.getUserId(getCallingUid()));
Dianne Hackborn74ee8652012-09-07 18:33:18 -0700259 }
260
261 /**
Brad Fitzpatricka0527f22010-03-25 20:40:34 -0700262 * Reset the identity of the incoming IPC on the current thread. This can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 * be useful if, while handling an incoming call, you will be calling
264 * on interfaces of other objects that may be local to your process and
265 * need to do permission checks on the calls coming into them (so they
266 * will check the permission of your own local process, and not whatever
267 * process originally called you).
Brad Fitzpatricka0527f22010-03-25 20:40:34 -0700268 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 * @return Returns an opaque token that can be used to restore the
270 * original calling identity by passing it to
271 * {@link #restoreCallingIdentity(long)}.
Brad Fitzpatricka0527f22010-03-25 20:40:34 -0700272 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 * @see #getCallingPid()
274 * @see #getCallingUid()
275 * @see #restoreCallingIdentity(long)
276 */
277 public static final native long clearCallingIdentity();
Brad Fitzpatricka0527f22010-03-25 20:40:34 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 /**
Brad Fitzpatricka0527f22010-03-25 20:40:34 -0700280 * Restore the identity of the incoming IPC on the current thread
281 * back to a previously identity that was returned by {@link
282 * #clearCallingIdentity}.
283 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 * @param token The opaque token that was previously returned by
285 * {@link #clearCallingIdentity}.
Brad Fitzpatricka0527f22010-03-25 20:40:34 -0700286 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 * @see #clearCallingIdentity
288 */
289 public static final native void restoreCallingIdentity(long token);
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700290
291 /**
Eugene Susla6a7006a2017-03-13 12:57:58 -0700292 * Convenience method for running the provided action enclosed in
293 * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity}
294 *
Eugene Suslacf00ade2017-04-10 11:51:58 -0700295 * Any exception thrown by the given action will be caught and rethrown after the call to
296 * {@link #restoreCallingIdentity}
297 *
Eugene Susla6a7006a2017-03-13 12:57:58 -0700298 * @hide
299 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700300 public static final void withCleanCallingIdentity(@NonNull ThrowingRunnable action) {
Eugene Susla6a7006a2017-03-13 12:57:58 -0700301 long callingIdentity = clearCallingIdentity();
Eugene Suslacf00ade2017-04-10 11:51:58 -0700302 Throwable throwableToPropagate = null;
Eugene Susla6a7006a2017-03-13 12:57:58 -0700303 try {
Eugene Susla2f5ee712017-06-23 17:25:24 -0700304 action.runOrThrow();
Eugene Suslacf00ade2017-04-10 11:51:58 -0700305 } catch (Throwable throwable) {
306 throwableToPropagate = throwable;
Eugene Susla6a7006a2017-03-13 12:57:58 -0700307 } finally {
308 restoreCallingIdentity(callingIdentity);
Eugene Suslacf00ade2017-04-10 11:51:58 -0700309 if (throwableToPropagate != null) {
310 throw ExceptionUtils.propagate(throwableToPropagate);
311 }
Eugene Susla6a7006a2017-03-13 12:57:58 -0700312 }
313 }
314
315 /**
316 * Convenience method for running the provided action enclosed in
317 * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity} returning the result
318 *
Eugene Suslacf00ade2017-04-10 11:51:58 -0700319 * Any exception thrown by the given action will be caught and rethrown after the call to
320 * {@link #restoreCallingIdentity}
321 *
Eugene Susla6a7006a2017-03-13 12:57:58 -0700322 * @hide
323 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700324 public static final <T> T withCleanCallingIdentity(@NonNull ThrowingSupplier<T> action) {
Eugene Susla6a7006a2017-03-13 12:57:58 -0700325 long callingIdentity = clearCallingIdentity();
Eugene Suslacf00ade2017-04-10 11:51:58 -0700326 Throwable throwableToPropagate = null;
Eugene Susla6a7006a2017-03-13 12:57:58 -0700327 try {
Eugene Susla2f5ee712017-06-23 17:25:24 -0700328 return action.getOrThrow();
Eugene Suslacf00ade2017-04-10 11:51:58 -0700329 } catch (Throwable throwable) {
330 throwableToPropagate = throwable;
331 return null; // overridden by throwing in finally block
Eugene Susla6a7006a2017-03-13 12:57:58 -0700332 } finally {
333 restoreCallingIdentity(callingIdentity);
Eugene Suslacf00ade2017-04-10 11:51:58 -0700334 if (throwableToPropagate != null) {
335 throw ExceptionUtils.propagate(throwableToPropagate);
336 }
Eugene Susla6a7006a2017-03-13 12:57:58 -0700337 }
338 }
339
340 /**
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700341 * Sets the native thread-local StrictMode policy mask.
342 *
343 * <p>The StrictMode settings are kept in two places: a Java-level
344 * threadlocal for libcore/Dalvik, and a native threadlocal (set
345 * here) for propagation via Binder calls. This is a little
346 * unfortunate, but necessary to break otherwise more unfortunate
347 * dependencies either of Dalvik on Android, or Android
348 * native-only code on Dalvik.
349 *
350 * @see StrictMode
351 * @hide
352 */
353 public static final native void setThreadStrictModePolicy(int policyMask);
354
355 /**
356 * Gets the current native thread-local StrictMode policy mask.
357 *
358 * @see #setThreadStrictModePolicy
359 * @hide
360 */
361 public static final native int getThreadStrictModePolicy();
362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 /**
364 * Flush any Binder commands pending in the current thread to the kernel
365 * driver. This can be
366 * useful to call before performing an operation that may block for a long
367 * time, to ensure that any pending object references have been released
368 * in order to prevent the process from holding on to objects longer than
369 * it needs to.
370 */
371 public static final native void flushPendingCommands();
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 /**
374 * Add the calling thread to the IPC thread pool. This function does
375 * not return until the current process is exiting.
376 */
377 public static final native void joinThreadPool();
Jeff Brown1951ce82013-04-04 22:45:12 -0700378
379 /**
380 * Returns true if the specified interface is a proxy.
381 * @hide
382 */
383 public static final boolean isProxy(IInterface iface) {
384 return iface.asBinder() != iface;
385 }
386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 /**
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700388 * Call blocks until the number of executing binder threads is less
389 * than the maximum number of binder threads allowed for this process.
Wale Ogunwale8d906342015-04-15 09:10:03 -0700390 * @hide
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700391 */
392 public static final native void blockUntilThreadAvailable();
393
394 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 * Default constructor initializes the object.
396 */
397 public Binder() {
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700398 mObject = getNativeBBinderHolder();
399 NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400
401 if (FIND_POTENTIAL_LEAKS) {
402 final Class<? extends Binder> klass = getClass();
403 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
404 (klass.getModifiers() & Modifier.STATIC) == 0) {
405 Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
406 klass.getCanonicalName());
407 }
408 }
409 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 /**
412 * Convenience method for associating a specific interface with the Binder.
413 * After calling, queryLocalInterface() will be implemented for you
414 * to return the given owner IInterface when the corresponding
415 * descriptor is requested.
416 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700417 public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 mOwner = owner;
419 mDescriptor = descriptor;
420 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 /**
423 * Default implementation returns an empty interface name.
424 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700425 public @Nullable String getInterfaceDescriptor() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 return mDescriptor;
427 }
428
429 /**
430 * Default implementation always returns true -- if you got here,
431 * the object is alive.
432 */
433 public boolean pingBinder() {
434 return true;
435 }
436
437 /**
438 * {@inheritDoc}
439 *
440 * Note that if you're calling on a local binder, this always returns true
441 * because your process is alive if you're calling it.
442 */
443 public boolean isBinderAlive() {
444 return true;
445 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 /**
448 * Use information supplied to attachInterface() to return the
449 * associated IInterface if it matches the requested
450 * descriptor.
451 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700452 public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700453 if (mDescriptor != null && mDescriptor.equals(descriptor)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 return mOwner;
455 }
456 return null;
457 }
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -0700458
459 /**
460 * Control disabling of dump calls in this process. This is used by the system
461 * process watchdog to disable incoming dump calls while it has detecting the system
462 * is hung and is reporting that back to the activity controller. This is to
463 * prevent the controller from getting hung up on bug reports at this point.
464 * @hide
465 *
466 * @param msg The message to show instead of the dump; if null, dumps are
467 * re-enabled.
468 */
469 public static void setDumpDisabled(String msg) {
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600470 sDumpDisabled = msg;
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -0700471 }
472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 /**
474 * Default implementation is a stub that returns false. You will want
475 * to override this to do the appropriate unmarshalling of transactions.
476 *
477 * <p>If you want to call this, call transact().
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700478 *
Dianne Hackborn18482ae2017-08-01 17:41:00 -0700479 * <p>Implementations that are returning a result should generally use
480 * {@link Parcel#writeNoException() Parcel.writeNoException} and
481 * {@link Parcel#writeException(Exception) Parcel.writeException} to propagate
482 * exceptions back to the caller.</p>
483 *
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700484 * @param code The action to perform. This should
485 * be a number between {@link #FIRST_CALL_TRANSACTION} and
486 * {@link #LAST_CALL_TRANSACTION}.
487 * @param data Marshalled data being received from the caller.
488 * @param reply If the caller is expecting a result back, it should be marshalled
489 * in to here.
490 * @param flags Additional operation flags. Either 0 for a normal
491 * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
492 *
493 * @return Return true on a successful call; returning false is generally used to
494 * indicate that you did not understand the transaction code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700496 protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 int flags) throws RemoteException {
498 if (code == INTERFACE_TRANSACTION) {
499 reply.writeString(getInterfaceDescriptor());
500 return true;
501 } else if (code == DUMP_TRANSACTION) {
502 ParcelFileDescriptor fd = data.readFileDescriptor();
503 String[] args = data.readStringArray();
504 if (fd != null) {
505 try {
506 dump(fd.getFileDescriptor(), args);
507 } finally {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700508 IoUtils.closeQuietly(fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 }
510 }
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -0700511 // Write the StrictMode header.
512 if (reply != null) {
513 reply.writeNoException();
514 } else {
515 StrictMode.clearGatheredViolations();
516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 return true;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700518 } else if (code == SHELL_COMMAND_TRANSACTION) {
519 ParcelFileDescriptor in = data.readFileDescriptor();
520 ParcelFileDescriptor out = data.readFileDescriptor();
521 ParcelFileDescriptor err = data.readFileDescriptor();
522 String[] args = data.readStringArray();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700523 ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700524 ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
525 try {
526 if (out != null) {
527 shellCommand(in != null ? in.getFileDescriptor() : null,
528 out.getFileDescriptor(),
529 err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
Dianne Hackborn354736e2016-08-22 17:00:05 -0700530 args, shellCallback, resultReceiver);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700531 }
532 } finally {
533 IoUtils.closeQuietly(in);
534 IoUtils.closeQuietly(out);
535 IoUtils.closeQuietly(err);
536 // Write the StrictMode header.
537 if (reply != null) {
538 reply.writeNoException();
539 } else {
540 StrictMode.clearGatheredViolations();
541 }
542 }
543 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 }
545 return false;
546 }
547
548 /**
549 * Implemented to call the more convenient version
550 * {@link #dump(FileDescriptor, PrintWriter, String[])}.
551 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700552 public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 FileOutputStream fout = new FileOutputStream(fd);
Dianne Hackborndb4e33f2013-04-01 17:28:16 -0700554 PrintWriter pw = new FastPrintWriter(fout);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 try {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700556 doDump(fd, pw, args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 } finally {
558 pw.flush();
559 }
560 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700561
562 void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600563 final String disabled = sDumpDisabled;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700564 if (disabled == null) {
565 try {
566 dump(fd, pw, args);
567 } catch (SecurityException e) {
568 pw.println("Security exception: " + e.getMessage());
569 throw e;
570 } catch (Throwable e) {
571 // Unlike usual calls, in this case if an exception gets thrown
572 // back to us we want to print it back in to the dump data, since
573 // that is where the caller expects all interesting information to
574 // go.
575 pw.println();
576 pw.println("Exception occurred while dumping:");
577 e.printStackTrace(pw);
578 }
579 } else {
580 pw.println(sDumpDisabled);
581 }
582 }
583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 /**
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700585 * Like {@link #dump(FileDescriptor, String[])}, but ensures the target
586 * executes asynchronously.
587 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700588 public void dumpAsync(@NonNull final FileDescriptor fd, @Nullable final String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700589 final FileOutputStream fout = new FileOutputStream(fd);
Dianne Hackborndb4e33f2013-04-01 17:28:16 -0700590 final PrintWriter pw = new FastPrintWriter(fout);
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700591 Thread thr = new Thread("Binder.dumpAsync") {
592 public void run() {
593 try {
594 dump(fd, pw, args);
595 } finally {
596 pw.flush();
597 }
598 }
599 };
600 thr.start();
601 }
602
603 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 * Print the object's state into the given stream.
605 *
606 * @param fd The raw file descriptor that the dump is being sent to.
607 * @param fout The file to which you should dump your state. This will be
608 * closed for you after you return.
609 * @param args additional arguments to the dump request.
610 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700611 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
612 @Nullable String[] args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 }
614
615 /**
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700616 * @param in The raw file descriptor that an input data stream can be read from.
617 * @param out The raw file descriptor that normal command messages should be written to.
618 * @param err The raw file descriptor that command error messages should be written to.
619 * @param args Command-line arguments.
Dianne Hackborn354736e2016-08-22 17:00:05 -0700620 * @param callback Callback through which to interact with the invoking shell.
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700621 * @param resultReceiver Called when the command has finished executing, with the result code.
622 * @throws RemoteException
623 * @hide
624 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700625 public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
626 @Nullable FileDescriptor err,
627 @NonNull String[] args, @Nullable ShellCallback callback,
628 @NonNull ResultReceiver resultReceiver) throws RemoteException {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700629 onShellCommand(in, out, err, args, callback, resultReceiver);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700630 }
631
632 /**
633 * Handle a call to {@link #shellCommand}. The default implementation simply prints
634 * an error message. Override and replace with your own.
Dianne Hackborn2e931f52016-01-28 12:21:17 -0800635 * <p class="caution">Note: no permission checking is done before calling this method; you must
636 * apply any security checks as appropriate for the command being executed.
637 * Consider using {@link ShellCommand} to help in the implementation.</p>
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700638 * @hide
639 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700640 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
641 @Nullable FileDescriptor err,
642 @NonNull String[] args, @Nullable ShellCallback callback,
643 @NonNull ResultReceiver resultReceiver) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700644 FileOutputStream fout = new FileOutputStream(err != null ? err : out);
645 PrintWriter pw = new FastPrintWriter(fout);
646 pw.println("No shell command implementation.");
647 pw.flush();
648 resultReceiver.send(0, null);
649 }
650
651 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 * Default implementation rewinds the parcels and calls onTransact. On
653 * the remote side, transact calls into the binder to do the IPC.
654 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700655 public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 int flags) throws RemoteException {
Joe Onorato43a17652011-04-06 19:22:23 -0700657 if (false) Log.v("Binder", "Transact: " + code + " to " + this);
Rahul Chaturvedi52613f92015-06-17 23:54:08 -0400658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 if (data != null) {
660 data.setDataPosition(0);
661 }
662 boolean r = onTransact(code, data, reply, flags);
663 if (reply != null) {
664 reply.setDataPosition(0);
665 }
666 return r;
667 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669 /**
670 * Local implementation is a no-op.
671 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700672 public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 }
674
675 /**
676 * Local implementation is a no-op.
677 */
Dianne Hackborn4cd650c2017-07-31 17:38:53 -0700678 public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679 return true;
680 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700681
Dianne Hackbornfad079d2014-09-26 15:46:24 -0700682 static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700683 if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
Dianne Hackborn017c6a22014-09-25 17:41:34 -0700684 // Trying to send > 800k, this is way too much
Dianne Hackbornfad079d2014-09-26 15:46:24 -0700685 StringBuilder sb = new StringBuilder();
686 sb.append(msg);
687 sb.append(": on ");
688 sb.append(obj);
689 sb.append(" calling ");
690 sb.append(code);
691 sb.append(" size ");
692 sb.append(parcel.dataSize());
693 sb.append(" (data: ");
694 parcel.setDataPosition(0);
695 sb.append(parcel.readInt());
696 sb.append(", ");
697 sb.append(parcel.readInt());
698 sb.append(", ");
699 sb.append(parcel.readInt());
700 sb.append(")");
701 Slog.wtfStack(TAG, sb.toString());
Dianne Hackborn017c6a22014-09-25 17:41:34 -0700702 }
703 }
704
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700705 private static native long getNativeBBinderHolder();
706 private static native long getFinalizer();
Brad Fitzpatrick5b747192010-07-12 11:05:38 -0700707
708 // Entry point from android_util_Binder.cpp's onTransact
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000709 private boolean execTransact(int code, long dataObj, long replyObj,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 int flags) {
711 Parcel data = Parcel.obtain(dataObj);
712 Parcel reply = Parcel.obtain(replyObj);
713 // theoretically, we should call transact, which will call onTransact,
714 // but all that does is rewind it, and we just got these from an IPC,
715 // so we'll just call it directly.
716 boolean res;
Igor Murashkin7eb6cfe2013-08-16 14:07:11 -0700717 // Log any exceptions as warnings, don't silently suppress them.
718 // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
Jorim Jaggi25ee0bc2016-11-01 16:17:22 -0700719 final boolean tracingEnabled = Binder.isTracingEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 try {
Jorim Jaggi25ee0bc2016-11-01 16:17:22 -0700721 if (tracingEnabled) {
722 Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 res = onTransact(code, data, reply, flags);
Makoto Onukif9b941f2016-03-10 17:19:08 -0800725 } catch (RemoteException|RuntimeException e) {
726 if (LOG_RUNTIME_EXCEPTION) {
Igor Murashkin7eb6cfe2013-08-16 14:07:11 -0700727 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
Makoto Onukif9b941f2016-03-10 17:19:08 -0800728 }
729 if ((flags & FLAG_ONEWAY) != 0) {
730 if (e instanceof RemoteException) {
731 Log.w(TAG, "Binder call failed.", e);
732 } else {
733 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
734 }
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700735 } else {
736 reply.setDataPosition(0);
737 reply.writeException(e);
Igor Murashkin7eb6cfe2013-08-16 14:07:11 -0700738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 res = true;
Jorim Jaggi25ee0bc2016-11-01 16:17:22 -0700740 } finally {
741 if (tracingEnabled) {
742 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 }
Dianne Hackbornfad079d2014-09-26 15:46:24 -0700745 checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 reply.recycle();
747 data.recycle();
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700748
749 // Just in case -- we are done with the IPC, so there should be no more strict
750 // mode violations that have gathered for this thread. Either they have been
751 // parceled and are now in transport off to the caller, or we are returning back
752 // to the main transaction loop to wait for another incoming transaction. Either
753 // way, strict mode begone!
754 StrictMode.clearGatheredViolations();
755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 return res;
757 }
758}
759
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700760/**
761 * Java proxy for a native IBinder object.
762 * Allocated and constructed by the native javaObjectforIBinder function. Never allocated
763 * directly from Java code.
764 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765final class BinderProxy implements IBinder {
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700766 // See android_util_Binder.cpp for the native half of this.
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700767
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600768 // Assume the process-wide default value when created
769 volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking;
770
Hans Boehm29f388f2017-10-03 18:01:20 -0700771 /*
772 * Map from longs to BinderProxy, retaining only a WeakReference to the BinderProxies.
773 * We roll our own only because we need to lazily remove WeakReferences during accesses
774 * to avoid accumulating junk WeakReference objects. WeakHashMap isn't easily usable
775 * because we want weak values, not keys.
776 * Our hash table is never resized, but the number of entries is unlimited;
777 * performance degrades as occupancy increases significantly past MAIN_INDEX_SIZE.
778 * Not thread-safe. Client ensures there's a single access at a time.
779 */
780 private static final class ProxyMap {
781 private static final int LOG_MAIN_INDEX_SIZE = 8;
782 private static final int MAIN_INDEX_SIZE = 1 << LOG_MAIN_INDEX_SIZE;
783 private static final int MAIN_INDEX_MASK = MAIN_INDEX_SIZE - 1;
Hans Boehmc79595f2017-11-03 15:56:59 -0700784 // Debuggable builds will throw an AssertionError if the number of map entries exceeds:
785 private static final int CRASH_AT_SIZE = 5_000;
Hans Boehm29f388f2017-10-03 18:01:20 -0700786
787 /**
788 * We next warn when we exceed this bucket size.
789 */
790 private int mWarnBucketSize = 20;
791
792 /**
793 * Increment mWarnBucketSize by WARN_INCREMENT each time we warn.
794 */
795 private static final int WARN_INCREMENT = 10;
796
797 /**
798 * Hash function tailored to native pointers.
799 * Returns a value < MAIN_INDEX_SIZE.
800 */
801 private static int hash(long arg) {
802 return ((int) ((arg >> 2) ^ (arg >> (2 + LOG_MAIN_INDEX_SIZE)))) & MAIN_INDEX_MASK;
803 }
804
805 /**
806 * Return the total number of pairs in the map.
807 */
Hans Boehmd2fb7df2018-01-02 17:36:27 -0800808 private int size() {
Hans Boehm29f388f2017-10-03 18:01:20 -0700809 int size = 0;
810 for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
811 if (a != null) {
812 size += a.size();
813 }
814 }
815 return size;
816 }
817
818 /**
Hans Boehmd2fb7df2018-01-02 17:36:27 -0800819 * Return the total number of pairs in the map containing values that have
820 * not been cleared. More expensive than the above size function.
821 */
822 private int unclearedSize() {
823 int size = 0;
824 for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
825 if (a != null) {
826 for (WeakReference<BinderProxy> ref : a) {
827 if (ref.get() != null) {
828 ++size;
829 }
830 }
831 }
832 }
833 return size;
834 }
835
836 /**
Hans Boehm29f388f2017-10-03 18:01:20 -0700837 * Remove ith entry from the hash bucket indicated by hash.
838 */
839 private void remove(int hash, int index) {
840 Long[] keyArray = mMainIndexKeys[hash];
841 ArrayList<WeakReference<BinderProxy>> valueArray = mMainIndexValues[hash];
842 int size = valueArray.size(); // KeyArray may have extra elements.
843 // Move last entry into empty slot, and truncate at end.
844 if (index != size - 1) {
845 keyArray[index] = keyArray[size - 1];
846 valueArray.set(index, valueArray.get(size - 1));
847 }
848 valueArray.remove(size - 1);
849 // Just leave key array entry; it's unused. We only trust the valueArray size.
850 }
851
852 /**
853 * Look up the supplied key. If we have a non-cleared entry for it, return it.
854 */
855 BinderProxy get(long key) {
856 int myHash = hash(key);
857 Long[] keyArray = mMainIndexKeys[myHash];
858 if (keyArray == null) {
859 return null;
860 }
861 ArrayList<WeakReference<BinderProxy>> valueArray = mMainIndexValues[myHash];
862 int bucketSize = valueArray.size();
863 for (int i = 0; i < bucketSize; ++i) {
864 long foundKey = keyArray[i];
865 if (key == foundKey) {
866 WeakReference<BinderProxy> wr = valueArray.get(i);
867 BinderProxy bp = wr.get();
868 if (bp != null) {
869 return bp;
870 } else {
871 remove(myHash, i);
872 return null;
873 }
874 }
875 }
876 return null;
877 }
878
879 private int mRandom; // A counter used to generate a "random" index. World's 2nd worst RNG.
880
881 /**
882 * Add the key-value pair to the map.
883 * Requires that the indicated key is not already in the map.
884 */
885 void set(long key, @NonNull BinderProxy value) {
886 int myHash = hash(key);
887 ArrayList<WeakReference<BinderProxy>> valueArray = mMainIndexValues[myHash];
888 if (valueArray == null) {
889 valueArray = mMainIndexValues[myHash] = new ArrayList<>();
890 mMainIndexKeys[myHash] = new Long[1];
891 }
892 int size = valueArray.size();
893 WeakReference<BinderProxy> newWr = new WeakReference<>(value);
894 // First look for a cleared reference.
895 // This ensures that ArrayList size is bounded by the maximum occupancy of
896 // that bucket.
897 for (int i = 0; i < size; ++i) {
898 if (valueArray.get(i).get() == null) {
899 valueArray.set(i, newWr);
900 Long[] keyArray = mMainIndexKeys[myHash];
901 keyArray[i] = key;
902 if (i < size - 1) {
903 // "Randomly" check one of the remaining entries in [i+1, size), so that
904 // needlessly long buckets are eventually pruned.
905 int rnd = Math.floorMod(++mRandom, size - (i + 1));
906 if (valueArray.get(i + 1 + rnd).get() == null) {
907 remove(myHash, i + 1 + rnd);
908 }
909 }
910 return;
911 }
912 }
913 valueArray.add(size, newWr);
914 Long[] keyArray = mMainIndexKeys[myHash];
915 if (keyArray.length == size) {
916 // size >= 1, since we initially allocated one element
917 Long[] newArray = new Long[size + size / 2 + 2];
918 System.arraycopy(keyArray, 0, newArray, 0, size);
919 newArray[size] = key;
920 mMainIndexKeys[myHash] = newArray;
921 } else {
922 keyArray[size] = key;
923 }
924 if (size >= mWarnBucketSize) {
Andreas Gampe3fc030f2017-12-27 09:30:45 -0800925 final int totalSize = size();
Hans Boehm29f388f2017-10-03 18:01:20 -0700926 Log.v(Binder.TAG, "BinderProxy map growth! bucket size = " + size
Andreas Gampe3fc030f2017-12-27 09:30:45 -0800927 + " total = " + totalSize);
Hans Boehm29f388f2017-10-03 18:01:20 -0700928 mWarnBucketSize += WARN_INCREMENT;
Hans Boehmd2fb7df2018-01-02 17:36:27 -0800929 if (Build.IS_DEBUGGABLE && totalSize >= CRASH_AT_SIZE) {
930 // Use the number of uncleared entries to determine whether we should
931 // really report a histogram and crash. We don't want to fundamentally
932 // change behavior for a debuggable process, so we GC only if we are
933 // about to crash.
934 final int totalUnclearedSize = unclearedSize();
935 if (totalUnclearedSize >= CRASH_AT_SIZE) {
936 dumpProxyInterfaceCounts();
937 Runtime.getRuntime().gc();
938 throw new AssertionError("Binder ProxyMap has too many entries: "
939 + totalSize + " (total), " + totalUnclearedSize + " (uncleared), "
940 + unclearedSize() + " (uncleared after GC). BinderProxy leak?");
941 } else if (totalSize > 3 * totalUnclearedSize / 2) {
942 Log.v(Binder.TAG, "BinderProxy map has many cleared entries: "
943 + (totalSize - totalUnclearedSize) + " of " + totalSize
944 + " are cleared");
945 }
Hans Boehmc79595f2017-11-03 15:56:59 -0700946 }
Hans Boehm29f388f2017-10-03 18:01:20 -0700947 }
948 }
949
Andreas Gampe3fc030f2017-12-27 09:30:45 -0800950 /**
Hans Boehmd2fb7df2018-01-02 17:36:27 -0800951 * Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps.
Andreas Gampe3fc030f2017-12-27 09:30:45 -0800952 */
Hans Boehmd2fb7df2018-01-02 17:36:27 -0800953 private void dumpProxyInterfaceCounts() {
Andreas Gampe3fc030f2017-12-27 09:30:45 -0800954 Map<String, Integer> counts = new HashMap<>();
955 for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
956 if (a != null) {
957 for (WeakReference<BinderProxy> weakRef : a) {
958 BinderProxy bp = weakRef.get();
959 String key;
960 if (bp == null) {
961 key = "<cleared weak-ref>";
962 } else {
963 try {
964 key = bp.getInterfaceDescriptor();
965 } catch (Throwable t) {
966 key = "<exception during getDescriptor>";
967 }
968 }
969 Integer i = counts.get(key);
970 if (i == null) {
971 counts.put(key, 1);
972 } else {
973 counts.put(key, i + 1);
974 }
975 }
976 }
977 }
978 Map.Entry<String, Integer>[] sorted = counts.entrySet().toArray(
979 new Map.Entry[counts.size()]);
980 Arrays.sort(sorted, (Map.Entry<String, Integer> a, Map.Entry<String, Integer> b)
981 -> b.getValue().compareTo(a.getValue()));
982 Log.v(Binder.TAG, "BinderProxy descriptor histogram (top ten):");
983 int printLength = Math.min(10, sorted.length);
984 for (int i = 0; i < printLength; i++) {
985 Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i].getKey() + " x"
986 + sorted[i].getValue());
987 }
Andreas Gampe3fc030f2017-12-27 09:30:45 -0800988 }
989
Hans Boehm29f388f2017-10-03 18:01:20 -0700990 // Corresponding ArrayLists in the following two arrays always have the same size.
991 // They contain no empty entries. However WeakReferences in the values ArrayLists
992 // may have been cleared.
993
994 // mMainIndexKeys[i][j] corresponds to mMainIndexValues[i].get(j) .
995 // The values ArrayList has the proper size(), the corresponding keys array
996 // is always at least the same size, but may be larger.
997 // If either a particular keys array, or the corresponding values ArrayList
998 // are null, then they both are.
999 private final Long[][] mMainIndexKeys = new Long[MAIN_INDEX_SIZE][];
1000 private final ArrayList<WeakReference<BinderProxy>>[] mMainIndexValues =
1001 new ArrayList[MAIN_INDEX_SIZE];
1002 }
1003
1004 private static ProxyMap sProxyMap = new ProxyMap();
1005
1006 /**
1007 * Return a BinderProxy for IBinder.
1008 * This method is thread-hostile! The (native) caller serializes getInstance() calls using
1009 * gProxyLock.
1010 * If we previously returned a BinderProxy bp for the same iBinder, and bp is still
1011 * in use, then we return the same bp.
1012 *
1013 * @param nativeData C++ pointer to (possibly still empty) BinderProxyNativeData.
1014 * Takes ownership of nativeData iff <result>.mNativeData == nativeData. Caller will usually
1015 * delete nativeData if that's not the case.
1016 * @param iBinder C++ pointer to IBinder. Does not take ownership of referenced object.
1017 */
1018 private static BinderProxy getInstance(long nativeData, long iBinder) {
1019 BinderProxy result = sProxyMap.get(iBinder);
1020 if (result == null) {
1021 result = new BinderProxy(nativeData);
1022 sProxyMap.set(iBinder, result);
1023 }
1024 return result;
1025 }
1026
1027 private BinderProxy(long nativeData) {
1028 mNativeData = nativeData;
1029 NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeData);
1030 }
1031
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001032 /**
1033 * Guestimate of native memory associated with a BinderProxy.
1034 * This includes the underlying IBinder, associated DeathRecipientList, and KeyedVector
1035 * that points back to us. We guess high since it includes a GlobalRef, which
1036 * may be in short supply.
1037 */
1038 private static final int NATIVE_ALLOCATION_SIZE = 1000;
1039
1040 // Use a Holder to allow static initialization of BinderProxy in the boot image, and
1041 // to avoid some initialization ordering issues.
1042 private static class NoImagePreloadHolder {
1043 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
1044 BinderProxy.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
1045 }
1046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001047 public native boolean pingBinder();
1048 public native boolean isBinderAlive();
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 public IInterface queryLocalInterface(String descriptor) {
1051 return null;
1052 }
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001053
1054 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Dianne Hackbornfad079d2014-09-26 15:46:24 -07001055 Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001056
1057 if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
1058 // For now, avoid spamming the log by disabling after we've logged
1059 // about this interface at least once
1060 mWarnOnBlocking = false;
1061 Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
1062 new Throwable());
1063 }
1064
Jorim Jaggi25ee0bc2016-11-01 16:17:22 -07001065 final boolean tracingEnabled = Binder.isTracingEnabled();
1066 if (tracingEnabled) {
1067 final Throwable tr = new Throwable();
1068 Binder.getTransactionTracker().addTrace(tr);
1069 StackTraceElement stackTraceElement = tr.getStackTrace()[1];
1070 Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
1071 stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
1072 }
1073 try {
1074 return transactNative(code, data, reply, flags);
1075 } finally {
1076 if (tracingEnabled) {
1077 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
1078 }
1079 }
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001080 }
1081
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001082 private static native long getNativeFinalizer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 public native String getInterfaceDescriptor() throws RemoteException;
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001084 public native boolean transactNative(int code, Parcel data, Parcel reply,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 int flags) throws RemoteException;
1086 public native void linkToDeath(DeathRecipient recipient, int flags)
1087 throws RemoteException;
1088 public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
1089
1090 public void dump(FileDescriptor fd, String[] args) throws RemoteException {
1091 Parcel data = Parcel.obtain();
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -07001092 Parcel reply = Parcel.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 data.writeFileDescriptor(fd);
1094 data.writeStringArray(args);
1095 try {
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -07001096 transact(DUMP_TRANSACTION, data, reply, 0);
1097 reply.readException();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 } finally {
1099 data.recycle();
Brad Fitzpatrickeb75888e2010-07-26 17:47:45 -07001100 reply.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 }
1102 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -07001103
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001104 public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
1105 Parcel data = Parcel.obtain();
1106 Parcel reply = Parcel.obtain();
1107 data.writeFileDescriptor(fd);
1108 data.writeStringArray(args);
1109 try {
1110 transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001111 } finally {
1112 data.recycle();
1113 reply.recycle();
1114 }
1115 }
1116
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001117 public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
Dianne Hackborn354736e2016-08-22 17:00:05 -07001118 String[] args, ShellCallback callback,
1119 ResultReceiver resultReceiver) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001120 Parcel data = Parcel.obtain();
1121 Parcel reply = Parcel.obtain();
1122 data.writeFileDescriptor(in);
1123 data.writeFileDescriptor(out);
1124 data.writeFileDescriptor(err);
1125 data.writeStringArray(args);
Dianne Hackborn354736e2016-08-22 17:00:05 -07001126 ShellCallback.writeToParcel(callback, data);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001127 resultReceiver.writeToParcel(data, 0);
1128 try {
1129 transact(SHELL_COMMAND_TRANSACTION, data, reply, 0);
1130 reply.readException();
1131 } finally {
1132 data.recycle();
1133 reply.recycle();
1134 }
1135 }
1136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 private static final void sendDeathNotice(DeathRecipient recipient) {
Joe Onorato43a17652011-04-06 19:22:23 -07001138 if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 try {
1140 recipient.binderDied();
1141 }
1142 catch (RuntimeException exc) {
1143 Log.w("BinderNative", "Uncaught exception from death notification",
1144 exc);
1145 }
1146 }
Hans Boehmeb6d62c2017-09-20 15:59:12 -07001147
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001148 /**
1149 * C++ pointer to BinderProxyNativeData. That consists of strong pointers to the
1150 * native IBinder object, and a DeathRecipientList.
1151 */
1152 private final long mNativeData;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153}