Aosp(四)android13自定义系统服务
作者:访客发布时间:2023-11-16分类:程序开发学习浏览:168
前言
我们在开发当中难免要自定义一个系统服务去获取系统数据或者操作,常见的、PWS、wms等等都是系统服务,运行于System_SERVER进程,并且向服务管理器进程注册其活页夹以便其他进程获取活页夹与对应的服务进行通信。为了新增自定义系统服务,我们可以参考AMS等原生系统服务编写如下文件:
1、Aidl文件:生成粘结剂类,其中存根即为粘结剂的服务端;
2、XXManager服务:系统服务类,继承自存根;
3、XXManager:封装了Aidl接口方法的类,相当于Binder客户端(Proxy),其他进程通过此类完成与系统服务的通信。
一、增加系统服务
1.1艾滋病
在框架/基本/核心/Java/android/应用程序/服务中编写IZxxManager.aidl
package android.app;
/**
* {@hide}
*/
interface IZxxManager {
String request(String msg);
}
1.2系统服务
/frameworks/base/services/core/java/com/android/server/zxx/ZxxManagerService.java
package com.android.server.zxx;
import android.app.IZxxManager;
import android.os.RemoteException;
public class ZxxManagerService extends IZxxManager.Stub {
@Override
public String request(String msg) throws RemoteException {
return "ZxxManagerService接收数据:"+msg;
}
}
注意:如果以当前案例的方式新增自定义系统服务,因为系统服务注册表中需要使用到com.zxx
:build/core/tasks/check_boot_jars/package_whitelist.txt,下的类,为了让其获取此包下类的引用,需要配置加入:com\.zxx\..*
那就是。否则会因为无法获取类引用而编译报错!
dalvik\..*
libcore\..*
android\..*
com\.android\..*
com\.zxx\..*
1.3%添加上下文常量
/frameworks/base/core/java/android/context/Context.java 添加公共静态最终字符串ZXX_SERVICE=“ZXX”;
@StringDef(suffix = { "_SERVICE" }, value = {
POWER_SERVICE,
//@hide: POWER_STATS_SERVICE,
WINDOW_SERVICE,
LAYOUT_INFLATER_SERVICE,
ACCOUNT_SERVICE,
ACTIVITY_SERVICE,
ZXX_SERVICE,
1.4%客户端代理
/frameworks/base/core/java/android/app/ZxxManager.java
package android.app;
import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Singleton;
import android.os.ServiceManager;
import android.annotation.Nullable;
import android.app.IZxxManager;
//代表系统服务
@SystemService(Context.ZXX_SERVICE)
public class ZxxManager {
/**
* @hide 只能系统调用
*/
public ZxxManager() {
}
/**
* @hide 只能系统调用
*/
public static IZxxManager getServerice(){
return I_ZXX_MANAGER_SINGLETON.get();
}
//限制framework中的定义无法被外部应用访问
@UnsupportedAppUsage
private static final Singleton<IZxxManager> I_ZXX_MANAGER_SINGLETON =
new Singleton<IZxxManager>() {
@Override
protected IZxxManager create() {
final IBinder b= ServiceManager.getService(Context.ZXX_SERVICE);
final IZxxManager im=IZxxManager.Stub.asInterface(b);
return im;
}
};
@Nullable
public String request(@Nullable String msg){
try{
return getServerice().request(msg);
}catch (RemoteException e){
throw e.rethrowFromSystemServer();
}
}
}
1.5注册系统服务
1.5.1系统服务器
1.5.1.1无生命周期注册
Frameworks/base/services/java/com/android/server/SystemServer.java中启动其他服务方法中注册系统服务
import com.android.server.zxx.ZxxManagerService;
private void startOtherServices(){
//......
ServiceManager.addService(Context.ZXX_SERVICE,new ZxxManagerService());
//......
}
1.5.1.2有生命周期注册
系统服务需要通过ServiceManager.addService("xx", new XXManagerService);
将自己(活页夹存根)注册进入SM才能够让其他进程利用活页夹与之通信而自定义系统服务如果需要根据系统启动的不同阶段进行不同的处理则需要注册生命周期回调.以AMS为例:
/frameworks/base/services/java/com/android/server/SystemService中启动AM:
private void startBootstrapServices() {
//...
// Activity manager runs the show.
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
//...
mActivityManagerService.setSystemProcess();
//...
}
AMS中的集合系统流程方法的实现为:
public void setSystemProcess() {
//...
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
//...
}
设置系统进程中会完成向SM注册AMS的实现。而在设置系统进程之前有一段代码:
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
则为注册生命周期监听、ActivityManager服务。生命周期就相当于生命周期的回调接口对象,它继承自:
/frameworks/base/services/core/java/com/android/server/SystemService。这个系统服务中主要需要实现两个方法:
OnStart():mSystemServiceManager.startService第一时间回调该函数。
启动阶段(INT阶段):系统启动的各个阶段会回调该函数
- 系统服务这是一个依赖项,只有_WAIT_FOR_DEFAULT_DISPLAY:服务中进行了对应处理;
- 系统服务.PHASE_LOCK_SETTINGS_READY:经过这个引导阶段后,服务才可以接收到尾锁相关设置数据;
- 系统服务.阶段_系统_服务_就绪:经过这个引导阶段后,服务才可以安全地使用核心系统服务
- 系统服务.PHASE_ACTIVE_MANAGER_READY:经过这个引导阶段后,服务可以发送广播
- SystemService.PHASE_THIRD_PARTY_APPS_CAN_START:经过这个引导阶段后,服务可以启动第三方应用,第三方应用也可以通过Binder来调用服务.
- 系统服务.PHASE_BOOT_COMPLETED:经过这个引导阶段后,说明服务启动完成,这时用户就可以和设备进行交互。
比如AMS中的生命周期:
public static final class Lifecycle extends SystemService {
@Override
public void onBootPhase(int phase) {
mService.mBootPhase = phase;
if (phase == PHASE_SYSTEM_SERVICES_READY) {
mService.mBatteryStatsService.systemServicesReady();
mService.mServices.systemServicesReady();
} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
// 准备广播处理
mService.startBroadcastObservers();
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
mService.mPackageWatchdog.onPackagesReady();
}
}
}
在AMS中会处理PHASE_ACTIVITY_MANAGER_READY
,经过这个阶段后,也就是需要在下一个阶段PHASE_THIRD_PARTY_APPS_CAN_START
才可以发送广播.
1.5.2系统服务注册表
Frameworks/base/core/java/android/app/SystemServiceRegistry.java在注册应用系统服务获取器,有一个Static块执行了用于注册服务寄存器
import android.app.ZxxManager;
static{
registerService(Context.ZXX_SERVICE, ZxxManager.class,
new CachedServiceFetcher<ZxxManager>() {
@Override
public ZxxManager createService(ContextImpl ctx) {
return new ZxxManager();
}});
}
1.6配置SELinux权限
1.6.1修改的文件路径有:
系统/sePolicy/私有/服务上下文;
activity u:object_r:activity_service:s0
zxx u:object_r:zxx_service:s0
System/sepolicy/Private/untrusted_app_all.te;
allow untrusted_app zxx_service:service_manager find;
System/sepolicy/public/service.te;
type activity_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
type zxx_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
注意:System/sePolicy/PreBuild/api/底下也有28.0、29.0、30.0、31.0、32.0、33.0里面的私有/公共对应的文件也要同样添加以上代码
1.6.2去除检查权限校准
System/sepolicy/build/soong/service_fuzzer_bindings.go在
var (
ServiceFuzzerBindings = map[string][]string{
...
"activity": EXCEPTION_NO_FUZZER,
"zxx": EXCEPTION_NO_FUZZER,
...
}
)
1.7%更新并编译、刷机
#方式一:更新编译运行
# 更新api
make update-api
# 编译
m
#运行模拟器
emulator
#方式一:更新编译刷机
#编译
make update-api
make –j4
#刷机
adb reboot bootloader
reboot flashall -w
1.8%验证服务是否添加成功
adb shell service list | grep zxx
二、使用自定义服务
2.1方式一创建相同的壳类
创建同样的包和类,方法可以不实现,利用双亲委托机制一般只是用来调试自己的服务功能是否正常
package android.app;
public class ZxxManager {
public String request(String msg){
return null;
}
}
2.2方式二通过修改sdk配置自定义sdk
制作SDK
2.2.1复制开发工具包
把正在使用的sdk复制一份并改名为android-33.car,android-33.car中的平台和源下的平台同样也复制一份
2.2.2替换android.jar
将复制出来的原生sdk/Platform中的android.jar用自己编译出的替换 Out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes-header.jar 或者 Out/target/common/obj/PACKAGING/android_jar_intermediates目录下面,会生成android.jar和android.jar android--存根-src.jar两个文件,将这个两个文件替换到android工作室使用的sdk的对应平台目录下面,我使用的是api33,目录为平台/android-66(自定义)/
2.2.3修改sdk配置
2.2.3.1源.属性
Android-33.car\platforms\android-66\source.properties修改
#指定自定义平台标识为66(可以是任意数字,但为了与原生标识区分)
#修改:
Pkg.Desc=Android SDK Platform 66
Pkg.UserSrc=false
#修改:
Platform.Version=66
Platform.CodeName=
Pkg.Revision=1
#修改:
AndroidVersion.ApiLevel=66
Layoutlib.Api=15
Layoutlib.Revision=1
Platform.MinToolsRev=22
2.2.3.2 Package.xml
Android-32.car\platforms\android-321\package.xml修改
<localPackage path="platforms;android-66" obsolete="false">
<type-details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="ns5:platformDetailsType">
<!-- 修改 -->
<api-level>66</api-level>
<codename></codename>
<layoutlib api="15"/></type-details>
<revision>
<major>1</major>
</revision>
<!-- 修改 -->
<display-name>Android SDK Platform 66</display-name>
<uses-license ref="android-sdk-license"/>
</localPackage>
2.2.4配置源码跳转
修改android-33.car\Sources\android-66目录下的参考第3步Soure.Properties和Package.xml文件
2.3.方式三使用框架.jar
make javac-check-framework
Out/target/common/obj/JAVA_LIBRARIES/framework_intermediates在拷贝Classes.jar重新命名Framework.jar,作为导入JAR使用
三、常见问题
1、在系统/sePolicy/预构建/api/*底下所以sdk版本的内网/公网按照1.6的形式所有都给它添加
2、$ANDROID_BUILD_TOP/system/sepolicy/BUILD/soong/service_fuzzer_bindings.go,按Activity这种格式,自定义的服务的加进去,就不会检查了
//system/sepolicy/contexts:fuzzer_bindings_test running service:fu
FAILED: out/soong/.intermediates/system/sepolicy/contexts/fuzzer_bindings_test/android_common/timestamp
out/host/linux-x86/bin/fuzzer_bindings_check -s out/soong/.intermediates/system/sepolicy/contexts/plat_service_contexts/android_common/gen/plat_service_contexts -b out/soong/.intermediates/bindings.json && touch out/soong/.intermediates/system/sepolicy/contexts/fuzzer_bindings_test/android_common/timestamp # hash of input list: d6d7c35d085ab532427370293bbe7778939ca920eb7f04227649468b94741599
error: Service 'zxx' is being added, but we have no fuzzer on file for it. Fuzzers are listed at $ANDROID_BUILD_TOP/system/sepolicy/build/soong/service_fuzzer_bindings.go
NOTE: automatic service fuzzers are currently not supported in Java (b/232439254) and Rust (b/164122727). In this case, please ignore this for now and add an entry for yournew service in service_fuzzer_bindings.go
If you are writing a new service, it may be subject to attack from other potentially malicious processes. A fuzzer can be written automatically by adding these things:
- a cc_fuzz Android.bp entry
- a main file that constructs your service and calls 'fuzzService'
An examples can be found here:
- $ANDROID_BUILD_TOP/hardware/interfaces/vibrator/aidl/default/fuzzer.cpp
- https://source.android.com/docs/core/architecture/aidl/aidl-fuzzing
This is only ~30 lines of configuration. It requires dependency injection for your service which is a good practice, and (in AOSP) you will get bugs automatically filed on you. You will find out about issues without needing to backport changes years later, and the system will automatically find ways to reproduce difficult to solve issues for you.
This error can be bypassed by adding entry for new service in $ANDROID_BUILD_TOP/system/sepolicy/build/soong/service_fuzzer_bindings.go
- Android Fuzzing and Security teams
- 程序开发学习排行
-
- 1鸿蒙HarmonyOS:Web组件网页白屏检测
- 2HTTPS协议是安全传输,为啥还要再加密?
- 3HarmonyOS鸿蒙应用开发——数据持久化Preferences
- 4记解决MaterialButton背景颜色与设置值不同
- 5鸿蒙HarmonyOS实战-ArkUI组件(RelativeContainer)
- 6鸿蒙HarmonyOS实战-ArkUI组件(Stack)
- 7[Android][NDK][Cmake]一文搞懂Android项目中的Cmake
- 8Android广播如何解决Sending non-protected broadcast问题
- 9鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
- 最近发表
-
- WooCommerce最好的WordPress常用插件下载博客插件模块的相关产品
- 羊驼机器人最好的WordPress常用插件下载博客插件模块
- IP信息记录器最好的WordPress常用插件下载博客插件模块
- Linkly for WooCommerce最好的WordPress常用插件下载博客插件模块
- 元素聚合器Forms最好的WordPress常用插件下载博客插件模块
- Promaker Chat 最好的WordPress通用插件下载 博客插件模块
- 自动更新发布日期最好的WordPress常用插件下载博客插件模块
- WordPress官方最好的获取回复WordPress常用插件下载博客插件模块
- Img to rss最好的wordpress常用插件下载博客插件模块
- WPMozo为Elementor最好的WordPress常用插件下载博客插件模块添加精简版