一.概述
1.1 概念
Binder是Android提供的一種IPC機(jī)制(進(jìn)程間通信機(jī)制)。
特點(diǎn):更加方便靈活
Android其他IPC機(jī)制:管道、socket
作用:Android系統(tǒng)基本可以看作是基于Binder機(jī)制的C/S架構(gòu),binder把系統(tǒng)的各部分連接在一起
1.2 ServiceManager、Client、Server之間的關(guān)系
ServiceManager:管理系統(tǒng)中的各種服務(wù)(Service)
三者交互關(guān)系如圖:

總結(jié):
1.一個(gè)Server進(jìn)程可以注冊(cè)多個(gè)Service
2.Server要先注冊(cè)一些Service到ServiceManager中,所以Server是ServiceManager的客戶(hù)端,ServiceManager是服務(wù)端
3.如果Client進(jìn)程想使用某個(gè)Service服務(wù),則先要到ServiceManager獲取服務(wù)相關(guān)信息,所以Client是ServiceManager的客戶(hù)端
4.Client根據(jù)得到的Service信息與Service所在的Server進(jìn)程建立通信通路,然后就可以直接與Service直接交互了,所以Client也是Server的客戶(hù)端
5.三者之間通信均是基于Binder機(jī)制
二.MediaServer
本文章以MediaServer為例,來(lái)分析Binder機(jī)制。之所以選擇MediaServer作為切入點(diǎn),是因?yàn)檫@個(gè)Server是系統(tǒng)諸多重要Service的棲息地,它們包括:
AudioFlinger:音頻系統(tǒng)中的核心服務(wù)。
AudioPolicyService:音頻系統(tǒng)中關(guān)于音頻策略的重要服務(wù)。
MediaPlayerService:多媒體系統(tǒng)中的重要服務(wù)。
CameraService:有關(guān)攝像/照相的重要服務(wù)。
2.1 MediaServer入口函數(shù)
frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
//1.獲得一個(gè)ProcessState實(shí)例,單例模式
sp<ProcessState> proc(ProcessState::self());
//2.MediaServer作為ServiceManager的客戶(hù)端,要向ServiceManager注冊(cè)服務(wù)
//調(diào)用defaultServiceManager()得到一個(gè)IServiceManager
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
//3.初始化服務(wù)
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
//4.創(chuàng)建一個(gè)線程池
ProcessState::self()->startThreadPool();
//5.將IPCThreadState加入線程池
IPCThreadState::self()->joinThreadPool();
}
MediaServer的入口函數(shù),主要做了5件事
1.獲取當(dāng)前進(jìn)程的一個(gè)ProcessState對(duì)象,ProcessState在同一進(jìn)程單例
2.向ServiceManager注冊(cè)服務(wù)
3.初始化服務(wù)
4.創(chuàng)建一個(gè)線程池
5.將當(dāng)前IPC線程狀態(tài)加入線程池
2.2 ProcessState
每個(gè)進(jìn)程只有一個(gè)ProcessState對(duì)象,它的調(diào)用方式如下:
//獲取一個(gè)ProcessState實(shí)例
sp<ProcessState> proc(ProcessState::self());
下面來(lái)分析下ProcessState
2.2.1ProcessState::self()函數(shù)
frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
//創(chuàng)建一個(gè)ProcessState
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
self()方法使用了單例模式,保證了每個(gè)進(jìn)程只有一個(gè)ProcessState對(duì)象
1 ProcessState的構(gòu)造函數(shù)
frameworks/native/libs/binder/ProcessState.cpp
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
//打開(kāi)dev/binder驅(qū)動(dòng)
, mDriverFD(open_driver(driver))
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
//2.mmap與binder的驅(qū)動(dòng)建立映射關(guān)系
//BINDER_VM_SIZE定義為(1*1024*1024)- (4096*2)= 1M-8K,這也是Intent傳遞的數(shù)據(jù)為何不能超過(guò)1M的原因,因?yàn)镮ntent傳遞數(shù)據(jù)使用到了binder機(jī)制,所以會(huì)受到BINDER_VM_SIZE的定義限制
//binder驅(qū)動(dòng)會(huì)分配一塊內(nèi)存來(lái)接收數(shù)據(jù)
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
close(mDriverFD);
mDriverFD = -1;
mDriverName.clear();
}
}
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
2 打開(kāi)binder設(shè)備
open_driver的作用就是打開(kāi)/dev/binder這個(gè)設(shè)備,它是Android在內(nèi)核中為完成進(jìn)程間通信而專(zhuān)門(mén)設(shè)置的一個(gè)虛擬設(shè)備,具體實(shí)現(xiàn)如下所示:
frameworks/native/libs/binder/ProcessState.cpp
static int open_driver(const char *driver)
{
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd >= 0) {
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1) {
ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
close(fd);
fd = -1;
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
close(fd);
fd = -1;
}
//這個(gè)fd支持的最大線程數(shù)為DEFAULT_MAX_BINDER_THREADS=15
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
} else {
ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
}
return fd;
}
至此,ProcessState::self()函數(shù)就分析完畢。ProcessState::self()函數(shù)主要有兩個(gè)作用
1.打開(kāi)dev/binder設(shè)備,可以與內(nèi)核的Binder驅(qū)動(dòng)進(jìn)行交互
2.對(duì)返回的fd對(duì)象使用mmap,內(nèi)核分配一塊兒內(nèi)存,這樣binder驅(qū)動(dòng)就可以接收數(shù)據(jù)
2.3 defaultServiceManager()
//調(diào)用defaultServiceManager()得到一個(gè)IServiceManager
sp<IServiceManager> sm = defaultServiceManager();
defaultServiceManager實(shí)際調(diào)用的是IServiceManager的defaultServiceManager()函數(shù),源碼如下:
frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager(){
//單例模式
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
//創(chuàng)建gDefaultServiceManager
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
defaultServiceManager函數(shù)調(diào)用了interface_cast函數(shù)進(jìn)行對(duì)gDefaultServiceManager的賦值,最終發(fā)現(xiàn),調(diào)用了ProcessState的getContextObject函數(shù),getContextObject函數(shù)代碼如下:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
getContextObject函數(shù)中調(diào)用了getStrongProxyForHandle(0)的函數(shù),如下
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 != NULL) {
// 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. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !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.
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
//創(chuàng)建一個(gè)BpBinder,對(duì)于新創(chuàng)建的資源,b為空,此處handle為0
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);
}
}
//返回一個(gè)BpBinder
return result;
}
2.3.1 BpBinder
BpBinder是IBinder的派生類(lèi),BpBinder的p意味著proxy,也就是用于客戶(hù)端與服務(wù)端通信的代理類(lèi)。
提到BpBinder就不得不提一下BBinder,它們都是IBinder的派生類(lèi),如下

