Android 11系統(tǒng)服務(wù)的添加(java 層)

目標(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ù)的客戶端代理浅妆。

category.png

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)用

  1. 拷貝代碼

    app 開發(fā)的時(shí)候因?yàn)闆]有引用修改后的framework.jar, 可以先把a(bǔ)idl 和 manager 代碼拷貝到項(xiàng)目中愤炸。注意包名需要和在framework添加的一致期揪。

app_manager.png
  1. 編寫測(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是包名的前綴凤薛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诞仓,隨后出現(xiàn)的幾起案子缤苫,更是在濱河造成了極大的恐慌,老刑警劉巖墅拭,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件活玲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡谍婉,警方通過查閱死者的電腦和手機(jī)舒憾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來穗熬,“玉大人镀迂,你說我怎么就攤上這事∷缆剑” “怎么了招拙?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長措译。 經(jīng)常有香客問我,道長饰序,這世上最難降的妖魔是什么领虹? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮求豫,結(jié)果婚禮上塌衰,老公的妹妹穿的比我還像新娘诉稍。我一直安慰自己,他們只是感情好最疆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布杯巨。 她就那樣靜靜地躺著,像睡著了一般努酸。 火紅的嫁衣襯著肌膚如雪服爷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天获诈,我揣著相機(jī)與錄音仍源,去河邊找鬼。 笑死舔涎,一個(gè)胖子當(dāng)著我的面吹牛笼踩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亡嫌,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼嚎于,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了挟冠?” 一聲冷哼從身側(cè)響起匾旭,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎圃郊,沒想到半個(gè)月后价涝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡持舆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年色瘩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逸寓。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡居兆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出竹伸,到底是詐尸還是另有隱情泥栖,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布勋篓,位于F島的核電站吧享,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏譬嚣。R本人自食惡果不足惜钢颂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拜银。 院中可真熱鬧殊鞭,春花似錦遭垛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至趾盐,卻和暖如春庶喜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谤碳。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工溃卡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜒简。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓瘸羡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親搓茬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子犹赖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容