源码基于:Android R
0. 前言
上一文中详细分析了servicemanger 的启动流程,我们知道 servicemanager 作为 binder 机制中的一个特殊service,利用service map管理所有service,也是所有binder 通信的入口。
本文着重分析 service 的注册流程,下一文着重分析service 的获取流程。
1. 概念
1.1 ProcessState
Binder 中每个进程都会有且只有一个 ProcessState 用来记录 “进程状态”,初始化驱动设备,记录了驱动的名称、FD,记录进程线程数量的上限,记录binder 的 context obj,产生 binder 的线程名称,启动 binder 线程等等。
ProcessState 使用 self() 函数获取对象,因为有 vndbinder 和binder共用一份代码,所以,如果需要使用vndbinder ,需要在调用 self() 函数前调用 intWithDriver() 来指定驱动设备。
详细代码可以查看上一文的第 4 节。
1.2 IPCThreadState
同 ProcessState,每个进程有很多的线程用来记录 “线程状态”,在每次binder 的BINDER_WRITE_READ 调用后,驱动都会根据情况确定是否需要 spawn 线程,而创建一个PoolThread(详见ProcessState) 都会伴随一个IPCThreadState进行管理。
1.3 BpBinder
BpBinder 展开后就是Binder Proxy,也就是 Binder 代理的含义。BpBinder 是客户端用来与服务交互的代理类,负责实现跨进程传输的传输机制,不关心具体的传输内容。通信功能由其它类和函数实现,但由于这些类和函数被BpBinder代理,所以客户端需要通过BpBinder来发送Binder通信数据。
1.4 BBinder
BBinder代表服务端,可以理解为服务的 Binder 实体,当服务端从 Binder 驱动中读取到数据后,由BBinder类进行处理。
2. defaultServiceManager()
servicemanger 作为binder 的特殊service,如果需要与其进行通信,需要获取到 binder 的代理端,而这个入口就是使用 defaultServiceManager。
Android R 的代码与之前很大的不同,下面列一下对比的代码。
Android R 之前:
sp<IServiceManager> defaultServiceManager()
{if (gDefaultServiceManager != NULL) return gDefaultServiceManager;{AutoMutex _l(gDefaultServiceManagerLock);while (gDefaultServiceManager == NULL) {gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));if (gDefaultServiceManager == NULL)sleep(1);}}return gDefaultServiceManager;
}
Android R 之后:
frameworks/native/libs/binder/IServiceManager.cppsp<IServiceManager> defaultServiceManager()
{std::call_once(gSmOnce, []() {sp<AidlServiceManager> sm = nullptr;while (sm == nullptr) {sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));if (sm == nullptr) {ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());sleep(1);}}gDefaultServiceManager = new ServiceManagerShim(sm);});return gDefaultServiceManager;
}
这是一个全局的接口函数,维护两个全局的变量 gSmOnce 和 gDefaultServiceManager。
代码中使用了 c++11 的特性 call_once(),保证在多线程中 call_once() 中指定的函数只会被调用一次。这里指定的函数是 lambda 函数。
该函数分三个部分剖析:
- AidlServiceManager 是什么?
- ProcessState::self()->getContextObject(nullprt) 获取的是什么?
- ServiceManagerShim 是什么?
之所以采用这种方式,应该是为了兼容 aidl 的native 调用和native 本身的调用。
另外,不同于R 之前,通过 defaultServiceManager() 接口获取到的 ServcieManager 的代理其实都是 ServiceManagerShim 对象。详细见下文。
2.1 头文件
#include <binder/IServiceManager.h>#include <android/os/BnServiceCallback.h>
#include <android/os/IServiceManager.h>
IServiceManager.cpp 依赖的直接头文件应该是 binder/IServiceManager.h,文件位于frameworks/native/libs/binder/include/binder/
另外两个头文件是通过编译器编译出来的,之所以会出现两个 IServiceManager.h ,是因为binder/IServiceManager.h 还是作为 native 开发的入口,而 android/os/IServcieManager.h 则作为其impl,主要为了兼容aidl 通信。
详细可以查看:
./soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_cortex-a55_shared/gen/aidl/android/os/IServiceManager.h
2.2 AidlServcieManager
frameworks/native/libs/binder/IServiceManager.cppusing AidlServiceManager = android::os::IServiceManager;
可以看出 AidlServiceManager 就是指的 android::os::IServiceManager,这里使用 AidlServcieManager 作为别名,也为了区分源生的 IServiceManager 类。
2.3 getContextObject(nullptr)
frameworks/native/libs/binder/ProcessState.cppsp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{sp<IBinder> context = getStrongProxyForHandle(0);if (context == nullptr) {ALOGW("Not able to get context object on %s.", mDriverName.c_str());}// The root object is special since we get it directly from the driver, it is never// written by Parcell::writeStrongBinder.internal::Stability::tryMarkCompilationUnit(context.get());return context;
}
主要就是获取 handle 为0 的 IBinder,ServiceManager 作为一个特殊的 service,其特殊性就是handle 为0。
2.3.1 getStrongProxyForHandle()
frameworks/native/libs/binder/ProcessState.cppsp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{sp<IBinder> result;AutoMutex _l(mLock);//通过lookupHandleLocked() 获取handle对应的handle_entry,这里封装了binderhandle_entry* e = lookupHandleLocked(handle);if (e != nullptr) { //这里的entry基本都存在的IBinder* b = e->binder;//但有可能entry是新建的,此时binder为nullptrif (b == nullptr || !e->refs->attemptIncWeak(this)) {//对于ServiceManager本身,需要通过transact()进行PING 处理if (handle == 0) {Parcel data;status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, data, nullptr, 0);if (status == DEAD_OBJECT)return nullptr;}//通过BpBinder::create()创建 BpBinder,并添加到handle_entry中b = BpBinder::create(handle);e->binder = b;if (b) e->refs = b->getWeakRefs();result = b;} else {...}}return result;
}
如代码注释,重要逻辑有两个地方:
- 在lookupHandleLocked() 中会获取 handle 对应binder 的 handle_entry,对于新的 handle 会创建新的 handle_entry;
- 利用 transact() 确认handle 通信是否正常,如果状态正常,则会创建一个ServiceManager 的 BpBinder 返回,后面 addService()、getService() 等操作都是通过该BpBinder 来操作。
下面第 3 节,将 transact() 单独拿出来分析,后面的binder 通信都是通过这里进行。
在了解完 transact() 函数之后,继续来看下这里,此处transact() 的参数中 code 传入的是 PING_TRANSACTION,最终在 Binder.cpp 中会进行拦截处理,并返回 NO_ERROR。client 端在收到该返回后会通过 BpBinder::create() 创建出ServiceManager 在client 的代理BpServiceManager,其中 binder handle 会存放在代理中, 对于client 端都是通过这个handle 才能与 server 端通信。
注意的是,整个过程中 Interface 使用的是android.os.IServcieManager:
/out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/android/os/IServiceManager.hnamespace android {namespace os {class IServiceManager : public ::android::IInterface {DECLARE_META_INTERFACE(ServiceManager)...
}; }}
BpServiceManager.h:
/out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/android/os/BpServiceManager.hnamespace android {namespace os {class BpServiceManager : public ::android::BpInterface<IServiceManager> {...
}; }}
BnServiceManager.h:
/out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/android/os/BnServiceManager.hnamespace android {namespace os {
class BnServiceManager : public ::android::BnInterface<IServiceManager> {...
}; }}
ServcieManager.h:
frameworks/native/cmds/servicemanager/ServiceManager.hnamespace android {using os::IClientCallback;
using os::IServiceCallback;class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {
2.4 interface_cast<AidlServiceManager>
sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
在 getContextObject() 拿到 IServiceManager 的 BpBinder 之后,通过 interface_cast<INTERFACE>:
frameworks/native/libs/binder/include/binder/IInterface.htemplate<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{return INTERFACE::asInterface(obj);
}
在 IServiceManager.h 中已经 DECLARE_META_INTERFACE:
namespace android {namespace os {class IServiceManager : public ::android::IInterface {DECLARE_META_INTERFACE(ServiceManager)...
}; }}
说白了,就是通过 interface_case<> 将 IBinder 对象转换成 INTERFACE 对象,这里指的是将从 IServiceManager 中获取的 BpBinder 转换成 AidlServiceManager 对象。
2.5 ServiceManagerShim
当通过上面获取到 sm之后,会通过 ServiceManagerShim 进行构造:
frameworks/native/libs/binder/IServiceManager.cppclass ServiceManagerShim : public IServiceManager
{
public:explicit ServiceManagerShim (const sp<AidlServiceManager>& impl);sp<IBinder> getService(const String16& name) const override;sp<IBinder> checkService(const String16& name) const override;status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated, int dumpsysPriority) override;Vector<String16> listServices(int dumpsysPriority) override;sp<IBinder> waitForService(const String16& name16) override;bool isDeclared(const String16& name) override;// for legacy ABIconst String16& getInterfaceDescriptor() const override {return mTheRealServiceManager->getInterfaceDescriptor();}IBinder* onAsBinder() override {return IInterface::asBinder(mTheRealServiceManager).get();}
private:sp<AidlServiceManager> mTheRealServiceManager;
};ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl): mTheRealServiceManager(impl)
{}
从构造函数中得知,ServiceManagerShim 就是 AidlServiceManager 的native 端封装。
后面开发过程中都会通过 defaultServiceManager() 接口获取ServiceManager 的代理 BpServiceManager,为了方便记忆,下面通过框架图进一步的说明:
图中共有 4 条调用线路:
第一条:Client 端通过 defaultServiceManager() 接口调用获取到 sp<IServiceManager> 实例,而这个实例是全局变量 gDefaultServiceManager,其实就是 ServiceManagerShim 类型的对象;
第二条:在第一条中已经提到了,通过defaultServiceManager() 获取到的其实就是ServiceManagerShim 类型的对象,使用 ServiceManagerShim 类型的目的其实就是为了封装 AidlServiceManager,即该类中的成员变量 mTheRealServiceManager;
第三条:如第二条所述,ServiceManagerShim 中的 mTheRealServiceManager 就是封装AidlServiceManager 所在,而 mTheRealServiceManager 也就是BpServiceManager 实例;
第四条:经过 mTheRealServiceManager 调用后进行binder 通信,会调用到ServiceManager,因为 BnServiceManager 被 ServiceManager 继承,BBinder 的onTransact() 是在BnServiceManager 中,所以最终处理会指向 BnServiceManager 的onTransact();
3. IPCThreadState::transact()
frameworks/native/libs/binder/IPCThreadState.cppstatus_t IPCThreadState::transact(int32_t handle,uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
{status_t err;flags |= TF_ACCEPT_FDS;err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);...if ((flags & TF_ONE_WAY) == 0) {......if (reply) {err = waitForResponse(reply);} else {Parcel fakeReply;err = waitForResponse(&fakeReply);}...} else {err = waitForResponse(nullptr, nullptr);}return err;
}
transact 参数有5 个:
- handle, 每个BpBinder 都有handle,在创建的时候会传入,当要跟 servicemanager 通信时,需要拿到 servicemanager 的代理,即 handle 为0 的 BpBinder;
- code, BC_TRANSACTION 操作的详细命令码;
- data,传送携带的数据;
- replay,从server 端返回的数据;
- flags,传送配套的flags;
3.1 writeTransactionData()
frameworks/native/libs/binder/IPCThreadState.cppstatus_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{binder_transaction_data tr;tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */tr.target.handle = handle;tr.code = code;tr.flags = binderFlags;tr.cookie = 0;tr.sender_pid = 0;tr.sender_euid = 0;const status_t err = data.errorCheck();if (err == NO_ERROR) {tr.data_size = data.ipcDataSize();tr.data.ptr.buffer = data.ipcData();tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);tr.data.ptr.offsets = data.ipcObjects();} else if (statusBuffer) {tr.flags |= TF_STATUS_CODE;*statusBuffer = err;tr.data_size = sizeof(status_t);tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);tr.offsets_size = 0;tr.data.ptr.offsets = 0;} else {return (mLastError = err);}mOut.writeInt32(cmd);mOut.write(&tr, sizeof(tr));return NO_ERROR;
}
将transact 传输携带的 data,转换成驱动所需要的数据类型 binder_transaction_data,并携带cmd 一同存入到 mOut,等待下一次的 execute。
其中 tr.data.ptr.buffer 记录了Parcel传输的数据,tr.data.ptr.offsets记录下 “待传数据” 中所有binder对象的具体位置。
3.2 waitForResponse()
当writeTransactionData() 完成之后线程就处于等待 server 端处理,调用 waitForResponse() 进入等待。
frameworks/native/libs/binder/IPCThreadState.cppstatus_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{uint32_t cmd;int32_t err;while (1) {if ((err=talkWithDriver()) < NO_ERROR) break;err = mIn.errorCheck();if (err < NO_ERROR) break;if (mIn.dataAvail() == 0) continue;cmd = (uint32_t)mIn.readInt32();switch (cmd) {case BR_TRANSACTION_COMPLETE:...case BR_DEAD_REPLY:...case BR_FAILED_REPLY:...case BR_ACQUIRE_RESULT:...case BR_REPLY:{binder_transaction_data tr;err = mIn.read(&tr, sizeof(tr));ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");if (err != NO_ERROR) goto finish;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 {err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);freeBuffer(nullptr,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), this);}} else {freeBuffer(nullptr,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), this);continue;}}goto finish;default:err = executeCommand(cmd);if (err != NO_ERROR) goto finish;break;}}...return err;
}
waitForResponse() 是client 进程通过 binder 驱动与 server 通信的核心处理部分。
通过 talkWithDriver() 在上一篇博文中已经分析过:
- 主要通过 BINDER_WRITE_READ 通知驱动;
- 如果是事务处理 client 端会在 mOut 中携带 cmd BC_TRANSACTION;
- 驱动 ioctl 收到 BINDER_WRITE_READ 会进入 binder_ioctl_write_read() 进行进一步处理;
- 如果驱动发现收到的 binder_write_read 有write 的数据(即client需要传输数据),认为client 端携带了data 过来,会进行 binder_thread_write() 处理;
- 如果驱动发现收到的 binder_write_read 有read 数据(即client需要从server 回收数据),认为client 需要接收server 数据,会进行 binder_thread_read() 处理;
- 调用 binder_thread_read() 时,驱动会根据 proc 相关的信息,找到 server 的cookie,根据需求确定执行 BR_TRANSACTION 还是 BR_REPLY,最终通过 binder_stat_br 执行;
- client 端 BC_TRANSACTION 过来,驱动转换成 BR_TRANSACTION 通知到server;
- server端也有个 waitForResponse(),在收到 BR_TRANSACTION 时,进入executeCommand(),在处理完后会发出 BC_REPLY 并通过 BINDER_WRITE_READ 通知回驱动,驱动转换成 BR_REPLY 通知回client;
- client 端调用的 talkWithDriver() 返回后,会处理 BR_REPLY 的 case,将 mIn 中的数据读出来并存储到 Parcel *reply 中;
3.2.1 executeCommand()
来看下server 端在收到 BR_TRANSACTION 后的处理
frameworks/native/libs/binder/IPCThreadState.cppstatus_t IPCThreadState::executeCommand(int32_t cmd)
{...case BR_TRANSACTION_SEC_CTX:case BR_TRANSACTION:{binder_transaction_data_secctx tr_secctx;binder_transaction_data& tr = tr_secctx.transaction_data;...Parcel buffer;...Parcel reply;status_t error;...if (tr.target.ptr) {// We only have a weak reference on the target object, so we must first try to// safely acquire a strong reference before doing anything else with it.if (reinterpret_cast<RefBase::weakref_type*>(tr.target.ptr)->attemptIncStrong(this)) {error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);} else {error = UNKNOWN_TRANSACTION;}} else {error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);}if ((tr.flags & TF_ONE_WAY) == 0) {...sendReply(reply, 0);} else {...}...}break;
}
对于handle不为0 的,会通过 BBinder 的 transact() 进行处理,对于handle 为0,也就是servicemanager 中收到 BR_TRANSACTION,即用 the_conext_object(servicemanger在运行时已经将context obj 保存到全局变量 the_context_object)调用 transact()。
其实不管 handle 为多少,最终都是通过BBinder 调用的transact()。
在 transact() 成功返回后如果是 TF_ONE_WAY 方式通信,server 会通过sendReply() 将返回值通过给client 端。
4. addService()
frameworks/native/libs/binder/IServiceManager.cppstatus_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,bool allowIsolated, int dumpsysPriority)
{Status status = mTheRealServiceManager->addService(String8(name).c_str(), service, allowIsolated, dumpsysPriority);return status.exceptionCode();
}
终于拿到了ServiceManager 的BpInterface,后面的调用都是通过ServiceManagerShim 对象,但这里只是做了下封装,实际上还是要通过BpInterface,即BpServiceManager 来调用:
out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/frameworks/native/libs/binder/aidl/android/os/IServiceManager.cpp::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) {::android::Parcel _aidl_data;::android::Parcel _aidl_reply;::android::status_t _aidl_ret_status = ::android::OK;::android::binder::Status _aidl_status;_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); //写入descriptorif (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}_aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name); //写入service nameif (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}_aidl_ret_status = _aidl_data.writeStrongBinder(service); //写入BBinderif (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}_aidl_ret_status = _aidl_data.writeBool(allowIsolated); //写入allowIsolatedif (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}_aidl_ret_status = _aidl_data.writeInt32(dumpPriority); //写入dumpPriorityif (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}//带入code、_aidl_data,以及用来回复的_aidl_reply_aidl_ret_status = remote()->transact(::android::IBinder::FIRST_CALL_TRANSACTION + 2 /* addService */, _aidl_data, &_aidl_reply);if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IServiceManager::getDefaultImpl())) {return IServiceManager::getDefaultImpl()->addService(name, service, allowIsolated, dumpPriority);}if (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}//_aidl_reply 中存放的是addService 的返回值_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);if (((_aidl_ret_status) != (::android::OK))) {goto _aidl_error;}if (!_aidl_status.isOk()) {return _aidl_status;}_aidl_error:_aidl_status.setFromStatusT(_aidl_ret_status);return _aidl_status;
}
这里主要有两点:
- BBinder 是通过 writeStrongBinder()接口存放到 _aidl_data 中,后面会单独分析该函数;
- 使用 BpBinder->transact() 进行binder 通信;
4.1 BpBinder::transact()
remote() 就是 IServcieManager 的 BpBinder,在 getContextObject() 的时候create 出来的,来看下 BpBinder 的 transact():
frameworks/native/libs/binder/BpBinder.cppstatus_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{...status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);...
}
这里调用到 3.2.1 节,最终通过 BBinder的 transact():
frameworks/native/libs/binder/Binder.cppstatus_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{data.setDataPosition(0);status_t err = NO_ERROR;switch (code) {case PING_TRANSACTION:err = pingBinder();break;case EXTENSION_TRANSACTION:err = reply->writeStrongBinder(getExtension());break;case DEBUG_PID_TRANSACTION:err = reply->writeInt32(getDebugPid());break;default:err = onTransact(code, data, reply, flags);break;}// In case this is being transacted on in the same process.if (reply != nullptr) {reply->setDataPosition(0);}return err;
}
BBinder 的 onTransact() 会在Bn 端被覆盖,这里指的是BnServiceManager:
out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/frameworks/native/libs/binder/aidl/android/os/IServiceManager.cppcase ::android::IBinder::FIRST_CALL_TRANSACTION + 2 /* addService */:{::std::string in_name;::android::sp<::android::IBinder> in_service;bool in_allowIsolated;int32_t in_dumpPriority;if (!(_aidl_data.checkInterface(this))) {_aidl_ret_status = ::android::BAD_TYPE;break;}_aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name);if (((_aidl_ret_status) != (::android::OK))) {break;}_aidl_ret_status = _aidl_data.readStrongBinder(&in_service);if (((_aidl_ret_status) != (::android::OK))) {break;}_aidl_ret_status = _aidl_data.readBool(&in_allowIsolated);if (((_aidl_ret_status) != (::android::OK))) {break;}_aidl_ret_status = _aidl_data.readInt32(&in_dumpPriority);if (((_aidl_ret_status) != (::android::OK))) {break;}::android::binder::Status _aidl_status(addService(in_name, in_service, in_allowIsolated, in_dumpPriority));_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);if (((_aidl_ret_status) != (::android::OK))) {break;}if (!_aidl_status.isOk()) {break;}}break;
addServcie() 最终会调用到真正实现 BnServiceManager 的地方,也就是ServcieManager 中的addService():
frameworks/native/cmds/servicemanager/ServiceManager.cppStatus ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {auto ctx = mAccess->getCallingContext();//应用进程没有权限注册服务if (multiuser_get_app_id(ctx.uid) >= AID_APP) {return Status::fromExceptionCode(Status::EX_SECURITY);}// selinux 曲线是否允许注册为SELABEL_CTX_ANDROID_SERVICEif (!mAccess->canAdd(ctx, name)) {return Status::fromExceptionCode(Status::EX_SECURITY);}//传入的IBinder 不能为nullptrif (binder == nullptr) {return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);}//service name 需要符合要求,由0-9、a-z、A-Z、下划线、短线、点号、斜杠组成,name 长度不能超过127if (!isValidServiceName(name)) {LOG(ERROR) << "Invalid service name: " << name;return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);}//这里应该是需要普通的vnd service 进行vintf 声明
#ifndef VENDORSERVICEMANAGERif (!meetsDeclarationRequirements(binder, name)) {// already loggedreturn Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);}
#endif // !VENDORSERVICEMANAGER//注册linkToDeath,监听service 状态if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {LOG(ERROR) << "Could not linkToDeath when adding " << name;return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);}//添加到map 中auto entry = mNameToService.emplace(name, Service {.binder = binder,.allowIsolated = allowIsolated,.dumpPriority = dumpPriority,.debugPid = ctx.debugPid,});//确认是否注册了service callback,如果注册调用回调auto it = mNameToRegistrationCallback.find(name);if (it != mNameToRegistrationCallback.end()) {for (const sp<IServiceCallback>& cb : it->second) {entry.first->second.guaranteeClient = true;// permission checked in registerForNotificationscb->onRegistration(name, binder);}}return Status::ok();
}
addServcie() 实现部分,之前在servicemanager 启动一文中已经有简单的分析过。
这里有两个注意点:
- linkToDeath();
- mNameToService;
4.1.1 mNameToService
先来看下这个变量。
frameworks/native/cmds/servciemanager/ServiceManager.hstruct Service {sp<IBinder> binder; // not nullbool allowIsolated;int32_t dumpPriority;bool hasClients = false; // notifications sent on true -> false.bool guaranteeClient = false; // forces the client check to truepid_t debugPid = 0; // the process in which this service runs// the number of clients of the service, including servicemanager itselfssize_t getNodeStrongRefCount();};using ServiceMap = std::map<std::string, Service>;
...
ServiceMap mNameToService;
在 ServiceManager 类中有这样的定义。
mNameToService 其实就是 name-Service 的map,当addService() 流程执行到 ServiceManager 中,最终会将新的 service 存放在该变量中,而之后 Client 端也可以通过 getService() 来从 mNameToService 中获取name 对应的 service。
getService() 详细可以查看《Android Binder通信原理(三):service获取》一文。
4.1.2 linkToDeath()
addService() 中有这一段逻辑:
if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {}
binder 在Bp 端传入的参数为 service,也就是 BBinder,在transact 之前需要将其存放到data 中,使用的是函数 writeStrongBinder(),详细看第 4 节。
frameworks/native/libs/binder/Parcel.cppstatus_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{return flattenBinder(val);
}status_t Parcel::flattenBinder(const sp<IBinder>& binder)
{flat_binder_object obj;if (IPCThreadState::self()->backgroundSchedulingDisabled()) {/* minimum priority for all nodes is nice 0 */obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;} else {/* minimum priority for all nodes is MAX_NICE(19) */obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;}if (binder != nullptr) {BBinder *local = binder->localBinder();if (!local) {BpBinder *proxy = binder->remoteBinder();if (proxy == nullptr) {ALOGE("null proxy");}const int32_t handle = proxy ? proxy->handle() : 0;obj.hdr.type = BINDER_TYPE_HANDLE;obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */obj.handle = handle;obj.cookie = 0;} else {if (local->isRequestingSid()) {obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;}obj.hdr.type = BINDER_TYPE_BINDER;obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());obj.cookie = reinterpret_cast<uintptr_t>(local);}} else {obj.hdr.type = BINDER_TYPE_BINDER;obj.binder = 0;obj.cookie = 0;}return finishFlattenBinder(binder, obj);
}
flattenBinder() 的目的是将 Binder 扁平化,把一个Binder实体“压扁”并写入Parcel。这里"压扁"的含义,其实就是把Binder对象整理成 flat_binder_object 变量。如果压扁的是 Binder实体,那么 flat_binder_object 用 cookie 域记录 binder 实体的指针,即BBinder指针,而如果打扁的是Binder代理,那么 flat_binder_object 用handle域记录的binder代理的句柄值。
接着 flatten_binder() 调用了一个关键的 finish_flatten_binder() 函数。这个函数内部会记录下刚刚被扁平化的 flat_binder_object 在parcel中的位置。说得更详细点儿就是,parcel 对象内部会有一个buffer,记录着parcel中所有扁平化的数据,有些扁平数据是普通数据,而另一些扁平数据则记录着binder对象。所以parcel中会构造另一个mObjects数组,专门记录那些binder扁平数据所在的位置。
Parcel 会随着transact 的 BC_TRANSACTION 传入 binder 驱动,在驱动中会根据特殊需求,将flat_binder_object 转换,例如:
ret = binder_translate_binder(fp, t, thread);
或
ret = binder_translate_handle(fp, t, thread);
如果是 BBinder 会将 flat_binder_object 中 hdr.type 从 BINDER_TYPE_BINDER转换为BINDER_TYPE_HANDLE。
这里暂时不详细分析了,后面会在驱动一节中重点分析数据传输的过程。
回来开始,BBinder 通过驱动后会通过 BR_TRANSACTION 传到服务端,会在 IPCThreadState 的executeCommand() 中重新转换成Parcel,并最终传入BBinder->transact(),这里会传入addService()。所以,这里binder->remoteBinder() != nullptr 是真。
至此,service 注册的流程分析完毕,总结如下:
- servcie 作为servicemanager 的client 端,需要通过defaultServiceManager 获取servicemanager 的代理;
- 将service 的Binder 作为参数,传入addService(),并通过Parcel.writeStrongBinder() 将 Binder 压缩为flat_binder_object;
- 通过BpServiceManager 所对应的BpBinder->transact(),将data 和reply 传入,通过service 所在进程中的IPCThreadState->transact 进行talkWithDriver,通过 BC_TRANSACTION 将code和data 传入驱动, 经过驱动后将 flat_binder_object 做适当的 translate;
- servicemanger 进程中IPCThreadState 收到 BR_TRANSACTION 后通过 the_context_object->transact 通知到 BnServiceManager;
- BBinder->onTransact() 会对addService() 对应的code做对应处理,调用实现ServiceManager::addService();
- 将 translate 后的Binder 存进mNameToService 中,用于get、check、list;