一 Media Service進程啟動
Init.rc中描述的service對應linux 的進程:
Media進程定義:
service media /system/bin/mediaserver class main user media group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc ioprio rt 4
servicemanager 進程定義:
service servicemanager /system/bin/servicemanager class core user system group system
Media中有很多Native Service(AudioFlinger MediaPlayerService CameraService
AudioPolicyService等),整個Android(native或者framework)的Service都需要加入
servicemanager中進行統一管理。
那么Media Process 與ServiceManager Process是如何進行通信的呢——Binder.
通過Media Process中使用binder進行完成IPC過程,學習Binder的概念和使用方法。
\frameworks\av\media\mediaserver\ main_mediaserver.cpp:
int main(int argc, char** argv) { //創建ProcessState 當前進程屬性
sp<ProcessState> proc(ProcessState::self()); //IServiceManager對象
sp<IServiceManager> sm = defaultServiceManager(); //初始化MediaPlayerService服務對象
MediaPlayerService::instantiate(); …… //啟動進程的線程池
ProcessState::self()->startThreadPool(); //執行線程消息循環
IPCThreadState::self()->joinThreadPool(); }
Sp:指針運算符和普通運算符的重載 StrongPointer。
二 Media Process執行過程
1 ProcessState對象創建
當前進程的狀態屬性,對象創建:
sp<ProcessState> ProcessState::self() { Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess; }
ProcessState構造函數:
ProcessState::ProcessState() : mDriverFD(open_driver()) //打開binder驅動設備
, mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { //將binder的fd映射到當前進程虛擬空間地址中 與binder進行交互
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); } }
打開binder設備:
static int open_driver() { //打開binder設備驅動
int fd = open("/dev/binder", O_RDWR); if (fd >= 0) { //bidner最大支持線程數
size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); } return fd; }
ProcessState對象創建過程所做的事:
打開/dev/binder設備,得到binder設備的fd;
將bidner設備fd映射到當前進程虛擬地址空間建立交互的通道;
2 IServiceManager對象創建
sp<IServiceManager> sm = defaultServiceManager();
為什么需要一個IServiceManager對象呢,這個類是個抽象提供接口
class IServiceManager : public IInterface { virtual sp<IBinder> getService( const String16& name) const = 0; virtual status_t addService( const String16& name, const sp<IBinder>& service, bool allowIsolated = false) = 0; …… };
通過IServiceManager派生對象操作將Service加入到ServiceManager中.
defaultServiceManager()函數:
sp<IServiceManager> defaultServiceManager() { //單例對象
if (gDefaultServiceManager != NULL) return gDefaultServiceManager; AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { //創建對象
gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } return gDefaultServiceManager; }
ProcessState::self()->getContextObject(NULL):得到一個IBinder對象
ProcessState::self()剛才所創建的ProcessState對象。
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) { return getStrongProxyForHandle(0); } sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); //從表中查詢一個handle對應的handle_entry //若沒有則創建一個 handle == 0
handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { //handle_entry對象成員初始化 創建handle=0的BpBinder
b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } } return result; }
handle_entry是什么呢?
struct handle_entry { IBinder* binder; RefBase::weakref_type* refs; };
也就是說ProcessState 有一個表Vector<handle_entry>mHandleToObject;
表里面的每一項存儲了一個binder,每一個binder對應一個handle。
Handle = 0是什么,句柄? 代表誰的句柄——ServiceManager在binder中的資源。
從ProcessState::self()->getContextObject(NULL)得到一個 IBinder——BpBinder(0);
於是得到:
gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
使用interface_cast將IBinder實例轉化成IServiceManager實例。
3 interface_cast函數
\frameworks\native\include\binder\IInterface.h:
interface_cast是個內聯模板函數:
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
結合前面就是:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj) { return IServiceManager::asInterface(obj); }
所以需要到IServiceManager里面去看看是如何實現的
4 IServiceManager類
\frameworks\native\include\binder\IServiceManager.h:
IServiceManager是一個抽象類:
class IServiceManager : public IInterface { public: //宏聲明
DECLARE_META_INTERFACE(ServiceManager); virtual sp<IBinder> getService( const String16& name) const = 0; virtual status_t addService( const String16& name, const sp<IBinder>& service, bool allowIsolated = false) = 0; …… }
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(); \
替換成IServiceManager:
//實現時傳入:android.os.IServiceManager
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();
實現\frameworks\native\include\binder\IServiceManager.cpp:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
IMPLEMENT_META_INTERFACE實現:
看一下asInterface接口:
#define 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 != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == NULL) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ } \
替換成IServiceManager:
android::sp<IServiceManager> IServiceManager::asInterface( const android::sp<android::IBinder>& obj) { //obj BpBinder實例
android::sp<IServiceManager> intr; if (obj != NULL) { //返回NULL
intr = static_cast<IServiceManager*>( obj->queryLocalInterface( IServiceManager::descriptor).get()); if (intr == NULL) { intr = new BpServiceManager(obj); } } return intr; }
這里得到IServiceManager 實例:
BpServiceManager:new BpServiceManager(new BpBinder(0));
5 BpServiceManager 和 BpInterface類
\frameworks\native\libs\binder\ IServiceManager.cpp:BpServiceManager
class BpServiceManager : public BpInterface<IServiceManager> { public: //impl就是 new BpBinder(0)
BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { } virtual sp<IBinder> checkService(const String16& name) const { …… remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); } virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { …… remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); } }
\frameworks\native\include\binder\ IInterface.h:模板類BpInterface
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase // INTERFACE IServiceManager
{ public: BpInterface(const sp<IBinder>& remote); protected: virtual IBinder* onAsBinder(); };
BpInterface構造函數:
template<typename INTERFACE> inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) {
}
BpRefBase構造函數:
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) { // IBinder mRemote 指向 o.get() :new BpBinder(0)
}
gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
實際為:
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
Bn代表Binder Native Bp代表Binder Proxy
BpServiceManager代理的BpBinder實例 BpBinder代理的handle(0)
這個關系有些復雜,看一下類繼承結構圖:
上面這個結構看起來感覺很熟悉——Bridge模式。將Binder數據交互和功能處理橋接起來。
在Media Process 的main函數中通過:
sp<IServiceManager> sm = defaultServiceManager();
我們得到了sm:是BpServiceManager對象。
三 MediaPlayerService加入到ServiceManager中
回到main函數中:
int main(int argc, char** argv) { //創建ProcessState 當前進程屬性
sp<ProcessState> proc(ProcessState::self()); //IServiceManager對象
sp<IServiceManager> sm = defaultServiceManager(); //初始化MediaPlayerService服務對象
MediaPlayerService::instantiate(); //執行到這里
…… //啟動進程的線程池
ProcessState::self()->startThreadPool(); //執行線程消息循環
IPCThreadState::self()->joinThreadPool(); }
1 MediaPlayerService初始化過程
void MediaPlayerService::instantiate() { // defaultServiceManager就是上面所述得到的BpServiceManager對象
defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService()); }
BpServiceManager添加Service:
virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { //生成數據包Parcel
Parcel data, reply; // Write RPC headers 寫入Interface名字 得到“android.os.IServiceManager”
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); //寫入Service名字 “media.player”
data.writeString16(name); //寫入服務
data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); // remote()返回BpBinder對象
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; }
remote()->transact 到BpBinder中:
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { //到當前進程IPCThreadState中 mHandle=0
status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT; }
2 IPCThreadState中寫入數據到Binder設備過程
IPCThreadState::self()->transact過程:
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err = data.errorCheck(); flags |= TF_ACCEPT_FDS; //將數據轉化成binder_transaction_data 寫入到Parcel實例mOut中
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); //寫入數據
err = waitForResponse(reply); return err; } status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { while (1) { //將數據寫入到Binder設備中
talkWithDriver(); …… } return err; } status_t IPCThreadState::talkWithDriver(bool doReceive) { //將數據封裝成binder_write_read結構
binder_write_read bwr; do { //將數據寫入到所打開的Binder設備中
ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) …… } while (err == -EINTR); return NO_ERROR; }
將MediaPlayerService加入到ServiceManager中,
這里就通過BpServiceManager的AddService將數據寫入到Binder設備傳遞給ServiceManager。
繼續Media Process過程
四 Media Process消息循環
int main(int argc, char** argv) { //啟動進程的線程池
ProcessState::self()->startThreadPool(); //走到了這里 //執行線程消息循環
IPCThreadState::self()->joinThreadPool(); }
1 創建工作者線程
startThreadPool:\frameworks\native\libs\binder\ ProcessState.cpp:
void ProcessState::startThreadPool() { spawnPooledThread(true); } void ProcessState::spawnPooledThread(bool isMain) { //創建PoolThread對象 並run ,非線程
sp<Thread> t = new PoolThread(isMain); t->run(buf); }
PoolThread繼承Thread
執行Thread的run函數:
status_t Thread::run(const char* name, int32_t priority, size_t stack) { //創建線程mThread _threadLoop
bool res; res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread); return NO_ERROR; }
現在有兩個線程:主線程和mThread線程
mThread線程執行:_threadLoop
int Thread::_threadLoop(void* user) { Thread* const self = static_cast<Thread*>(user); do { //調用子類的threadLoop
result = self->threadLoop(); …… } while(strong != 0); return 0; } class PoolThread : public Thread { protected: virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); return false; } };
2 進程間通信消息循環過程
消息循環:
void IPCThreadState::joinThreadPool(bool isMain) { mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); status_t result; //消息循環
do { int32_t cmd; //從binder設備中讀取命令
result = talkWithDriver(); if (result >= NO_ERROR) { cmd = mIn.readInt32(); //執行命令
result = executeCommand(cmd); } …… } while (result != -ECONNREFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false); }
命令執行:
status_t IPCThreadState::executeCommand(int32_t cmd) { BBinder* obj; RefBase::weakref_type* refs; switch (cmd) { case BR_DECREFS: break; case BR_ATTEMPT_ACQUIRE: break; case BR_TRANSACTION: binder_transaction_data tr; result = mIn.read(&tr, sizeof(tr)); if (tr.target.ptr) { //將目標對象轉化成BBinder
sp<BBinder> b((BBinder*)tr.cookie); //調用BBinder的transact 函數
const status_t error = b->transact(tr.code, buffer, &reply, tr.flags); } break; …… default: } return result; }
binder_transaction_data.cookie:target object cookie目標對象,這個target object是指那個呢?
在Media Process里面有幾個Service:AudioFlinger、MediaPlayerService、CameraService等。
這個目標是這其中Service中的一個,假設目標對象為為MediaPlayerService,那為何要轉化成BBinder呢?
3 Service對命令的處理
線程從binder接收到消息命令,將命令傳遞給Service處理。將目標對象轉化成BBinder,然后調度此命令;
命令從遠端傳遞到本地端進行處理,每個Service都對應BnXXX對象來處理遠端BpXXX傳來的命令。
sp<BBinder> b((BBinder*)tr.cookie);
const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
這里b代表某個Service:假設為MediaPlayerService;弄清楚執行過程,要弄清楚類繼承關系。
本地端BnMediaPlayerService消息處理過程:真正的對象是MediaPlayerService實例。
從BBinder ->transact開始傳遞:
status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { //onTransact是個virtual函數 派生類BnMediaPlayerService重寫
err = onTransact(code, data, reply, flags); return err; } status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case CREATE: { pid_t pid = data.readInt32(); sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder()); //create是個virtual函數 派生類MediaPlayerService重寫
sp<IMediaPlayer> player = create(pid, client, audioSessionId); //創建player寫入到數據包中 傳回
reply->writeStrongBinder(player->asBinder()); return NO_ERROR; } break; …… default: return BBinder::onTransact(code, data, reply, flags); } }
可以看看Client類繼承關系結構圖:
看到這個跟上面的MediaPlayerService繼承關系非常的相似,
這個結構也非常的熟悉——Adapter模式;將binder消息交互和命令處理適配到一起。
五 Client端與Service端交互
Client對Service進行使用Binder通信,是得到一個Service BnXXX端對象的代理,在Client 為BpXXX代理,
然后使用此代理進行相關的操作. 前面在使用ServiceManager就是此種方式進行。
實際上通信的基礎是Binder,Proxy不過是在Binder上進行了一層封裝,封裝了對binder驅動的底層操作,使具有面向對象的特性。
任意兩個進程通過Binder進行通信,就是先得到另一個進程的binder標識,通過此binder進行數據交換。
1 新增加一個服務
看下面media Palyer類繼承結構。
實現Bn端類繼承結構:
實現Bp端類繼承結構:
可以看到 :
- 需要定義服務公共接口IMediaPlayerService;
- 實現服務Bn端 派發消息BnMediaPlayerService;
- 實現服務的命令處理MediaPlayerService;
- 實現服務代理BpMediaPlayerService;
2 Client獲取Service服務
Native Service以及framework Service都是加入到ServiceManger中,
不管native端還是Framework端得Service 其實都是要滿足上面遠程對象代理結構。
native端獲取service:
//獲取ServiceManager的代理對象
sp<IServiceManager> sm = defaultServiceManager(); //通過ServiceManager獲取media Service binder
binder = sm->getService(String16("media.player")); //將binder封裝 構造media Service代理對象 BpMediaPlayerService
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
framework層的service,借助AIDL文件,實現跨進程的通信:
所有framework端service想要作為公共的服務,被別的應用程序調用,都要實現AIDL文件,服務要繼承該AIDL文件內部類Stub。
其實AIDL文件是對Framework中service作為進程通信的框架的封裝,系統自動生成中間需要的代碼和步驟,統一結構:還是binder代理,服務代理。
下面看看PowerManagerService實現。
PowerManagerService服務:
\frameworks\base\services\java\com\android\server\PowerManagerService.java
public class PowerManagerService extends IPowerManager.Stub…… { public void goToSleep(long time){ …… } }; AIDL文件:\frameworks\base\core\java\android\os\IPowerManager.aidl interface IPowerManager { void goToSleep(long time); …… }
AIDL對應的Java文件:
AIDL會自動生成一個對應的Java的interface文件,看看這個接口文件。
AIDL自動生成對應java文件位置:\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\src\core\java\android\os
public interface IPowerManager extends android.os.IInterface { //IPowerManager 內部類 Stub
public static abstract class Stub extends android.os.Binder implements android.os.IPowerManager { public static android.os.IPowerManager asInterface( android.os.IBinder obj) { //生成一個Proxy對象
return new android.os.IPowerManager.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) { switch (code) { case TRANSACTION_goToSleep: this.goToSleep(_arg0); return true; …… } } //Stub內部類Proxy
private static class Proxy implements android.os.IPowerManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } public void goToSleep(long time) { //將數據打包成Parcel
android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); _data.writeInterfaceToken(DESCRIPTOR); _data.writeLong(time); //傳輸數據到binder 到相關的Service 進程 // IPCThreadState::transact方法中完成
mRemote.transact(Stub.TRANSACTION_goToSleep, _data, _reply,0); _reply.readException(); } } } //goToSleep接口對應的ID
static final int TRANSACTION_goToSleep = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); //接口
public void goToSleep(long time); }
看下其中類結構:
AIDL自動生成對應的java文件,將結構過程進行了統一,自動生成中間代碼。
Application獲取用Service:
IPowerManager m mPowerManagerService; //獲取service的bingder
IBinder binder = ServiceManager.getService("power"); //創建service代理對象
mPowerManagerService = IPowerManager.Stub.asInterface(binder); //調用接口
mPowerManagerService.goToSleep();
Native Service和 Framework Service結構方式基本一致的。
進程間通信Linux系統已經提供了很多方式,比如Socket,為什么Android非要另辟蹊徑,設計了Binder呢?
可以閱讀一下:http://www.cnblogs.com/bastard/archive/2012/10/17/2728155.html
Game Over !
參考文檔:
http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
http://blog.csdn.net/maxleng/article/details/5490770
注:
“我們其實還一部分沒有研究,就是同一個進程之間的對象傳遞與遠程傳遞是區別的。同一個進程間專遞服務地和對象,
就沒有代理BpBinder產生,而只是對象的直接應用了。應用程序並不知道數據是在同一進程間傳遞還是不同進程間傳遞,
這個只有內核中的Binder知道,所以內核Binder驅動可以將Binder對象數據類型從BINDER_TYPE_BINDER修改為
BINDER_TYPE_HANDLE或者BINDER_TYPE_WEAK_HANDLE作為引用傳遞。” ——來自上述地址
這個可以看到在SystemServer運行的Service之間使用時,直接轉化成了對應的對象,而不是通過代理。