ServiceManager是如何管理java层service的

2023-06-12 14:25:48 浏览数 (1)

前言

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。

0 人点赞