Binder機制分析(2)——從MediaService中看Binder的實現和使用(1)
本文是對《Android技術內幕-系統卷》第三章的摘抄和整理。
1. MediaService入口, 獲取ServiceManager
下面我們就從MediaService的原始碼入手進行分析,首先,MediaService的入口函式的實現位於“framework\base\media\mediaServer\main_mediaserver.cpp”。int main(int argc, char* argv)
{
//獲得ProcessState例項
sp<ProcessState> proc(ProcessState::self());
//得到一個ServiceManager物件
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
//初始化MediaService服務
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
//啟動程式的執行緒池
ProcessState::self()->startThreadPool();
//將自己加入到執行緒池
IPCThreadState::self()->joinThreadPool();
}
1.1 defaultServiceManager()的實現
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
//建立gDefaultServiceManager
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
這裡採用了singleton模式,如果全域性的gDefaultServiceManager不為NULL,則直接返回;否則,建立一個gDefaultServiceManager。
1.2 getContextObject()的實現
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
if (supportsProcesses()) {
return getStrongProxyForHandle(0);
} else {
return getContextObject(String16("default"), caller);
}
}
1.3 getStrongProxyForHandle的實現
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)) {
b = new BpBinder(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;
}
將建立過程交給ProcessState::getStrongProxyForHandle()函式來實現,第一次進入該函式則會建立一個BpBinder物件並返回。
1.4 interface_cast的實現
大家可能會疑惑,明明建立的是一個BpBinder物件,為什麼最後卻通過interface_cast函式強制轉換為IServiceManager。
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
替換INTERFACE:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
其中,INTERFACE對應於IServiceManager,因此我們需要繼續找到IServiceManager::asInterface(...)的實現。在IServiceManager中我們可以看到一個如下所示的巨集:
DECLARE_META_INTERFACE(ServiceManager);
1.5 DECLARE_META_INTERFACE分析
#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();
替換INTERFACE:
#define DECLARE_META_INTERFACE(INTERFACE)
static const Android::String16 descriptor;
static android::sp<IServiceManager> asInterface(
const Android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
IServiceManager();
virtual ~IServiceManager();
1.6 IMPLEMENT_META_INTERFACE分析
IMPLEMENT_META_INTERFACE(ServiceManager, "Android.os.IServiceManager"); //IServiceManager.cpp
#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() { }
替換INTERFACE:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
const Android::String16 IServiceManager::descriptor("Android.os.IServiceManager");
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
Android::sp<IServiceManager> ServiceManager::asInterface(
const Android::sp<android::IBinder>& obj) //實際上obj = BpBinder(0);
{
Android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj); //實際上obj = BpBinder(0);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
1.7 asInterface的實現
該函式首先會根據描述符去查詢本地的Interface,如果沒有查詢到,則會執行“new Bp##INTERFACE(obj);”,實際上就是建立了一個BpServiceManager例項。
因為這個命名也以Bp開頭,也許它與上一節介紹的Binder機制的伺服器代理物件有關,其實BpServiceManager就是ServiceManager的Binder代理物件。
1.8 BpServiceManager實現
在IServiceManager.cpp中可以找到BpServiceManager的實現:
BpServiceManager(const sp<IBinder>& impl) //實際上impl = BpBinder(0);
: BpInterface<IServiceManager>(impl)
{
}
這裡的impl就是之前通過ProcessState::getContextObject建立的BpBinder物件。接著進入BpInterface的建構函式,它位於IInterface.h中:
inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote) //實際上remote = BpBinder(0);
: BpRefBase(remote)
{
}
最終會進入BpRefBase的建構函式,它位於Binder.cpp中:
BpRefBase::BpRefBase(const sp<IBinder>& o) //實際上o = BpBinder(0);
: mRemote(o.get()), mRefs(NULL), mState(0) //實際上mRemote = BpBinder(0);
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); //Removed on first
mRefs = mRemote->createWeak(this); //Held for our entire
}
}
o.get()實際上就是之前通過ProcessState::getContextObject建立的BpBinder物件,即mRemote指向BpBinder物件。也就是說,“sp<IServiceManager> sm = defaultServiceManager();”語句返回的實際上是BpServiceManager,它的remote物件是BpBinder,傳入的handle引數是0。
得到了BpServiceManager物件後,我們就可以通過Binder與ServiceManager進行互動了。
2. 新增Service到ServiceManager:
2.1 MediaPlayerService::instantiate()分析
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
MediaPlayerService建構函式:
MediaPlayerService::MediaPlayerService()
{
LOGV("MediaPlayerService created");
mNextConnId = 1;
}
初始化過程為:首先,構造一個MediaPlayerService。
然後,通過defaultServiceManager()獲得之前建立的BpServiceManager,並呼叫其addService函式。
而MediaPlayerService又繼承自BnMediaPlayerService,實際上就是MediaPlayerService服務,對應於Binder機制中的服務端。
2.2 BpServiceManager::addService的實現
virtual status_t addService(const String16& name, const sp<IBinder>& service) //service就是BnMediaPlayerService
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); //通過巨集DECLARE_META_INTERFACE所定義的描述符"Android.os.Iservice Manager"。
data.writeString16(name); //name就是"media.player"
data.writeStrongBinder(service); //service就是BnMediaPlayerService
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); //remote()返回mRemout,也就是BpBinder(0)
return err == NO_ERROR ? reply.readInt32() : err;
}
首先呼叫writeInterfaceToken寫入Interface的名稱IServiceManager::getInterfaceDescriptor(),寫入的名稱實際上就是前面在IServiceManager中,
然後,通過writeString16寫入服務的名稱,根據引數可以知道該服務的名稱為media.player;
最後,通過writeStrongBinder寫入服務,也就是上面所說的MediaPlayerService,即BnMediaPlayerService。
準備好要傳送的命令包後,通過remote()獲得其mRemote物件(前面分析過,該物件實際上就是在defaultServiceManager()中建立的BpBinder物件,也就是BpBinder(0));
呼叫transact函式來傳送命令包,傳送的命令為新增服務ADD_SERVICE_TRANSACTION。
2.3 IPCThreadState::self()->transact
BpBinder::transact最終會呼叫 IPCThreadState::self()->transact來傳送資料。
而在IPCThreadState中,最終還是通過writeTransactionData函式來完成資料的傳送的。
傳送之後,waitForResponse函式會等待反饋的結果,在writeTransactionData中會將要傳送的資料整理為一個binder_transaction_data結構體(請參見Binder驅動的部分)。
直到進入talkWithDriver函式中才會真正開始利用Binder驅動來進行通訊。對於驅動的操作,當然就是ioctl了。talkWithDriver函式中的傳送片段如程式碼清單3-60所示。
talkWithDriver的實現片段
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
BpServiceManager傳送的資訊應該由BnServiceManager來接收,但是Android中並沒有BnServiceManager。
因此,具體的接收操作會由Service Manager來完成。具體操作流程請參考上一篇關於Service Manager的實現,也就是其中的svcmgr_handler函式。
3. 總結
1)通過ProcessState::self()函式獲得ProcessState物件,並開啟Binder裝置。
2)通過defaultServiceManager得到BpServiceManager例項。
3)通過MediaPlayerService::instantiate()得到MediaPlayerService服務BnMediaPlayer Service,並通過BpServiceManager::addService將MediaPlayerService服務加入到Service Manager的list中。
相關文章
- Binder機制分析(2)——從MediaService中看Binder的實現和使用(2)
- Binder機制分析(1)——Binder結構簡介
- Binder機制分析(3)—— 實現自己的Service
- Binder機制
- Binder學習(二)Binder機制解析
- 【Android原始碼】Binder機制和AIDL分析Android原始碼AI
- Binder總結篇2-Binder使用
- Binder通訊機制
- Binder Java層的實現原理分析Java
- Android的IPC機制BinderAndroid
- Binder機制之AIDLAI
- 藉助 AIDL 理解 Android Binder 機制——AIDL 的使用和原理分析AIAndroid
- Binder機制的細節補充
- Android IPC機制(三):淺談Binder的使用Android
- Android Binder機制淺析Android
- Binder總結篇1-Binder原理
- C++ binder 實現C++
- 藉助 AIDL 理解 Android Binder 機制——Binder 來龍去脈AIAndroid
- 圖解Android中的binder機制圖解Android
- Android進階(六)Binder機制Android
- android Binder機制深入淺出Android
- Android Binder機制文章轉載Android
- Android 系統原始碼-2:Binder 通訊機制Android原始碼
- Binder Java層分析Java
- 理解 Android Binder 機制(三):Java層AndroidJava
- Android的IPC機制(三)——Binder連線池Android
- 理解 Android Binder 機制(二):C++層AndroidC++
- Android系統之Binder通訊機制Android
- 理解 Android Binder 機制(一):驅動篇Android
- Binder通訊機制與IPC通訊.md
- Binder基礎業務分析
- Binder池淺談分析
- Android Binder IPC分析Android
- 從AIDL開始談Android程式間Binder通訊機制AIAndroid
- Binder的使用方法和原始碼解析原始碼
- 3分鐘帶你看懂android的Binder機制Android
- Binder學習(三)通過AIDL分析Binder通訊流程AI
- c++閹割版binder實現C++