【Android车载系列】第11章 系统服务-SystemServer自定义服务

43 篇文章 1 订阅
13 篇文章 43 订阅

1 编写自定义系统服务

1.1 AIDL接口定义

系统源码目录/frameworks/base/core/java/android/app/下新建AIDL接口IYvanManager.aidl

package android.app;

/**
* 目录:/frameworks/base/core/java/android/app/IYvanManager.aidl
*/
interface IYvanManager{
    String request(String msg);
}

1.2 服务端

package com.android.server.yvan;

import android.app.IYvanManager;
import android.os.RemoteException;


/**
 * 服务端   AMS PMS WMS
 * 目录:/frameworks/base/services/core/java/com/android/server/yvan/YvanManagerService.java
 */
public class YvanManagerService extends IYvanManager.Stub {
    @Override
    public String request(String msg) throws RemoteException {
        return "YvanManagerService接收数据:"+msg;
    }
}

1.3 客户端

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;
/**
 * 客户端
 * 目录:/frameworks/base/core/java/android/app/YvanManager.java
 */
@SystemService(Context.YVAN_SERVICE)
public class YvanManager{
    /**
     * @hide
     */
    public YvanManager() {
    }
    /**
     * @hide
     */
    public static IYvanManager getServerice(){
        return I_YVAN_MANAGER_SINGLETON.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IYvanManager> I_YVAN_MANAGER_SINGLETON =
            new Singleton<IYvanManager>() {
                @Override
                protected IYvanManager create() {
                    final IBinder b= ServiceManager.getService(Context.YVAN_SERVICE);
                    final IYvanManager im=IYvanManager.Stub.asInterface(b);
                    return im;
                }
            };


    @Nullable
    public String request(@Nullable String msg){
        try{
            return getServerice().request(msg);
        }catch (RemoteException e){
            throw e.rethrowFromSystemServer();
        }
    }
}

1.4 添加上下文件常量

  1. /frameworks/base/core/java/android/context/Context.java文件下添加服务名字:
public static final String YVAN_SERVICE = "yvan";
  1. 常量内增加该服务YVAN_SERVICE
	@StringDef(suffix = { "_SERVICE" }, value = {
            POWER_SERVICE,
            //@hide: POWER_STATS_SERVICE,
            WINDOW_SERVICE,
            LAYOUT_INFLATER_SERVICE,
            ACCOUNT_SERVICE,
            ACTIVITY_SERVICE,
            YVAN_SERVICE,

1.5 注册BINDER

1.5.1 frameworks/base/services/java/com/android/server/SystemServer.java文件下startOtherServices()方法下将服务添加

ServiceManager.addService(Context.YVAN_SERVICE,new YvanManagerService());

1.5.2 获取服务在Context中getSystemService()方法ContextImpl中实现

SystemServiceRegistry.getSystemService(this, name);

1.5.3 frameworks/base/core/java/android/app/SystemServiceRegistry.java为用于给客户端获取服务的类,其中有一个static块 执行了registerService()用于注册

registerService(Context.YVAN_SERVICE, YvanManager.class,
                new CachedServiceFetcher<YvanManager>() {
                    @Override
                    public YvanManager createService(ContextImpl ctx) {
                        return new YvanManager();
                    }});

1.5.4 最后修改SeLinux安全权限

system/sepolicy/prebuilts/api/32.0/private/ 与 system/sepolicy/private/ 目录下,分别修改以下三个文件
在这里插入图片描述

1.service_contexts
#配置自定义服务selinux角色
yvan u:object_r:yvan_service:s0
用户:角色:类型:安全级别

2.service.te
#配置自定义服务类型的权限
type yvan_service,
app_api_service, ephemeral_app_api_service,
system_server_service,
service_manager_type;

3.untrusted_app_all.te
#允许所有app使用自定义服务
allow untrusted_app_all yvan_service:service_manager find;

1.5.5 更新并编译

#更新:make update-api
#编译:m
#运行模拟器:emulator

1.5.6 服务添加成功验证

adb shell service list |grep yvan

2 使用自定义服务

2.1 方法一:利用双亲委托机制

一般只是用来调试自己的服务功能是否正常

package android.app;

public class YvanManager {
    public String request(String msg){
        return null;
    }
}

// 使用
YvanManager yvanManager=(YvanManager)getSystemService("yvan");
String str=yvanManager.request("app msg!");
Log.i("yvan",str);

2.2 方法二:通过修改SDK配置

自定义SDK给应用层使用

2.2.1 把正在使用的SDK复制一份并改名为android-32.car,android-32.car中的platforms和sources下的平台同样也复制一份

2.2.2 将复制出来的原生SDK/platforms中的android.jar用自己编译出的替换

out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes-header.jar

2.2.3 修改SDK配置

2.2.3.1 修改android-32.car\platforms\android-321\source.properties
	#指定自定义平台标识为321(可以是任意数字,但为了与原生标识区分,请使用三位数) 
	#修改: 
		Pkg.Desc=Android SDK Platform 321 
		Pkg.UserSrc=false 
	#修改: 
		Platform.Version=321 
		Platform.CodeName= 
		Pkg.Revision=1 
	#修改: 
		AndroidVersion.ApiLevel=321 
		Layoutlib.Api=15 
		Layoutlib.Revision=1 
		Platform.MinToolsRev=22
2.2.3.2 修改 android-32.car\platforms\android-321\package.xml
<localPackage path="platforms;android-321" obsolete="false"> 
 <type-details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:type="ns5:platformDetailsType"> 
 <!-- 修改 --> 
 <api-level>321</api-level> 
 <codename></codename> 
 <layoutlib api="15"/></type-details> 
 <revision> 
 <major>1</major> 
 </revision> 
 <!-- 修改 --> 
 <display-name>Android SDK Platform 321</display-name> 
 <uses-license ref="android-sdk-license"/> 
</localPackage>

2.2.4 配置源码跳转

修改android-32.car\sources\android-321目录下的,参考第3步source.propertiespackage.xml文件

3 思考题

如何编写自定义服务并要求有系统执行过程的生命周期管理???参考AMS服务的生命周期管理。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__Yvan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值