作者:秋城 一、前言Servicemanager 程序(以下简称SM)是 Android 系统 binder 模块重要的组成部分,扮演着类似 C/S 架构中的 DNS 服务器的角色,提供服务增查和权限管理等功能支撑 在 Android 11 之前的版本里,SM 是面向 binder 驱动编程,直接使用 open、mmap、ioctl 等 api 与 binder 驱动交互。而从 Android 11 开始,SM 放弃使用这些较底层的接口,转向 libbinder 库和 AIDL。标志性的提交如下,该提交奠定了新的 SM 架构基础,此后多次提交对此进行完善填充 frameworks/native servicemanager: use libbinder Bug: 135768100Test: boot Test: servicemanager_test Change-Id: I9d657b6c0d0be0f763b6d54e0e6c6bc1c1e3fc7a (cherry picked from commit 3e092daa14c63831d76d3ad6e56b2919a0523536) 本文代码基于 Android 12,以 SM 为主视角,从架构和情景流程上带大家认识新的 Native Binder 二. 软件架构2.1 架构概述 图1:切换到 aidl 和 libbinder 后的 ServiceManager 类关系图 图注: 一图胜千言,11 之前的 SM 是写在 c 文件里,没有类的概念,现在基于 aidl 和 libbinder,使用 cpp 语言,用 uml 就可以很形象地展示类关系了。就着这幅图我们大致描述新的软件架构
一些 libbinder 的用于继承的公共类请读者自行剥离,而不是将其归入某一端。例如 IBinder,我们知道他是 BBinder 和 BpBinder 的父类,是公共的接口约束
之前无该辅助类,而是直接操作 BpServiceManager,这个辅助类封装了 aidl 自动生成的 BpServiceManager,所以现在的客户端代码流就变成如下三步: 1.用户代码 2.libbinder代码 binder/IServiceManager.cpp#ServiceManagerShim 3.aidl代码 android/os/IServiceManager.cpp#BpServiceManager接口 所以 libbinder 中的 ServiceManagerShim 起到了一个中转的作用,把请求转给 out 下 aidl 自动生成的 BpServiceManager
原来是在 libbinder#IServiceManager.cpp 中手写实现,现在是 aidl 帮你实现。 当然,该文件中同样自动实现了 BnServiceManager 类 代码路径 out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_shared/gen/aidl/android/os/IServiceManager.cpp
原来是没有 Bn 的,而是一个 binder_loop 方法沟通驱动,现在则是ServiceManager 继承了 BnServiceManager 来获得代码流。
Waiter 类。新增了 binder 匿名服务用来向 sm 注册跨进程的回调,当 sm 检测到有服务注册时,会返回通知
IServiceCallback.aidl 这个匿名 binder 服务就是用于该目的,可以监听某个服务的客户端数量 2.2、文件路径
AIDL 是一种方便的接口定义语言,用于 Binder-IPC 编程。详细介绍与使用可参考:AIDL Overview 我们关注三个 aidl,分别是 IServiceManager.aidl、IServiceCallback.aidl、IClientCallback.aidl,对应的编译后生成的文件路径为: out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm_armv8-a_shared/gen/aidl/android/os/ IClientCallback.cpp IServiceCallback.cpp IServiceManager.cpp
frameworks/native/libs/binder/IServiceManager.cpp
frameworks/native/cmds/servicemanager/ main.cpp Access.cpp ServiceManager.cpp 本小节仅展示涉及变迁的文件路径。简洁起见只写了 cpp 文件,对应的 h 头文件可以附近查找。 另外需要特别区分的是,有两个 IServiceManager。 一个在 libbinder 中,是 Android 的 name space,直接被用户#include<binder/IServiceManager>使用。 另一个是 aidl 自动生成的 Android os 的 name space,被上面的 libbinder 所使#include<android/os/IServiceManager>。 2.3、小结 第二章节从全局的角度展示了 SM 切换到 aidl 和 libbinder的软件架构,结合图来看还是非常清楚易于理解的 接下来跟踪几个情景流程,展示新架构中的细节 三 servicemanager 启动流程分析图2:servicemanager 启动时序图 如上图,启动流程的变动主要在进入循环的方式,Android 11 之前是通过binder_loop方法,而现在是通过 looper。下面展示细节 frameworks/native/cmds/servicemanager/main.cpp int main(int argc, char** argv) { if (argc > 2) { LOG(FATAL) << "usage: " << argv[0] << " [binder driver]"; } const char* driver = argc == 2 ? argv[1] : "/dev/binder";//沟通binder驱动,open,mmap sp<ProcessState> ps = ProcessState::initWithDriver(driver); ps->setThreadPoolMaxThreadCount(0); //oneway限制,sm发起的binder调用必须是单向,否则打印堆栈日志提示 ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY); //实例化ServiceManager,传入Access类用于鉴权 sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>()); if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { LOG(ERROR) << "Could not self register servicemanager"; } //设置全局变量给IPCThreadState IPCThreadState::self()->setTheContextObject(manager); //注册到驱动,成为binder管理员,handle是0 ps->becomeContextManager(); //准备looper sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/); //通知驱动BC_ENTER_LOOPER,监听驱动fd,有消息时回调到handleEvent处理binder调用 BinderCallback::setupTo(looper); //服务的注册监听相关 ClientCallbackCallback::setupTo(looper, manager); //无限循环等消息 while(true) { looper->pollAll(-1); } // should not be reached return EXIT_FAILURE;} 和原来的 servicemanager 服务相比较,使用了 libbinder 后,代码更规范化,和其他 native 的服务风格一致了。
突然想起一个题目,servicemanager 映射的虚拟内存有多大?现在的答案是和普通应用一样大:1M-2 页。 frameworks/native/libs/binder/ProcessState.cpp #define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) 启动流程比较清晰不多赘述,下一小节看 addService 的流程。 四、addService 流程分析图3:defaultServiceManager流程 图4:addService 客户端流程 图5:addService 服务端流程 先上图,总览 native 的代码流程,客户端是 libbinder 里的 IServiceManager.cpp,服务端是我们的 ServiceManager.cpp 4.1 ServiceManagerShim::addService frameworks/native/libs/binder/IServiceManager.cpp status_t ServiceManagerShim::(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();} 直接使用的 mTheRealServiceManager,澄清疑问,mTheRealServiceManager 是谁? 4.1.1 mTheRealServiceManager 是谁? frameworks/native/libs/binder/IServiceManager.cpp #include <android/os/IServiceManager.h>using AidlServiceManager = android::os::IServiceManager;class ServiceManagerShim : public IServiceManager{protected: sp<AidlServiceManager> mTheRealServiceManager;......ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl): mTheRealServiceManager(impl){} 可以看到,mTheRealServiceManager 就是一个 android::os::IServiceManager 类型的实例,并且在 ServiceManagerShim 实例化时赋值。 那么 ServiceManagerShim 何时实例化呢?答案是 defaultServiceManager() 中 frameworks/native/libs/binder/IServiceManager.cpp sp<IServiceManager> defaultServiceManager(){ std::call_once(gSmOnce, []() { sp<AidlServiceManager> sm = nullptr; while (sm == nullptr) { //1、拿到AidlServiceManager类型的BpServiceManager(new BpBinder(0))实例 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); } } //2、new ServiceManagerShim gDefaultServiceManager = sp<ServiceManagerShim>::make(sm); }); return gDefaultServiceManager;} 如注释1、2,mTheRealServiceManager 就是在这样流程中赋值的。他的真是面目是BpServiceManager(new BpBinder(0))。 由图1可知,我们拿到了操作 binder 驱动的入口,BpServiceManager-->BpBinder-->IPCThreadState-->ioctl 关于一部分旧知识会贴拓展链接本文不做展开。interface_cast 的实现可参考:浅谈 Android 系统进程间通信(IPC)机制Binder 中的 Server 和 Client 获得 Service Manager 接口之路 好现在返回上节,直接走入 BpServiceManager#addService 方法 4.2 BpServiceManager::addService out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm_armv8-a_shared/gen/aidl/android/os/IServiceManager.cpp namespace android {namespace os {BpServiceManager::BpServiceManager(const ::android::sp<::android::IBinder>& _aidl_impl) : BpInterface<IServiceManager>(_aidl_impl){//_aidl_impl就是BpBinder(0)实例}-------------------------------------------------- ::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) {::android::Parcel _aidl_data; _aidl_data.markForBinder(remoteStrong());//0、和rpc binder有关::android::Parcel _aidl_reply;::android::status_t _aidl_ret_status = ::android::OK;::android::binder::Status _aidl_status; //1、写interface _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error;} //2、写name _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name); if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error;} //3、写binder对象 _aidl_ret_status = _aidl_data.writeStrongBinder(service); if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error;} //4、写allowIsolated _aidl_ret_status = _aidl_data.writeBool(allowIsolated); if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error;} //5、写dumpPriority _aidl_ret_status = _aidl_data.writeInt32(dumpPriority); if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error;} //6、借助BpBinder(0)-transact来发起binder通信 _aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_addService, _aidl_data, &_aidl_reply, 0); 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;} //7、如果有返回值就从这个parcel包里读 _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;} 把 Android 10 的贴上来,我们对比看看 frameworks/native/libs/binder/IServiceManager.cpp virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); data.writeInt32(dumpsysPriority); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; } 和11之前手写的 BpServiceManager 相比,本质是没变的,就是多了些花里胡哨的规范性代码。 到这里,客户端的代码就大致展示完了,transact 再往后就是旧有的流程,可参考:浅谈 Android 系统进程间通信(IPC)机制 Binder 中的 Server 和 Client 获得Service Manager 接口之路 之后走到 binder 驱动,驱动又根据 handle == 0 找到对端,我们的 servicemanager 进程,唤醒他开始处理请求。 4.3 BinderCallback::handleEvent 如图4:addService 服务端流程,现在开始服务端的流程展示 frameworks/native/cmds/servicemanager/main.cpp class BinderCallback : public LooperCallback {public:...... int handleEvent(int /* fd */, int /* events */, void* /* data */) override { IPCThreadState::self()->handlePolledCommands(); return 1; // Continue receiving callbacks. }}; 之后走到 BR_TRANSACTION frameworks/native/libs/binder/IPCThreadState.cpp status_t IPCThreadState::executeCommand(int32_t cmd){switch ((uint32_t)cmd) {case BR_TRANSACTION: { if (tr.target.ptr) { //因为目的端sm所以是tr.target.ptr是0 }else {//开始业务分发 error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } the_context_object 是 SM 启动的时候设置好的 sp<BBinder> the_context_object;void IPCThreadState::setTheContextObject(const sp<BBinder>& obj){ the_context_object = obj;} 是 ServiceManager 类实例,所以也是一个 BBinder 对象,所以就有了 transact()-->onTransact() 的处理能力。 所以现在the_context_object->transact()调用就走到 BBinder 的 transact 又走到BnServiceManager的onTransact()方法,回到了这个aidl自动生成的IServiceManager.cpp文件里 兜兜转转还是在这个文件 out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm_armv8-a_shared/gen/aidl/android/os/IServiceManager.cpp ::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_addService:{ ::std::string in_name; ::android::sp<::android::IBinder> in_service; bool in_allowIsolated; int32_t in_dumpPriority; //检查interface if (!(_aidl_data.checkInterface(this))) { _aidl_ret_status = ::android::BAD_TYPE; break; } //读name _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name); if (((_aidl_ret_status) != (::android::OK))) { break; } //读binder _aidl_ret_status = _aidl_data.readStrongBinder(&in_service); if (((_aidl_ret_status) != (::android::OK))) { break; } //读in_allowIsolated _aidl_ret_status = _aidl_data.readBool(&in_allowIsolated); if (((_aidl_ret_status) != (::android::OK))) { break; } //读in_dumpPriority _aidl_ret_status = _aidl_data.readInt32(&in_dumpPriority); if (((_aidl_ret_status) != (::android::OK))) { break; } //调用真正的ServiceManager.cpp中的实现 ::android::binder::Status _aidl_status(addService(in_name, in_service, in_allowIsolated, in_dumpPriority)); //如果有返回写返回到_aidl_reply _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); if (((_aidl_ret_status) != (::android::OK))) { break; } if (!_aidl_status.isOk()) { break; }} 和Bp端是对称的操作,下一步走到 ServiceManager.cpp::addService 方法 4.4 ServiceManager::addService frameworks/native/cmds/servicemanager/ServiceManager.cpp Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) { auto ctx = mAccess->getCallingContext(); // uid鉴权 if (multiuser_get_app_id(ctx.uid) >= AID_APP) { return Status::fromExceptionCode(Status::EX_SECURITY); } //selinux鉴权 if (!mAccess->canAdd(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY); } if (binder == nullptr) { return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); } //检查name命名 if (!isValidServiceName(name)) { LOG(ERROR) << "Invalid service name: " << name; return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); } //如果vndservicemanager则检查VINTF manifest#ifndef VENDORSERVICEMANAGER if (!meetsDeclarationRequirements(binder, name)) { // already logged return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); }#endif // !VENDORSERVICEMANAGER //和rpc有关,死亡监听 // implicitly unlinked when the binder is removed if (binder->remoteBinder() != nullptr && binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) { LOG(ERROR) << "Could not linkToDeath when adding " << name; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } //新增一个结构体到map中 // Overwrite the old service if it exists mNameToService[name] = Service { .binder = binder, .allowIsolated = allowIsolated, .dumpPriority = dumpPriority, .debugPid = ctx.debugPid, }; //架构中提到的waiteForService的跨进程 auto it = mNameToRegistrationCallback.find(name); if (it != mNameToRegistrationCallback.end()) { for (const sp<IServiceCallback>& cb : it->second) { mNameToService[name].guaranteeClient = true; // permission checked in registerForNotifications cb->onRegistration(name, binder); } } return Status::ok();} 五、其他值得关注的细节前两节是全局总览、经典情景的视角看代码,现在我们换一个视角,展示一些边边角角的内容为上面的主干填充细节。 5.1 Servicemanager 的能力变化 Android 11 之前仅有 4 种接口暴露给应用 frameworks/native/libs/binder/include/binder/IServiceManager.h enum { GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, CHECK_SERVICE_TRANSACTION, ADD_SERVICE_TRANSACTION, LIST_SERVICES_TRANSACTION, }; 而 Android 11 增加到9个,Android 12 又增加到 13 个 out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm_armv8-a_shared/gen/aidl/android/os/BnServiceManager.h class BnServiceManager : public ::android::BnInterface<IServiceManager> {public: static constexpr uint32_t TRANSACTION_getService = ::android::IBinder::FIRST_CALL_TRANSACTION + 0; static constexpr uint32_t TRANSACTION_checkService = ::android::IBinder::FIRST_CALL_TRANSACTION + 1; static constexpr uint32_t TRANSACTION_addService = ::android::IBinder::FIRST_CALL_TRANSACTION + 2; static constexpr uint32_t TRANSACTION_listServices = ::android::IBinder::FIRST_CALL_TRANSACTION + 3; static constexpr uint32_t TRANSACTION_registerForNotifications = ::android::IBinder::FIRST_CALL_TRANSACTION + 4; static constexpr uint32_t TRANSACTION_unregisterForNotifications = ::android::IBinder::FIRST_CALL_TRANSACTION + 5; static constexpr uint32_t TRANSACTION_isDeclared = ::android::IBinder::FIRST_CALL_TRANSACTION + 6; static constexpr uint32_t TRANSACTION_getDeclaredInstances = ::android::IBinder::FIRST_CALL_TRANSACTION + 7; static constexpr uint32_t TRANSACTION_updatableViaApex = ::android::IBinder::FIRST_CALL_TRANSACTION + 8; static constexpr uint32_t TRANSACTION_getConnectionInfo = ::android::IBinder::FIRST_CALL_TRANSACTION + 9; static constexpr uint32_t TRANSACTION_registerClientCallback = ::android::IBinder::FIRST_CALL_TRANSACTION + 10; static constexpr uint32_t TRANSACTION_tryUnregisterService = ::android::IBinder::FIRST_CALL_TRANSACTION + 11; static constexpr uint32_t TRANSACTION_getServiceDebugInfo = ::android::IBinder::FIRST_CALL_TRANSACTION + 12; 从这些接口的变动我们也可以很清晰地把握住 servicemanager 的前进方向 5.2 DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE frameworks/native/libs/binder/include/binder/IInterface.h #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) static_assert(internal::allowedManualInterface(NAME), "b/64223827: Manually written binder interfaces are " "considered error prone and frequently have bugs. " "The preferred way to add interfaces is to define " "an .aidl file to auto-generate the interface. If " "an interface must be manually written, add its " "name to the whitelist."); DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \-----------------------------constexpr const char* const kManualInterfaces[] = { "android.app.IActivityManager", "android.app.IUidObserver", "android.drm.IDrm", "android.dvr.IVsyncCallback", "android.dvr.IVsyncService", "android.gfx.tests.ICallback", "android.gfx.tests.IIPCTest",...... 以后手写的 native 服务需要关注下这个宏,做了限制。谷歌建议是现在的 native服务都用 aidl,别手写 5.3 String16、String8 与 name aidl 改造之前,都是一路 String16 从客户端传到服务端,而现在需要绕一些路了。还是以 addService 为例 status_t ServiceManagerShim::addService(const String16& name,){ Status status = mTheRealServiceManager->addService( String8(name).c_str(), );在这里转一次,16转成8 ------------------------------------------ _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name); 在BpServiceManager里又转了一次,8转16 ------------------------------------------ _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name); 现在来到BnServiceManager继续转,16转8 转来转去快晕了。总结就是,SM 服务端都是操作的 utf8,而 libbinder 客户端都是 utf16。有修改的话需要注意下编码问题 也可能是由于这个转换问题,在服务端加了个服务名检查 bool isValidServiceName(const std::string& name) { if (name.size() == 0) return false; if (name.size() > 127) return false; for (char c : name) { if (c == '_' || c == '-' || c == '.' || c == '/') continue; if (c >= 'a' && c <= 'z') continue; if (c >= 'A' && c <= 'Z') continue; if (c >= '0' && c <= '9') continue; return false; } return true;} 5.4 服务保存的数据结构 SM 需要保存服务及其对应的信息,Android 11 前用的链表 svc_list,成员是 svc_info 结构体;Android 11 后用的 map,成员也是结构体 frameworks/native/cmds/servicemanager/ServiceManager.h struct Service { sp<IBinder> binder; // not null bool allowIsolated; int32_t dumpPriority; bool hasClients = false; // notifications sent on true -> false. bool guaranteeClient = false; // forces the client check to true pid_t debugPid = 0; // the process in which this service runs // the number of clients of the service, including servicemanager itself ssize_t getNodeStrongRefCount(); }; using ServiceMap = std::map<std::string, Service>; ServiceMap mNameToService; 这个 Service 结构体有了更多的信息和能力,getNodeStrongRefCount() 方法可以获取该服务有多少个客户端 5.5 listServices 返回值 Android 11 之前的实现是客户端循环 checkService,Android 11 之后是直接返回的是 std::vector
frameworks/native/libs/binder/IServiceManager.cpp Vector<String16> ServiceManagerShim::listServices(int dumpsysPriority){ std::vector<std::string> ret; if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) { return {}; } Vector<String16> res; res.setCapacity(ret.size()); for (const std::string& name : ret) { res.push(String16(name.c_str())); } return res;}
frameworks/native/cmds/servicemanager/ServiceManager.cpp Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) { size_t toReserve = 0; for (auto const& [name, service] : mNameToService) { (void) name; if (service.dumpPriority & dumpPriority) ++toReserve; } outList->reserve(toReserve); for (auto const& [name, service] : mNameToService) { (void) service; if (service.dumpPriority & dumpPriority) { outList->push_back(name); } } 这里也可以看到字符编码的问题,客户端用的是 utf16,而服务端用的是 utf8
frameworks/native/cmds/dumpsys/dumpsys.cpp if (services.empty() || showListOnly) { services = listServices(priorityFlags, asProto); ...... if (N > 1) { for (size_t i=0; i<N; i++) { sp<IBinder> service = sm_->checkService(services[i]); 获取到服务列表后为什么再循环 check 一遍呢?我感觉是没有必要的。 5.6 waitForService 与 IServiceCallback.aidl 利用了匿名 binder 来传递回调,有兴趣可以自己看看
frameworks/native/libs/binder/IServiceManager.cpp sp<IBinder> ServiceManagerShim::waitForService(const String16& name16){ class Waiter : public android::os::BnServiceCallback { Status onRegistration(const std::string& /*name*/, const sp<IBinder>& binder) override { ...... sp<Waiter> waiter = sp<Waiter>::make(); if (Status status = mTheRealServiceManager->registerForNotifications(name, waiter);
frameworks/native/cmds/servicemanager/ServiceManager.cpp Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {auto it = mNameToRegistrationCallback.find(name); if (it != mNameToRegistrationCallback.end()) { for (const sp<IServiceCallback>& cb : it->second) { mNameToService[name].guaranteeClient = true; // permission checked in registerForNotifications cb->onRegistration(name, binder); } }
frameworks/native/libs/binder/aidl/android/os/IServiceCallback.aidl 5.7 IClientCallback.aidl IServiceManager.aidl 中定义的接口,都是在#include <binder/IServiceManager.h>吗?答案为否。IClientCallback 就是这样一个例子 想用 registerClientCallback 方法注册回调,需要直接使用#include <android/os/IServiceManager.h>拿到 BpServiceManager 实例,来通信 这个接口没有暴露在 libbinder 的 IServiceManager 中 这个回调用于监听某个服务有 client,和 IServiceCallback.aidl 一样是匿名 binder服务,一个例子 LazyServiceRegistrar.cpp,可自行了解。 代码路径 frameworks/native/libs/binder/aidl/android/os/IClientCallback.aidl 六、总结
|
|