目标
1,创建一个系统服务, TestService
2,在android11中使用getSystemService方法获取该服务并调用里面的方法。
环境
开发板: rk3568
Android系统: android 11
编译环境: ubuntu 20.04 deskop
添加系统服务步骤
定义系统服务aidl接口和代理manager类
因为系统服务是运行在system_server进程中,所以app要调用我们的自定义service需通过跨进程通讯,Android中跨进程通讯使用AIDL,所以我们这里定义一个ITestManager.aidl文件,另外还需要定一个服务的代理manager类,用于app调用。
1).在/frameworks/base目录下新建一个文件夹myservice,在myservice目录下新建/java/android/mymodule/test 目录,可以根据自己的需要命名。
在/frameworks/base/myservice/java/android/mymodule/test目录下存放ITestManager.aidl,及TestManager.java。用作系统服务的客户端代理。
ITestManager.aidl及 TestManager.java内容如下:
package android.mymodule.test;
interface ITestManager {
void testMethod();
}
package android.mymodule.test;
import android.util.Slog;
import android.os.RemoteException;
import android.annotation.SystemService;
import android.content.Context;
public class TestManager {
private final ITestManager mService;
public TestManager(ITestManager mService) {
//这里把ITestManager传进来,可以看看系统其它service,都是这样写的
this.mService = mService;
}
public void testMethod() {
try {
mService.testMethod();
Slog.i("add_service_test", "TestManager testMethod:");
} catch (RemoteException ex) {
ex.printStackTrace();
}
}
// public native String stringFromJNI();
}
2). 在base/Android.bp 添加下面patch内容,把刚建立TestManager 和aidl文件加入android的编译文件中。
diff --git a/Android.bp b/Android.bp
index bf6c99d0cf29..3f0e1d4f9b03 100644
--- a/Android.bp
+++ b/Android.bp
@@ -216,6 +216,16 @@ filegroup {
path: "mms/java",
}
+filegroup {
+ name: "framework-myservice-source",
+ srcs: [
+ "myservice/java/**/*.java",
+ "myservice/java/**/*.aidl",
+ ],
+ path: "myservice/java",
+}
+
+
filegroup {
name: "framework-non-updatable-sources",
srcs: [
@@ -286,6 +296,7 @@ filegroup {
":framework-statsd-sources",
":framework-tethering-srcs",
":framework-wifi-updatable-sources",
+ ":framework-myservice-source",
":updatable-media-srcs",
]
}
@@ -1219,8 +1230,10 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x
"--api-lint-ignore-prefix android.icu. " +
"--api-lint-ignore-prefix java. " +
"--api-lint-ignore-prefix junit. " +
+ "--api-lint-ignore-prefix android.mymodule. "+
"--api-lint-ignore-prefix org. "
+
build = [
"StubLibraries.bp",
"ApiDocs.bp",
添加系统服务TestService
在/frameworks/base/core/java/com/android/server 目录下添加自己的service文件, 继承自ITestManager.stub。我这边建了个TestService.java, 内容如下:
package com.android.server;
import android.content.Context;
import android.util.Slog;
import android.wqmodule.test.ITestManager;
//这里的ITestManager.Stub是固定写法
public class TestService extends ITestManager.Stub {
private final Context mContext;
public TestService(Context context) {
super();
mContext = context;
}
public void testMethod() {
// 测试方法,为了测试执行情况,在这里加log
Slog.i("add_service_test", "TestService getString " +);
}
}
将TestService 加入到android的系统服务
(1)添加string 变量TEST_SERVICE = "test" 到系统中,这样客户端可以使用 getSystemService(Context.TEST_SERVICE) 获取客户端的实例
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8472144a92cf..93b22eed6e94 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3494,6 +3494,7 @@ public abstract class Context {
//@hide: TIME_ZONE_DETECTOR_SERVICE,
PERMISSION_SERVICE,
LIGHTS_SERVICE,
+ TEST_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -3812,6 +3813,8 @@ public abstract class Context {
*/
public static final String ALARM_SERVICE = "alarm";
+ public static final String TEST_SERVICE = "test";
+
/**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.app.NotificationManager} for informing the user of
(2)修改 frameworks/base/services/java/com/android/server/SystemServer.java 文件,在 startOtherServices 方法里面增加以下代码:
// add test service
t.traceBegin("TestService");
ServiceManager.addService(Context.TEST_SERVICE, new TestService(context));
t.traceEnd();
(3) 在frameworks/base/core/java/com/android/app/SystemServiceRegistry.java 注册TestManager
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index e599a5ce81ef..701a56503988 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -213,6 +213,8 @@ import com.android.internal.util.Preconditions;
import java.util.Map;
import java.util.Objects;
+import android.mymodule.test.TestManager;
+import android.mymodule.test.ITestManager;
/**
* Manages all of the system services that can be returned by {@link Context#getSystemService}.
* Used by {@link ContextImpl}.
@@ -257,6 +259,15 @@ public final class SystemServiceRegistry {
return new CaptioningManager(ctx);
}});
+ registerService(Context.TEST_SERVICE,TestManager.class,
+ new CachedServiceFetcher(){
+ @Override
+ public TestManager createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(Context.TEST_SERVICE);
+ Log.i("add_service_test","SystemServiceRegistry registerService method");
+ return new TestManager(ITestManager.Stub.asInterface(b));
+ }});
+
registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
new CachedServiceFetcher() {
@Override
Selinux 规则设置
Android 11的 selinux 规则是放在 system/sepolicy 目录下的。注意需要修改所有的service.te和service_contexts文件,可以参考network_time_update_service 来修改。修改的patch 如下:
diff --git a/prebuilts/api/30.0/public/service.te b/prebuilts/api/30.0/public/service.te
index f27772eab..03792dd74 100644
--- a/prebuilts/api/30.0/public/service.te
+++ b/prebuilts/api/30.0/public/service.te
@@ -39,6 +39,7 @@ type vold_service, service_manager_type;
type vr_hwc_service, service_manager_type;
type vrflinger_vsync_service, service_manager_type;
+
# system_server_services broken down
type accessibility_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
type account_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
@@ -134,6 +135,7 @@ type netstats_service, app_api_service, ephemeral_app_api_service, system_server
type network_management_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
type network_score_service, system_api_service, system_server_service, service_manager_type;
type network_stack_service, system_server_service, service_manager_type;
+type test_service, system_server_service, service_manager_type;
type network_time_update_service, system_server_service, service_manager_type;
type notification_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
type oem_lock_service, system_api_service, system_server_service, service_manager_type;
diff --git a/private/service_contexts b/private/service_contexts
index 5c6f1a476..10d4315e3 100644
--- a/private/service_contexts
+++ b/private/service_contexts
@@ -150,6 +150,7 @@ network_stack u:object_r:network_stack_service:s0
network_management u:object_r:network_management_service:s0
network_score u:object_r:network_score_service:s0
network_time_update_service u:object_r:network_time_update_service:s0
+test_service u:object_r:test_service:s0
nfc u:object_r:nfc_service:s0
notification u:object_r:notification_service:s0
oem_lock u:object_r:oem_lock_service:s0
diff --git a/public/service.te b/public/service.te
index f27772eab..b92f169c8 100644
--- a/public/service.te
+++ b/public/service.te
@@ -135,6 +135,7 @@ type network_management_service, app_api_service, ephemeral_app_api_service, sys
type network_score_service, system_api_service, system_server_service, service_manager_type;
type network_stack_service, system_server_service, service_manager_type;
type network_time_update_service, system_server_service, service_manager_type;
+type test_service, system_server_service, service_manager_type;
type notification_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
type oem_lock_service, system_api_service, system_server_service, service_manager_type;
type otadexopt_service, system_server_service, service_manager_type;
编译
切记一定要先在根目录执行make update-api更新一下 api 接口,再整编系统。否则会报错
测试service添加是否成功
adb shell下运行service list | grep Test
可以看到
154 test: [android.mymodule.test.ITestManager]
说明添加成功
app调用
-
拷贝代码
app 开发的时候因为没有引用修改后的framework.jar, 可以先把aidl 和 manager 代码拷贝到项目中。注意包名需要和在framework添加的一致。
-
编写测试测试代码
在mainActivity中添加一个button,添加button的点击事件测试service的调用
testBtn.setOnClickListener { val myManager = getSystemService("test") as TestManager myManager.testMethod() }
遇到的坑及解决方法
1.make update-api报错:
/frameworks/base/myservice/java/android/mymodule/test/ITestManager.java:105: e
rror: Missing nullability on parameter `impl` in method `setDefaultImpl` [Miss
ingNullability]
out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/srcjars
/frameworks/base/myservice/java/android/mymodule/test/ITestManager.java:118: e
rror: Missing nullability on method `getDefaultImpl` return [MissingNullabilit
y]
frameworks/base/myservice/java/android/mymodule/test/TestManager.java:12: erro
r: Managers must always be obtained from Context; no direct constructors [Mana
gerConstructor]
frameworks/base/myservice/java/android/mymodule/test/TestManager.java:12: erro
r: Missing nullability on parameter `mService` in method `TestManager` [Missin
gNullability]
14 new API lint issues were found.
See tools/metalava/API-LINT.md for how to handle these.
metalava detected access to files that are not explicitly specified. See /medi
a/wxkly/wxkly3/ROCKCHIP_ANDROID11.0_SDK_RELEASE/out/soong/.intermediates/frame
works/base/api-stubs-docs/android_common/api-stubs-docs-violations.txt for det
ails.
$************************************************************\nYour API change
s are triggering API Lint warnings or errors.\nTo make these errors go away, f
ix the code according to the\nerror and/or warning messages above.\n\nIf it is
not possible to do so, there are workarounds:\n\n1. You can suppress the erro
rs with @SuppressLint("")\n2. You can update the baseline by executing the
following\n command:\n cp \\\n "/media/wxkly/wxkly3/ROCKCHIP_AN
DROID11.0_SDK_RELEASE$/out/soong/.intermediates/frameworks/base/api-stubs-docs
/android_common/api_lint_baseline.txt" \\\n "/media/wxkly/wxkly3/ROCKCHI
P_ANDROID11.0_SDK_RELEASE$/frameworks/base/api/lint-baseline.txt"\n To submi
t the revised baseline.txt to the main Android\n repository, you will need a
pproval.\n************************************************************\n
解决方法:
这个问题是因为 Android 11 开启了lint代码检查,所以我们需要在framework/base 下的Android.bp忽略掉代码检查
metalava_framework_docs_args = "
"--api-lint-ignore-prefix android.mymodule. "
其中 android.mymodule是包名的前缀。