BBinder是與BpBinder為一對(duì)的,也用于通信的類(lèi)。BpBinder代表的是客戶(hù)端的proxy,BBinder則代表與之交互的服務(wù)端。一個(gè)BpBinder只能和對(duì)應(yīng)的BBinder進(jìn)行通信,即BpBinderA只能與BBinderA進(jìn)行通信,不會(huì)出現(xiàn)與BBinderB進(jìn)行通信現(xiàn)象,通過(guò)handle的值來(lái)標(biāo)識(shí)對(duì)應(yīng)的BBinder,保障正確性。getStrongProxyForHandle方法中handle的值為0,代表的正是ServiceManager中對(duì)應(yīng)的BBinder。
來(lái)看一下BpBinder的create方法
frameworks/native/libs/binder/BpBinder.cpp
BpBinder* BpBinder::create(int32_t handle) {
int32_t trackedUid = -1;
if (sCountByUidEnabled) {
trackedUid = IPCThreadState::self()->getCallingUid();
AutoMutex _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[trackedUid];
if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) {
if (sBinderProxyThrottleCreate) {
return nullptr;
}
} else {
if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
getuid(), trackedUid, trackedValue);
sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
if (sLimitCallback) sLimitCallback(trackedUid);
if (sBinderProxyThrottleCreate) {
ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
" count drops below %d",
trackedUid, getuid(), sBinderProxyCountLowWatermark);
return nullptr;
}
}
}
sTrackingMap[trackedUid]++;
}
return new BpBinder(handle, trackedUid);
}
緊跟著看下BpBinder(handle, trackedUid)構(gòu)造函數(shù)
frameworks/native/libs/binder/BpBinder.cpp
BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
, mTrackedUid(trackedUid)
{
ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle, this);
}
這里出現(xiàn)了IPCThreadState::self()函數(shù)。到這里并沒(méi)有發(fā)現(xiàn)任何與通信動(dòng)作相關(guān)的操作。到此處為止,我們只是創(chuàng)建了一個(gè)BpBinder的對(duì)象,具體還并沒(méi)有對(duì)它進(jìn)行任何調(diào)用,所以我們要翻回頭再去看當(dāng)時(shí)接受BpBinder參數(shù)的方法,即interface_cast函數(shù),繼續(xù)跟進(jìn)
frameworks/native/include/binder/IInterface.h
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
此處的INTERFACE是IServiceManager,所以此處代碼相當(dāng)于返回了IServiceManager.asInterface(obj),又回到了IServiceManager中去了。繼續(xù)看IServiceManger的asInterface函數(shù)。注意,此處的IServiceManger為IServiceManger.h而不是IServiceManger.cpp。
frameworks/native/include/binder/IServiceManager.h
class IServiceManager : public IInterface
{
public:
//非常重要的一個(gè)宏
DECLARE_META_INTERFACE(ServiceManager)
/**
* Must match values in IServiceManager.java
*/
/* Allows services to dump sections according to priorities. */
static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
/**
* Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the
* same priority as NORMAL priority but the services are not called with dump priority
* arguments.
*/
static const int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3;
static const int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL |
DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
static const int DUMP_FLAG_PROTO = 1 << 4;
/**
* Retrieve an existing service, blocking for a few seconds
* if it doesn't yet exist.
*/
virtual sp<IBinder> getService( const String16& name) const = 0;
/**
* Retrieve an existing service, non-blocking.
*/
virtual sp<IBinder> checkService( const String16& name) const = 0;
/**
* Register a service.
*/
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated = false,
int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
/**
* Return list of all existing services.
*/
virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
}
先看下DECLARE_META_INTERFACE宏當(dāng)中是如何定義的
frameworks/native/include/binder/IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE) \
static const ::android::String16 descriptor; \
static ::android::sp<I##INTERFACE> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE();
替換、翻譯過(guò)來(lái)我們得到一段這樣的代碼
static const ::android::String16 descriptor;
//定義一個(gè)asInterface函數(shù)
static ::android::sp<IServiceManger> asInterface(
const android::sp<android::IBinder>& obj)
virtual const android::String16& getInterfaceDescriptor() const;
//定義IServiceManger的構(gòu)造方法
IServiceManger();
virtual ~ IServiceManger();
DECLARE_META_INTERFACE宏定義了一些方法,這些方法的實(shí)現(xiàn)是在IServiceManger.cpp中,查找IServiceManger.cpp發(fā)現(xiàn)了另外一個(gè)宏
frameworks/native/libs/binder/IServiceManager.cpp
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
繼續(xù)跟進(jìn),發(fā)現(xiàn)IMPLEMENT_META_INTERFACE定義在了IInterface.h文件
frameworks/native/include/binder/IInterface.h
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const ::android::String16 I##INTERFACE::descriptor(NAME); \
const ::android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
替換后得到了以下代碼
const ::android::String16 IServiceManger::descriptor("android.os.IServiceManager");
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
android::sp<IServiceManager> IServiceManager::asInterface(
const android::sp<android::IBinder>& obj)
{
android::sp< IServiceManager > intr;
if (obj != NULL) {
intr = static_cast< IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
//obj就是BpBinder
//此處實(shí)際上真正返回的是一個(gè)BpServiceManager對(duì)象
intr = new BpServiceManager(obj);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
到此,我們發(fā)現(xiàn)inferface_cast函數(shù)最終返回了一個(gè)BpServiceManager對(duì)象,這個(gè)BpServiceManager就是將BpBinder轉(zhuǎn)化成了一個(gè)IServiceManager對(duì)象,最終返回給了defaultServiceManager()函數(shù)。
這里又出現(xiàn)了一個(gè)BpServiceManager,既然inferface_cast方法要求返回的是一個(gè)IServiceManager,那么BpServiceManager一定是它的一個(gè)派生類(lèi),接下來(lái)介紹下IServiceManager家族
2.3.2 IServiceManager家族

由圖可知,BpServiceManager與BbServiceManager不同,BbServiceManager是通過(guò)實(shí)現(xiàn)BBinder接口進(jìn)行通信,BpServiceManager又是如何實(shí)現(xiàn)通信的呢?上文中創(chuàng)建一個(gè)BpServiceManager需要一個(gè)BpBinder參數(shù),所以BpServiceManager是通過(guò)設(shè)置BpBinder變量,通過(guò)這個(gè)BpBinder來(lái)實(shí)現(xiàn)通信的。查看BpServiceManager的父接口BpInterface
frameworks/native/include/binder/IInterface.h
//定義構(gòu)造方法
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote):
BpRefBase(remote){}
BpRefBase的實(shí)現(xiàn)如下
frameworks/native/libs/binder/Binder.cpp
BpRefBase::BpRefBase(const sp<IBinder>& o)
//mRemote變量最終等于new出來(lái)的BpBinder
: mRemote(o.get()), mRefs(NULL), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
}
原來(lái),是BpServiceManager的一個(gè)變量mRemote指向了BpBinder。至此,我們的魔術(shù)表演結(jié)束,回想一下defaultServiceManager函數(shù),可以得到以下兩個(gè)關(guān)鍵對(duì)象:
1.有一個(gè)BpBinder對(duì)象,它的handle值是0。
2.有一個(gè)BpServiceManager對(duì)象,它的mRemote值是BpBinder。
2.4 MediaPlayerService的注冊(cè)
frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
defaultServiceManager()函數(shù)返回的實(shí)際上是BpServiceManager,BpServiceManager定義在IServiceManager.cpp文件中,BpServiceManager的addService函數(shù)如下:
frameworks/native/libs/binder/IServiceManager.cpp
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
//remote實(shí)際上是BpBinder,實(shí)際傳輸數(shù)據(jù)的方法
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
至此,我們完成了業(yè)務(wù)層的數(shù)據(jù)打包,然后進(jìn)入到傳輸層傳輸數(shù)據(jù)。
2.4.1 BpBinder的transact函數(shù)
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) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
這里看到了一個(gè)方法IPCThreadState::self()->transact(mHandle, code, data, reply, flags),實(shí)際上傳輸過(guò)程是調(diào)用了該函數(shù),我們先看下IPCThreadState::self()函數(shù)
frameworks/native/libs/binder/IPCThreadState.cpp
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {//第一次進(jìn)來(lái)為false
restart:
//TLS為T(mén)hread local storage線程本地存儲(chǔ)空間的簡(jiǎn)稱(chēng),該空間每條線程都有,且不共享
const pthread_key_t k = gTLS;
//pthread_getspecific/pthread_setspecific可以獲取/設(shè)置空間內(nèi)容
//從線程本地存儲(chǔ)空間可以獲取到IPCThreadState對(duì)象
//如果該空間設(shè)置了IPCThreadState則直接返回
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
//否則創(chuàng)建一個(gè)IPCThreadState返回
return new IPCThreadState;
}
if (gShutdown) {
ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
return NULL;
}
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {//第一次進(jìn)來(lái)為false
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
if (key_create_value != 0) {
pthread_mutex_unlock(&gTLSMutex);
ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
strerror(key_create_value));
return NULL;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
接下來(lái)看下IPCThreadState的構(gòu)造函數(shù)
frameworks/native/libs/binder/IPCThreadState.cpp
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
//將自己設(shè)置到本地線程的存儲(chǔ)空間中
pthread_setspecific(gTLS, this);
clearCaller();
//mIn是接收數(shù)據(jù)的,mOut是把發(fā)送的數(shù)據(jù)寫(xiě)入緩沖的
//設(shè)置mIn的數(shù)據(jù)長(zhǎng)度
mIn.setDataCapacity(256);
//設(shè)置mOut的數(shù)據(jù)長(zhǎng)度
mOut.setDataCapacity(256);
}
每個(gè)線程都有一個(gè)唯一的IPCThreadState,每個(gè)IPCThreadState都有一個(gè)mIn和mOut對(duì)象,mIn對(duì)象是用來(lái)接收來(lái)自Binder的數(shù)據(jù),mOut是用于把從客戶(hù)端傳輸?shù)椒?wù)的數(shù)據(jù),寫(xiě)入緩沖。
分析完IPCThreadState的self和構(gòu)造函數(shù)后,接下來(lái)分析下IPCThreadState的transact方法,這個(gè)方法實(shí)際上就是BpBinder中真正傳輸數(shù)據(jù)的方法。
frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err;
flags |= TF_ACCEPT_FDS;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
<< handle << " / code " << TypeCode(code) << ": "
<< indent << data << dedent << endl;
}
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
//BC_XXX的標(biāo)記,是從客戶(hù)端傳輸數(shù)據(jù)到服務(wù)端,BR_XXX的標(biāo)記是從服務(wù)端傳輸?shù)娇蛻?hù)端
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
#if 0
if (code == 4) { // relayout
ALOGI(">>>>>> CALLING transaction 4");
} else {
ALOGI(">>>>>> CALLING transaction %d", code);
}
#endif
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
#if 0
if (code == 4) { // relayout
ALOGI("<<<<<< RETURNING transaction 4");
} else {
ALOGI("<<<<<< RETURNING transaction %d", code);
}
#endif
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
<< handle << ": ";
if (reply) alog << indent << *reply << dedent << endl;
else alog << "(none requested)" << endl;
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
此段代碼,簡(jiǎn)單來(lái)說(shuō)就是先發(fā)送數(shù)據(jù)到服務(wù),然后再等待服務(wù)傳輸數(shù)據(jù)回來(lái)的過(guò)程。
先來(lái)看一下writeTransactionData函數(shù)
frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
//要發(fā)送的數(shù)據(jù)
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);
}
//將命令寫(xiě)入到mOut中,并不直接發(fā)送到服務(wù)
mOut.writeInt32(cmd);
//將要傳輸?shù)臄?shù)據(jù)寫(xiě)入到mOut中,并不直接發(fā)送到服務(wù)
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
現(xiàn)在,已經(jīng)把a(bǔ)ddService的請(qǐng)求信息寫(xiě)到了mOut中,接下來(lái)看看發(fā)送和接收數(shù)據(jù)的方法,waitForResponse
status_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();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT:
{
ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
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(NULL,
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(NULL,
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;
}
}
finish:
if (err != NO_ERROR) {
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
先看下其中的talkWithDriver函數(shù)
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
binder_write_read bwr;
// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
//接收數(shù)據(jù)緩沖區(qū)的填充,如果收到服務(wù)的數(shù)據(jù),直接寫(xiě)在mIn里
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
if (outAvail != 0) {
alog << "Sending commands to driver: " << indent;
const void* cmds = (const void*)bwr.write_buffer;
const void* end = ((const uint8_t*)cmds)+bwr.write_size;
alog << HexDump(cmds, bwr.write_size) << endl;
while (cmds < end) cmds = printCommand(alog, cmds);
alog << dedent;
}
alog << "Size of receive buffer: " << bwr.read_size
<< ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
IF_LOG_COMMANDS() {
alog << "About to read/write, write size = " << mOut.dataSize() << endl;
}
#if defined(__ANDROID__)
//用于與服務(wù)端傳輸數(shù)據(jù)的方法,ioctl
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
IF_LOG_COMMANDS() {
alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
}
} while (err == -EINTR);
IF_LOG_COMMANDS() {
alog << "Our err: " << (void*)(intptr_t)err << ", write consumed: "
<< bwr.write_consumed << " (of " << mOut.dataSize()
<< "), read consumed: " << bwr.read_consumed << endl;
}
if (err >= NO_ERROR) {
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else {
mOut.setDataSize(0);
processPostWriteDerefs();
}
}
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
alog << "Remaining data size: " << mOut.dataSize() << endl;
alog << "Received commands from driver: " << indent;
const void* cmds = mIn.data();
const void* end = mIn.data() + mIn.dataSize();
alog << HexDump(cmds, mIn.dataSize()) << endl;
while (cmds < end) cmds = printReturnCommand(alog, cmds);
alog << dedent;
}
return NO_ERROR;
}
return err;
}
talkWithDriver完成了把注冊(cè)信息傳輸?shù)椒?wù),并接收服務(wù)返回到信息寫(xiě)入到mIn中的過(guò)程,接下來(lái)再來(lái)看下如何處理服務(wù)返回的信息,處理方法就是executeCommand(cmd)。我們看下代碼
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
case BR_OK:
break;
case BR_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
ALOG_ASSERT(refs->refBase() == obj,
"BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
obj->incStrong(mProcess.get());
IF_LOG_REMOTEREFS() {
LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
obj->printRefs();
}
mOut.writeInt32(BC_ACQUIRE_DONE);
mOut.writePointer((uintptr_t)refs);
mOut.writePointer((uintptr_t)obj);
break;
case BR_RELEASE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
ALOG_ASSERT(refs->refBase() == obj,
"BR_RELEASE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
IF_LOG_REMOTEREFS() {
LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
obj->printRefs();
}
mPendingStrongDerefs.push(obj);
break;
case BR_INCREFS:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
refs->incWeak(mProcess.get());
mOut.writeInt32(BC_INCREFS_DONE);
mOut.writePointer((uintptr_t)refs);
mOut.writePointer((uintptr_t)obj);
break;
case BR_DECREFS:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
// NOTE: This assertion is not valid, because the object may no
// longer exist (thus the (BBinder*)cast above resulting in a different
// memory address).
//ALOG_ASSERT(refs->refBase() == obj,
// "BR_DECREFS: object %p does not match cookie %p (expected %p)",
// refs, obj, refs->refBase());
mPendingWeakDerefs.push(refs);
break;
case BR_ATTEMPT_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
{
const bool success = refs->attemptIncStrong(mProcess.get());
ALOG_ASSERT(success && refs->refBase() == obj,
"BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
mOut.writeInt32(BC_ACQUIRE_RESULT);
mOut.writeInt32((int32_t)success);
}
break;
case BR_TRANSACTION:
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
Parcel buffer;
buffer.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);
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
//ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Parcel reply;
status_t error;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_TRANSACTION thr " << (void*)pthread_self()
<< " / obj " << tr.target.ptr << " / code "
<< TypeCode(tr.code) << ": " << indent << buffer
<< dedent << endl
<< "Data addr = "
<< reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
<< ", offsets addr="
<< reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
}
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);
}
//ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
// mCallingPid, origPid, origUid);
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
if (error < NO_ERROR) reply.setError(error);
sendReply(reply, 0);
} else {
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
mCallingPid = origPid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
<< tr.target.ptr << ": " << indent << reply << dedent << endl;
}
}
break;
case BR_DEAD_BINDER:
{
BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->sendObituary();
mOut.writeInt32(BC_DEAD_BINDER_DONE);
mOut.writePointer((uintptr_t)proxy);
} break;
case BR_CLEAR_DEATH_NOTIFICATION_DONE:
{
BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->getWeakRefs()->decWeak(proxy);
} break;
case BR_FINISHED:
result = TIMED_OUT;
break;
case BR_NOOP:
break;
case BR_SPAWN_LOOPER:
//這里將收到來(lái)自驅(qū)動(dòng)的指示,創(chuàng)建一個(gè)線程,用于和binder通信
mProcess->spawnPooledThread(false);
break;
default:
ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd);
result = UNKNOWN_ERROR;
break;
}
if (result != NO_ERROR) {
mLastError = result;
}
return result;
}
2.5 startThreadPool和joinThreadPool
frameworks/av/media/mediaserver/main_mediaserver.cpp
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
startThreadPool()代碼如下,
frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
//如果沒(méi)有startPool則調(diào)用
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
再跟進(jìn)看下spawnPooledThread
frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
繼續(xù)跟進(jìn)PoolThread
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
PoolThread是定義在ProcessState.cpp中的定義的Thread的子類(lèi),從代碼上來(lái)看,最終調(diào)用的還是joinThreadPool,再看下joinThreadPool函數(shù)
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
abort();
}
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
至此,我們發(fā)現(xiàn)一個(gè)有兩個(gè)線程在與Binder通信,一個(gè)是通過(guò)ProcessState::self()->startThreadPool()函數(shù),開(kāi)啟的一個(gè)子線程進(jìn)行通信,一個(gè)是通過(guò)IPCThreadState::self()->joinThreadPool()函數(shù),主線程進(jìn)行通信。
三.ServiceManager
3.1 ServiceManager原理
defaultServiceManager返回的是一個(gè)BpServiceManager,通過(guò)它可以把命令請(qǐng)求發(fā)送給handle值為0的目的端。按照IServiceManager“家譜”來(lái)看,無(wú)論如何也應(yīng)該有一個(gè)類(lèi)從BnServiceManager派生出來(lái)并處理這些來(lái)自遠(yuǎn)方的請(qǐng)求吧?很可惜,源碼中竟然沒(méi)有這樣一個(gè)類(lèi)存在!但確實(shí)又有這么一個(gè)程序完成了BnServiceManager未盡的工作,這個(gè)程序就是ServiceManager,它的代碼在Service_manager.c中。
3.1.1 ServiceManager入口函數(shù)
ServiceManager的入口函數(shù)如下:
frameworks/native/cmds/servicemanager/service_manager.c
int main(int argc, char** argv)
{
struct binder_state *bs;
union selinux_callback cb;
char *driver;
if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}
//1.打開(kāi)binder設(shè)備
bs = binder_open(driver, 128*1024);
if (!bs) {
#ifdef VENDORSERVICEMANAGER
ALOGW("failed to open binder driver %s\n", driver);
while (true) {
sleep(UINT_MAX);
}
#else
ALOGE("failed to open binder driver %s\n", driver);
#endif
return -1;
}
//2.成為大管家
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
#ifdef VENDORSERVICEMANAGER
sehandle = selinux_android_vendor_service_context_handle();
#else
sehandle = selinux_android_service_context_handle();
#endif
selinux_status_open(true);
if (sehandle == NULL) {
ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
abort();
}
if (getcon(&service_manager_context) != 0) {
ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
abort();
}
//循環(huán)處理來(lái)自client的請(qǐng)求
binder_loop(bs, svcmgr_handler);
return 0;
}
3.12 打開(kāi)binder設(shè)備
binder_open代碼如下
frameworks/native/cmds/servicemanager/binder.c
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
struct binder_state *bs;
struct binder_version vers;
bs = malloc(sizeof(*bs));
if (!bs) {
errno = ENOMEM;
return NULL;
}
//1.打開(kāi)設(shè)備
bs->fd = open(driver, O_RDWR | O_CLOEXEC);
if (bs->fd < 0) {
fprintf(stderr,"binder: cannot open %s (%s)\n",
driver, strerror(errno));
goto fail_open;
}
if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
(vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
fprintf(stderr,
"binder: kernel driver version (%d) differs from user space version (%d)\n",
vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
goto fail_open;
}
//2.內(nèi)存映射
bs->mapsize = mapsize;
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
if (bs->mapped == MAP_FAILED) {
fprintf(stderr,"binder: cannot map device (%s)\n",
strerror(errno));
goto fail_map;
}
return bs;
fail_map:
close(bs->fd);
fail_open:
free(bs);
return NULL;
}
3.1.3 成為大管家
frameworks/native/cmds/servicemanager/binder.c
int binder_become_context_manager(struct binder_state *bs)
{
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
3.1.4 binder_loop
frameworks/native/cmds/servicemanager/binder.c
/*
binder_handler func參數(shù)是一個(gè)函數(shù)指針,這些請(qǐng)求最終調(diào)用binder_handler處理
*/
void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
uint32_t readbuf[32];
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(uint32_t));
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
break;
}
//接收請(qǐng)求,并解析,最終交給binder_handler函數(shù)類(lèi)型的func處理
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
if (res == 0) {
ALOGE("binder_loop: unexpected reply?!\n");
break;
}
if (res < 0) {
ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
break;
}
}
}
3.1.5 集中處理
frameworks/native/cmds/servicemanager/service_manager.c
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
uint32_t dumpsys_priority;
//ALOGI("target=%p code=%d pid=%d uid=%d\n",
// (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
if (txn->target.ptr != BINDER_SERVICE_MANAGER)
return -1;
if (txn->code == PING_TRANSACTION)
return 0;
// Equivalent to Parcel::enforceInterface(), reading the RPC
// header with the strict mode policy mask and the interface name.
// Note that we ignore the strict_policy and don't propagate it
// further (since we do no outbound RPCs anyway).
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
if ((len != (sizeof(svcmgr_id) / 2)) ||
memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
fprintf(stderr,"invalid id %s\n", str8(s, len));
return -1;
}
if (sehandle && selinux_status_updated() > 0) {
#ifdef VENDORSERVICEMANAGER
struct selabel_handle *tmp_sehandle = selinux_android_vendor_service_context_handle();
#else
struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
#endif
if (tmp_sehandle) {
selabel_close(sehandle);
sehandle = tmp_sehandle;
}
}
switch(txn->code) {
//獲取服務(wù)
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
//s表示服務(wù)名
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;
//注冊(cè)服務(wù)
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
dumpsys_priority = bio_get_uint32(msg);
if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
txn->sender_pid))
return -1;
break;
//獲取所有已注冊(cè)的服務(wù)的名字
case SVC_MGR_LIST_SERVICES: {
uint32_t n = bio_get_uint32(msg);
uint32_t req_dumpsys_priority = bio_get_uint32(msg);
if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;
}
si = svclist;
// walk through the list of services n times skipping services that
// do not support the requested priority
while (si) {
if (si->dumpsys_priority & req_dumpsys_priority) {
if (n == 0) break;
n--;
}
si = si->next;
}
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
3.2 服務(wù)的注冊(cè)
svcmgr_handler中switch/case語(yǔ)句塊中,就是ServiceManager處理來(lái)自所有客戶(hù)端的請(qǐng)求的代碼塊,其中SVC_MGR_ADD_SERVICE分支表示的就是注冊(cè)服務(wù)的內(nèi)容。代碼塊中do_add_service就是真正處理注冊(cè)服務(wù)的邏輯。
frameworks/native/cmds/servicemanager/service_manager.c
int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle,
uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) {
struct svcinfo *si;
//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
// allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
if (!handle || (len == 0) || (len > 127))
return -1;
//判斷是否可以注冊(cè)
if (!svc_can_register(s, len, spid, uid)) {
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
str8(s, len), handle, uid);
return -1;
}
si = find_svc(s, len);
if (si) {
if (si->handle) {
ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
str8(s, len), handle, uid);
svcinfo_death(bs, si);
}
si->handle = handle;
} else {
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
if (!si) {
ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",
str8(s, len), handle, uid);
return -1;
}
si->handle = handle;
si->len = len;
memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
si->name[len] = '\0';
si->death.func = (void*) svcinfo_death;
si->death.ptr = si;
si->allow_isolated = allow_isolated;
si->dumpsys_priority = dumpsys_priority;
si->next = svclist;
svclist = si;
}
binder_acquire(bs, handle);
binder_link_to_death(bs, handle, &si->death);
return 0;
}
3.2.1 不是所有服務(wù)都可以注冊(cè)
do_add_service函數(shù)中的svc_can_register函數(shù)是用來(lái)判斷這個(gè)注冊(cè)服務(wù)的請(qǐng)求是否可以注冊(cè)。代碼如下:
static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
{
const char *perm = "add";
//不允許app去注冊(cè)
if (multiuser_get_app_id(uid) >= AID_APP) {
return 0; /* Don't allow apps to register services */
}
return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
四.MediaPlayerService和它的Client
4.1 查詢(xún)ServiceManager
一個(gè)Client想要得到某個(gè)Service的信息,就必須先和ServiceManager打交道,通過(guò)調(diào)用getService函數(shù)來(lái)獲取對(duì)應(yīng)Service的信息。以IMediaDeathNotifier.cpp中的getMediaPlayerService()為例,它的代碼如下所示:
frameworks/av/media/libmedia/IMediaDeathNotifier.cpp
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
//此處就是與ServiceManager打交道,獲取一個(gè)BpServiceManager
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
//通過(guò)名字,查詢(xún)服務(wù),獲取到一個(gè)BpBinder
binder = sm->getService(String16("media.player"));
if (binder != 0) {
break;
}
ALOGW("Media player service not published, waiting...");
//如果還沒(méi)有注冊(cè),等待0.5s
usleep(500000); // 0.5 s
} while (true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
//還是通過(guò)interface_cast函數(shù),獲取到一個(gè)BpMediaPlayerService
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}
這段代碼與之前的服務(wù)注冊(cè)幾乎流程差不多,只不過(guò)之前的是注冊(cè)服務(wù),最終調(diào)用的是addService,此處是getService。這段代碼主要做了三件事
1.調(diào)用defaultServiceManager(),獲取一個(gè)BpServiceManager對(duì)象,也就是ServiceManager。
2.通過(guò)ServiceManager調(diào)用的getService方法,通過(guò)名字獲取到一個(gè)BpBinder。
3.再通過(guò)interface_cast函數(shù),通過(guò)內(nèi)部的宏獲取到一個(gè)BpMediaPlayerService,返回。
最終我們的到了一個(gè)MediaPlayerService,我們可以通過(guò)它來(lái)調(diào)用MediaPlayerService的服務(wù)方法,例如createMediaRecorder和createMetadataRetriever等
4.2 服務(wù)與Client通信
MediaPlayerService駐留在MediaServer進(jìn)程中,這個(gè)進(jìn)程有兩個(gè)線程在talkWithDriver。假設(shè)其中有一個(gè)線程收到了請(qǐng)求信息,它最終會(huì)通過(guò)executeCommand調(diào)用來(lái)處理這個(gè)請(qǐng)求,實(shí)現(xiàn)代碼如下所示:
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
case BR_OK:
break;
case BR_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
ALOG_ASSERT(refs->refBase() == obj,
"BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
obj->incStrong(mProcess.get());
IF_LOG_REMOTEREFS() {
LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
obj->printRefs();
}
mOut.writeInt32(BC_ACQUIRE_DONE);
mOut.writePointer((uintptr_t)refs);
mOut.writePointer((uintptr_t)obj);
break;
case BR_RELEASE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
ALOG_ASSERT(refs->refBase() == obj,
"BR_RELEASE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
IF_LOG_REMOTEREFS() {
LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
obj->printRefs();
}
mPendingStrongDerefs.push(obj);
break;
case BR_INCREFS:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
refs->incWeak(mProcess.get());
mOut.writeInt32(BC_INCREFS_DONE);
mOut.writePointer((uintptr_t)refs);
mOut.writePointer((uintptr_t)obj);
break;
case BR_DECREFS:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
// NOTE: This assertion is not valid, because the object may no
// longer exist (thus the (BBinder*)cast above resulting in a different
// memory address).
//ALOG_ASSERT(refs->refBase() == obj,
// "BR_DECREFS: object %p does not match cookie %p (expected %p)",
// refs, obj, refs->refBase());
mPendingWeakDerefs.push(refs);
break;
case BR_ATTEMPT_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
{
const bool success = refs->attemptIncStrong(mProcess.get());
ALOG_ASSERT(success && refs->refBase() == obj,
"BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
mOut.writeInt32(BC_ACQUIRE_RESULT);
mOut.writeInt32((int32_t)success);
}
break;
case BR_TRANSACTION:
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
Parcel buffer;
buffer.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);
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
//ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Parcel reply;
status_t error;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_TRANSACTION thr " << (void*)pthread_self()
<< " / obj " << tr.target.ptr << " / code "
<< TypeCode(tr.code) << ": " << indent << buffer
<< dedent << endl
<< "Data addr = "
<< reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
<< ", offsets addr="
<< reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
}
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)) {
//調(diào)用了BBinder的transact返回了信息
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);
}
//ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
// mCallingPid, origPid, origUid);
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
if (error < NO_ERROR) reply.setError(error);
sendReply(reply, 0);
} else {
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
mCallingPid = origPid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
<< tr.target.ptr << ": " << indent << reply << dedent << endl;
}
}
break;
case BR_DEAD_BINDER:
{
BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->sendObituary();
mOut.writeInt32(BC_DEAD_BINDER_DONE);
mOut.writePointer((uintptr_t)proxy);
} break;
case BR_CLEAR_DEATH_NOTIFICATION_DONE:
{
BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->getWeakRefs()->decWeak(proxy);
} break;
case BR_FINISHED:
result = TIMED_OUT;
break;
case BR_NOOP:
break;
case BR_SPAWN_LOOPER:
mProcess->spawnPooledThread(false);
break;
default:
ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd);
result = UNKNOWN_ERROR;
break;
}
if (result != NO_ERROR) {
mLastError = result;
}
return result;
}
BBinder和業(yè)務(wù)層有什么關(guān)系?我們以MediaPlayerService為例,來(lái)梳理一下其派生關(guān)系,如圖所示:

