源码基于:Android R
0. 前言
上一篇博文中 已经得知如何通过 defaultServiceManager() 得来的 BpInterface 与 servciemanager 进行通信,并分析了addServcie() 的流程,这里再来看下service 的获取过程。
1. getService()
这个接口有两种方式,一个是通过 defaultServiceManager() 获取到 servicemanager 的 BpBinder,然后再通过该代理的 getService() 进行调用;另一个是 IServiceManager.h 中直接提供了全局的接口函数。
1.1 全局接口函数 getService()
frameworks/native/libs/binder/include/binder/IServiceManager.h
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) != nullptr) return NO_ERROR;
}
return NAME_NOT_FOUND;
}
这里封装了 defaultServiceManager(),然后再调用 getService()。
1.2 代理接口函数 getService()
frameworks/native/libs/binder/IServiceManager.cpp
sp<IBinder> ServiceManagerShim::getService(const String16& name) const
{
static bool gSystemBootCompleted = false;
sp<IBinder> svc = checkService(name);
if (svc != nullptr) return svc;
const bool isVendorService =
strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
const long timeout = 5000;
int64_t startTime = uptimeMillis();
// Vendor code can't access system properties
if (!gSystemBootCompleted && !isVendorService) {
#ifdef __ANDROID__
char bootCompleted[PROPERTY_VALUE_MAX];
property_get("sys.boot_completed", bootCompleted, "0");
gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false;
#else
gSystemBootCompleted = true;
#endif
}
// retry interval in millisecond; note that vendor services stay at 100ms
const long sleepTime = gSystemBootCompleted ? 1000 : 100;
int n = 0;
while (uptimeMillis() - startTime < timeout) {
n++;
ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(),
ProcessState::self()->getDriverName().c_str());
usleep(1000*sleepTime);
sp<IBinder> svc = checkService(name);
if (svc != nullptr) return svc;
}
ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
return nullptr;
}
代码逻辑比较简单,通过checkServcie() 确认servcie 是否存在,如果没有会有 5s 的retry,如果还是没有 checkService() 成功,则返回nullptr。
2. checkService()
frameworks/native/libs/binder/IServiceManager.cpp
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
sp<IBinder> ret;
if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
return nullptr;
}
return ret;
}
上一篇博文 已经分析过 BpBinder 到 BBinder 的通信流程,对于BpServcieManager,其handle 比较特殊,值为0,其实无论特殊与否,最终都会调用到 BBinder 的 transact():
frameworks/native/libs/binder/Binder.cpp
status_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;
}
除了特殊的code,其他的都会继续调用onTransact,而BBinder 的onTransact 会被Bn端覆盖掉。
2.1 BpServiceManager::checkService()
out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/frameworks/native/libs/binder/aidl/android/os/IServiceManager.cpp
::android::binder::Status BpServiceManager::checkService(const ::std::string& name, ::android::sp<::android::IBinder>* _aidl_return) {
::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());
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 = remote()->transact(::android::IBinder::FIRST_CALL_TRANSACTION + 1 /* checkService */, _aidl_data, &_aidl_reply);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IServiceManager::getDefaultImpl())) {
return IServiceManager::getDefaultImpl()->checkService(name, _aidl_return);
}
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_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
这里主要是将code 为 ::android::IBinder::FIRST_CALL_TRANSACTION + 1 传到server 端, 携带的参数有两个,一个是 name 会写到 _aidl_data 传到server 端,另外一个是 _aidl_return,需要在 transact 返回后从 _aidl_reply 中读出来。
注意这里的 _aidl_replay.readNullableStrongBinder(),后面统一分析。
2.2 BnServiceManager::onTransact()
out/soong/.intermediates/frameworks/native/libs/binder/libbinder/.../gen/aidl/frameworks/native/libs/binder/aidl/android/os/IServiceManager.cpp
case ::android::IBinder::FIRST_CALL_TRANSACTION + 1 /* checkService */:
{
::std::string in_name;
::android::sp<::android::IBinder> _aidl_return;
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;
}
::android::binder::Status _aidl_status(checkService(in_name, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
首先是将参数 in_name 读出来,并将参数 _aidl_return 一并带入到真正实现 BnServiceManager 的地方。调用完成后会将 _aidl_return 存入到 _aidl_reply 中。
这里注意下Parcel 的 writeStrongBinder(),后面与BpServiceManager 中的readNullableStrongBinder() 统一分析。
接下来看下 ServiceManager 中实现的地方:
2.3 ServiceManager::checkService()
frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
*outBinder = tryGetService(name, false);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
auto ctx = mAccess->getCallingContext();
sp<IBinder> out;
Service* service = nullptr;
if (auto it = mNameToService.find(name); it != mNameToService.end()) {
service = &(it->second);
if (!service->allowIsolated) {
uid_t appid = multiuser_get_app_id(ctx.uid);
bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
if (isIsolated) {
return nullptr;
}
}
out = service->binder;
}
if (!mAccess->canFind(ctx, name)) {
return nullptr;
}
if (!out && startIfNotFound) {
tryStartService(name);
}
if (out) {
// Setting this guarantee each time we hand out a binder ensures that the client-checking
// loop knows about the event even if the client immediately drops the service
service->guaranteeClient = true;
}
return out;
}
这里不多分析,主要是将 mNameToService 中 add 进去的service 再次取出来,上一篇博文 提到了service 的 BBinder 经过驱动后会转成 remote 方式,checkService() 返回后会将 IBinder 存放到Parcel,通过接口 writeStrongBinder():
frameworks/native/libs/binder/Parcel.cpp
status_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);
}
IBinder 不再是BBbinder 了,localBinder 为nullptr,配置好 hdr.type 为 HANDLE 方式,在Bp 端会通过 readNullableStrongBinder() 进行 unflattenBinder():
_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
{
return unflattenBinder(val);
}
status_t Parcel::unflattenBinder(sp<IBinder>* out) const
{
const flat_binder_object* flat = readObject(false);
if (flat) {
switch (flat->hdr.type) {
case BINDER_TYPE_BINDER: {
sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
return finishUnflattenBinder(binder, out);
}
case BINDER_TYPE_HANDLE: {
sp<IBinder> binder =
ProcessState::self()->getStrongProxyForHandle(flat->handle);
return finishUnflattenBinder(binder, out);
}
}
}
return BAD_TYPE;
}
在writeStrongBinder() 的时候hdr.type 设置的是HANDLE,所以,这里通过getStrongProxyForHandle() 接口:
frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
if (status == DEAD_OBJECT)
return nullptr;
}
b = BpBinder::create(handle);
e->binder = b;
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;
}
通过接口 lookupHandleLocked() 查询进程中的 handle ,如果存在了就直接返回,如果没有则通过BpBinder::create() 新建一个。
至此,service 的获取流程已经分析完毕,总结下流程:
- 通过 defaultServiceManager() 获取到 servciemanager 的代理 BpServiceManager;
- 通过代理 BpBinder 调用 getService(),而service 的Binder 通过checkServcie() 获取;
- 调用BpBinder->transact() 将code 、data、reply 传入,IPCThreadState->transact() 会talkWithDriver() 调用;
- servciemanager 中 IPCThreadState 收到 BR_TRANSACTION 后会调用 BBinder->transact(),进而调用 BBinder->onTransact();
- ServiceManager 中会将之前 addService() 存放到 mNameToService 中的servcie IBinder 取出,并通过 writeStrongBinder() 写入reply 中;
- BBinder->onTransact() 返回后 sendReply(),client 端会收到 BR_REPLY,并将 data read 到reply;
- Bp端对 _aidl_reply 进行 unfattenBinder(),得到 sercie 的BpBinder;