1. 问题的提出
    dumpsys是一个非常有用的命令,可以用来查看打印一些系统服务数据

    adb shell dumpsys display
    adb shell dumpsys battery

详细内容可以搜索dumpsys查看

在查看代码的时候,发现
publishBinderService(“battery”, new BinderService());

private final class BinderService extends Binder {    @Override    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)                != PackageManager.PERMISSION_GRANTED) {            pw.println("Permission Denial: can't dump Battery service from from pid="                    + Binder.getCallingPid()                    + ", uid=" + Binder.getCallingUid());            return;        }        dumpInternal(pw, args);    }}

猜测dumpsys 服务名
可以调用的服务是在这里设置的
publishBinderService(“battery”, new BinderService());

于是,照葫芦画瓢,写了一句
publishBinderService(“atest”, new BinderService());

预料adb shell dumpsys atest 会进行打印调用

结果呢?
编译后,手机不能开机了。
好在可以在DDMS里抓到log

01-01 00:00:57.841: E/AndroidRuntime(817): * FATAL EXCEPTION IN SYSTEM PROCESS: main
01-01 00:00:57.841: E/AndroidRuntime(817): java.lang.RuntimeException: Failed to start service com.android.server.BatteryService: onStart threw an exception
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServiceManager.startService(SystemServiceManager.java:119)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServer.startCoreServices(SystemServer.java:621)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServer.run(SystemServer.java:372)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServer.main(SystemServer.java:258)
01-01 00:00:57.841: E/AndroidRuntime(817): at java.lang.reflect.Method.invoke(Native Method)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:739)
01-01 00:00:57.841: E/AndroidRuntime(817): Caused by: java.lang.SecurityException

一个字符串名称异常导致了系统不能开机,也就是说,一个字符就可以让系统不能开机,太可怕了

在publishBinderService(“atest”, new BinderService());
调用的时候进行try catch处理
结果还好,系统可以开机了
01-01 13:20:07.860: D/BatteryService(968): ================ atest ============
01-01 13:20:07.861: E/SELinux(325): avc: denied { add } for service=atest scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager
01-01 13:20:07.862: E/ServiceManager(325): add_service(‘atest’,28) uid=1000 - PERMISSION DENIED
01-01 13:20:07.862: D/BatteryService(968): ================ atest catch ============
01-01 13:20:07.862: W/System.err(968): java.lang.SecurityException
01-01 13:20:07.868: W/System.err(968): at android.os.BinderProxy.transactNative(Native Method)

还不错,打印出了具体信息,SELinux权限的问题

搜索
SELinux(325): avc: denied { add } for service
在stackoverflow上看到一种解决方案
To file:
android-dev\external\sepolicy\service.te
Add:
type mytest_service, system_api_service, system_server_service, service_manager_type;
To file:
android-dev\external\sepolicy\service_contexts
Add:
mytestservice u:object_r:mytest_service:s0
where mytestservice your name service

修改android/external/sepolicy 里的文件

修改后编译,还是抛异常

查找代码
find . -name *.c|xargs grep ’ PERMISSION DENIED’
./frameworks/native/cmds/servicemanager/service_manager.c: ALOGE(“add_service(‘%s’,%x) uid=%d - PERMISSION DENIED\n”,
./frameworks/native/cmds/servicemanager/service_manager.c: ALOGE(“list_service() uid=%d - PERMISSION DENIED\n”,

修改了te文件还是有异常,??
这个不清楚是不是编译的问题,现在决定跳过赋权,对服务调用进行测试
修改./frameworks/native/cmds/servicemanager/service_manager.c
int do_add_service(struct binder_state *bs,
const uint16_t *s, size_t len,
uint32_t handle, uid_t uid, int allow_isolated,
pid_t spid)
{
struct svcinfo *si;

//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,//        allow_isolated ? "allow_isolated" : "!allow_isolated", uid);if (!handle || (len == 0) || (len > 127))    return -1;if (!svc_can_register(s, len, spid)) {    ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",         str8(s, len), handle, uid);

ALOGE(“=======test go =======”);
// return -1;
}

就可以调用自定义服务了
dumpsysatestdumpsysatestBinderService2dumpcalled====================


  1. ap调用测试
    adb shell dumpsys atest
    可以调用atest服务的dump方法

再写个ap进行测试
Binder aObject;
try {
aObject = (Binder)getSystemService(“atest”);
int id = aObject.getCallingPid();
System.out.println(“Pid = ” + id);
Log.d(“test614”, “Pid = ” + id);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

Log
01-05 09:32:35.122: D/test614(801): Pid = 801

这样调用的都是binder里的接口方法,如果要自定义方法,aidl就出场了
详细使用可以查看这位达人的系列blog
http://www.cloudchou.com/android/post-447.html
写的非常好

  1. 总结
    这里通过添加一个自定义服务,了解了addService的一些信息。

binder是用来进行进程间通信的,和ICE通信机制类似。
采用一些数据传送方法,把client和server关联交互起来

更多相关文章

  1. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
  2. Android通过webview调起微信和支付宝app进行支付
  3. Android开发------------杂记
  4. android_apps_frameworks_通话处理流程
  5. Android(安卓)中的menu以及自定义menu
  6. Android之SharePreferences数据存储
  7. Android开发20——单个监听器监听多个按钮点击事件
  8. android 卸载应用、打开应用、获得系统中已安装应用列表
  9. 【原创】如何在Android中为TextView动态设置drawableLeft等

随机推荐

  1. 安装Android(安卓)studio 时候显示:SDK to
  2. Android(安卓)Bundle类
  3. Android单元测试总结
  4. 当scroll时改变item的背景
  5. 深入浅出Android之学习笔记
  6. Android(安卓)Studio常见布局报错及解决
  7. eclipse中android的安装
  8. activity页面切换效果
  9. Android——ViewGroup的一个用法实例
  10. android]Android(安卓)线程优先级修改