Android 11系统服务的添加(java 层)

目标

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。用作系统服务的客户端代理。

category.png

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<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 规则设置

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

  1. 拷贝代码

    app 开发的时候因为没有引用修改后的framework.jar, 可以先把aidl 和 manager 代码拷贝到项目中。注意包名需要和在framework添加的一致。

app_manager.png
  1. 编写测试测试代码

    在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("<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

解决方法:

这个问题是因为 Android 11 开启了lint代码检查,所以我们需要在framework/base 下的Android.bp忽略掉代码检查

metalava_framework_docs_args = "
"--api-lint-ignore-prefix android.mymodule. "

其中 android.mymodule是包名的前缀。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,135评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,317评论 3 397
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,596评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,481评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,492评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,153评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,737评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,657评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,193评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,276评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,420评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,093评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,783评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,262评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,787评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,427评论 2 359

推荐阅读更多精彩内容