Android 시작: ContentProvider 데이터 변경 수신

18471 단어
ServiceMananger android          ,   init        ,                    service。  :InputMethodService、ActivityManagerService 。 ServiceManager           :add_service、check_service。   service    add_service         ServiceManager ,      ,  check_service   service    。

   

          :

[java] view plain copy

    int main(int argc, char **argv)  
    {  
        struct binder_state *bs;  
        void *svcmgr = BINDER_SERVICE_MANAGER;  
        bs = binder_open(128*1024);  
        if (binder_become_context_manager(bs)) {  
            LOGE("cannot become context manager (%s)
", strerror(errno)); return -1; } svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler); return 0; } main , : /dev/binder , 128K 。 Binder , context_manager , Binder , service , , svcmgr_handler 。 ServiceManager 。 , service , svcmgr_handler: [java] view plain copy int svcmgr_handler(struct binder_state *bs, struct binder_txn *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; unsigned len; void *ptr; uint32_t strict_policy; // LOGI("target=%p code=%d pid=%d uid=%d
",
// txn->target, txn->code, txn->sender_pid, txn->sender_euid); if (txn->target != svcmgr_handle) return -1; // Equivalent to Parcel::enforceInterface(), reading the RPC // header with the strict mode policy mask and the interface name. // Note that we ignore the strict_policy and don't propagate it // further (since we do no outbound RPCs anyway). strict_policy = bio_get_uint32(msg); s = bio_get_string16(msg, &len); if ((len != (sizeof(svcmgr_id) / 2)) || memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { fprintf(stderr,"invalid id %s
", str8(s)); return -1; } switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); ptr = do_find_service(bs, s, len); if (!ptr) break; bio_put_ref(reply, ptr); return 0; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); ptr = bio_get_ref(msg); if (do_add_service(bs, s, len, ptr, txn->sender_euid)) return -1; breakcase SVC_MGR_LIST_SERVICES: { unsigned n = bio_get_uint32(msg); si = svclist; while ((n-- > 0) && si) si = si->next; if (si) { bio_put_string16(reply, si->name); return 0; } return -1; } default: LOGE("unknown code %d
", txn->code); return -1; } bio_put_uint32(reply, 0); return 0; } Service , service, : [java] view plain copy case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); ptr = bio_get_ref(msg); if (do_add_service(bs, s, len, ptr, txn->sender_euid)) return -1; break; do_add_service : [java] view plain copy int do_add_service(struct binder_state *bs, uint16_t *s, unsigned len, void *ptr, unsigned uid) { struct svcinfo *si; // LOGI("add_service('%s',%p) uid=%d
", str8(s), ptr, uid);
if (!ptr || (len == 0) || (len > 127)) return -1if (!svc_can_register(uid, s)) { LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED
", str8(s), ptr, uid); return -1; } si = find_svc(s, len); if (si) { if (si->ptr) { LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED
", str8(s), ptr, uid); return -1; } si->ptr = ptr; } else { si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY
", str8(s), ptr, uid); return -1; } si->ptr = ptr; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; si->death.func = svcinfo_death; si->death.ptr = si; si->next = svclist; svclist = si; } binder_acquire(bs, ptr); binder_link_to_death(bs, ptr, &si->death); return 0; } , service, , 。 [java] view plain copy if (!svc_can_register(uid, s)) { LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED
", str8(s), ptr, uid); return -1; } service , , : [java] view plain copy si = find_svc(s, len); if (si) { if (si->ptr) { LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED
", str8(s), ptr, uid); return -1; } si->ptr = ptr; } : [java] view plain copy si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY
", str8(s), ptr, uid); return -1; } , service, svcList 。 , ServiceManager service svclist。 service name handler。 ,service 。 service 。 : [java] view plain copy case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); ptr = do_find_service(bs, s, len); if (!ptr) break; bio_put_ref(reply, ptr); return 0; service, SVC_MGR_CHECK_SERVICE, reply, 。 do_find_service service 。 [java] view plain copy void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len) { struct svcinfo *si; si = find_svc(s, len); // LOGI("check_service('%s') ptr = %p
", str8(s), si ? si->ptr : 0);
if (si && si->ptr) { return si->ptr; } else { return 0; } } ServiceManager 。 ServiceManager :

좋은 웹페이지 즐겨찾기