06 Android系统之添加java层系统服务

网友投稿 1178 2022-05-30

引入概念

目前对android系统体系了解比较少,主要区分一下服务、系统服务这两个概念

Android服务是一个后台运行的组件,执行长时间运行且不需要用户交互的任务。在android开发中作为一个应用组件,通过继承类extern Service来使用。

06 Android系统之添加java层系统服务

Android系统服务。理解为随着andorid系统启动运行的service,分为本地守护进程、Native系统服务和Java系统服务。

有相同点更有不同点,但请不要把两个概念弄混淆了!!!

然后下面记录一下添加自定义一个java系统服务的步骤,参考于qiushao大神的blog。基于android-10版本的AOSP源码,

添加服务

1、 定义服务接口

首先我们得定义我们的服务名是什么,提供什么样的接口。在frameworks/base/core/java/android目录下添加pure文件夹

$ tree frameworks/base/core/java/android/pure frameworks/base/core/java/android/pure └── IHelloService.aidl # 使用 aidl 定义服务接口 0 directories, 1 file

1

2

3

4

5

定义接口文件IHelloService.aidl,模块名IHelloService,接口hello将实现播放指定路径的音频文件

package android.pure; interface IHelloService { void hello(String name); }

1

2

3

4

5

frameworks/base/Android.bp文件中找到模块名framework-defaults,添加

"core/java/android/pure/IHelloService.aidl",

1

此时,进入 framework/base 目录执行 mm -j 命令编译 framework.jar 模块。

编译成功后,会在 out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/android/pure 目录生成 IHelloService.java 这个文件

2、 实现接口

然后在frameworks/base/services/core/java/com/android/server下创建HelloService.java文件(接口实现) 内容如下

package com.android.server; import android.pure.IHelloService; import android.util.Log; public class HelloService extends IHelloService.Stub { private final String TAG = "HelloService"; public HelloService() { Log.d(TAG, "create hello service"); } @Override public void hello(String name) { Log.d(TAG, "hello " + name); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

3、 将服务添加到 ServiceManager

修改 frameworks/base/services/java/com/android/server/SystemServer.java 文件,在startOtherServices方法里面增加以下代码

// add hello service traceBeginAndSlog("HelloService"); ServiceManager.addService("HelloService", new HelloService()); traceEnd();

1

2

3

4

4、 编译验证 & 系统无法启动

现在已经实现的HelloService接口模块,并添加到ServiceManager。开始尝试整编下android源码

$ source ./build/envsetup.sh # 导出环境变量(之前执行过了) $ lunch product01-eng # 选择Product $ make api-stubs-docs-update-current-api -j4 # 更新API接口 $ make -j4 # 编译

1

2

3

4

然后启动emulator虚拟机,发现一直停留在logo界面,说明系统没起来。。这时候可以adb调试,我们查看一下log记录

$ emulator # 发现android系统界面没起来 ... ... $ adb shell logcat -b all > logSystem.txt # 抓取android层的 log ... ^C

1

2

3

4

5

6

日志中检索我们想要的关键字HelloService,发现

04-02 01:24:25.871 2224 2224 I SystemServer: HelloService 04-02 01:24:25.871 1528 1528 I auditd : avc: denied { add } for service=HelloService pid=2224 uid=1000 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0 04-02 01:24:25.871 2224 2224 E System : ****************************************** 04-02 01:24:25.871 2224 2224 E System : ************ Failure starting system services 04-02 01:24:25.871 2224 2224 E System : java.lang.SecurityException 04-02 01:24:25.871 2224 2224 E System : at android.os.BinderProxy.transactNative(Native Method) 04-02 01:24:25.871 2224 2224 E System : at android.os.BinderProxy.transact(BinderProxy.java:510) 04-02 01:24:25.871 2224 2224 E System : at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:156) 04-02 01:24:25.871 2224 2224 E System : at android.os.ServiceManager.addService(ServiceManager.java:192) 04-02 01:24:25.871 2224 2224 E System : at android.os.ServiceManager.addService(ServiceManager.java:161) 04-02 01:24:25.871 2224 2224 E System : at com.android.server.SystemServer.startOtherServices(SystemServer.java:920) 04-02 01:24:25.871 2224 2224 E System : at com.android.server.SystemServer.run(SystemServer.java:512) 04-02 01:24:25.871 2224 2224 E System : at com.android.server.SystemServer.main(SystemServer.java:349) 04-02 01:24:25.871 2224 2224 E System : at java.lang.reflect.Method.invoke(Native Method) 04-02 01:24:25.871 2224 2224 E System : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 04-02 01:24:25.871 2224 2224 E System : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:908) 04-02 01:24:25.871 2224 2224 D SystemServerTiming: HelloService took to complete: 1ms 04-02 01:24:25.871 2224 2224 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

然后定位到这一句04-02 01:24:25.871 1528 1528 I auditd : avc: denied { add } for service=HelloService pid=2224 uid=1000 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0,不理解没关系,google一下。发现是selinux方面的原因。

为了进一步验证猜想,将系统中的selinux关掉试试。通过setenforce 0命令,重启系统发现正常了,印证了之前的猜想,确实selinux配置的原因。

$ adb shell setenforce 0 # 禁用selinux $ emulator -wipe-data # 擦掉data区,重启系统

1

2

3

4

5、 设置selinux规则

然后我们只需要添加这个自定义服务HelloService相关的 SELinux 规则。为了方便之后验证,打开selinux

$ adb shell setenforce 1 # 打开selinux

