i.mx6 Android5.1.1 servicemanager本地服务
生活随笔
收集整理的這篇文章主要介紹了
i.mx6 Android5.1.1 servicemanager本地服务
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
接在之前的
i.mx6 Android5.1.1 初始化流程之init進程
i.mx6 Android5.1.1 初始化流程之init.rc解析
servicemanager是由init創建的本地服務,是binder的守護進程。
主要用來管理開發者創建的各種Server,并且向Client提供查詢Server遠程接口的功能。
?
#名字為servicemanager的服務,可執行文件的路徑在/system/bin/servicemanager #屬于core類,用戶為:system,用戶組為:system #critical:如果在幾分鐘內一直沒響應則重啟服務 #重啟servicemanager需要沖入如下的服務healthd,zygote,media,surfaceflinger,drm service servicemanager /system/bin/servicemanagerclass coreuser system group systemcriticalonrestart restart healthdonrestart restart zygoteonrestart restart mediaonrestart restart surfaceflingeronrestart restart drm?
可以得知其路徑在/system/bin/servicemanager
查看android.mk
include $(CLEAR_VARS) LOCAL_SHARED_LIBRARIES := liblog libselinux LOCAL_SRC_FILES := service_manager.c binder.c LOCAL_CFLAGS += $(svc_c_flags) LOCAL_MODULE := servicemanager include $(BUILD_EXECUTABLE)可以得知,就是在service_manager.c
int main(int argc, char **argv) {struct binder_state *bs;//打開binder設備驅動文件,并將Binder設備文件映射到servicemanger進程的地址空間中 bs = binder_open(128*1024);if (!bs) {ALOGE("failed to open binder driver\n");return -1;}//在binder驅動層設置服務管理者角色 if (binder_become_context_manager(bs)) {ALOGE("cannot become context manager (%s)\n", strerror(errno));return -1;}selinux_enabled = is_selinux_enabled();sehandle = selinux_android_service_context_handle();if (selinux_enabled > 0) {if (sehandle == NULL) {ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");abort();}if (getcon(&service_manager_context) != 0) {ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");abort();}}union selinux_callback cb;cb.func_audit = audit_callback;selinux_set_callback(SELINUX_CB_AUDIT, cb);cb.func_log = selinux_log_callback;selinux_set_callback(SELINUX_CB_LOG, cb);//接收到請求后的需要執行的回調函數svcmgr_handle = BINDER_SERVICE_MANAGER;//進入binder.c循環,等待客戶請求 binder_loop(bs, svcmgr_handler);return 0; }?
struct binder_state *binder_open(size_t mapsize) {。。。//打開設備節點bs->fd = open("/dev/binder", O_RDWR);。。。//映射bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);。。。 }
?
再看看直接的那個回調函數
int svcmgr_handler(struct binder_state *bs,struct binder_transaction_data *txn,struct binder_io *msg,struct binder_io *reply) {。。。 switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; }//查找相關的服務,如果有,則返回其句柄 handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid); if (!handle) break; bio_put_ref(reply, handle); return 0; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0;
//想servicemanager添加服務 if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)) return -1; break; case SVC_MGR_LIST_SERVICES: { uint32_t n = bio_get_uint32(msg); if (!svc_can_list(txn->sender_pid)) { ALOGE("list_service() uid=%d - PERMISSION DENIED\n", txn->sender_euid); return -1; } si = svclist; while ((n-- > 0) && si) si = si->next; if (si) { bio_put_string16(reply, si->name); return 0; } return -1; } default: ALOGE("unknown code %d\n", txn->code); return -1; } bio_put_uint32(reply, 0); return 0; }
?
void binder_loop(struct binder_state *bs, binder_handler func) {int res;struct binder_write_read bwr;uint32_t readbuf[32];bwr.write_size = 0;bwr.write_consumed = 0;bwr.write_buffer = 0;readbuf[0] = BC_ENTER_LOOPER;binder_write(bs, readbuf, sizeof(uint32_t));for (;;) {bwr.read_size = sizeof(readbuf);bwr.read_consumed = 0;bwr.read_buffer = (uintptr_t) readbuf;//讀取binder節點數據 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);if (res < 0) {ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));break;}//解析 res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);if (res == 0) {ALOGE("binder_loop: unexpected reply?!\n");break;}if (res < 0) {ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));break;}} }?
?
int binder_parse(struct binder_state *bs, struct binder_io *bio,uintptr_t ptr, size_t size, binder_handler func) {。。。switch(cmd) {。。。binder_dump_txn(txn);if (func) {unsigned rdata[256/4];struct binder_io msg;struct binder_io reply;int res;bio_init(&reply, rdata, sizeof(rdata), 4);bio_init_from_txn(&msg, txn);//注意:這個是之前我們傳進來的回調函數res = func(bs, txn, &msg, &reply);binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);}ptr += sizeof(*txn);break;} 。。。default:ALOGE("parse: OOPS %d\n", cmd);return -1;}}return r; }
?
小結:
1.申請一段內存,打開設備節點/dev/binder,同時將內存映射到內核中用來給binder使用
2.將自己設置為服務管理者
3.通過binder接口循環讀取查看是否有數據,當有數據傳來時,調用回調函數添加服務,或者查詢服務
轉載于:https://www.cnblogs.com/maogefff/p/7661289.html
總結
以上是生活随笔為你收集整理的i.mx6 Android5.1.1 servicemanager本地服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对象的封装方法2
- 下一篇: Android 联系人导入导出(VCar