Kartik Sankaran
Kartik Sankaran

Reputation: 290

How to check if two Android binder proxy objects are equal?

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

Upvotes: 7

Views: 3826

Answers (2)

6b72
6b72

Reputation: 126

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.

Upvotes: 11

Joel
Joel

Reputation: 4762

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.

Upvotes: 0

Related Questions