Linux 角度看binder原理(五)
获取service
const sp<IMediaPlayerService>
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
sp<IServiceManager> sm = defaultServiceManager();//拿到BpServiceManager
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.player"));//获取MediaPlayerService
if (binder != 0) {
break;
}
ALOGW("Media player service not published, waiting...");
usleep(500000); // 0.5 s
} while (true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);//设置死亡通知
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);//创建代理对象。
}
ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}
首先获取了ServiceManage,这个过程上一篇中已经讲过了。通过 sm->getService获取media.player这个服务,如果拿不到binder那么就sleep0.5s继续循环。getService这个过程和获取ServiceManager很像。
sm->getService
/ complexity, this could be attempted.
sp<IBinder> ServiceManagerShim::getService(const String16& name) const
{
static bool gSystemBootCompleted = false;
sp<IBinder> svc = checkService(name);
if (svc != nullptr) return svc;
.........
}
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
sp<IBinder> ret;
if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
return nullptr;
}
return ret;
}
上一篇中知道defaultServiceManager获取到的是BpServiceManager的封装类ServiceManagerShim,获取服务的调用getService->checkService->mTheRealServiceManager.checkService,mTheRealServiceManager就是BpServiceManager,又到了aidl生成的文件。
::android::binder::Status BpServiceManager::checkService(const ::std::string& name, ::android::sp<::android::IBinder>* _aidl_return) {
::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;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name);//将数据写入_aidl_data
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_checkService, _aidl_data, &_aidl_reply, 0);//调用transact传送数据
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);//获取binder对象
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
在上一篇中已经讲了remote()->transact,调用链为BpBinder->transact() ->IPCThreadState::self()->transact() ->IPCThreadState::writeTransactionData->IPCThreadState::waitForResponse->BinderCallback-> IPCThreadState::getAndExecuteCommand->IPCThreadState::executeCommand->BnServiceManager::onTransact
//BnServiceManager::onTransact
case BnServiceManager::TRANSACTION_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;
和addservice一样,这里调用了checkService,最后将调用结果返回。
::android::binder::Status BpServiceManager::checkService(const ::std::string& name, ::android::sp<::android::IBinder>* _aidl_return) {
::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;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
...........
_aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_checkService, _aidl_data, &_aidl_reply, 0);
............
_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
............
return _aidl_status;
}
也是通过IPC调用回到了ServiceManager中
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()) {//从mNameToService中查询当前名字的服务,就是在addservice添加的地方
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;
}
到了ServiceManager中,其实就应该知道我们注册的时候是通过addservice将服务保存到了mNameToService中,现在查询肯定也是通过mNameToService来查询这个服务。拿到服务之后返回,在BpServiceManager中通过readNullableStrongBinder来读取binder。
#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
{
..........
#ifdef BINDER_WITH_KERNEL_IPC
const flat_binder_object* flat = readObject(false);
if (flat) {
switch (flat->hdr.type) {
case BINDER_TYPE_BINDER: {//如果是本地对象直接获取,这时候flat_binder_object->cookie指向BBinder
sp<IBinder> binder =
sp<IBinder>::fromExisting(reinterpret_cast<IBinder*>(flat->cookie));
return finishUnflattenBinder(binder, out);
}
case BINDER_TYPE_HANDLE: {//如果是远程对象调用 ProcessState::self()->getStrongProxyForHandle创建BpBinder,flat->handle就是远程binder对象的handle
sp<IBinder> binder =
ProcessState::self()->getStrongProxyForHandle(flat->handle);
return finishUnflattenBinder(binder, out);
}
}
}
return BAD_TYPE;
#else // BINDER_WITH_KERNEL_IPC
LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
}
status_t Parcel::finishUnflattenBinder(
const sp<IBinder>& binder, sp<IBinder>* out) const
{
int32_t stability;
status_t status = readInt32(&stability);
if (status != OK) return status;
status = internal::Stability::setRepr(binder.get(), static_cast<int16_t>(stability),
true /*log*/);
if (status != OK) return status;
*out = binder;
return OK;
}
上一篇中提到ProcessState::self()->getStrongProxyForHandle(handle)相当于BpBinder::create(handle),readNullableStrongBinder通过flat->hdr.type来判断拿到的binder是否是当前进程的,分别获取BBinder和BpBinder对象返回。
interface_cast(binder)
拿到服务之后通过interface_cast来创建了一个BpMediaPlayerService,后续和MediaPlayerService的交互就通过BpMediaPlayerService来处理。interface_cast在上一篇也讲过就是通过asInterface来创建一个对象,实现就是通过模板方法。
#frameworks/av/media/libmedia/include/media/IMediaPlayerService.h
DECLARE_META_INTERFACE(MediaPlayerService);
#frameworks/av/media/libmedia/IMediaPlayerService.cpp
IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
在IMediaPlayerService.h中通过DECLARE_META_INTERFACE声明asInterface,在IMediaPlayerService.cpp中IMPLEMENT_META_INTERFACE来实现方法。
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const ::android::StaticString16 I##INTERFACE##_descriptor_static_str16( \
__IINTF_CONCAT(u, NAME)); \
const ::android::String16 I##INTERFACE::descriptor(I##INTERFACE##_descriptor_static_str16); \
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(I##INTERFACE, I##INTERFACE, Bp##INTERFACE)
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(ITYPE, INAME, BPTYPE) \
::android::sp<ITYPE> ITYPE::asInterface(const ::android::sp<::android::IBinder>& obj) { \
::android::sp<ITYPE> intr; \
if (obj != nullptr) { \
intr = ::android::sp<ITYPE>::cast(obj->queryLocalInterface(ITYPE::descriptor)); \
if (intr == nullptr) { \
intr = ::android::sp<BPTYPE>::make(obj); \
} \
} \
return intr; \
} \
//带入MediaPlayerService,"android.media.IMediaPlayerService"
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(IMediaPlayerService, IMediaPlayerService, BpMediaPlayerService)
::android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const ::android::sp<::android::IBinder>& obj) {
::android::sp<IMediaPlayerService> intr;
if (obj != nullptr) {
intr = ::android::sp<IMediaPlayerService>::cast(obj->queryLocalInterface(IMediaPlayerService::descriptor));
if (intr == nullptr) {
intr = ::android::sp<BPMediaPlayerService>::make(obj);
}
}
return intr;
}
通过模板方法拿到BPMediaPlayerService一个service的获取就结束了。