目標(biāo)
1,創(chuàng)建一個(gè)系統(tǒng)服務(wù), TestService
2,在android11中使用getSystemService方法獲取該服務(wù)并調(diào)用里面的方法。
環(huán)境
開發(fā)板: rk3568
Android系統(tǒng): android 11
編譯環(huán)境: ubuntu 20.04 deskop
添加系統(tǒng)服務(wù)步驟
定義系統(tǒng)服務(wù)aidl接口和代理manager類
因?yàn)橄到y(tǒng)服務(wù)是運(yùn)行在system_server進(jìn)程中碎乃,所以app要調(diào)用我們的自定義service需通過跨進(jìn)程通訊蝶怔,Android中跨進(jìn)程通訊使用AIDL捎迫,所以我們這里定義一個(gè)ITestManager.aidl文件初茶,另外還需要定一個(gè)服務(wù)的代理manager類螺戳,用于app調(diào)用盖腿。
1).在/frameworks/base目錄下新建一個(gè)文件夾myservice翩腐,在myservice目錄下新建/java/android/mymodule/test 目錄,可以根據(jù)自己的需要命名。
在/frameworks/base/myservice/java/android/mymodule/test目錄下存放ITestManager.aidl,及TestManager.java泥畅。用作系統(tǒng)服務(wù)的客戶端代理浅妆。
ITestManager.aidl及 TestManager.java內(nèi)容如下:
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傳進(jìn)來摄欲,可以看看系統(tǒng)其它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內(nèi)容按咒,把剛建立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",
添加系統(tǒng)服務(wù)TestService
在/frameworks/base/core/java/com/android/server 目錄下添加自己的service文件, 繼承自ITestManager.stub吼野。我這邊建了個(gè)TestService.java, 內(nèi)容如下:
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() {
// 測(cè)試方法,為了測(cè)試執(zhí)行情況阳准,在這里加log
Slog.i("add_service_test", "TestService getString " +);
}
}
將TestService 加入到android的系統(tǒng)服務(wù)
(1)添加string 變量TEST_SERVICE = "test" 到系統(tǒng)中,這樣客戶端可以使用 getSystemService(Context.TEST_SERVICE) 獲取客戶端的實(shí)例
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 注冊(cè)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<TestManager>(){
+ @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<AccountManager>() {
@Override
Selinux 規(guī)則設(shè)置
Android 11的 selinux 規(guī)則是放在 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;
編譯
切記一定要先在根目錄執(zhí)行make update-api更新一下 api 接口卧蜓,再整編系統(tǒng)盛霎。否則會(huì)報(bào)錯(cuò)
測(cè)試service添加是否成功
adb shell下運(yùn)行service list | grep Test
可以看到
154 test: [android.mymodule.test.ITestManager]
說明添加成功
app調(diào)用
-
拷貝代碼
app 開發(fā)的時(shí)候因?yàn)闆]有引用修改后的framework.jar, 可以先把a(bǔ)idl 和 manager 代碼拷貝到項(xiàng)目中愤炸。注意包名需要和在framework添加的一致期揪。
-
編寫測(cè)試測(cè)試代碼
在mainActivity中添加一個(gè)button,添加button的點(diǎn)擊事件測(cè)試service的調(diào)用
testBtn.setOnClickListener { val myManager = getSystemService("test") as TestManager myManager.testMethod() }
遇到的坑及解決方法
1.make update-api報(bào)錯(cuò):
/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("<id>")\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
解決方法:
這個(gè)問題是因?yàn)?Android 11 開啟了lint代碼檢查规个,所以我們需要在framework/base 下的Android.bp忽略掉代碼檢查
metalava_framework_docs_args = "
"--api-lint-ignore-prefix android.mymodule. "
其中 android.mymodule是包名的前綴凤薛。