BnMediaPlayerService實(shí)現(xiàn)了onTransact函數(shù),它將根據(jù)消息碼調(diào)用對(duì)應(yīng)的業(yè)務(wù)邏輯函數(shù),這些業(yè)務(wù)邏輯函數(shù)由MediaPlayerService來(lái)實(shí)現(xiàn)。這一路的歷程,如下面的代碼所示:
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:
reply->writeInt32(pingBinder());
break;
default:
//調(diào)用子類(lèi)的onTransact()
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
frameworks/av/media/libmedia/IMediaPlayerService.cpp
status_t BnMediaPlayerService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code) {
case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IMediaPlayerClient> client =
interface_cast<IMediaPlayerClient>(data.readStrongBinder());
audio_session_t audioSessionId = (audio_session_t) data.readInt32();
sp<IMediaPlayer> player = create(client, audioSessionId);
reply->writeStrongBinder(IInterface::asBinder(player));
return NO_ERROR;
} break;
case CREATE_MEDIA_RECORDER: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const String16 opPackageName = data.readString16();
//子類(lèi)要實(shí)現(xiàn)createMediaRecorder
sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName);
reply->writeStrongBinder(IInterface::asBinder(recorder));
return NO_ERROR;
} break;
case CREATE_METADATA_RETRIEVER: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
//子類(lèi)要實(shí)現(xiàn)createMetadataRetriever()
sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
reply->writeStrongBinder(IInterface::asBinder(retriever));
return NO_ERROR;
} break;
case ADD_BATTERY_DATA: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
uint32_t params = data.readInt32();
addBatteryData(params);
return NO_ERROR;
} break;
case PULL_BATTERY_DATA: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
pullBatteryData(reply);
return NO_ERROR;
} break;
case LISTEN_FOR_REMOTE_DISPLAY: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const String16 opPackageName = data.readString16();
sp<IRemoteDisplayClient> client(
interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
if (client == NULL) {
reply->writeStrongBinder(NULL);
return NO_ERROR;
}
String8 iface(data.readString8());
sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));
reply->writeStrongBinder(IInterface::asBinder(display));
return NO_ERROR;
} break;
case GET_CODEC_LIST: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IMediaCodecList> mcl = getCodecList();
reply->writeStrongBinder(IInterface::asBinder(mcl));
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}