在 Binder 系統中,分爲 Client ServiceManager Server 三部分,C++是面向對象的語言,因此,這三者對應三個類的實例。ServiceManager 由 Android系統實現,我們只需要實現我們自己的 client 和 Server 類即可。
在 Binder 系統 C 的實現中,我們的 Client 和 Server 都實現了 sddone 和 reduceone 函數,名稱一樣,內容不一樣,因此在 C++ 中,將這些函數統一封裝成一個接口類 ICalculateService ,放在 ICalculateService.h 中。
1
/* 參考: frameworks\av\include\media\IMediaPlayerService.h */
2
3
#ifndef ANDROID_ICALCULATESRVICE_H
4
#define ANDROID_ICALCULATESRVICE_H
5
6
#include <utils/Errors.h> // for status_t
7
#include <utils/KeyedVector.h>
8
#include <utils/RefBase.h>
9
#include <utils/String8.h>
10
#include <binder/IInterface.h>
11
#include <binder/Parcel.h>
12
13
#define SVR_CMD_ADD_ONE 0
14
#define SVR_CMD_REDUCE_ONE 1
15
16
17
namespace android {
18
19
class ICalculateService: public IInterface
20
{
21
public:
22
DECLARE_META_INTERFACE(CalculcateService);
23
virtual void addone(int n) = 0;
24
virtual int reduceone(int n) = 0;
25
};
26
27
class BnCalculateService: public BnInterface<ICalculateService>
28
{
29
public:
30
virtual status_t onTransact( uint32_t code,
31
const Parcel& data,
32
Parcel* reply,
33
uint32_t flags = 0);
34
35
virtual void addone(int n);
36
virtual int reduceone(int n);
37
38
};
39
}
40
41
#endif
1
template<typename INTERFACE>
2
class BnInterface : public INTERFACE, public BBinder
3
{
4
public:
5
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
6
virtual const String16& getInterfaceDescriptor() const;
7
8
protected:
9
virtual IBinder* onAsBinder();
10
};
可以看到,這個ICalculateService接口非常簡單,定義了兩個純虛函數,所謂的純虛函數就是作爲標準接口,在子類中實現。
同時可以看到,這裏還定義了一個 BnCalculateService ,它就是我們的 Server ,這個 BnCalculateService 繼承自 BnInterface
模板類ICalculateService 類 和 BBinder 類,BBinder 繼承自 IBindre,他們都是抽象類,其中 onTransact 就是在 BBinder 類中定義的。
BnCalculateService 的意思是 Binder native Calculate Service ,函數實現放在:BnCalculateService.cpp 中
1
/* 參考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
2
3
#define LOG_TAG "CalculateService"
4
5
#include "ICalculateService.h"
6
7
8
namespace android {
9
10
status_t BnCalculateService::onTransact( uint32_t code,
11
const Parcel& data,
12
Parcel* reply,
13
uint32_t flags)
14
{
15
/* 解析數據,調用addone/reduceone */
16
17
switch (code) {
18
case SVR_CMD_ADD_ONE: {
19
int32_t policy = data.readInt32();
20
int32_t n = data.readInt32();
21
22
/* 把返回值寫入reply傳回去 */
23
reply->writeInt32(result);
24
25
return NO_ERROR;
26
} break;
27
28
case SVR_CMD_REDUCE_ONE: {
29
30
/* 從data中取出參數 */
31
int32_t policy = data.readInt32();
32
int32_t n = data.readInt32();
33
34
/* 把返回值寫入reply傳回去 */
35
reply->writeInt32(result);
36
37
return NO_ERROR;
38
} break;
39
default:
40
return BBinder::onTransact(code, data, reply, flags);
41
}
42
}
43
44
int32_t BnCalculateService::addone(int32_t n)
45
{
46
ALOGI("server add one : %d\n", cnt++);
47
return ++n;
48
49
int32_t BnCalculateService::sayhello_to(int32_t n)
50
{
51
ALOGI("server reduce one : %d\n", n);
52
return --n;
53
}
54
55
}
定義好了這個 Server 類如何使用?
1
/* 參考: frameworks\av\media\mediaserver\Main_mediaserver.cpp */
2
3
#define LOG_TAG "HelloService"
4
//#define LOG_NDEBUG 0
5
6
#include <fcntl.h>
7
#include <sys/prctl.h>
8
#include <sys/wait.h>
9
#include <binder/IPCThreadState.h>
10
#include <binder/ProcessState.h>
11
#include <binder/IServiceManager.h>
12
#include <cutils/properties.h>
13
#include <utils/Log.h>
14
15
#include "ICalculateService.h"
16
17
18
using namespace android;
19
20
int main(void)
21
{
22
/* addService */
23
24
/* while(1){ read data, 解析數據, 調用服務函數 } */
25
26
/* 打開驅動, mmap */
27
sp<ProcessState> proc(ProcessState::self());
28
29
/* 獲得BpServiceManager */
30
sp<IServiceManager> sm = defaultServiceManager();
31
32
sm->addService(String16("calculate"), new BnCalculateService());
33
34
/* 循環體 */
35
ProcessState::self()->startThreadPool();
36
IPCThreadState::self()->joinThreadPool();
37
38
return 0;
39
}
下面來看 Client
1
/* 參考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
2
3
#include "ICalculateService.h"
4
5
namespace android {
6
7
class BpCalculateService: public BpInterface<ICalculateService>
8
{
9
public:
10
BpCalculateService(const sp<IBinder>& impl)
11
: BpInterface<ICalculateService>(impl)
12
{
13
}
14
15
int addone(int n)
16
{
17
Parcel data, reply;
18
19
data.writeInt32(0);
20
data.writeInt32(n);
21
22
23
remote()->transact(SVR_CMD_REDUCE_ONE, data, &reply);
24
25
return reply.readInt32();
26
}
27
28
int reduceone(int n)
29
{
30
/* 構造/發送數據 */
31
Parcel data, reply;
32
33
data.writeInt32(0);
34
data.writeInt32(n);
35
36
37
remote()->transact(SVR_CMD_REDUCE_ONE, data, &reply);
38
39
return reply.readInt32();
40
}
41
42
};
43
44
IMPLEMENT_META_INTERFACE(CalculateService, "android.media.ICalculateService");
45
46
}
47
1
#define LOG_TAG "CalculateService"
2
//#define LOG_NDEBUG 0
3
4
#include <fcntl.h>
5
#include <sys/prctl.h>
6
#include <sys/wait.h>
7
#include <binder/IPCThreadState.h>
8
#include <binder/ProcessState.h>
9
#include <binder/IServiceManager.h>
10
#include <cutils/properties.h>
11
#include <utils/Log.h>
12
13
#include "ICalculateService.h"
14
15
using namespace android;
16
17
/* ./test_client hello
18
* ./test_client hello <name>
19
*/
20
int main(int argc, char **argv)
21
{
22
int cnt;
23
24
if (argc < 2){
25
ALOGI("Usage:\n");
26
ALOGI("%s <hello|goodbye>\n", argv[0]);
27
ALOGI("%s <hello|goodbye> <name>\n", argv[0]);
28
return -1;
29
}
30
31
/* getService */
32
/* 打開驅動, mmap */
33
sp<ProcessState> proc(ProcessState::self());
34
35
/* 獲得BpServiceManager */
36
sp<IServiceManager> sm = defaultServiceManager();
37
38
sp<IBinder> binder =
39
sm->getService(String16("calculate"));
40
41
if (binder == 0)
42
{
43
ALOGI("can't get calculate service\n");
44
return -1;
45
}
46
47
/* service肯定是BpCalculateServie指針 */
48
sp<ICalculateService> service =
49
interface_cast<ICalculateService>(binder);
50
51
52
/* 多態,調用Service的函數 */
53
cnt = service->reduceone(argv[2]);
54
ALOGI("client call reduceone, result = %d", cnt);
55
56
return 0;
57
}
58
IBinder 如何轉換成 ICalculateService ?
1
template<typename INTERFACE>
2
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
3
{
4
return INTERFACE::asInterface(obj);
5
}
可以看出,interface_cast 是個模板函數,在這,它將調用 ICalculateService::asInterface(binder)
asInterface 從哪來的?
1
class ICalculateService: public IInterface
2
{
3
public:
4
DECLARE_META_INTERFACE(CalculcateService);
5
virtual void addone(int n) = 0;
6
virtual int reduceone(int n) = 0;
7
};
1
#define DECLARE_META_INTERFACE(INTERFACE) \
2
static const android::String16 descriptor; \
3
static android::sp<I##INTERFACE> asInterface( \
4
const android::sp<android::IBinder>& obj); \
5
virtual const android::String16& getInterfaceDescriptor() const; \
6
I##INTERFACE(); \
7
virtual ~I##INTERFACE();
實際是:
1
#define DECLARE_META_INTERFACE(INTERFACE) \
2
static const android::String16 descriptor; \
3
static android::sp<ICalculcateService> asInterface( \
4
const android::sp<android::IBinder>& obj); \
5
virtual const android::String16& getInterfaceDescriptor() const; \
6
ICalculcateService(); \
7
virtual ~ICalculcateService();
那個這個 asInterface 函數的實現在哪?
1
class BpCalculateService: public BpInterface<ICalculateService>
2
{
3
public:
4
BpCalculateService(const sp<IBinder>& impl)
5
: BpInterface<ICalculateService>(impl)
6
{
7
}
8
9
int addone(int n)
10
{
11
...
12
}
13
14
int reduceone(int n)
15
{
16
...
17
}
18
19
};
20
21
IMPLEMENT_META_INTERFACE(CalculateService, "android.media.ICalculateService");
22
23
}
24
1
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
2
const android::String16 I##INTERFACE::descriptor(NAME); \
3
const android::String16& \
4
I##INTERFACE::getInterfaceDescriptor() const { \
5
return I##INTERFACE::descriptor; \
6
} \
7
android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
8
const android::sp<android::IBinder>& obj) \
9
{ \
10
android::sp<I##INTERFACE> intr; \
11
if (obj != NULL) { \
12
intr = static_cast<I##INTERFACE*>( \
13
obj->queryLocalInterface( \
14
I##INTERFACE::descriptor).get()); \
15
if (intr == NULL) { \
16
intr = new Bp##INTERFACE(obj); \
17
} \
18
} \
19
return intr; \
20
} \
21
I##INTERFACE::I##INTERFACE() { } \
22
I##INTERFACE::~I##INTERFACE() { }
替換完之後就是這個樣子:
1
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
2
const android::String16 ICalculcateService::descriptor(NAME); \
3
const android::String16& \
4
ICalculcateService::getInterfaceDescriptor() const { \
5
return ICalculcateService::descriptor; \
6
} \
7
android::sp<ICalculcateService> ICalculcateService::asInterface( \
8
const android::sp<android::IBinder>& obj) \
9
{ \
10
android::sp<ICalculcateService> intr; \
11
if (obj != NULL) { \
12
intr = static_cast<ICalculcateService*>( \
13
obj->queryLocalInterface( \
14
ICalculcateService::descriptor).get()); \
15
if (intr == NULL) { \
16
intr = new BpCalculcateService(obj); \
17
} \
18
} \
19
return intr; \
20
} \
21
ICalculcateService::ICalculcateService() { } \
22
ICalculcateService::~ICalculcateService() { }
1
sp<IInterface> IBinder::queryLocalInterface(const String16& /*descriptor*/)
2
{
3
return NULL;
4
}
因此,這裏直接返回的是,new BpCalculateService(binder)
也就是說 interface_cast<ICalculateService>(binder) 的最終結果 new BpCalculateService(binder)
binder 是通過 getService 構造的 BpBinder 對象的指針(BpBinder繼承自IBinder)
先不關心 binder 怎麼來的,先來看看如何用 binder(BpBinder)來構造BpXXXService
BpXXXService 繼承自 BpInterface<IXXXService> 繼承自 BpRefBase
1
BpRefBase::BpRefBase(const sp<IBinder>& o)
2
: mRemote(o.get()), mRefs(NULL), mState(0)
3
{
4
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
5
6
if (mRemote) {
7
mRemote->incStrong(this); // Removed on first IncStrong().
8
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
9
}
10
}
o 是 binder ,o 是個智能指針,o.get() 返回這個指針所指向的對象的指針,也就是 mRemote 指向了 binder
也就是說 interface_cast<ICalculateService>(binder) 的最終結果,構造了一個 BpCalculateService 它裏邊的 mRemote 指向一個 BpBinder
binder 獲取的過程:
1
sp<IServiceManager> sm = defaultServiceManager();
2
3
sp<IBinder> binder =
4
sm->getService(String16("calculate"));
defaultServiceManager IServiceManager 類的接口,它的 getService 函數在 BpServiceManager 類中實現,
1
virtual sp<IBinder> getService(const String16& name) const
2
{
3
unsigned n;
4
for (n = 0; n < 5; n++){
5
sp<IBinder> svc = checkService(name);
6
if (svc != NULL) return svc;
7
ALOGI("Waiting for service %s...\n", String8(name).string());
8
sleep(1);
9
}
10
return NULL;
11
}
12
13
virtual sp<IBinder> checkService( const String16& name) const
14
{
15
Parcel data, reply;
16
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
17
data.writeString16(name);
18
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
19
return reply.readStrongBinder();
20
}
1
sp<IBinder> Parcel::readStrongBinder() const
2
{
3
sp<IBinder> val;
4
unflatten_binder(ProcessState::self(), *this, &val);
5
return val;
6
}
1
status_t unflatten_binder(const sp<ProcessState>& proc,
2
const Parcel& in, sp<IBinder>* out)
3
{
4
const flat_binder_object* flat = in.readObject(false);
5
6
if (flat) {
7
switch (flat->type) {
8
case BINDER_TYPE_BINDER:
9
*out = reinterpret_cast<IBinder*>(flat->cookie);
10
return finish_unflatten_binder(NULL, *flat, in);
11
case BINDER_TYPE_HANDLE:
12
*out = proc->getStrongProxyForHandle(flat->handle);
13
return finish_unflatten_binder(
14
static_cast<BpBinder*>(out->get()), *flat, in);
15
}
16
}
17
return BAD_TYPE;
18
}
1
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
2
{
3
sp<IBinder> result;
4
5
AutoMutex _l(mLock);
6
7
handle_entry* e = lookupHandleLocked(handle);
8
9
IBinder* b = e->binder;
10
if (b == NULL || !e->refs->attemptIncWeak(this)) {
11
12
b = new BpBinder(handle);
13
e->binder = b;
14
if (b) e->refs = b->getWeakRefs();
15
result = b;
16
}
17
18
return result;
19
}
getService 的過程:
構造數據發送數據,在 reply 中取出 handle,通過 handle 構造一個 BpBinder 對象,mHandle = handle
也就是說我們獲取服務的時候是得到了一個服務的 handle ,然後用這個 handle 構造對應的代理類,BpXXXService,在通過BpXXXService代理類的函數來訪問具體的服務。
前面說到,getService 函數也是在一個代理類中實現的,BpServiceManager 中,看看它是怎麼來的:
1
sp<IServiceManager> sm = defaultServiceManager();
1
sp<IServiceManager> defaultServiceManager()
2
{
3
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
4
5
{
6
AutoMutex _l(gDefaultServiceManagerLock);
7
while (gDefaultServiceManager == NULL) {
8
gDefaultServiceManager = interface_cast<IServiceManager>(
9
ProcessState::self()->getContextObject(NULL));
10
if (gDefaultServiceManager == NULL)
11
sleep(1);
12
}
13
}
14
15
return gDefaultServiceManager;
16
}
剛開始的時候,gDefaultServiceManager 爲 NULL:
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
1
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
2
{
3
return getStrongProxyForHandle(0);//new BpBinder(0);
4
}
也就是 interface_cast<IServiceManager>(new BpBinder(0))
和前面分析的一樣,這裏應該是用 BpBinder(0)構造一個 BpServiceManager對象,BpServiceManager 中的 mRemote 指向 BpBinder(0),mHandle = 0
總結:
訪問服務先需要構造代理類,通過 handle 構造 BpBinder,BpBinder 中的 mHandle = handle
通過 BpBinder 構造 BpXXX 代理類對象(代理類對象中的 mRemote 指向 BpBinder)然後付給一個接口類的指針,比如 IServiceManager 或者 IHelloService
利用多態的特性,用父類指針比如 IServiceManager 或者 IHelloService,直接調用 BpXXX 中的函數訪問服務。
後面需要分析:
如何訪問服務的?
BnXXXService 如何註冊服務的,收到消息如何處理的