基于Android源码添加一个系统服务

基于Android源码添加一个系统服务

服务(Service)是Android四大组件之一,而系统服务则是Android中非常重要的一部分, 像ActivityManagerService, PackageManagerService, WindowManagerService, 这些系统服务都是Framework层的关键服务。日常开发中都不可避免要使用到服务,部分需求无法在App应用层面实现,则需要通过添加自定义的系统服务才方便实现及管理。那么如何基于Android源码添加一个系统服务:
1、编写AIDL文件
添加服务首先是编写AIDL文件, AIDL文件一般添加到如下路径下:frameworks/base/core/java/com/android/led
1.1 ILedService.aidl 内容如下:

package android.led;
interface ILedService {
    void systemReady();
void updatePowerLed();
......
}

1.2 将 ILedService.aidl 加入编译
修改 frameworks/base/Android.bp 文件,
在 LOCAL_SRC_FILES += \ 后参考core/java/android/os/IUserManager.aidl \ 的写法,
添加一行

core/java/android/led/ILedService.aidl \

2、编写Manager类
Android API 中有很多Manager类, 这些类一般都是某个系统服务的客户端代理类, 其实我们不写Manager类, 只通过AIDL文件自动生成的类, 也可以完成功能, 但封装一下AIDL接口使用起来更方便, 我们测试用的Manager类为 LedManager, 在 frameworks/base/core/java/android/led/ 目录创建LedManager.java

package android.led;

import android.led.ILedService;
import android.os.RemoteException;

import android.annotation.NonNull;

public class LedManager {

    private final ILedService ledService;

    public LedManager(@NonNull ILedService ledService) {
        this.ledService = ledService;
    }

    public void systemReady(){
        try {
            ledService.systemReady();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void updatePowerLed(){

        try {
            ledService.updatePowerLed();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
}
...
...
}

3、创建系统服务 LedService
在 frameworks/base/services/core/java/com/android/server/ 目录创建 ThunderService.java,
构造函数是否传入 Context 参数可按照需求来定,参考系统其他 Service 的写法,一般是会传入的。

package com.android.server;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
...
public class LedService extends ILedService.Stub {

    private final String TAG = "LedService";
    
 public LedService(@NonNull Context context){
        super();
        this.mContext = context;
             
    }
@Override
    public void systemReady() throws RemoteException {

}
@Override
    public void updatePowerLed() throws RemoteException {
        
        
    }
...
...
}

4、将自定义 LedService 加入到 SystemServer
4.1 修改 frameworks/base/core/java/android/content/Context.java ,添加如下:

+ /**
+ * Add for LedService
+ */
+ public static final String THUNDER_SERVICE = "led";

4.2 修改 frameworks/base/services/java/com/android/server/SystemServer.java ,在 startOtherServices() 方法中添加如下:

+        //add by chyb for led service
+        t.traceBegin("StartLedService");
+        ServiceManager.addService(Context.LED_SERVICE, new LedService(mSystemContext));
+        t.traceEnd();
+        //add by chyb end

可参考原生的系统服务添加,格式类似。

5、将 ThunderManager 注册到 SystemService
修改 frameworks/base/core/java/android/app/SystemServiceRegistry.java
文件,添加:

+         //add for led service
+        registerService(Context.LED_SERVICE, LedManager.class,
+                new CachedServiceFetcher<LedManager>() {
+                    @Override
+                    public LedManager createService(ContextImpl ctx) {
+                        IBinder b = ServiceManager.getService(Context.LED_SERVICE);
+                        Log.i("add_service_led","SystemServiceRegistry registerService method");
+                        return new LedManager(ILedService.Stub.asInterface(b));
+                        //return new DisplayHashManager();
+                    }});
+        //add  end

6、添加 selinux 权限

修改system/sepolicy/private/service_contexts文件,添加:
+led      u:object_r:led_service:s0

修改system/sepolicy/public/service.te文件,添加
+type led_service, system_api_service, system_server_service, service_manager_type;

7、重新编译系统api : make update-api
修改 framework 下的源码后,需要先执行 make update-api ,
此操作会更新如下文件:

frameworks/base/api/system-current.txt
frameworks/base/api/system-removed.txt

然后再执行 make 编译即可。

8、编写APP测试
两种方式进行调用
(1)在源码的 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/ 目录下会生成 classes.jar 文件,
这个就是编译生成的 framework 依赖包,将其导入 AndroidStudio 工程就使用 LedManager 了。
(2)通过拷贝LedManager 与aidl文件到工程中,注意包名要与ledManager与aidl一致,如图所示:

在这里插入图片描述

代码示例:

LedManager ledManager =(LedManager) getSystemService("led");
ledManager.updatePowerLed()

然后就可以愉快的进行调用调试了

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值