servicemanager做爲一個守護進程在開機時被啓動,此後就能夠說servicemanager的服務端已經就緒,其它服務(如MediaService等具體服務)就能夠向servicemanager註冊本身了,爲了實現和servicemanager的交互,在libbinder庫中也爲servicemanager提供了客戶端(即代理部分),相關核心類就是下圖中的IServiceManager和BpServiceManager。android
這篇筆記就來分析servicemanager代理端的典型流程實現。ide
獲取servicemanager代理對象;
註冊服務;
獲取服務;
獲取servicemanager代理
// client經過IServiceManager和servicemanager通訊,經過該接口獲取BpServiceManager(IServiceManager的子類)對象
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL)
return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
// IServiceManager是根據BpBinder對象構造出來的,這裏的interface_cast轉換也很關鍵
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}函數
全局的gDefaultServiceManager表示每一個進程只會持有一個BpServiceManager對象指針,實際上也只須要有一個該對象。有兩步核心操做:ui
ProcessState::self()->getContextObject(NULL);
interface_cast<IServiceManager>();
getContextObject()
// 獲取BpBinder對象
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
// 參數0很是重要,指定了要獲取的服務的句柄,0表示servicemanager
return getStrongProxyForHandle(0);
}this
// 當前進程持有的全部其它service的句柄
Vector<handle_entry>mHandleToObject;
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;代理
AutoMutex _l(mLock);
// 獲取或者新建handle對應的handle_entry
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;
}
// 建立BpBinder對象
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;
}指針
整個過程的核心在BpBinder::create(),建立一個BpBinder對象,傳入的handle爲0,0特指servicemanager。code
interface_cast<IServiceManager>()
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}orm
對應到這裏就是IServiceManager::asInterface(),該函數並無直接實現,libbinder提供了兩個宏,其中包含了該函數的實現,這兩個宏分別爲DECLARE_META_INTERFACE()和IMPLEMENT_META_INTERFACE()。這兩個宏的展開過程再也不細述,直接看最終的結果:server
::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) {
// 返回的就是BpServiceManager對象,obj就是包裝了0句柄的BpBinder對象
intr = new BpServiceManager(obj);
}
}
return intr;
}
註冊服務
通常,服務註冊過程以下面的示例代碼所示(來自BinderService::publish()):
// 向系統註冊服務
static status_t publish(bool allowIsolated = false, int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)
{
// 獲取BpServiceManager對象
sp<IServiceManager> sm(defaultServiceManager());
// 調用addService()方法,前兩個入參分別爲服務名字和服務對象指針
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags);
}
addService()是由BpServiceManager實現的。
virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority)
{
Parcel data, reply;
// 向servicemanager發送該調用請求
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
// 要註冊的服務信息
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
// 調用BpBinder中的transact()
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
remote()函數是BpServiceManager從BpRefBase中繼承來的,返回的就是封裝了server端句柄的BpBinder對象指針。
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) {
// 調用的是IPCThreadState中的transact()
status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
最後經過IPCThreadState中的transact()將要傳遞給servicemager的數據寫入binder驅動。
獲取服務
客戶端要想調用服務端提供的接口,首先要獲取服務端的代理,這是經過BpServiceManager::getService()實現的。
// 入參就是服務的名字
virtual sp<IBinder> getService(const String16& name) const
{
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
// 判斷是不是廠商本身實現的binder驅動
const bool isVendorService = strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
const long timeout = uptimeMillis() + 5000;
if (!gSystemBootCompleted) {
char bootCompleted[PROPERTY_VALUE_MAX];
property_get("sys.boot_completed", bootCompleted, "0");
gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false;
}
// retry interval in millisecond.
const long sleepTime = gSystemBootCompleted ? 1000 : 100;
// 最多等待5s,獲取封裝了服務端句柄的BpBinder對象
int n = 0;
while (uptimeMillis() < timeout) {
n++;
if (isVendorService) {
ALOGI("Waiting for vendor service %s...", String8(name).string());
CallStack stack(LOG_TAG);
} else if (n%10 == 0) {
ALOGI("Waiting for service %s...", String8(name).string());
}
usleep(1000*sleepTime);
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
}
ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
return NULL;
}
如上,實際調用的是checkService():
virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); return reply.readStrongBinder(); }