1.1. AOSP添加SystemService

1.1.1. 整体步骤

  1. 定义服务接口文件(aidl文件)

  2. 实现服务接口(...Service.java)

  3. 添加aidl文件到编译脚本(./framework/base/Android.mk)

  4. 添加服务到SystemServer(ServiceManager.addService)

  5. 添加Manager供应用层调用(SystemServiceRegistry.registerService)

下面记录添加系统服务ComputerService的过程

1. 定义服务接口文件(aidl文件)

// IComputerInterface.aidl

package android.os;

// Declare any non-default types here with import statements
// ccf
/**
* @hide
*/
interface IComputerInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    int plus(int a, int b);

    int reduce(int a, int b);
}

该接口文件包含两个函数,plusreduce

一般系统服务的aidl文件都放在framework\base\core\java\android\os目录中。

2. 实现服务接口

package com.android.server;

import android.content.Context;
import android.os.IComputerInterface;
import android.os.RemoteException;
import android.util.Log;

public class ComputerService extends IComputerInterface.Stub {

    private static final String TAG = "ComputerService";

    public ComputerService(Context context) {
        super();
    }

    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
        Log.e(TAG, "basicTypes");
    }

    @Override
    public int plus(int a, int b) throws RemoteException {
        Log.e(TAG, "plus(" + a + " + " + b + ")");
        return a + b;
    }

    @Override
    public int reduce(int a, int b) throws RemoteException {
        Log.e(TAG, "reduce(" + a + " - " + b + ")");
        return a - b;
    }
}

服务实现了plusreduce功能。

3. 添加aidl文件到编译脚本

framework/base/Android.mk文件中添加aidl文件。

core/java/android/os/IComputerInterface.aidl \

4. 添加服务到SystemServer

在SystemServer中,通过ServiceManager.addService添加系统服务。

traceBeginAndSlog("StartComputerService");
try {
    Slog.i("SystemServer", "add ComputerService");
    ServiceManager.addService("computer", new ComputerService(context));
} catch (Throwable e) {
    reportWtf("starting ComputerService", e);
}
traceEnd();

5. 添加Manager供应用层调用

添加ComputerManager

package android.os;

import android.content.Context;
import android.os.RemoteException;
import android.util.Log;

/**
 * @hide
 */
public class ComputerManager {

    final String TAG = "ComputerManager";

    private Context mContext;

    private IComputerInterface mService;

    public ComputerManager(Context context, IComputerInterface service) {
        this.mContext = context;
        this.mService = service;
    }

    public int plus(int a, int b) throws RemoteException {
        Log.e(TAG, "plus(" + a + " + " + b + ")");
        return mService.plus(a, b);
    }

    public int reduce(int a, int b) throws RemoteException {
        Log.e(TAG, "reduce(" + a + " - " + b + ")");
        return mService.reduce(a, b);
    }
}

注册到SystemService

registerService("computer", ComputerManager.class,
        new CachedServiceFetcher<ComputerManager>() {
            @Override
            public ComputerManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getServiceOrThrow("computer");
                Log.w(TAG, "createComputerService: " + b);
                return new ComputerManager(ctx, IComputerInterface.Stub.asInterface(b));
            }});

1.2. 问题记录

直接编译上面的代码,没有报错,但是系统启动后,系统服务里面并没有ComputerService,抓取日志发现添加服务被拒绝了。

12-03 08:30:55.521  1539  1539 I SystemServer: add ComputerService
12-03 08:30:55.521  1322  1322 E SELinux : avc:  denied  { add } for service=computer pid=1539 uid=1000 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0
12-03 08:30:55.521  1322  1322 E ServiceManager: add_service('computer',6a) uid=1000 - PERMISSION DENIED
12-03 08:30:55.522  1539  1539 W SystemServer: ***********************************************
12-03 08:30:55.522  1539  1539 E SystemServer: BOOT FAILURE starting ComputerService
12-03 08:30:55.522  1539  1539 E SystemServer: java.lang.SecurityException

查询得知添加系统服务时需要添加SELinux权限,需要我们手动去添加。

参考window_service,给computer服务添加权限。

system/sepolicy/prebuilts/api/26.0/nonplat_sepolicy.cil
system/sepolicy/prebuilts/api/26.0/private/service_contexts
system/sepolicy/prebuilts/api/26.0/public/service.te
system/sepolicy/private/compat/26.0/26.0.cil
system/sepolicy/private/service_contexts
system/sepolicy/public/service.te

再次重新编译后,computer服务被添加到了系统服务中。

1.3. App层调用

添加了系统服务后,在上层App中可以调用它。

@SuppressLint("WrongConstant")
private void computerServiceTest() {
    Object computer = getSystemService("computer");
    Log.d("TAG", "ComputerService: " + computer);
    Method[] ms = computer.getClass().getDeclaredMethods();
    for (Method m : ms) {
        if (m.getName().equals("plus")) {
            m.setAccessible(true);
            try {
                Object result = m.invoke(computer, 1, 2);
                Log.d("TAG", "ComputerService.plus = " + result);
            } catch (Exception e) {
                Log.d("TAG", "ComputerService.plus.e = " + e);
            }
        }
        if (m.getName().equals("reduce")) {
            m.setAccessible(true);
            try {
                Object result = m.invoke(computer, 2, 1);
                Log.d("TAG", "ComputerService.reduce = " + result);
            } catch (Exception e) {
                Log.d("TAG", "ComputerService.reduce.e = " + e);
            }
        }
    }
}

开发过程中,由于没有编译出sdk,所以通过反射的方式获取plus方法和reduce方法,然后进行调用。

参考:

results matching ""

    No results matching ""