7

I have a question regarding Android's binder. If I understood correctly, a Binder can be passed between processes. On the service side, there is a Binder object (the original object). On the client side (in separate process), there is a BinderProxy object which handles the AIDL data marshalling.

My question is - how do you check if two BinderProxy objects are equal? By equal I mean, they refer to the same Binder object in the service process. Can we use the equals() method? Do BinderProxy objects have the same memory address as the original Binder objects?

Thanks!

Edit:

In response to David Wasser's comment:

The reason why I need to do this is little complicated to explain, but let me see if I can explain it clearly --

The remote service offers an AIDL API (which the client gets by receiving the IBinder in the onServiceConnected). The AIDL API, among other things, contains two methods --

IBinder getInterface ( String interfaceName );

void releaseInterface ( IBinder binder );

The idea is that the client applications can request the remote service for binders for different interfaces. The interface implementations' dex code and their binders are loaded into the service dynamically, and not known beforehand. The service provides these 2 AIDL methods for the client apps to access those dynamically loaded interfaces' binders, based on the interface name.

So say there is App1 and App2. Each does 'binder1 = getInterface( "SomeInterface1" );' and gets a binder for that dynamically loaded interface 'SomeInterface1'. After using it, the apps release the interface binder by saying 'releaseInterface( binder1 );' so that the service can unload the interface's dex code and do some cleanup.

However, the interface dex code cannot be unloaded unless both App1 and App2 have released the interface binder. So, in the service, I maintain a reference count for each dynamically loaded binder. (Say a Map key{Binder} ==> value{reference count}). When an App does getInterface(), I increase the reference count. When it does releaseInterface(binder1), I should decrease the reference count. But, to do so, I need to check the whether binder1 is equal to the binder keys in the Map.

Note that the binder has been passed from service (original binder object) to the client app (a binder proxy returned by getInterface()) and back again to the service (as a parameter of releaseInterface() - is it still a proxy, or the original??).

It is possible for App1 and App2 to get different binder objects (different implementations of an interface) for the same interface name. That's why, I use the binder for releasing.

Hope this wasn't too confusing! Thanks for the help.

Kartik

Onik
  • 19,396
  • 14
  • 68
  • 91
Kartik Sankaran
  • 290
  • 3
  • 11
  • For sure the BinderProxy object has a different memory address from the original Binder object. The `equals()` method isn't overriden in BinderProxy so I would assume that you can't use that for comparison. What is it you want to do? Maybe there's another way to solve this. – David Wasser Jul 13 '12 at 09:42
  • Thanks for the quick response! I have edited my question to include the reason for checking two binders are equal. – Kartik Sankaran Jul 13 '12 at 16:03
  • I read your additional comments. Off top of my head, I would assume that sinc you are doing this comparison in the service, that you will have the same Binder objects because the proxy objects are in the other processes. So you should be able to use `equals()`. However, to be sure, why don't you just cobble together a small test program that does exactly what you've described. This should be easy to do and will give you a definitive answer. I always prefer seeing something with my own eyes rather than taking someone elses' word for it ;-) Empirical evidence is the best evidence! – David Wasser Jul 15 '12 at 08:20
  • Yes, I think you are right about that. Let me try using equals(). If it doesn't work, I may solve this problem in another way: Give a cookie value to each App, and ask them to specify the cookie value while releasing the binder. But hope that equals() does the job. Thanks for the help! – Kartik Sankaran Jul 15 '12 at 12:04

2 Answers2

11

The binder proxy object has a asBinder() method that returns the underlying IBinder object that can be used to check for underlying equality of between Binder Proxies.

I'm not familiar with the mechanism, but I see that this method is used inside the LocationManagerService.java file within the Android source code to register/unregister ILocationListener objects.

6b72
  • 126
  • 1
  • 3
  • I had tried this method in my code, and so far it seems to work correctly. Thanks for the answer, marking this as correct :) – Kartik Sankaran Jun 04 '13 at 10:27
  • > ... can be used to check for underlying equality between Binder Proxies. How? `if (binder1 == binder2)`? Other? – badfd May 08 '21 at 15:17
0

As far as I can tell, there is not easy solution for this. BinderProxy is a final class inside of android.os.Binder. You can find the source here. One solution might be to create your own class that extends Binder and create your own implementation to either store an instance of the Binder in the BinderProxy or the other way around. Its hard because neither class has a direct reference to the other. Sorry if I am misunderstanding your question or am just way off here.

Joel
  • 4,732
  • 9
  • 39
  • 54