1

Android 10 的 selinux 规则是放在 system/sepolicy 目录下的。不怎么了解SELinux规则,可以参考现有的系统服务的规则去添加,这里参考的是 network_time_update_service 服务。

$ cd system/sepolicy # selinux规则在这个目录 $ grep -nr network_time_update_service # 查找network_time_update_service服务相关的selinux配置

1

2

涉及到的文件很多,有部分文件是不需要修改的,我们先把找到的所有 service.te 和 service_contexts 都参考 network_time_update_service 加上 HelloService 的配置。

$ find -name service.te ./prebuilts/api/27.0/public/service.te # 需要 ./prebuilts/api/28.0/public/service.te # 需要 ./prebuilts/api/28.0/private/service.te ./prebuilts/api/29.0/public/service.te # 需要 ./prebuilts/api/29.0/private/service.te ./prebuilts/api/26.0/public/service.te # 需要 ./public/service.te # 需要 ./private/service.te $ find -name service_contexts ./reqd_mask/service_contexts ./prebuilts/api/27.0/private/service_contexts # 需要 ./prebuilts/api/28.0/private/service_contexts # 需要 ./prebuilts/api/29.0/private/service_contexts # 需要 ./prebuilts/api/26.0/private/service_contexts # 需要 ./private/service_contexts # 需要

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

其中

service_contexts上添加HelloService u:object_r:HelloService:s0;

service.te上添加type HelloService, system_server_service, service_manager_type;。

6、 编译验证

最后再次编译一遍,启动届满没有什么问题了。adb进入系统查看一下有没有这个服务

$ source ./build/envsetup.sh # 导出环境变量(之前执行过了) $ lunch product01-eng # 选择Product $ make api-stubs-docs-update-current-api -j4 # 更新api接口 $ make -j4 # 编译 .... .... $ adb shell pure:/ # service list | grep HelloService 16 HelloService: [android.pure.IHelloService] pure:/ #

1

2

3

4

5

6

7

8

9

10

11

错误记录

1、 添加服务后,make -j4编译系统报错

error: Added package android.pure [AddedPackage] Aborting: Found compatibility problems checking the public API against the API in /home/mi/source/android-10/frameworks/base/api/current.txt -e ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1. You can add '@hide' javadoc comments to the methods, etc. listed in the errors above. 2. You can update current.txt by executing the following command: make api-stubs-docs-update-current-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** 09:05:24 ninja failed with: exit status 1 #### failed to build some targets (06:37 (mm:ss)) ####

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

解决思路: 没有更新服务接口,编译前执行make api-stubs-docs-update-current-api -j4

2、添加selinux后,编译报错

SELinux: The following public types were found added to the policy without an entry into the compatibility mapping file(s) found in private/compat/V.v/V.v[.ignore].cil, where V.v is the latest API level. HelloService See examples of how to fix this: https://android-review.git.corp.google.com/c/platform/system/sepolicy/+/781036 https://android-review.git.corp.google.com/c/platform/system/sepolicy/+/852612 [ 20% 5/24] build out/target/product/pure/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0 FAILED: out/target/product/pure/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0 /bin/bash -c "(out/host/linux-x86/bin/treble_sepolicy_tests -l out/host/linux-x86/lib64/libsepolwrap.so -f out/target/product/pure/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/pure/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/pure/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/pure/obj/ETC/treble_sepolicy_tests_28.0_intermediates/28.0_mapping.combined.cil -o out/target/product/pure/obj/ETC/treble_sepolicy_tests_28.0_intermediates/built_28.0_plat_sepolicy -p out/target/product/pure/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/pure/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble ) && (touch out/target/product/pure/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0 )" SELinux: The following public types were found added to the policy without an entry into the compatibility mapping file(s) found in private/compat/V.v/V.v[.ignore].cil, where V.v is the latest API level. HelloService See examples of how to fix this: https://android-review.git.corp.google.com/c/platform/system/sepolicy/+/781036 https://android-review.git.corp.google.com/c/platform/system/sepolicy/+/852612 21:45:48 ninja failed with: exit status 1 #### failed to build some targets (16 seconds) ####

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

解决思路: selinux没配置好,没有将配置覆盖所有需要的te文件。检查本地配置,按照上面的方法,在配置一下。

3、启动emulator之后,系统没起来,同时log报错

hinzer@ubuntu:android-10$ emulator -wipe-data emulator: WARNING: Couldn't find crash service executable /home/hinzer/source/android-10/prebuilts/android-emulator/linux-x86_64/emulator64-crash-service emulator: WARNING: system partition size adjusted to match image file (3083 MB > 800 MB) qemu_ram_alloc_user_backed: call context mismatch in svga_surface_destroy # 这个错误 ....

1

2

3

4

5

6

7

8

解决方法: 通过网络查询到解决方法,由于我这边是VM上运行Ubuntu虚拟机,然后在跑emulator。我需要把VM设置中的显示器中的图形渲染关闭,这一操作需要关闭虚拟机,重启后在运行emulator 验证就没有问题了。

小结

查看日志 使用logcat -b all,不清楚不要过滤处理,查看全部log

不确定的情况下,可以系统上直接启动/禁止selinux验证猜想,然后进一步调试

参考资料

Android系统开发入门-7.添加java层系统服务

官方文档 - 服务概览

官方文档- SELinux

Android 系统服务

Android IDE Java

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:在AI Studio上部署外部可以直接调用的云端服务
下一篇:大前端学习 -- NuxtJS学习笔记
相关文章