1.1. AOSP添加SystemService
1.1.1. 整体步骤
定义服务接口文件(aidl文件)
实现服务接口(...Service.java)
添加aidl文件到编译脚本(./framework/base/Android.mk)
添加服务到SystemServer(ServiceManager.addService)
添加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);
}
该接口文件包含两个函数,plus和reduce。
一般系统服务的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;
}
}
服务实现了plus和reduce功能。
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方法,然后进行调用。
参考: