美文网首页
Add system service in framework

Add system service in framework

作者: 故事的小黄花er | 来源:发表于2017-07-24 17:30 被阅读127次

前言:
准备记录一下自己的学习笔记,本文代码基于Android M 源码

1.编写AIDL

android/frameworks/base/core/java/android/os/ITestService.aidl

interface ITestService {
    test();
}

2.修改mk文件

android/frameworks/base/Android.mk

LOCAL_SRC_FILES += \
    core/java/android/os/ITestService.aidl

3.编写真正工作的服务类,继承ITestService.Stub类

(目前他并不是一个真正的服务,下面会通过SystemServer注册)
android/frameworks/base/services/core/java/com/android/server/TestService.java

public class TestService extends ITestService.Stub {
    //实现ITestService.aidl中定义的接口。
    test()  {
        //调用native方法
    }
}

4.编写一个TestService管理类,TestServiceManager,方便app调用

android/frameworks/base/core/java/android/os/TestServiceManager.java

public class TestServiceManager {
    private static final String TAG = "TestServiceManager";

    private final ITestService mService;

    public TestServiceManager() {
        mService = ITestService.Stub.asInterface(
                ServiceManager.getService("test"));
    }

    public TestServiceManager(Context context) {
        super(context);
        mService = ITestService.Stub.asInterface(
                ServiceManager.getService("test"));
    }

    public void test() {
        if (mService == null) {
            Log.w(TAG, "Failed");
            return;
        }
        try {
            mService.test();
        } catch (RemoteException e) {
            Log.w(TAG, "Failed.", e);
        }
    }
}

5.将自定义服务注册到SystemServer,使得开机过程中被添加。

android/frameworks/base/services/java/com/android/server/SystemServer.java
简单看一下流程,从main函数进入,会调用自身的run方法

public static void main(String[] args) {
      new SystemServer().run();
}

在run方法中,通过下面的方法启动:开机,核心,以及其他服务

private void run() {
    ...
    // Start services.
    try {
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
     } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }
    ...
}

因此可以把自己创建的service 添加到startOtherServices中

public final class SystemServer {
    ....
    private void startOtherServices() {
        ....
        TestService test = null;
        ....
        Slog.i(TAG, "Test Service");
        test = new TestService(context);
        ServiceManager.addService("test", test);
        //ServiceManager.addService(Context.TEST_SERVICE, test);
        ....
        try {
            test.systemReady();
        } catch (Throwable e) {
            reportWtf("making Test Service ready", e);
        }
    }
    ....
}

:另外可以把"test"字段,定义在Context中,方便从app中获取service
android/frameworks/base/core/java/android/content/Context.java

    public static final String TEST_SERVICE = "test";

6.让app侧,可以通过getSystemService接口获得服务

android/frameworks/base/core/java/android/app/ContextImpl.java
通过查看getSystemService实现

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}

实际是通过SystemServiceRegistry.getSystemService来获取具体的服务
android/frameworks/base/core/java/android/app/SystemServiceRegistry.java

public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
}
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();

获取系统服务是通过ServiceFetcher的getService来获取的,并且SYSTEM_SERVICE_FETCHERS就是一个Map实例,所以肯定是通过put方法为它赋值的, 通过registerService注册

private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

所以在SystemServiceRegistry的static静态代码块中进行注册

static {
.....
        registerService(Context.VIBRATOR_SERVICE, TestServiceManager.class,
                new CachedServiceFetcher<TestServiceManager>() {
            @Override
            public Vibrator createService(ContextImpl ctx) {
                return new TestServiceManager(ctx);
            }});
.....
}

7.更新API

由于在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,执行完后会发现frameworks\base\api\current.xml文件中多出自己定义的一些东西。current.xml这个文件包含了所有系统所有能被应用层使用的类及其方法等。
之后再使用make编出来的固件及jar包就能包含自定义的接口。

最后:
在framework 添加自己的服务就算完了,向上为app提供接口,向下与HAL层交互。下一步准备学习一下framework与HAL层之间的桥梁JNI。

相关文章

网友评论

      本文标题:Add system service in framework

      本文链接:https://www.haomeiwen.com/subject/qjsbkxtx.html