文章目录
本文代码源码来自Android 2.2.3,承接上一篇:
【Android Binder】从源码出发,剖析Binder机制的实现流程
继续探索ServiceManager是如何通过binder处理客户端的请求的。
回顾
MediaServer的注册入口:
int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
::android::hardware::configureRpcThreadpool(16, false);
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
::android::hardware::joinRpcThreadpool();
}
在binder那篇文章的分析中,我们得知defaultServiceManager()返回的是一个BpServiceManager。通过它可以把请求发送给handle值为0的目的端。从IServiceManager的继承关系中,我们可以推断出来,无论如何都会有一个类从BnServiceManager派生出来,去处理这些来自远端的请求。
下面是IServiceManager的继承关系:
但是源码里面却没有这样一个类,因为实现这个工作的另外一个类ServiceManager。
为了解答捋清楚ServiceManager是怎么实现这些工作的,我们需要从源码出发理解其中的来龙去脉。
service_manager.c
我们直接从它的main函数开始:
///frameworks/base/cmds/servicemanager/service_manager.c
int main(int argc, char **argv)
250{
251 struct binder_state *bs;
252 void *svcmgr = BINDER_SERVICE_MANAGER;
253 //打开binder设备
254 bs = binder_open(128*1024);
255 //变成manager
256 if (binder_become_context_manager(bs)) {
257 LOGE("cannot become context manager (%s)\n", strerror(errno));
258 return -1;
259 }
260
261 svcmgr_handle = svcmgr;
//处理客户端发送过来的请求。
262 binder_loop(bs, svcmgr_handler);
263 return 0;
264}
binder_open
先看下 bs = binder_open(128*1024);
// /frameworks/base/cmds/servicemanager/binder.c
94struct binder_state *binder_open(unsigned mapsize)
95{
96 struct binder_state *bs;
97
98 bs = malloc(sizeof(*bs));
99 if (!bs) {
100 errno = ENOMEM;
101 return 0;
102 }
103
//打开binder设备
104 bs->fd = open("/dev/binder", O_RDWR);
105 if (bs->fd < 0) {
106 fprintf(stderr,"binder: cannot open device (%s)\n",
107 strerror(errno));
108 goto fail_open;
109 }
110
111 bs->mapsize = mapsize;
//内存映射
112 bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
113 if (bs->mapped == MAP_FAILED) {
114 fprintf(stderr,"binder: cannot map device (%s)\n",
115 strerror(errno));
116 goto fail_map;
117 }
118
119 /* TODO: check version */
120
121 return bs;
122
123fail_map:
124 close(bs->fd);
125fail_open:
126 free(bs);
127 return 0;
128}
这里和之前分析的一样,打开binder设备然后通过mmap进行内存映射。
binder_become_context_manager
137int binder_become_context_manager(struct binder_state *bs)
138{
139 return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
140}
这里通过ioctl和binder驱动进行交互。
binder_loop
///frameworks/base/cmds/servicemanager/binder.c
struct binder_write_read bwr;
357void binder_loop(struct binder_state *bs, binder_handler func)
358{
359 int res;
360 struct binder_write_read bwr;
361 unsigned readbuf[32];
362
363 bwr.write_size = 0;
364 bwr.write_consumed = 0;
365 bwr.write_buffer = 0;
366
367 readbuf[0] = BC_ENTER_LOOPER;
368 binder_write(bs, readbuf, sizeof(unsigned));
369
//循环
370 for (;;) {
371 bwr.read_size = sizeof(readbuf);
372 bwr.read_consumed = 0;
373 bwr.read_buffer = (unsigned) readbuf;
374
375 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
376
377 if (res < 0) {
378 LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
379 break;
380 }
381 //注意,这里传入一个函数func
382 res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
383 if (res == 0) {
384 LOGE("binder_loop: unexpected reply?!\n");
385 break;
386 }
387 if (res < 0) {
388 LOGE("binder_loop: io error %d %s\n", res, strerror(errno));
389 break;
390 }
391 }
392}
这里把接收的请求传递给了binder_parse:
binder_parse
194int binder_parse(struct binder_state *bs, struct binder_io *bio,
195 uint32_t *ptr, uint32_t size, binder_handler func)
196{
197 int r = 1;
198 uint32_t *end = ptr + (size / 4);
199
200 while (ptr < end) {
201 uint32_t cmd = *ptr++;
202#if TRACE
203 fprintf(stderr,"%s:\n", cmd_name(cmd));
204#endif
205 switch(cmd) {
206 case BR_NOOP:
207 break;
208 case BR_TRANSACTION_COMPLETE:
209 break;
210 case BR_INCREFS:
211 case BR_ACQUIRE:
212 case BR_RELEASE:
213 case BR_DECREFS:
214#if TRACE
215 fprintf(stderr," %08x %08x\n", ptr[0], ptr[1]);
216#endif
217 ptr += 2;
218 break;
219 case BR_TRANSACTION: {
220 struct binder_txn *txn = (void *) ptr;
221 if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
222 LOGE("parse: txn too small!\n");
223 return -1;
224 }
225 binder_dump_txn(txn);
226 if (func) {
227 unsigned rdata[256/4];
228 struct binder_io msg;
229 struct binder_io reply;
230 int res;
231
232 bio_init(&reply, rdata, sizeof(rdata), 4);
233 bio_init_from_txn(&msg, txn);
234 res = func(bs, txn, &msg, &reply);
235 binder_send_reply(bs, &reply, txn->data, res);
236 }
237 ptr += sizeof(*txn) / sizeof(uint32_t);
238 break;
239 }
240 case BR_REPLY: {
241 struct binder_txn *txn = (void*) ptr;
242 if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
243 LOGE("parse: reply too small!\n");
244 return -1;
245 }
246 binder_dump_txn(txn);
247 if (bio) {
248 bio_init_from_txn(bio, txn);
249 bio = 0;
250 } else {
251 /* todo FREE BUFFER */
252 }
253 ptr += (sizeof(*txn) / sizeof(uint32_t));
254 r = 0;
255 break;
256 }
257 case BR_DEAD_BINDER: {
258 struct binder_death *death = (void*) *ptr++;
259 death->func(bs, death->ptr);
260 break;
261 }
262 case BR_FAILED_REPLY:
263 r = -1;
264 break;
265 case BR_DEAD_REPLY:
266 r = -1;
267 break;
268 default:
269 LOGE("parse: OOPS %d\n", cmd);
270 return -1;
271 }
272 }
273
274 return r;
275}
上面代码循环执行了接收数据和处理数据。
但是不知道func函数做了什么,接着看他的入参函数func:
svcmgr_handler
///frameworks/base/cmds/servicemanager/service_manager.c
187int svcmgr_handler(struct binder_state *bs,
188 struct binder_txn *txn,
189 struct binder_io *msg,
190 struct binder_io *reply)
191{
192 struct svcinfo *si;
193 uint16_t *s;
194 unsigned len;
195 void *ptr;
196
197// LOGI("target=%p code=%d pid=%d uid=%d\n",
198// txn->target, txn->code, txn->sender_pid, txn->sender_euid);
199
200 if (txn->target != svcmgr_handle)
201 return -1;
202
203 s = bio_get_string16(msg, &len);
204
205 if ((len != (sizeof(svcmgr_id) / 2)) ||
206 memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
207 fprintf(stderr,"invalid id %s\n", str8(s));
208 return -1;
209 }
210
211 switch(txn->code) {
212 case SVC_MGR_GET_SERVICE:
213 case SVC_MGR_CHECK_SERVICE:
214 s = bio_get_string16(msg, &len);
215 ptr = do_find_service(bs, s, len);
216 if (!ptr)
217 break;
218 bio_put_ref(reply, ptr);
219 return 0;
220
221 case SVC_MGR_ADD_SERVICE:
222 s = bio_get_string16(msg, &len);
223 ptr = bio_get_ref(msg);
224 if (do_add_service(bs, s, len, ptr, txn->sender_euid))
225 return -1;
226 break;
227
228 case SVC_MGR_LIST_SERVICES: {
229 unsigned n = bio_get_uint32(msg);
230
231 si = svclist;
232 while ((n-- > 0) && si)
233 si = si->next;
234 if (si) {
235 bio_put_string16(reply, si->name);
236 return 0;
237 }
238 return -1;
239 }
240 default:
241 LOGE("unknown code %d\n", txn->code);
242 return -1;
243 }
244
245 bio_put_uint32(reply, 0);
246 return 0;
247}
这里的各个case分支分别定义了IServiceManager的各个业务函数。来看下它的do_add_service函数:
do_add_service
///frameworks/base/cmds/servicemanager/service_manager.c
141int do_add_service(struct binder_state *bs,
142 uint16_t *s, unsigned len,
143 void *ptr, unsigned uid)
144{
145 struct svcinfo *si;
146// LOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);
147
148 if (!ptr || (len == 0) || (len > 127))
149 return -1;
150
151 if (!svc_can_register(uid, s)) {
152 LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
153 str8(s), ptr, uid);
154 return -1;
155 }
156 ...
185}
先看下svc_can_register的实现:
svc_can_register
74int svc_can_register(unsigned uid, uint16_t *name)
75{
76 unsigned n;
77 //这里如果是root用户或者system用户,就允许注册
78 if ((uid == 0) || (uid == AID_SYSTEM))
79 return 1;
80
81 for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
82 if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
83 return 1;
84
85 return 0;
86}
87
这里遍历了allowed数组进行判断,allowed的实现:
allowed[]
21/* TODO:
22 * These should come from a config file or perhaps be
23 * based on some namespace rules of some sort (media
24 * uid can register media.*, etc)
25 */
26static struct {
27 unsigned uid;
28 const char *name;
29} allowed[] = {
30#ifdef LVMX
31 {
AID_MEDIA, "com.lifevibes.mx.ipc" },
32#endif
33 {
AID_MEDIA, "media.audio_flinger" },
34 {
AID_MEDIA, "media.player" },
35 {
AID_MEDIA, "media.camera" },
36 {
AID_MEDIA, "media.audio_policy" },
37 {
AID_RADIO, "radio.phone" },
38 {
AID_RADIO, "radio.sms" },
39 {
AID_RADIO, "radio.phonesubinfo" },
40 {
AID_RADIO, "radio.simphonebook" },
41/* TODO: remove after phone services are updated: */
42 {
AID_RADIO, "phone" },
43 {
AID_RADIO, "isms" },
44 {
AID_RADIO, "iphonesubinfo" },
45 {
AID_RADIO, "simphonebook" },
46};
如果Server进程权限不够的话,需要在allowed数组里面进行添加。我们可以知道的信息是,这里会扫描注册的服务。
接着看我们前面没有分析完的do_add_service方法:
141int do_add_service(struct binder_state *bs,
142 uint16_t *s, unsigned len,
143 void *ptr, unsigned uid)
144{
145...
151 if (!svc_can_register(uid, s)) {
152 LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
153 str8(s), ptr, uid);
154 return -1;
155 }
156
157 si = find_svc(s, len);
158 if (si) {
159 if (si->ptr) {
160 LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED\n",
161 str8(s), ptr, uid);
162 return -1;
163 }
164 si->ptr = ptr;
165 } else {
166 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
167 if (!si) {
168 LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",
169 str8(s), ptr, uid);
170 return -1;
171 }
172 si->ptr = ptr;
173 si->len = len;
174 memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
175 si->name[len] = '\0';
176 si->death.func = svcinfo_death;//service退出的通知函数
177 si->death.ptr = si;
178 si->next = svclist;
179 svclist = si;
180 }
181
182 binder_acquire(bs, ptr);
//服务退出之后,需要做一些清理工作,例如释放malloc出来的内存。这个函数执行该操作
183 binder_link_to_death(bs, ptr, &si->death);
184 return 0;
185}
阶段总结
代码分析到这里,我们总结下,前面代码中ServicManager打开了binder设备,让自己成为manager,接着进入循环并通过ioctl与binder设备进行交互,用于来处理客户端发过来的消息。
我们不禁去思考ServiceManager存在的价值是什么。
ServiceManager可以通过字符串查找对应的Service,这个与DNS很类似。并且ServiceManager对服务进行了权限控制,使得并非所有服务都能进行注册,这无疑提高了Android的安全性和各种服务的条理性。
再上升到架构设计的层面去思考:由于各种原因,服务生死无常,假如每个客户端访问服务前都要去检测当前需要的服务是否正常运行,那么Android系统也太不好用了(从应用工程师或者手机用户的角度),设计一个ServiceManager这样的角色对所有服务进行统一的管理势在必行。
Client如何通过ServiceManager与目的服务通信?
前面我们得知一个客户端想要找某个服务端,需要先通过ServiceManager。
但是找到ServiceManager之后,客户端是怎么拿到想要的服务的呢?这个问题还是没有弄明白。
我们承接前面的分析,继续发起mediaservice探索吧。
下面我们从media相关的方法IMediaDeathNotifier的getMediaPlayerService()入手。
IMediaDeathNotifier::getMediaPlayerService()
///frameworks/base/media/libmedia/IMediaDeathNotifier.cpp
33// establish binder interface to MediaPlayerService
34/*static*/const sp<IMediaPlayerService>&
35IMediaDeathNotifier::getMediaPlayerService()
36{
37 LOGV("getMediaPlayerService");
38 Mutex::Autolock _l(sServiceLock);
39 if (sMediaPlayerService.get() == 0) {
40 sp<IServiceManager> sm = defaultServiceManager();
41 sp<IBinder> binder;
42 do {
//向ServiceManager查询对应的服务信息,返回BpBinder
43 binder = sm->getService(String16("media.player"));
44 if (binder != 0) {
45 break;
46 }
47 LOGW("Media player service not published, waiting...");
//如果ServiceManager还没有注册对应的服务,则循环等待
48 usleep(500000); // 0.5 s
49 } while(true);
50
51 if (sDeathNotifier == NULL) {
52 sDeathNotifier = new DeathNotifier();
53 }
54 binder->linkToDeath(sDeathNotifier);
//通过interface_cast,把binder转换为BpMediaPlayerService。这里binder中的handle是目的端MediaPlayerService。
55 sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
56 }
57 LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
58 return sMediaPlayerService;
59}
这个函数通过与ServiceManager通信,拿到一个MediaPlayerService通信的BpBinder,然后通过转换变成BpMediaPlayerService。
既然有了BpMediaPlayerService,那么就可以使用IMediaPlayerService定义的接口函数了,诸如:createMediaRecorder(pid_t pid)、createMetadataRetriever(pid_t pid)等。
executeCommand
binder分析那篇文章我们知道MediaPlayService在MediaService进程中,会开启开启两个线程执行talkWithDriver,talkWithDriver会执行到executeCommand方法,请先提醒自己一遍,这是服务端的执行代码:
///frameworks/base/libs/binder/IPCThreadState.cpp
838status_t IPCThreadState::executeCommand(int32_t cmd)
839{
//BBinder,不就是服务端的代理类吗?
840 BBinder* obj;
841 RefBase::weakref_type* refs;
842 status_t result = NO_ERROR;
843
844 switch (cmd) {
845 case BR_ERROR:
846 result = mIn.readInt32();
847 break;
848
849 case BR_OK:
850 break;
851
852 case BR_ACQUIRE:
853 refs = (RefBase::weakref_type*)mIn.readInt32();
854 obj = (BBinder*)mIn.readInt32();
855 LOG_ASSERT(refs->refBase() == obj,
856 "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
857 refs, obj, refs->refBase());
858 obj->incStrong(mProcess.get());
859 IF_LOG_REMOTEREFS() {
860 LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
861 obj->printRefs();
862 }
863 mOut.writeInt32(BC_ACQUIRE_DONE);
864 mOut.writeInt32((int32_t)refs);
865 mOut.writeInt32((int32_t)obj);
866 break;
867
868 case BR_RELEASE:
869 refs = (RefBase::weakref_type*)mIn.readInt32();
870 obj = (BBinder*)mIn.readInt32();
871 LOG_ASSERT(refs->refBase() == obj,
872 "BR_RELEASE: object %p does not match cookie %p (expected %p)",
873 refs, obj, refs->refBase());
874 IF_LOG_REMOTEREFS() {
875 LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
876 obj->printRefs();
877 }
878 mPendingStrongDerefs.push(obj);
879 break;
880
881 case BR_INCREFS:
882 refs = (RefBase::weakref_type*)mIn.readInt32();
883 obj = (BBinder*)mIn.readInt32();
884 refs->incWeak(mProcess.get());
885 mOut.writeInt32(BC_INCREFS_DONE);
886 mOut.writeInt32((int32_t)refs);
887 mOut.writeInt32((int32_t)obj);
888 break;
889
890 case BR_DECREFS:
891 refs = (RefBase::weakref_type*)mIn.readInt32();
892 obj = (BBinder*)mIn.readInt32();
893 // NOTE: This assertion is not valid, because the object may no
894 // longer exist (thus the (BBinder*)cast above resulting in a different
895 // memory address).
896 //LOG_ASSERT(refs->refBase() == obj,
897 // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
898 // refs, obj, refs->refBase());
899 mPendingWeakDerefs.push(refs);
900 break;
901
902 case BR_ATTEMPT_ACQUIRE:
903 refs = (RefBase::weakref_type*)mIn.readInt32();
904 obj = (BBinder*)mIn.readInt32();
905
906 {
907 const bool success = refs->attemptIncStrong(mProcess.get());
908 LOG_ASSERT(success && refs->refBase() == obj,
909 "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
910 refs, obj, refs->refBase());
911
912 mOut.writeInt32(BC_ACQUIRE_RESULT);
913 mOut.writeInt32((int32_t)success);
914 }
915 break;
916
917 case BR_TRANSACTION:
918 {
919 binder_transaction_data tr;
920 result = mIn.read(&tr, sizeof(tr));
921 LOG_ASSERT(result == NO_ERROR,
922 "Not enough command data for brTRANSACTION");
923 if (result != NO_ERROR) break;
924
//通信数据的处理
925 Parcel buffer;
926 buffer.ipcSetDataReference(
927 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
928 tr.data_size,
929 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
930 tr.offsets_size/sizeof(size_t), freeBuffer, this);
931
932 const pid_t origPid = mCallingPid;
933 const uid_t origUid = mCallingUid;
934
935 mCallingPid = tr.sender_pid;
936 mCallingUid = tr.sender_euid;
937
938 int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
939 if (gDisableBackgroundScheduling) {
940 if (curPrio > ANDROID_PRIORITY_NORMAL) {
941 // We have inherited a reduced priority from the caller, but do not
942 // want to run in that state in this process. The driver set our
943 // priority already (though not our scheduling class), so bounce
944 // it back to the default before invoking the transaction.
945 setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
946 }
947 } else {
948 if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
949 // We want to use the inherited priority from the caller.
950 // Ensure this thread is in the background scheduling class,
951 // since the driver won't modify scheduling classes for us.
952 // The scheduling group is reset to default by the caller
953 // once this method returns after the transaction is complete.
954 androidSetThreadSchedulingGroup(mMyThreadId,
955 ANDROID_TGROUP_BG_NONINTERACT);
956 }
957 }
958
959 //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
960
961 Parcel reply;
962 IF_LOG_TRANSACTIONS() {
963 TextOutput::Bundle _b(alog);
964 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
965 << " / obj " << tr.target.ptr << " / code "
966 << TypeCode(tr.code) << ": " << indent << buffer
967 << dedent << endl
968 << "Data addr = "
969 << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
970 << ", offsets addr="
971 << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
972 }
//tr.target,应该就是指客户端
973 if (tr.target.ptr) {
974 sp<BBinder> b((BBinder*)tr.cookie);
//执行transact
975 const status_t error = b->transact(tr.code, buffer, &reply, 0);
976 if (error < NO_ERROR) reply.setError(error);
977
978 } else {
//the_context_object,结合前面ServiceManager执行的binder_become_context_manager,有没有可能就是指ServiceManager?
979 const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
980 if (error < NO_ERROR) reply.setError(error);
981 }
982
983 //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
984 // mCallingPid, origPid, origUid);
985
986 if ((tr.flags & TF_ONE_WAY) == 0) {
987 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
988 sendReply(reply, 0);
989 } else {
990 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
991 }
992
993 mCallingPid = origPid;
994 mCallingUid = origUid;
995
996 IF_LOG_TRANSACTIONS() {
997 TextOutput::Bundle _b(alog);
998 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
999 << tr.target.ptr << ": " << indent << reply << dedent << endl;
1000 }
1001
1002 }
1003 break;
1004
1005 case BR_DEAD_BINDER:
1006 {
1007 BpBinder *proxy = (BpBinder*)mIn.readInt32();
1008 proxy->sendObituary();
1009 mOut.writeInt32(BC_DEAD_BINDER_DONE);
1010 mOut.writeInt32((int32_t)proxy);
1011 } break;
1012
1013 case BR_CLEAR_DEATH_NOTIFICATION_DONE:
1014 {
1015 BpBinder *proxy = (BpBinder*)mIn.readInt32();
1016 proxy->getWeakRefs()->decWeak(proxy);
1017 } break;
1018
1019 case BR_FINISHED:
1020 result = TIMED_OUT;
1021 break;
1022
1023 case BR_NOOP:
1024 break;
1025
1026 case BR_SPAWN_LOOPER:
1027 mProcess->spawnPooledThread(false);
1028 break;
1029
1030 default:
1031 printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
1032 result = UNKNOWN_ERROR;
1033 break;
1034 }
1035
1036 if (result != NO_ERROR) {
1037 mLastError = result;
1038 }
1039
1040 return result;
1041}
这个方法里面拿到了BBinder,也就是服务端代理类。在case:BR_TRANSACTION中,执行了transact方法,我们看下这个方法:
transact
///frameworks/base/libs/binder/Binder.cpp
96 status_t BBinder::transact(
97 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
98{
99 data.setDataPosition(0);
100
101 status_t err = NO_ERROR;
102 switch (code) {
103 case PING_TRANSACTION:
104 reply->writeInt32(pingBinder());
105 break;
106 default:
//默认走这里
107 err = onTransact(code, data, reply, flags);
108 break;
109 }
110
111 if (reply != NULL) {
112 reply->setDataPosition(0);
113 }
114
115 return err;
116}
执行了onTransact方法:
//frameworks/base/libs/binder/Binder.cpp
185status_t BBinder::onTransact(
186 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
187{
188 switch (code) {
189 case INTERFACE_TRANSACTION:
190 reply->writeString16(getInterfaceDescriptor());
191 return NO_ERROR;
192
193 case DUMP_TRANSACTION: {
194 int fd = data.readFileDescriptor();
195 int argc = data.readInt32();
196 Vector<String16> args;
197 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
198 args.add(data.readString16());
199 }
200 return dump(fd, args);
201 }
202 default:
203 return UNKNOWN_TRANSACTION;
204 }
205}
到这里我们需要理一下继承关系:
BnMediaPlayerService作为BBinder的子类,它覆盖实现了onTransact方法:
///frameworks/base/media/libmedia/IMediaPlayerService.cpp
151status_t BnMediaPlayerService::onTransact(
152 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
153{
154 switch(code) {
155 case CREATE_URL: {
156 CHECK_INTERFACE(IMediaPlayerService, data, reply);
157 pid_t pid = data.readInt32();
158 sp<IMediaPlayerClient> client =
159 interface_cast<IMediaPlayerClient>(data.readStrongBinder());
160 const char* url = data.readCString();
161
162 KeyedVector<String8, String8> headers;
163 int32_t numHeaders = data.readInt32();
164 for (int i = 0; i < numHeaders; ++i) {
165 String8 key = data.readString8();
166 String8 value = data.readString8();
167 headers.add(key, value);
168 }
169
170 sp<IMediaPlayer> player = create(
171 pid, client, url, numHeaders > 0 ? &headers : NULL);
172
173 reply->writeStrongBinder(player->asBinder());
174 return NO_ERROR;
175 } break;
176 case CREATE_FD: {
177 CHECK_INTERFACE(IMediaPlayerService, data, reply);
178 pid_t pid = data.readInt32();
179 sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
180 int fd = dup(data.readFileDescriptor());
181 int64_t offset = data.readInt64();
182 int64_t length = data.readInt64();
183 sp<IMediaPlayer> player = create(pid, client, fd, offset, length);
184 reply->writeStrongBinder(player->asBinder());
185 return NO_ERROR;
186 } break;
187 case DECODE_URL: {
188 CHECK_INTERFACE(IMediaPlayerService, data, reply);
189 const char* url = data.readCString();
190 uint32_t sampleRate;
191 int numChannels;
192 int format;
193 sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format);
194 reply->writeInt32(sampleRate);
195 reply->writeInt32(numChannels);
196 reply->writeInt32(format);
197 reply->writeStrongBinder(player->asBinder());
198 return NO_ERROR;
199 } break;
200 case DECODE_FD: {
201 CHECK_INTERFACE(IMediaPlayerService, data, reply);
202 int fd = dup(data.readFileDescriptor());
203 int64_t offset = data.readInt64();
204 int64_t length = data.readInt64();
205 uint32_t sampleRate;
206 int numChannels;
207 int format;
208 sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format);
209 reply->writeInt32(sampleRate);
210 reply->writeInt32(numChannels);
211 reply->writeInt32(format);
212 reply->writeStrongBinder(player->asBinder());
213 return NO_ERROR;
214 } break;
215 case SNOOP: {
216 CHECK_INTERFACE(IMediaPlayerService, data, reply);
217 sp<IMemory> snooped_audio = snoop();
218 reply->writeStrongBinder(snooped_audio->asBinder());
219 return NO_ERROR;
220 } break;
221 case CREATE_MEDIA_RECORDER: {
222 CHECK_INTERFACE(IMediaPlayerService, data, reply);
//获取请求数据中的pid
223 pid_t pid = data.readInt32();
//
224 sp<IMediaRecorder> recorder = createMediaRecorder(pid);
225 reply->writeStrongBinder(recorder->asBinder());
226 return NO_ERROR;
227 } break;
228 case CREATE_METADATA_RETRIEVER: {
229 CHECK_INTERFACE(IMediaPlayerService, data, reply);
230 pid_t pid = data.readInt32();
231 sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid);
232 reply->writeStrongBinder(retriever->asBinder());
233 return NO_ERROR;
234 } break;
235 case GET_OMX: {
236 CHECK_INTERFACE(IMediaPlayerService, data, reply);
237 sp<IOMX> omx = getOMX();
238 reply->writeStrongBinder(omx->asBinder());
239 return NO_ERROR;
240 } break;
241 default:
242 return BBinder::onTransact(code, data, reply, flags);
243 }
244}
我们随便看下一个子类的方法:createMediaRecorder
83 ///frameworks/base/media/libmedia/IMediaPlayerService.cpp
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid)
84 {
85 Parcel data, reply;
86 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
87 data.writeInt32(pid);
88 remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
89 return interface_cast<IMediaRecorder>(reply.readStrongBinder());
90 }
是个虚函数,其它有关IMediaPlayerService的也都是虚函数,子类也许会覆盖实现它。重点是这里已经是MediaService已经处理并响应客户端的请求了。
阶段总结
到这里我们也该继续总结一波了,前面MediaService有两个线程在不断talkWithDriver,然后通过executeCommand一直执行到BBinder的子类BnMediaPlayerService的onTransact方法,它就是真正处理客户端的请求。
所以说ServiceManager还是跟前面分析的那样,作为一个服务管理者,客户端要向某个服务发起请求,要先向ServiceManager发起请求,ServiceManager会代替客户端拿到对应服务,然后那个服务就去响应客户端的请求。ServiceManager在这个过程还是充当服务管理者的角色,确实人如其名。
总结
在整个环节下来,我们很明显可以看到Android采取了CS架构的设计思想。有客户端,有服务端,也有服务端的管理者。
参考
《深入理解Android 卷1》