Binder系列01:一个简单的Binder Service Demo
参考文献:
- https://blog.csdn.net/liyuntonglyt/article/details/61912822
- https://blog.csdn.net/ljsbuct/article/details/799183
- Binder系列:https://www.cnblogs.com/palance/p/5429111.html
Part I:IInterface/Bn/Bp之间的关系
Iinterface/Bn/Bp是Binder通信中的相关概念。Binder通信是一种client-server的通信结构,这3个类,是对Android Binder框架的抽象,其实这个BBinder,改成BnBinder可能更形象一些。但是要注意的是,一个IXXXService的继承图中,BpBinder并不在这个继承关系之中,也就是说BpBinder并没有子类, BpBinder的是存在于BpRefBase中的mRemote的成员变量中;换句话说,BBinder和BpBinder的功能并不是对称的。但是BBinder是在这个继承关系当中的,它的子类就是BnInterface。
从Client调用Service的过程中分析,就更清楚了。假设有一个IXXXService接口:
class IXXXService : public IInterface { .... public void helloWorld(const char* str); .... }
- Client调用service:Client得到一个BpXXXService以后
(a)会调用BpXXXService实现的helloWorld,它会将str参数打包到Parcel中。然后调用remote()->transact(xxx)
(b)remote()是在BpXXXService的父类BpRefBase中实现的,返回的就是一个BpBinder.实际上调用的就是BpBinder的transact
(c)BpBinder的transact实现,就是直接调用IPCThreadState::self()->transact()发送数据。
- Service接收client请求:
(a)通过IPCThreadState接收到client的请求后,首先会通过remote()调用BBinder的transact方法。
(b)BBinder的transact方法又会调用子类实现的虚拟方法onTransact。这个虚拟方法是在BnXXXService中实现的。
(c)onTransact方法,会通过传递进来的参数来判断,需要调用IXXXService中的那个方法,示例中只有一个helloWorld方法。
(d)直接调用helloWorld,就会找到它的真正实现,也就是BnXXXService的子类XXXService中的helloWorld方法。
总结一下,从上面的流程当中就可以看出前文说的,BpBinder并不在继承关系当中,它只是一个打包数据,并通过IPCThreadState::self()->transact()方法发送出去。而BBinder和BnXXXService的作用,就是接收IPCThreadState传递过来的信息,解包数据,并调用XXXService真正的实现。整个的调用过程是一个同步过程,在server处理的时候,client会block住。整个Binder通信的过程如下图(借用别人博客中的)所示。
首先来看IInterface类的定义:
class IInterface : public virtual RefBase { public: IInterface(); static sp<IBinder> asBinder(const IInterface*); static sp<IBinder> asBinder(const sp<IInterface>&); protected: virtual ~IInterface(); virtual IBinder* onAsBinder() = 0; };
可以看到,这个函数的实现非常简单,重点来看这两个函数:asBinder和onAsBinder。
asBinder的使用是将Interface类型转换为IBinder类型,其传参为IInterface指针,说明它可以实现下面两种类型的转换:
BnInterface->BBinder
BpInterface->BpBinder
还有一个相反的转换,asInterface完成的是Binder到Interface的转换
BBinder->BnInterface
BpBinder->BpInterface
在分析具体代码之前,有两个宏需要注意一下,这两个宏定义在frameworks\native\libs\binder\include\binder\IInterface.h文件中, frameworks\native\libs\gui\include\gui\ISurfaceComposer.h文件中使用了DECLARE_META_INTERFACE,而frameworks\native\libs\gui\ISurfaceComposer.cpp文件使用了IMPLEMENT_META_INTERFACE,二者是成对使用的。看代码的时候要注意这个地方。
ISurfaceComposer.h中 DECLARE_META_INTERFACE(SurfaceComposer) ISurfaceComposer.cpp中 IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
frameworks\native\libs\gui\SurfaceComposerClient.cpp文件通过getService()方法获取名为“SurfaceFlinger”的系统服务。getService方法在IServiceManager.h头文件中定义,因此需要包含该头文件
#include <binder/IServiceManager.h> …… void ComposerService::connectLocked() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } assert(mComposerService != NULL); …… }
在IServiceManager.h文件中查看getService方法的实现,它是先通过defaultServiceManager()方法拿到了系统ServiceManager,然后在ServiceManager中查找对应名字的服务。
template<typename INTERFACE> status_t getService(const String16& name, sp<INTERFACE>* outService) { const sp<IServiceManager> sm = defaultServiceManager(); if (sm != nullptr) { *outService = interface_cast<INTERFACE>(sm->getService(name)); if ((*outService) != NULL) return NO_ERROR; } return NAME_NOT_FOUND; }
getService方法中使用了一个interface_cast函数,它的实现是通过展开宏来控制的。这个宏定义在frameworks\native\libs\binder\include\binder\IInterface.h文件中。前面提到的两个宏在展开后会生成下面这个函数,也就是说getService()方法中调用的interface_cast方法其实是ISurfaceComposer类中实现的。
而此时该方法的入参obj其实是从系统Service Manager里面拿出来的SurfaceFlinger系统服务(在main_surfaceflinger.cpp的main函数中注册的),显然此时拿到obj不为null,所以会去调用queryLocalInterface接口去拿ISurfaceComposer的descriptor,queryLocalInterface方法做的事情很简单,就是去比较ISurfaceComposer::descriptor与SurfaceComposer::descriptor是否相等,或相等则返回该服务,若不待,则返回BpSurfaceComposer。而queryLocalInterface方法是在IBinder中定义的默认返回null,只有BnInterface实现了该接口,而BpInterface没有实现该接口(BBinder和BpBinder的功能并不是对称的),因此如果传进来的obj参数,是一个BBinder,就返回自身(这种情况应该是service和client在同一进程),如果是一个BpBinder,就new一个代理对象返回(这种情况应该是service和client在不同进程)。
::android::sp<ISurfaceComposer> ISurfaceComposer::asInterface( const ::android::sp<::android::IBinder>& obj) { ::android::sp< ISurfaceComposer > intr; if (obj != nullptr) { intr = static_cast< ISurfaceComposer *>( obj->queryLocalInterface( ISurfaceComposer::descriptor).get()); if (intr == nullptr) { intr = new BpSurfaceComposer (obj); } } return intr; } template<typename INTERFACE> inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(const String16& _descriptor) { if (_descriptor == INTERFACE::descriptor) return this; return nullptr; }
这两个宏的原始声明如下:
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); } #define DECLARE_META_INTERFACE(INTERFACE) \ public: \ static const ::android::String16 descriptor; \ static ::android::sp<I##INTERFACE> asInterface( \ const ::android::sp<::android::IBinder>& obj); \ virtual const ::android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \ static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl); \ static const std::unique_ptr<I##INTERFACE>& getDefaultImpl(); \ private: \ static std::unique_ptr<I##INTERFACE> default_impl; \ public: \ #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const ::android::String16 I##INTERFACE::descriptor(NAME); \ const ::android::String16& \ I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ ::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ const ::android::sp<::android::IBinder>& obj) \ { \ ::android::sp<I##INTERFACE> intr; \ if (obj != nullptr) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == nullptr) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ } \ std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl; \ bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\ { \ if (!I##INTERFACE::default_impl && impl) { \ I##INTERFACE::default_impl = std::move(impl); \ return true; \ } \ return false; \ } \ const std::unique_ptr<I##INTERFACE>& I##INTERFACE::getDefaultImpl() \ { \ return I##INTERFACE::default_impl; \ } \ I##INTERFACE::I##INTERFACE() { } \ I##INTERFACE::~I##INTERFACE() { } \ #define CHECK_INTERFACE(interface, data, reply) \ if (!(data).checkInterface(this)) { return PERMISSION_DENIED; } \
拿到BpSurfaceComposer服务后,即可以通过Bp向Bn发送消息进行Binder通信,这样,Client就可以间接的调用Server的接口进行功能操作了。看下BpSurfaceComposer的相关实现,这里所有的操作都是通过remote()->transact这个动作向Bn端发起调用的。
class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { public: virtual sp<ISurfaceComposerClient> createConnection() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } virtual void setTransactionState( const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeUint32(static_cast<uint32_t>(state.size())); for (const auto& s : state) { s.write(data); } data.writeUint32(static_cast<uint32_t>(displays.size())); for (const auto& d : displays) { d.write(data); } data.writeUint32(flags); remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } ······ }
而在Server端的实现中,如SurfaceFlinger实现了BnComposerService,SurfaceFlinger会重写onTransact函数,这这个函数里面会调用读取并解析Client写过来的数据,然后调用对应的方法来实现Client的需求动作。
status_t SurfaceFlinger::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t credentialCheck = CheckTransactCodeCredentials(code); if (credentialCheck != OK) { return credentialCheck; } status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { …… int n; switch (code) { case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE return NO_ERROR; case 1002: // SHOW_UPDATES n = data.readInt32(); mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); invalidateHwcGeometry(); repaintEverything(); return NO_ERROR; case 1004:{ // repaint everything repaintEverything(); return NO_ERROR; } case 1005:{ // force transaction Mutex::Autolock _l(mStateLock); setTransactionFlags( eTransactionNeeded| eDisplayTransactionNeeded| eTraversalNeeded); return NO_ERROR; } case 1006:{ // send empty update signalRefresh(); return NO_ERROR; } case 1008: // toggle use of hw composer n = data.readInt32(); mDebugDisableHWC = n ? 1 : 0; invalidateHwcGeometry(); repaintEverything(); return NO_ERROR; case 1009: // toggle use of transform hint n = data.readInt32(); mDebugDisableTransformHint = n ? 1 : 0; invalidateHwcGeometry(); repaintEverything(); return NO_ERROR; case 1010: // interrogate. reply->writeInt32(0); reply->writeInt32(0); reply->writeInt32(mDebugRegion); reply->writeInt32(0); reply->writeInt32(mDebugDisableHWC); return NO_ERROR; …… }
Part II:一个简单的Binder Service Demo
完整代码地址: https://github.com/hfts/BinderServiceDemo.git
BpXXX、BnXXX同时实现一个接口IXXX。BpXXX主要是用来处理java层传下来的服务请求,然后通过transact将处理请求传给BnXXX(通过binder)。BpINTERFACE是client端的代理接口,BnINTERFACE是server端的代理接口。注意这里面有一些命令规范,直接继承IInterface接口的接口一定要以I开关,表示这是一个接口。
IInterface相关的知识结构如下,Andorid系统已经做好了绝大部分,我们在使用IInterface的使用只需要实现下面图中的绿色部分即可。主要包含三个部分:
如Android中的SurfaceFlinger、Client(SurfaceFlinger中)则是分别实现了BnSurfaceComposer和BnSurfaceComposerClient,SurfaceFlinger、Client是真正的服务实现部分,Client端拿到只是BpSurfaceComposer和BpSurfaceComposerClient。
下面自己动手来实现一个简单的Binder Service服务 。
首先,定义ITestService接口:
class ITestService : public IInterface { public: DECLARE_META_INTERFACE(TestService) // detail: frameworks/native/libs/binder/include/binder/IInterface.h virtual void testFun_01() = 0; virtual void testFun_02() = 0; };
在Client端(Java或C++),需要通过getService方法来获取对应的服务,其实这里拿到的就是Binder Proxy对象,即BpBinder,BpBinder(Binder Proxy):主要功能是负责client向Bn发送调用请求的数据。它是client端binder通信的核心对象,通过调用transact函数,client就可以向Bn发送调用请求和数据。这里我们定义一个BpTestService,继承自ITestService,为Client做准备。
class BpTestService : public BpInterface<ITestService> { public: explicit BpTestService(const sp<IBinder> &impl) : BpInterface<ITestService>(impl) { } virtual ~BpTestService(); virtual void testFun_01() { std::cout << "BpTestService::testFun_01" << std::endl; Parcel data, reply; data.writeInterfaceToken(ITestService::getInterfaceDescriptor()); remote()->transact(BnTestService::TEST_01, data, &reply); } virtual void testFun_02() { std::cout << "BpTestService::testFun_02" << std::endl; Parcel data, reply; data.writeInterfaceToken(ITestService::getInterfaceDescriptor()); remote()->transact(BnTestService::TEST_02, data, &reply); } };
而Server端则对应BnBinder(Binder Native):BnBinder就是具体干事情的对象。这里我们定义一个BnTestService,继承自ITestService。BnTestService是真正的服务端实现,一般在具体实现中,BnTestService会实现一些服务端的基本功能,而更复杂和详细的功能,则是由BnTestService类的子类来实现的。
class BnTestService : public BnInterface<ITestService> { public: enum { TEST_01 = IBinder::FIRST_CALL_TRANSACTION, TEST_02, }; virtual void testFun_01() { std::cout << "BnTestService::testFun_01" << std::endl; } virtual void testFun_02() { std::cout << "BnTestService::testFun_02" << std::endl; } virtual status_t onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags = 0); };
BnTestService的onTransact函数的实现如下。
status_t BnTestService::onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { switch (code) { case TEST_01: CHECK_INTERFACE(ITestService, data, reply); testFun_01(); return NO_ERROR; case TEST_02: CHECK_INTERFACE(ITestService, data, reply); testFun_02(); return NO_ERROR; default: { return BBinder::onTransact(code, data, reply, flags); } } }
写Service,实现接口的虚函数
class TPrimeTestService : public BnTestService { public: explicit TPrimeTestService(); virtual void testFun_01(); virtual void testFun_02(); virtual status_t onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags); };
TPrimeTestService的具体实现部分
TPrimeTestService::TPrimeTestService() { } void TPrimeTestService::testFun_01() { std::cout << "TrpimeTestService::testFun_01" << std::endl; } void TPrimeTestService::testFun_02() { std::cout << "TrpimeTestService::testFun_02" << std::endl; } status_t TPrimeTestService::onTransact( uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { status_t err = BnTestService::onTransact(code, data, reply, flags); if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { CHECK_INTERFACE(ITestService, data, reply); std::cout << "TPrimeTestService::onTransact" << std::endl; } return err; }
服务的主函数中,获得ServiceManager,添加Service。
int main() { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); sm->addService(String16("tprime.TestService"), new tprime::TPrimeTestService()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); return 0; }
在Client获取上面注释的服务,并使用它:
int main() { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("tprime.TestService")); sp<tprime::ITestService> ts = interface_cast<tprime::ITestService>(binder); ts->testFun_01(); ts->testFun_02(); return 0; }
编译上述代码,会在out/target/product/generic_x86/system/bin目录下面生成两个可执行文件
ubuntu@ubuntu:~/projects/android_8_1_0_r41/out/target/product/generic_x86/system/bin$ ll | grep Test -rwxrwxr-x 1 ubuntu ubuntu 23284 10月 4 22:34 TestClient* -rwxrwxr-x 1 ubuntu ubuntu 27504 10月 4 22:34 TestServer*
将上述两个文件push到手机中(如push到data/tsdebug目录中),chmod给予可执行权限,在不同的终端中,先运行TestServer,再执行TestClient,实际的运行结果如下:
generic_x86:/data/tsdebug # ./TestClient BpTestService::testFun_01 BpTestService::testFun_02 generic_x86:/data/tsdebug # ./TestServer TrpimeTestService::testFun_01 TrpimeTestService::testFun_02