前言
ServiceManager是Binder机制的大管家,管理着android系统的各种Service。service向servicemanager注册,当client需要调用service时,先通过servicemanager查询到该service,client接着再与service通信。这些service有java层的,也有native层的。native层通过BpServiceManager/BnServiceManager实现的service与servicemanager的交互。这次打算聊一聊servicemanager管理java层service是如何实现的。
正文
IServiceManager接口
同native层类似,java层,aidl脚本依据IServiceManager.aidl生成IServiceManager接口类,包含子类IServiceManager.Stub和IServiceManager.Stub.Proxy,两者都实现了IServiceManager接口,前者代表server端,后者代表client端。
代码语言:txt复制 public interface IServiceManager extends android.os.IInterface
{
public static abstract class Stub extends android.os.Binder implements android.os.IServiceManager
{
public static android.os.IServiceManager asInterface(android.os.IBinder obj)
{
if (obj == null){
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IServiceManager){
return (IServiceManager)iin;
}
return new IServiceManager.Stub.Proxy(obj);
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException
{
String descriptor = DESCRIPTOR;
...
switch (code){
case TRANSACTION_getService:
{
String _arg0;
_arg0 = data.readString();
data.enforceNoDataAvail();
IBinder _result = getService(_agr0);
reply.writeNoException();
reply.writeStrongBinder(_result);
break;
}
...
}
}
}
private static class Proxy implements IServiceManager
{
private IBinder mRemote;
Proxy(IBinder remote){
mRemote = remote;
}
@Override
public IBinder getService(String name) throws RemoteException
{
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
IBinder _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(name);
boolean _status = mRemote.transact(Stub.TRANSACTION_getService, _data, _reply, 0);
_reply.readException();
_result = _reply.readStrongBinder();
}finally{
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public IBinder checkService(String name) throws RemoteException
{
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
IBinder _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(name);
boolean _status = mRemote.transact(Stub.TRANSACTION_checkService, _data, _reply, 0);
_reply.readException();
_result = _reply.readStrongBinder();
}finally{
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}
client端->servicemanager的方式
java层使用ServiceManager类实现servicemanager的client端,通过getIServiceManager()获取servicemanager的代理类,其中BinderInternal.getContextObject()通过jni创建一个BinderProxy对象。
这里BinderProxy本来就是java类,为什么要通过jni创建呢?目的是创建BinderPrxoy对象的同时,也创建一个BpBinder对象,BinderProxy和BpBinder是一一对应的关系;同理,创建java层Binder对象时,也会通过jni创建一个BBinder对象。我们可以理解为BinderProxy/Binder封装了BpBinder/BBinder,实际工作的是后者。
代码语言:java复制public final class ServiceManager {
private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager(){
if (SServiceManager != null){
return sServiceManager;
}
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocing(BinderInternal.getContextObject()));
return sServiceManager;
}
public static IBinder getService(String name){
try {
IBinder service = sCache.get(name);
if (service != null){
return service;
} else {
return Binder.allowBlocking(rawGetServices(name));
}
} catch (RemoteException e){
...
}
return null;
}
private static IBinder rawGetService(String name) throws RemoteException {
final IBinder binder = getIServiceManager().getService(name);
...
return binder;
}
}
此时,获取到的servicemanager的代理类IServiceManagerProxy(BinderProxy)。
代码语言:java复制public final class ServiceManagerNative {
private ServiceManagerNative(){}
public static IServiceManager asInterface(IBinder obj){
if (obj == null){
return null;
}
return new ServiceManagerProxy(obj);
}
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote){
mRemote = remote;
//servicemanager实际的代理类
mServiceManager = IServiceManager.Stub.asInterface(remote);
}
public IBinder getService(String name) throws RemoteException {
return mServiceManager.checkService(name);
}
...
private IBinder mRemote;
private IServiceManager mServiceManager;
}
}
这样,我们使用ServiceManager.addService()/getService()等等方法时,会走到BinderProxy的transact()->transactNative()
代码语言:java复制public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
...
try {
return transactNative(code, data, reply, flags);
}finally{
...
}
}
public native boolean transactNative(int code, Parcel data, Parecl reply, int flags) throws RemoteException;
最终通过jni进入native层,通过BpBinder.transact()->IPCThreadState.transact()->writeTransactionData()->waitForResponse()进入binder驱动层,与servicemanager进程通信,等待返回结果。
注意,这里的servicemanager的服务端,使用的是native层的BnServiceManager,并没有使用到java层的IServiceManager.Stub
servicemanager->client端的方式
servicemanager接收到请求后,执行相应的操作IPCThreadState::executeCommand()->BBinder::transact()->BnServiceManager::onTransact(), 具体的实现方法在ServiceManager.cpp中,这里不详细开展了。
代码语言:text复制::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags){
::android::status_t _aidl_ret_status = ::android::OK;
switch(_aidl_code){
case BnServiceManager::TRANSACTION_getService:
::std::string in_name;
::android::sp<::android::IBinder> _aidl_return;
...
_aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name);
...
::android::binder::Status _aidl_status(getService(in_name, &_aidl_return));
...
_aidl_ret_status = _aidl_reply->writeStrongBinder(_aidl_return);
break;
case BnServiceManager::TRANSACTION_checkService:
...
}
}
数据组装完毕后,回到IPCThreadState::executeCommand(),执行sendReply()
代码语言:text复制status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags){
status_t err;
status_t statusBuffer;
err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
if (err < NO_ERROR) return err;
return waitForResponse(nullptr, nullptr);
}
通过binder驱动,将请求的结果返回给client端,如下所示,返回的结果写入了Parcel中。
代码语言:text复制status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){
...
while(1){
if ((err=talkWithDriver()) < NO_ERROR) break;
...
cmd = (uint32_t)mIn.readInt32();
switch(cmd){
...
case BR_REPLY:
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
...
if(reply){
if((tr.flags & TF_STATUS_CODE) == 0){
reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
}else{
...
}
}else{
...
}
goto finish;
}
}
finish:
if (err != NO_ERROR){
...
}
return err;
}
接着进入IServiceManager.Stub.Proxy类的方法中,通过Parcel.readStrongBinder()获取到与servicemanager通信的结果。
结论
servicemanager在管理java层service时,目前只使用了IServiceManager.Stub.Proxy作为代理类,并没有使用IServiceManager.Stub作为服务类,服务类使用的依然是native层的BnServiceManager。