There is such a piece of code in the previous analysis of “Constructing surfaceComposerClient”
bool ComposerService::connectLocked() { const String16 name("SurfaceFlinger"); mComposerService = waitForService<ISurfaceComposer>(name); if (mComposerService == nullptr) { return false; // fatal error or permission problem } ... ... }
waitForService, this article will take an in-depth look at its implementation.
android12\frameworks\ ative\libs\binder\include\binder\IServiceManager.h template<typename INTERFACE> sp<INTERFACE> waitForService(const String16 & amp; name) { const sp<IServiceManager> sm = defaultServiceManager(); return interface_cast<INTERFACE>(sm->waitForService(name)); } android12\frameworks\ ative\libs\binder\include\binder\IInterface.h template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder> & amp; obj) { return INTERFACE::asInterface(obj); }
If you can’t tell, replace the template class with ISurfaceComposer
sp<ISurfaceComposer> waitForService(const String16 & amp; name) { const sp<IServiceManager> sm = defaultServiceManager(); return interface_cast<ISurfaceComposer>(sm->waitForService(name)); } inline sp<ISurfaceComposer> interface_cast(const sp<IBinder> & amp; obj) { return ISurfaceComposer::asInterface(obj); }
Quickly find the implementation of ISurfaceComposer’s asInterface.
I searched for a long time but couldn’t find it.,,,, I searched for a long time and finally found it. It turned out that it was hidden with a macro.
android12\frameworks\ ative\libs\gui\include\gui\ISurfaceComposer.h class ISurfaceComposer: public IInterface { public: DECLARE_META_INTERFACE(SurfaceComposer) ... ... }
After expanding the macro, it looks like this
#define DECLARE_META_INTERFACE(INTERFACE) \ public: \ static const ::android::String16 descriptor; \ static ::android::sp<ISurfaceComposer> asInterface( \ const ::android::sp<::android::IBinder> & amp; obj); \ virtual const ::android::String16 & amp; getInterfaceDescriptor() const; \ ISurfaceComposer(); \ virtual ~ISurfaceComposer(); \ static bool setDefaultImpl(std::unique_ptr<ISurfaceComposer> impl); \ static const std::unique_ptr<ISurfaceComposer> & amp; getDefaultImpl(); \ private:\ static std::unique_ptr<ISurfaceComposer> default_impl; \ public: \
It looks like it’s just a statement here, and then keep looking. . . . . .
Finally found it in android12\frameworks\
ative\libs\gui\ISurfaceComposer.cpp
IMPLEMENT_META_INTERFACE(SurfaceComposer, “android.ui.ISurfaceComposer”);
After expanding the macro, you can see the following implementation:
::android::sp<ISurfaceComposer> ISurfaceComposer::asInterface( \ const ::android::sp<::android::IBinder> & amp; obj) \ {\ ::android::sp<ISurfaceComposer> intr; \ if (obj != nullptr) { \ intr = ::android::sp<ISurfaceComposer>::cast( \ obj->queryLocalInterface(ISurfaceComposer::descriptor)); \ if (intr == nullptr) { \ intr = ::android::sp<BpSurfaceComposer>::make(obj); \ } \ } \ return intr; \ } \
Oh, the point is, it turns out that using interface_cast will use the binder pointer to create a BpSurfaceComposer.
Let’s take a look at BpSurfaceComposer
BpSurfaceComposer implements many interfaces to interact with BnSurfaceComposer. Take createConnection as an example
android12\frameworks\ ative\libs\gui\ISurfaceComposer.cpp class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { public: explicit BpSurfaceComposer(const sp<IBinder> & amp; impl) : BpInterface<ISurfaceComposer>(impl) { } virtual ~BpSurfaceComposer(); virtual sp<ISurfaceComposerClient> createConnection() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, & amp;reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } ... ... }
In “Constructing surfaceComposerClient” conn = sf->createConnection();
There is no detailed introduction, but here is an introduction:
conn = sf->createConnection(); BpSurfaceComposer::createConnection() will actually be called here;
Through binder, send remote call BnSurfaceComposer::CREATE_CONNECTION;
CREATE_CONNECTION will be received in BnSurfaceComposer::onTransact; and createConnection() will be executed.
status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel & data, Parcel* reply, uint32_t flags) { switch(code) { case CREATE_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = IInterface::asBinder(createConnection()); reply->writeStrongBinder(b); return NO_ERROR; } }
Because SurfaceFlinger inherits BnSurfaceComposer, SurfaceFlinger::createConnection() is called here.
class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private ISchedulerCallback { ... ... }
Convert the created Client and return it through Binder.
Looking back at sp
virtual sp<ISurfaceComposerClient> createConnection() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, & amp;reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); }
Use the returned binder pointer to create BpSurfaceComposerClient. This process is consistent with this analysis.
Summarize:
This article sorts out the internal mechanism of waitForService and the calling process of Bpxxx/Bnxxx. This should be done for code reuse.
With BpSurfaceComposer, various interfaces of SurfaceFlinger can be called remotely.
As shown below
Creation is not easy, welcome to like and collect.