android默认支持吗
Android的binder驱动是支持的,但是上层只对libhwbinder开放,对于libbinder是默认关闭的。估计是为了防止滥用。如何打开libbinder的支持呢
libs/binder/Parcel.cpp 中在flatten_binder方法中添加一个flag即可打开支持
//注意这个0x800 就是FLAT_BINDER_FLAG_INHERIT_RT
obj.flags |= FLAT_BINDER_FLAG_ACCEPTS_FDS | 0x800;
这个flag会传到binder驱动里,表示是server是否开启了优先级继承
- 只打开这个flag还没完
还受到capbility的限制,一般对于initrc启动的服务可以这样添加:
启动服务时在rc脚本中使用"capabilities SYS_NICE"给服务赋予 CAP_SYS_NICE 权限。
但是对于java启动的系统服务,我们要找到进程创建的地方添加这个权限。
我们知道Activity的启动流程,service的启动流程,那么服务最后是通过zygote 创建进程的。
最终我们在core/jni/com_android_internal_os_Zygote.cpp里找到了CAP_SYS_NICE设置的地方,比如蓝牙模块默认就有这个属性,我们类比添加我们服务模块的这个属性。
- binder驱动分析
在binder驱动里node代表一个服务。在binder_init_node_ilocked函数里
会设置node的默认调度和优先级,inherit_rt 表是否开启优先级继承
priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
node->sched_policy = (flags & FLAT_BINDER_FLAG_SCHED_POLICY_MASK) >>
FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT;
node->min_priority = to_kernel_prio(node->sched_policy, priority);
node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
node->inherit_rt = !!(flags & FLAT_BINDER_FLAG_INHERIT_RT);
当客户端发起指令到server时候会调用binder_proc_transaction函数
这个函数里首先去找到一个可以用的thread,然后调用binder_transaction_priority,接着调用binder_do_set_priority。这个函数里有个权限的检查
has_cap_nice = has_capability_noaudit(task, CAP_SYS_NICE);
如果这些权限都检查过了,那么就去唤醒线程并设置优先级
sched_setscheduler_nocheck(task,
policy | SCHED_RESET_ON_FORK,
¶ms);
我们可以分别的在client端和server端打印优先级就可以看到是否启用成功!!
- binder调用完是否会恢复优先级
答案是会的!!
看下面我在binder驱动里打印的log
11-25 14:58:05.741 0 0 I binder : 2651 buffer release 71128, size 4-0, failed at 0
//client调用TRANSACTION 2651:2934 表示home应用的pid:tid
11-25 14:58:05.741 0 0 I binder : cxyffff e->call_type=0,e->from_proc=2651,e->from_thread=2934,e->context_name=binder
11-25 14:58:05.741 0 0 I binder : 2651:2934 BC_TRANSACTION 71150 -> 1837 - node 36817, data 000000781a0608e0-000000783202b7e0 size 88-8-0
//这里打印home传过来的调度策略和优先级
11-25 14:58:05.741 0 0 I binder : cxyffff is not TF_ONE_WAY t->priority.sched_policy=1,t->priority.prio=51
11-25 14:58:05.741 0 0 I binder : cxyffff will is one way
//这里应该表示server是否开启继承
11-25 14:58:05.741 0 0 I binder : cxyffff will binder_transaction_priority node->inherit_rt1=1
11-25 14:58:05.741 0 0 I binder : cxyffff in binder_proc_transaction topid:1837,node_prio.prio=51,node_prio.sched_policy=1,oneway=0
11-25 14:58:05.741 0 0 I binder : cxyfff pending_async=0
11-25 14:58:05.741 0 0 I binder : cxyffff will binder_transaction_priority node->inherit_rt2=1
11-25 14:58:05.741 0 0 I binder : cxyffff will binder_transaction_priority desired_prio prio 51:sched_policy:1
//这里表示server端原来的策略和优先级
11-25 14:58:05.741 0 0 I binder : cxyffff will t->saved_priority.sched_policy=0,t->saved_priority.prio=120,inherit_rt=1
11-25 14:58:05.741 0 0 I binder : cxyffff end desired_prio.prio=51,desired_prio.sched_policy=1
//这里做了has_cap_nice检查 暂时跳过
11-25 14:58:05.741 0 0 I binder : cxyfff binder_do_set_priority policy=1,priority=48,has_cap_nice=0,task->pid=1864,verify=0
//server用来处理这个事件的tid
11-25 14:58:05.741 0 0 I binder : cxyfff binder_do_set_priority 2.1 task->pid=1864
11-25 14:58:05.741 0 0 I binder : cxyfff binder_do_set_priority 3.1 task->pid=1864
11-25 14:58:05.741 0 0 I binder : cxyfff trace_binder_set_priority task->tgid=1837,task->pid=1864
//task->policy是server原来的策略 ,policy是要设置的策略
11-25 14:58:05.741 0 0 I binder : cxyfff trace_binder_set_priority task->policy=0 ,policy=1 ,task->pid=1864
11-25 14:58:05.741 0 0 I binder : cxyffff will binder_transaction_priority desired_prio prio 51:sched_policy:1
//这里是server端要执行的操作,线程开始工作
11-25 14:58:05.741 0 0 I binder : 1837:1864 BR_TRANSACTION 71150 2651:2934, cmd -2143260158 size 88-8 ptr 0000007989b36438-0000007989b36490
11-25 14:58:05.741 1003 1003 E /vendor/bin/adsprpcd: vendor/qcom/proprietary/commonsys-intf/adsprpc/src/adsprpcd.c:48:adsp daemon will restart after 25ms...
11-25 14:58:05.741 0 0 I binder : cxyffff e->call_type=2,e->from_proc=1837,e->from_thread=1864,e->context_name=binder
11-25 14:58:05.741 0 0 I binder : cxyffff is TF_ONE_WAY t->priority.sched_policy=1,t->priority.prio=51
11-25 14:58:05.742 0 0 I binder : cxyffff binder_restore_priority pid=1864,sched_policy=0,prio=120
11-25 14:58:05.742 0 0 I binder : cxyfff binder_do_set_priority policy=0,priority=0,has_cap_nice=0,task->pid=1864,verify=0
//这里是server端执行完工作,返回消息给kernel
11-25 14:58:05.742 0 0 I binder : 2651:2934 BR_REPLY 71151 0:0, cmd -2143260157 size 4-0 ptr 00000079dc265010-00000079dc265018
11-25 14:58:05.742 0 0 I binder : cxyfff binder_do_set_priority 2.1 task->pid=1864
11-25 14:58:05.742 0 0 I binder : cxyfff binder_do_set_priority 3.1 task->pid=1864
11-25 14:58:05.742 0 0 I binder : cxyfff trace_binder_set_priority task->tgid=1837,task->pid=1864
//这里开始恢复
11-25 14:58:05.742 0 0 I binder : cxyfff trace_binder_set_priority task->policy=1 ,policy=0 ,task->pid=1864
- flag的计算
obj.flags = priority & FLAT_BINDER_FLAG_PRIORITY_MASK;
obj.flags |= FLAT_BINDER_FLAG_ACCEPTS_FDS | 0x800;
obj.flags |= (policy & 3) << 9;
obj.flags = 48 & 0xff; 0x30
obj.flags |= 0x100 | 0x800; 0x900
obj.flags |= (1 & 3) << 9; 0x200
计算结果0xB30 1011 0011 0000
48 0011 0000
1<<9 0010 0000 0000
2304 1001 0000 0000