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(){
+        @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调用

  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("")\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是包名的前缀。

你可能感兴趣的:(Android 11系统服务的添加(java 层))