在客户端,我们通常都是使用ServiceManager的getService或者checkService方法去获取相应服务的proxy,
比如dumpsys.cpp中有
sp<IServiceManager> sm =defaultServiceManager();
sp<IBinder>service = sm->checkService(String16("power"));
这样就获取到了注册为power的服务的proxy了。
就这几句话,功能如此强大。
为什么呢?因为强大的封装,我们看到的这几行代码只是展现出来的冰山一角。
这里 sp<IServiceManager> sm = defaultServiceManager();
其实是获取到了serviceManager的proxy,通过这个proxy来和serviceManager进程交互。
defaultServiceManager()为什么可以获取到ServiceManager的proxy呢,因为它封装了BpBinder(0), Binder驱动中将handle值0作了特殊处理,对应着ServiceManager。
为了加强理解,我们直接使用BpBinder(0)来和ServiceManager进程进行通信。
BpBinder中的handle如同文件描述符fd,需要进行open操作后才可以使用,而且每个进程中对同一个文件的fd是独立的,他们的值不相关。(https://blog.csdn.net/aaajj/article/details/78034882)
但是,直接构造BpBinder(0)是可以的。因为0是全局的,预留的。
这里我们通过构造出的BpBinder(0)来进行transact操作。
BpBinder(0)
#include<binder/Parcel.h>
//#include<binder/ProcessState.h>
//#include<binder/IServiceManager.h>
#include<binder/TextOutput.h>
//#include<utils/Vector.h>
#include<binder/BpBinder.h>//
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
usingnamespace android;
intmain(int argc, char* const argv[])
{
int num = 0;
IBinder * service = newBpBinder(0);
if (argc > 1)
{
num = atoi(argv[1]);
}
printf("num = %d\n", num);
Parcel data;
Parcel reply;
//可以写为IServiceManager::getInterfaceDescriptor(),这里为了撇开与IServiceManager的关系,直接使用android.os.IServiceManager
data.writeInterfaceToken(String16("android.os.IServiceManager"));
data.writeInt32(num);
// SVC_MGR_LIST_SERVICES4
int err = service->transact(4, data,&reply, 0);
if (err == NO_ERROR)
{
aout << num << " is"<< reply.readString16() << endl;
}
return 0;
}
编译
mmmyBp0
push到手机上进行测试
Unknown:/data/local/tmp# ./myBp0 0
num= 0
0is myService
Unknown:/data/local/tmp# ./myBp0 1
num= 1
1is atest
Unknown:/data/local/tmp# ./myBp0 2
num= 2
2is sip
Unknown:/data/local/tmp# ./myBp0 3
num= 3
3is nfc
Unknown:/data/local/tmp# ./myBp0 4
num= 4
4is GbaService
对照服务列表来进行验证
Unknown:/data/local/tmp# service list
Found140 services:
0 myService: []
1 atest: []
2 sip: [android.net.sip.ISipService]
3 nfc: [android.nfc.INfcAdapter]
4 GbaService:[com.mediatek.gba.IGbaService]
可以看到,结果是一致的。