frameworks 之ServiceManager
ServiceManager 作为android中的路由器提供服务注册以及查询的功能。本文讲解对应的 启动,以及如何服务端和客户端一个沟通。
涉及到的类如下
- frameworks/native/cmds/servicemanager/servicemanager.rc
- frameworks/native/cmds/servicemanager/Android.bp
- frameworks/native/cmds/servicemanager/main.cpp
- frameworks/native/cmds/servicemanager/ServiceManager.h
- frameworks/native/cmds/servicemanager/ServiceManager.cpp
- frameworks/native/libs/binder/include/binder/IInterface.h
- frameworks/native/libs/binder/include/binder/Binder.h
- frameworks/native/libs/binder/include/binder/IBinder.h
- frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
- frameworks/native/libs/binder/Android.bp
- frameworks/native/libs/binder/include/binder/IServiceManager.h
- frameworks/native/libs/binder/Binder.cpp
解析启动入口
ServiceManager 也是在init解析时候,通过解析 rc 文件启动。对应的 rc 文件详解。可以看到启动名称为 servicemanager 对应执行的脚本为 /system/bin/servicemanager。所以 bp 肯定会生成对应的脚本名称为 servicemanager。
# frameworks/native/cmds/servicemanager/servicemanager.rc
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
# 表明这个Service对设备至关重要,如果Service在四分钟内退出超过4次,则设备将重启进入recovery模式
critical
# onrestart在重启时执行一条命令
onrestart restart apexd
onrestart restart audioserver
onrestart restart gatekeeperd
# 重启时,重启class为main、hal、early_hal的所有服务
onrestart class_restart main
onrestart class_restart hal
onrestart class_restart early_hal
writepid /dev/cpuset/system-background/tasks
shutdown critical
查看该目录对应的 Bp 文件,根据生成的名称,可以看到启动入口为 main.cpp 。(ServiceManager.cpp和Access.cpp一起生成了servicemanager_defaults,然后通过servicemanager_defaults编译生成可运行的servicemanager.)
# frameworks/native/cmds/servicemanager/Android.bp
cc_defaults {
name: "servicemanager_defaults",
...
srcs: [
"Access.cpp",
"ServiceManager.cpp",
],
...
}
...
cc_binary {
name: "servicemanager",
defaults: ["servicemanager_defaults"],
init_rc: ["servicemanager.rc"],
srcs: ["main.cpp"],
}
启动
查看对应 main.cpp 的 main 入口。其中会根据是否传参数传驱动节点,因为 rc 文件后面不带参数,所以 driver 值为 /dev/binder。该方法主要作用是
- 加载驱动,映射内存,主要在该方法进行 initWithDriver 。该方法的实现可查看 Binder启动 该文章。
- 创建 ServiceManager, 并通过 addService 添加自己到服务中。其中 ServiceManager继承BnServiceManager。(在头文件建中继承,该BnServiceManager 通过AIDL生成)
- 调用 setTheContextObject 设置到 单例 IPCThreadState 中,并且通过 ProcessState的****becomeContextManager 通知驱动设置为标识。
- 调用 Looper::prepare 初始化 Looper,并注册对应的回调监听。最后通过 pollAll 开启等待消息。)具体的实现可参看 Looper 文章。
// frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
// rc 文件没有参数 所以默认为 "/dev/binder"
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
// 和binder启动一样 调用 initWithDriver 里面也是调用 init 方法 打开驱动和映射内存大小
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
// 设置thread poll的最大线程数量
ps->setThreadPoolMaxThreadCount(0);
//设置调用限制,FATAL_IF_NOT_ONEWA意思是:在阻塞调用时中止进程
//oneway 限制,ServiceManager发起的 Binder 调用必须是单向,否则打印堆栈日志提示
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
// 实例化ServiceManager, Access为鉴权
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
// 将自己添加到服务中ServiceManager
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
// 创建设置全局变量给IPCThreadState, 并设置 ServiceManager 值给the_context_object
IPCThreadState::self()->setTheContextObject(manager);
// 将handle是0注册到binder驱动中
ps->becomeContextManager();
// 准备looper
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
// 以前是 binder_loop死 循环接收驱动的消息,现在是 通知驱动BC_ENTER_LOOPER,监听驱动fd,有消息时回调到handleEvent处理binder调用
// 在looper的 response
BinderCallback::setupTo(looper);
// 服务的注册监听相关
ClientCallbackCallback::setupTo(looper, manager);
// 无限循环等待消息
while(true) {
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
// frameworks/native/cmds/servicemanager/ServiceManager.h
class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {...}
becomeContextManager 通过 ioctl 跟驱动交互。
bool ProcessState::becomeContextManager()
{
AutoMutex _l(mLock);
flat_binder_object obj {
.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
};
int result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);
// fallback to original method
if (result != 0) {
android_errorWriteLog(0x534e4554, "121035042");
int unused = 0;
result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused);
}
if (result == -1) {
ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
}
return result == 0;
}
AIDL实现类
serviceManger 启动后,其他的服务端和客户端跟ServiceManger 不是直接跟 ServiceManger 交互,而是通过Binder驱动 跟 ServiceManger交互。
有几个类需要区分,非常重要
如果要创建一个AIDL交互,
需要Server端继承BnInterface, Client端继承BpInterface
BnInterface 在 IInterface.h 中,继承于 BBinder(而BBinder又继承于 IBinder)
BpInterface 在 IInterface.h 中,继承于 BpRefBase(而 RefBase 又继承于 RefBase)
// frameworks/native/libs/binder/include/binder/IInterface.h
// 继承于 BBinder
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
typedef INTERFACE BaseInterface;
virtual IBinder* onAsBinder();
};
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
explicit BpInterface(const sp<IBinder>& remote);
protected:
typedef INTERFACE BaseInterface;
virtual IBinder* onAsBinder();
};
BBinder 代码位于 Binder.h 中
// frameworks/native/libs/binder/include/binder/Binder.h
class BBinder : public IBinder
{
...
}
IBinder 位于IBinder.h 中
// frameworks/native/libs/binder/include/binder/IBinder.h
class [[clang::lto_visibility_public]] IBinder : public virtual RefBase
{
...
}
BpRefBase f位于 Binder.h 中
// frameworks/native/libs/binder/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
...
}
便于理解 可以总结为 Bp 代表 AIDL 客户端,Bn 代表 AIDL 服务端。
ServiceManger 的 AIDL 位于 frameworks/native/libs/binder/aidl/android/os/文件下,其中IServiceManager.aidl 定义了 addService 等方法。
对应模块下的 bp 文件定义了对该AIDL的引用
# frameworks/native/libs/binder/Android.bp
cc_library {
name: "libbinder",
// for vndbinder
vendor_available: true, vndk: { enabled: true, },
...
srcs: [
"Binder.cpp",
"BpBinder.cpp",
"IInterface.cpp",
"IPCThreadState.cpp",
"IServiceManager.cpp", //对应的cpp文件
...
":libbinder_aidl",//引用aidl文件
],
aidl: {//输出aidl头文件
export_aidl_headers: true,
},
},
// AIDL interface between libbinder and framework.jar
filegroup {
name: "libbinder_aidl",
srcs: [//aidl文件
"aidl/android/os/IClientCallback.aidl",
"aidl/android/os/IServiceCallback.aidl",
"aidl/android/os/IServiceManager.aidl",
"aidl/android/os/ServiceDebugInfo.aidl",
],
path: "aidl",
}
其中 IServiceManager.cpp 通过using 关键字定义了别名 AidlServiceManager,提供了 defaultServiceManager 方法。类ServiceManagerShim继承了IServiceManager,Client端的请求都是由ServiceManagerShim 代理类进行调用。
AIDL 生成的文件 位于 该目录下out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os。其中 IServiceManager.h, BnServiceManager.h,BpServiceManager.h,为生成了这几个类的头文件。IServiceManager.cpp 则是 BnServiceManager,BpServiceManager 的具体实现。该类主要实现对binder数据的调用。
客户端Bp发送讲解
正常我们对ServiceManger 添加服务调用 addService 代码如下
sp<ProcessState> proc(ProcessState::self());
//获取B对应BpServiceManager指针
sp<IServiceManager> sm = defaultServiceManager();
sp<SimpleManagerService> mService = new SimpleManagerService();
//通过IServiceManager注册服务
sm->addService(String16(NATIVESERVICE_NAME), mService, false);
ProcessState::self()->startThreadPool();
// 开启消息监听,不循环 测试程序会结束
IPCThreadState::self()->joinThreadPool();
1. 获取 BpServiceManager
可以看出调用 ServiceManger 第一步是调用 defaultServiceManager 获取对应的对ServiceManger代理对象。
defaultServiceManager 方法如下,部分代码中文说明。
sp<IServiceManager> defaultServiceManager()
{
std::call_once(gSmOnce, []() {
sp<AidlServiceManager> sm = nullptr;
while (sm == nullptr) {
// 拿到客户端BpServiceManager(new BpBinder(0))的实例
// frameworks/native/libs/binder/include/binder/IInterface.h
// (interface_cast<IServiceManager>() 等价于 IServiceManager::asInterface(),asInterface是通过模板函数来定义的
sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
// 如果为空 serviceManger还没好则循环睡眠1秒
if (sm == nullptr) {
ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
sleep(1);
}
}
gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
});
return gDefaultServiceManager;
}
interface_cast 方法需要一个参数,该参数为**BpBInder(0)**对象。具体流程如下,通过调用 getContextObject ,而该方法又会调用 getStrongProxyForHandle 并传入参数为0。
// frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
// 调用 getStrongProxyForHandle 传入参数为0
sp<IBinder> context = getStrongProxyForHandle(0);
if (context) {
// The root object is special since we get it directly from the driver, it is never
// written by Parcell::writeStrongBinder.
internal::Stability::markCompilationUnit(context.get());
} else {
ALOGW("Not able to get context object on %s.", mDriverName.c_str());
}
return context;
}
而 getStrongProxyForHandle 会创建对象并判断 handle 为0 ,继而创建了 BpBInder对象。这很重要。后续将会用到该对象。所以可以说 getContextObject 返回了 BpBinder对象。
// frameworks/native/libs/binder/ProcessState.cpp
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
// 第一次为空,所以size 等于0, 传进来的参数handle也为0,所以会插入一个实体类为空的
const size_t N=mHandleToObject.size();
if (N <= (size_t)handle) {
handle_entry e;
e.binder = nullptr;
e.refs = nullptr;
status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
if (err < NO_ERROR) return nullptr;
}
return &mHandleToObject.editItemAt(handle);
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
// 会判断是否大于该数字,如果小于则创建
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. The
// attemptIncWeak() is safe because we know the BpBinder destructor will always
// call expungeHandle(), which acquires the same lock we are holding now.
// We need to do this because there is a race condition between someone
// releasing a reference on this BpBinder, and a new reference on its handle
// arriving from the driver.
IBinder* b = e->binder;
// 因为刚插入所以为空
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
// Special case for context manager...
// The context manager is the only object for which we create
// a BpBinder proxy without already holding a reference.
// Perform a dummy transaction to ensure the context manager
// is registered before we create the first local reference
// to it (which will occur when creating the BpBinder).
// If a local reference is created for the BpBinder when the
// context manager is not present, the driver will fail to
// provide a reference to the context manager, but the
// driver API does not return status.
//
// Note that this is not race-free if the context manager
// dies while this code runs.
//
// TODO: add a driver API to wait for context manager, or
// stop special casing handle 0 for context manager and add
// a driver API to get a handle to the context manager with
// proper reference counting.
IPCThreadState* ipc = IPCThreadState::self();
CallRestriction originalCallRestriction = ipc->getCallRestriction();
ipc->setCallRestriction(CallRestriction::NONE);
Parcel data;
status_t status = ipc->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
ipc->setCallRestriction(originalCallRestriction);
if (status == DEAD_OBJECT)
return nullptr;
}
// 创建 BpBInder对象
sp<BpBinder> b = BpBinder::create(handle);
// 对实体类赋值
e->binder = b.get();
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
返回了 BpBInder 对象做参数参数,传进去 interface_cast 方法,该方法创建了对象代理对象。interface_cast 方法在 IInterface.h 。采用模板类,类似于java 范型方法。
// frameworks/native/libs/binder/include/binder/IInterface.h
// 模板类 类似范型
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
而上面调用 interface_cast 传进去的类型为 AidlServiceManager 也即为 IServiceManager 的别名。
// frameworks/native/libs/binder/IServiceManager.cpp
// 定义别名,所以 AidlServiceManager 就是 IServiceManager
using AidlServiceManager = android::os::IServiceManager;
iServiceManger 继承 IInterface, 查看 IInterface 里面的 asInterface 实现和定义
// frameworks/native/libs/binder/include/binder/IServiceManager.h
class IServiceManager : public IInterface { ... }
// frameworks/native/libs/binder/include/binder/IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE) \
public: \
... \
// 定义了方法
static ::android::sp<I##INTERFACE> asInterface( \
const ::android::sp<::android::IBinder>& obj);
可以看到 对应的实现 如果不为空则先进行获取,获取不到则创建对应的对象 可以看到根据对应的模板通过make创建对象, 返回的是 BpServiceManger。
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\
... \
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != nullptr) { \
intr = ::android::sp<I##INTERFACE>::cast( \
obj->queryLocalInterface(I##INTERFACE::descriptor)); \
if (intr == nullptr) {
// 通过make 创建带Bp实现类,也则是 BpServiceManger
intr = ::android::sp<Bp##INTERFACE>::make(obj); \
} \
} \
return intr; \
}
创建代理类 ServiceManagerShim 返回
接下来 通过make参数 创建 ServiceManagerShim代理类 (该类在IServiceManager.cpp)并将上面创建 BpServiceManger 作为参数传进去,查看对应的构造方法。该参数赋值给了 mTheRealServiceManager,所以 mTheRealServiceManager 就是 BpServiceManger。
// frameworks/native/libs/binder/IServiceManager.cpp
gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
// 构造方法赋值给了 mTheRealServiceManager
ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
: mTheRealServiceManager(impl)
{}
所以得到最终 defaultServiceManager 返回的就是 ServiceManagerShim 对象。
调用对应AIDL方法
用 addService 为例子,查看 ServiceManagerShim 的实现,可以看到该方法最终是调用 BpServiceManger 的方法。
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority)
{
// mTheRealServiceManager 为 BpServiceManger
Status status = mTheRealServiceManager->addService(
String8(name).c_str(), service, allowIsolated, dumpsysPriority);
return status.exceptionCode();
}
BpServiceManger 是 AIDL生成的,如上面AIDL的讲解以及对应生成路径,BpServiceManger 实现方法逻辑代码 在 IServiceManager.cpp,查看对应的实现方法可以看到 通过 创建 Parcel 实体类作为数据传输。然后通过调用关键代码 remote()->transact 通知驱动。
// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/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;
_aidl_data.markForBinder(remoteStrong());
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
// 注远程服务名称,getInterfaceDescriptor为远程服务端接口描述
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinder(service);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeBool(allowIsolated);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeInt32(dumpPriority);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
// 关键代码, 通过调用 remote()->transact
_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;
}
_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;
}
remote() 返回的是什么对象,查看生成头文件继承自 BpInterface,而 BpInterface 又继承 BpRefBase
// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/BpServiceManager.h
class BpServiceManager : public ::android::BpInterface<IServiceManager> {}
查看 BpRefBase,可以看到该对象又继承 RefBase,可以看到 方法 remote() 返回了 mRemote 对象。
// frameworks/native/libs/binder/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
protected:
explicit BpRefBase(const sp<IBinder>& o);
virtual ~BpRefBase();
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
// 返回的是 mRemote 对象
inline IBinder* remote() const { return mRemote; }
inline sp<IBinder> remoteStrong() const { return sp<IBinder>::fromExisting(mRemote); }
private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;
RefBase::weakref_type* mRefs;
std::atomic<int32_t> mState;
};
mRemote 又是在 在其构造方法通过参数赋值
// frameworks/native/libs/binder/Binder.cpp
// 通过构造参数传入
BpRefBase::BpRefBase(const sp<IBinder>& o)
: mRemote(o.get()), mRefs(nullptr), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
}
而因为 BpInterface 继承 BpRefBase 所以又是他将 将入参remote赋值给了BpRefBase。
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}
而上面 BpServiceManager 继承于BpInterface,所以该参数又来自BpServiceManager的构造参数。而上面调用 interface_cast 创建 BpServiceManager对象的时候,我们又知道 传进去的 就是 BpBinder(0)。 所以可知
remote() 返回的对象就是 BpBinder。所以 remote()->transact 调用的 就是 BpBinder 的 transact方法。
调用驱动通知
查看对应 BpBInder transact 方法。最终又会调用 IPCThreadState::self()->transact 方法
// frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
bool privateVendor = flags & FLAG_PRIVATE_VENDOR;
// don't send userspace flags to the kernel
flags = flags & ~FLAG_PRIVATE_VENDOR;
// user transactions require a given stability level
if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
using android::internal::Stability;
auto category = Stability::getCategory(this);
Stability::Level required = privateVendor ? Stability::VENDOR
: Stability::getLocalLevel();
if (CC_UNLIKELY(!Stability::check(category, required))) {
ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
category.debugString().c_str(),
String8(getInterfaceDescriptor()).c_str(),
Stability::levelString(required).c_str());
return BAD_TYPE;
}
}
status_t status;
if (CC_UNLIKELY(isRpcBinder())) {
status = rpcSession()->transact(rpcAddress(), code, data, reply, flags);
} else {
// //调用 IPCThreadState 方法
status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
}
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
查看 IPCThreadState 方法 该方法又会调用 writeTransactionData 方法。
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
....
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
// 写入数据
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
...
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
....
}
进入该方法,通知驱动的数据格式为 binder_transaction_data。所以要创建该实体类,并写入数据,因为是客户端,所以 cmd 为 BC_TRANSACTION
status_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;
}
waitForResponse 通过 talkWithDriver 方法跟 驱动通信将数据写入到驱动。该方法里面最终调用 ioctl 发送。
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
... //和Driver通信
if ((err=talkWithDriver()) < NO_ERROR) break;
...
}
status_t IPCThreadState::talkWithDriver(bool doReceive) {
...
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
...
}
这样客户端调用完整流程就结束了。
服务端Bn接收讲解
注册Binder回调监听
服务端的接收回到 一开始 main.cpp 注册的Looper监听回调。代码如下 通过 setupTo 方法 添加对应的监听。BinderCallback 主要监听对应的消息进行处理。
// frameworks/native/cmds/servicemanager/main.cpp
class BinderCallback : public LooperCallback {
public:
static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
// 实例化BinderCallback
sp<BinderCallback> cb = sp<BinderCallback>::make();
int binder_fd = -1;
//通过IPCThreadState获取binder_fd,即监听binder驱动的消息
IPCThreadState::self()->setupPolling(&binder_fd);
LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
// 添加文件描述符
int ret = looper->addFd(binder_fd,
Looper::POLL_CALLBACK,
Looper::EVENT_INPUT,
cb,
nullptr /*data*/);
LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
return cb;
}
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
IPCThreadState::self()->handlePolledCommands();
return 1; // Continue receiving callbacks.
}
};
int main(int argc, char** argv) {
...
// 在looper的 response
BinderCallback::setupTo(looper);
...
}
之前说过 Looper 通过 addFd 添加监听,添加对应的 fd 通过 setupPolling 方法获取,进去方法可知 返回的正是驱动FD。所以可知,监听的正在Binder驱动的响应。
// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::setupPolling(int* fd)
{
if (mProcess->mDriverFD < 0) {
return -EBADF;
}
mOut.writeInt32(BC_ENTER_LOOPER);
flushCommands();
// 驱动FD
*fd = mProcess->mDriverFD;
return 0;
}
Binder消息处理
通过 Looper 文章可知,有消息相应会触发 handleEvent 回调。查看BinderCallback 对应的 handleEvent 方法。而 handleEvent 里面又会调用 handlePolledCommands 方法。
// frameworks/native/cmds/servicemanager/main.cpp
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
IPCThreadState::self()->handlePolledCommands();
return 1; // Continue receiving callbacks.
}
查看 handlePolledCommands 又会接着调用 getAndExecuteCommand 方法。
// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::handlePolledCommands()
{
status_t result;
do {
result = getAndExecuteCommand();
} while (mIn.dataPosition() < mIn.dataSize());
processPendingDerefs();
flushCommands();
return result;
}
getAndExecuteCommand 会调用 talkWithDriver 读取对应的对象,并读取对应的cmd值,传进去 executeCommand 进行解析,对应的 cmd 为 BR_TRANSACTION。
status_t IPCThreadState::getAndExecuteCommand()
{
status_t result;
int32_t cmd;
//从binder driver获取mIn数据
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) return result;
// 读取出对应 CMD,服务端的应该为 BR_TRANSACTION
cmd = mIn.readInt32();
...
// 解析出对应的cmd,执行cmd
result = executeCommand(cmd);
...
}
return result;
}
查看对应的 executeCommand 方法。查看对应的 BR_TRANSACTION 解析可以看到最终调用了 the_context_object 方法。而 the_context_object 在 ServiceManger 的 main.cpp 方法,可知是通过 setTheContextObject 赋值,所以可知 the_context_object 即为 serviceManger。
// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::executeCommand(int32_t cmd)
{
...
switch ((uint32_t)cmd) {
case BR_TRANSACTION:
{
...
} else {
//sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
//IPCThreadState::self()->setTheContextObject(manager);//将manager设置给了the_context_object,所以the_context_object就是Server端ServerManager对象
//调用BBinder的transact
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
...
}
因为 ServiceManger 继承自 BnServiceManager (AIDL生成)
class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {}
而 BnServiceManager 又继承自 BnInterface
// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/BnServiceManager.h
class BnServiceManager : public ::android::BnInterface<IServiceManager> {}
BnInterface 又是继承 BBinder
// frameworks/native/libs/binder/include/binder/IInterface.h
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
typedef INTERFACE BaseInterface;
virtual IBinder* onAsBinder();
};
所以 the_context_object->transact 也就是调用了 BBinder的 transact 方法。查看对应实现,可发现该方法调用了 onTransact 方法。
// frameworks/native/libs/binder/Binder.cpp
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
if (reply != nullptr && (flags & FLAG_CLEAR_BUF)) {
reply->markSensitive();
}
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:
// 调用对应的 onTransact 方法
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;
}
BnServiceManager 实现了 onTransact 方法。 跟BpServiceManager一样,该类的方法实现也在AIDL 生成的 IServiceManager.cpp 里。查看 BnServiceManager 方法,这里举例 addService 方法,可以看到 最终调用了addService(in_name, in_service, in_allowIsolated, in_dumpPriority) 方法。该方法为ServiceManger实现,也就是回调了 ServiceManger类里面的方法
// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_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;
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;
}
// 调用 addService 方法,该方法为ServiceManger实现,也就是回调了 ServiceManger类里面的方法。
::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;
}
return _aidl_ret_status;
}
...
ServiceManger 的 addService 方法
// frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
...
// Overwrite the old service if it exists
mNameToService[name] = Service {
.binder = binder,
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
.debugPid = ctx.debugPid,
};
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();
}
至此 服务端也接收和处理完对应的Binder消息,实现 客户端到服务端通讯。
备注
在Android的Binder通信机制中,BR_TRANSACTION 和 BC_TRANSACTION 都是用于定义Binder通信中的消息类型的宏,但它们有着不同的作用和用途。
BR_TRANSACTION 用于定义一个读取操作的IO控制码,表示从用户空间读取数据到内核空间。
‘r’ 表示操作的方向,即从用户空间到内核空间的读取操作
BC_TRANSACTION 用于定义一个写入操作的IO控制码,表示从内核空间写入数据到用户空间。
‘c’ 表示操作的方向,即从内核空间到用户空间的写入操作。
struct binder_transaction_data 是与该IO操作相关联的数据结构,用于描述从内核传递到用户空间的Binder事务的详细信息。
IO控制码类型:_IOR 和 _IOW 分别用于指定读取和写入操作