I have a class extending android.os.Handler
. An instance of this handler is passed to the constructor of a Messenger
. The Messenger
's IBinder
from getBinder
is passed as the result of onBind
events in my service. Messages sent via the binder from remote applications do go to the handler's handleMessage
method, however calls to Binder.getCallingUid
and Binder.getCallingPid
within handleMessage
always return the uid and pid of the service's process (which is definitely not the same process as the remote application). handleMessage
is definitely part of an IPC transaction, isn't it? So where have I gone wrong? I need this to work for authentication of connecting applications.
Thanks in advance.
Edit
OK. I have this horrible feeling that handleMessage
is not part of the IPC transaction, because that happens in separate threads for AIDL which puts messages in a queue for the Messenger
. Is there any other way of getting the User ID and Process ID of the caller?
Make a custom Handler
class and override sendMessageAtTime
(this is the only overridable posting method in the Handler
class ), and then use it to create a Messenger
returned from onBind
.
In the sendMessageAtTime
method, you can get the pid/uid of the calling remote application by getCallingPid
and getCallingUid
.
But, in IPC using Messenger
, as opposed to using AIDL, getCallingPid
will always return 0 because the message sending by remote apps is asynchronous; transactions with IBinder.FLAG_ONEWAY
.
Therefore the uid is the only information available.
I have come up with what I feel is quite a neat way to fix this. All messages that come through IPC get reconstructed from a parcel using Message.CREATOR.createFromParcel
. So I have created a Java Dynamic Proxy Class (code pulled straight from the docs) that detects calls to createFromParcel
and adds the process id and user id as additional items in the message's bundle before returning the result. The message is guaranteed to be created within a transaction, looking at the source for Messenger
, so the IDs are correct. I then use reflection to replace the static final variable Message.CREATOR
with a proxy of itself. IDs are then pulled out of messages later outside of transactions when authentication is required.
So far this is working exactly as intended.
Previously I was trying to create an alternative version of Messenger
, and using reflection to access IMessenger
, but even Messenger
does not handle Message
s before transactions end. A proxy is a lot less work and less prone to errors involved in casting different implementations of IMessenger
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With