自定义系统服务首先要创建aidl文件、aidl的stub实现类以及服务的Manager类,总共涉及到三个文件,首先我们先定义文件的名称:(以下3个类为了方便可以现在androidStudio中编译)
(1)ILanceManager.aidl
(2)LanceManager.java
(3)LanceManagerService.java

1.编写AIDL文件(Stub) ILanceManager.aidl

frameworks/base/core/java/android/os/ILanceManager.aidl;

1
2
3
4
5
6
package android.os;
// Declare any non-default types here with import statements
/** *@hide */
interface ILanceManager {
String request(String msg);
}

注册AIDL(编译配置)frameworks/base/Android.dp

1
2
3
4
5
filegroup{ 
srcs: [...
"core/java/android/os/ILanceManager.aidl",
...
]}

有的aosp版本为frameworks/base/Android.mk

1
2
3
4
LOCAL_SRC_FILES+=...
core/java/android/app/IActivityManager.aidl \
core/java/com/lance/service/ILanceManager.aidl \
...

2.创建系统服务(extends Stub)LanceManagerService.java

frameworks/base/core/java/com/android/server/LanceManagerService.java

1
2
3
4
5
6
7
8
9
10
11
package com.android.service;
import android.app.ILanceManager;
import android.os.RemoteException;
import android.util.Log;
public class LanceManagerService extends ILanceManager.Stub {
@Override
public String request(String msg) throws RemoteException {
Log.e("tyl","request:"+msg);
return "LanceManagerService:"+msg;
}
}

注册系统服务:frameworks/base/core/java/android/content/Context.java 添加上下文

1
2
3
#line 3784 新增上下文
public static final String LANCE_SERVICE = "lance";//需要小写
#line 3384 将LANCE_SERVICE添加到value中

frameworks/base/services/java/com/android/server/SystemServer.java 中的startOtherServices方法中添加系统服务

1
2
import com.android.service.LanceManagerService;
ServiceManager.addService(Context.LANCE_SERVICE, new LanceManagerService());

3.创建客户端代理 LanceManager.java

frameworks/base/core/java/android/os/LanceManager.aidl;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package android.os;
import android.util.Log;

public class LanceManager {
private ILanceManager service;
/**
*@hide
*/
public LanceManager(ILanceManager iLanceManager){
this.service=iLanceManager;
}
/**
*@hide
*/
public void require(String msg){
try {
String value = service.request(msg);
Log.e("tyl","require="+value);
} catch (RemoteException e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
throw e.rethrowFromSystemServer();
}
}
}
}

注册客户端服务

frameworks/base/core/java/android/app/SystemServiceRegistry.java

1
2
3
4
5
6
7
8
9
10
11
12
13
import android.os.ILanceManager;
import android.os.LanceManager;
static {
//.....................
registerService(Context.LANCE_SERVICE, LanceManager.class,
new CachedServiceFetcher<LanceManager>() {
@Override
public LanceManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.LANCE_SERVICE);
ILanceManager service = ILanceManager.Stub.asInterface(b);
return new LanceManager(service);
}});
}

配置白名单 build/core/tasks/check_boot_jars/package_whitelist.txt(package_allowed_list.txt)

1
2
com\.android\..*//ILanceManager.aidl和LanceManager.java的路径,这里默认系统已有;
com\.enjoy\..* //如自定义文件夹则手动添加,例如enjoy为文件名;

3.添加SELinux权限

3.1 service_contexts

a. system/sepolicy/private/service_contexts文件
b. system/sepolicy/prebuilts/api/28.0/private/service_contexts文件
c. system/sepolicy/prebuilts/api/27.0/private/service_contexts文件
d. system/sepolicy/prebuilts/api/26.0/private/service_contexts文件
添加内容如下(注意这文件内容及格式都需要一致,要不然编译通不过

1
lance                                     u:object_r:lance_service:s0

3.2 service.te (未编译其他版本的报错,其他文件的其他版本未编译也make成功了)

a. system/sepolicy/public/service.te文件
b. system/sepolicy/prebuilts/api/28.0/public/service.te文件
c. system/sepolicy/prebuilts/api/27.0/public/service.te文件
d. system/sepolicy/prebuilts/api/26.0/public/service.te文件
添加内容如下(注意这文件内容及格式都需要一致,要不然编译通不过

1
type lance_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;

3.3 untrusted_app.te

a. system/sepolicy/private/untrusted_app文件
b. system/sepolicy/prebuilts/api/28.0/private/untrusted_app文件
c. system/sepolicy/prebuilts/api/27.0/private/untrusted_app文件
d.system/sepolicy/prebuilts/api/26.0/private/untrusted_app文件
添加内容如下(注意这文件内容及格式都需要一致,要不然编译通不过

1
allow untrusted_app_all lance_service:service_manager find;

3.4

添加完之后,使用make update-api更新

image-20230510111816106

上面报错是因为是系统api,所以在ILanceManager和LanceManager的方法中加上 /** @hide */

make update-api编译通过后执行make -j20

4.调用自定义服务

4.1利用java的双亲委派机制,在自己的工程中引入这些自定义服务相关联的类,这样就可以直接使用这些类了,不需要用到反射

1
2
3
//activity中执行
LanceManager service = (LanceManager) getSystemService("lance");
service.require("hhh");
1
2
3
4
5
6
7
8
package android.os;
//只保留LanceManager这个类即可,其他类不需要;
//包名需与源码一致
public class LanceManager这个类即可,其他类不需要; {
public String require(String msg){
return null;
}
}

我这里报错:No virtual method require(Ljava/lang/String;)Ljava/lang/String; in class Landroid/os/LanceManager; or its super classes (declaration of ‘android.os.LanceManager’ appears in /system/framework/framework.jar!classes2.dex)大致意思是已经有一个相同包名的类出现,不确定是不是因为android11加入了什么检查机制,目前没找到解决方案;

4.2 修改sdk的方式调用(两种方案:)

1.AOSP Make SDK替换原本的SDK,

2.把AOSP中编译的LanceManager添加到原本的SDK中;

下面路径拿到LanceManager.java和Context.java

1
2
3
out/target/common/obj/JAVA_LIBRARIES/framwrork_intermediates/class.jar(改成zip后解压)/android/os/LanceManager.java

out/target/common/obj/JAVA_LIBRARIES/framwrork_intermediates/class.jar(改成zip后解压)/android/content/Context.java

打开Studiod的SDK路径/platforms/android-30(这里和studio的demo版本对应)将android.jar备份1份防止出错,将android.jar改为android.zip,再对应Context.java和LanceManager.java的包名复制进去后重新改为jar文件;