【Android ServiceManager】从源码入手,剖析ServiceManager是如何处理客户端的请求的?

本文代码源码来自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》

猜你喜欢

转载自blog.csdn.net/Shujie_L/article/details/137342783