From d2c86ab546309f74dc8464a41e54814f865648a0 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Tue, 17 Jul 2018 16:30:40 +0200 Subject: [PATCH] Encourage creating Binder tokens with a descriptor. Binder tokens (Binder objects without an attached interface) are used a lot with Android. These tokens don't have an interface descriptor, which means that proxies (references) to these tokens are impossible to identify when looking at a heap dump. To make that easier, introduce a new constructor for Binder that allows the caller to specify a descriptor. Bug: 109888955 Test: builds, boots Change-Id: I18fd00483abc29edf87f84945323a10fe4f6cd42 --- api/current.txt | 1 + core/java/android/os/Binder.java | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/api/current.txt b/api/current.txt index e3db2566af481..95a3058a20466 100644 --- a/api/current.txt +++ b/api/current.txt @@ -32167,6 +32167,7 @@ package android.os { public class Binder implements android.os.IBinder { ctor public Binder(); + ctor public Binder(java.lang.String); method public void attachInterface(android.os.IInterface, java.lang.String); method public static final long clearCallingIdentity(); method public void dump(java.io.FileDescriptor, java.lang.String[]); diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 175b40513a010..3723d06f9f19b 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -391,9 +391,28 @@ public class Binder implements IBinder { public static final native void blockUntilThreadAvailable(); /** - * Default constructor initializes the object. + * Default constructor just initializes the object. + * + * If you're creating a Binder token (a Binder object without an attached interface), + * you should use {@link #Binder(String)} instead. */ public Binder() { + this(null); + } + + /** + * Constructor for creating a raw Binder object (token) along with a descriptor. + * + * The descriptor of binder objects usually specifies the interface they are implementing. + * In case of binder tokens, no interface is implemented, and the descriptor can be used + * as a sort of tag to help identify the binder token. This will help identify remote + * references to these objects more easily when debugging. + * + * @param descriptor Used to identify the creator of this token, for example the class name. + * Instead of creating multiple tokens with the same descriptor, consider adding a suffix to + * help identify them. + */ + public Binder(@Nullable String descriptor) { mObject = getNativeBBinderHolder(); NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject); @@ -405,6 +424,7 @@ public class Binder implements IBinder { klass.getCanonicalName()); } } + mDescriptor = descriptor; } /**