Android P中如何自定義一個系統Service

1. Context中新建service name

frameworks/base/core/java/android/content/Context.java

public static final String JUSTART_SERVICE = "justart";

2. 創建aidl文件

frameworks/base/core/java/android/app/IJustArt.aidl

package android.app;

/**
 * Created by justart on 2019/3/21.
 */

interface IJustArt {
    String getAllWifiInfo();
}

這裏的IJustArt.aidl負責APP端和system_server中的自定義service 通信

3. Android.bp 配置

frameworks/base/Android.bp

         "core/java/android/app/IActivityManager.aidl",
+        "core/java/android/app/IJustArt.aidl",

找一個熟悉的系統service對應的aidl文件,在下面添加一條即可。只有在這裏配置之後編譯系統才能找到他,將它編譯生成IJustArt.java,編譯之後的文件生成在 :\out\soong\.intermediates\frameworks\base\framework\android_common\gen\aidl\frameworks\base\core\java\android\app\IJustArt.java

4. service下創建自定義Service

frameworks/base/services/core/java/com/android/server/justart/JustArtService.java

package com.android.server.justart;

import android.os.RemoteException;

import android.app.IJustArt;

/**
 * Created by justart on 2019/3/21.
 */

public class JustArtService extends IJustArt.Stub{
    private final static String TAG = "JustArtService";
    public JustArtService(){

    }
    @Override
    public String getAllWifiInfo() throws RemoteException {
        String str = "this is justart test string demo haha";
        return str;
    }
}

個人在server目錄下創建一個justart文件夾,然後新建JustArtService,這裏僅有一個方法用來測試。

5. 創建Service對應APP端的manager類

frameworks/base/core/java/android/app/JustArt.java

package android.app;

import android.content.Context;
import android.os.RemoteException;
/**
 * Created by justart on 2019/3/21.
 */

public class JustArt {
    IJustArt service;
    Context mContext;
    public JustArt(Context context, IJustArt justArt){
        mContext = context;
        service = justArt;
    }
    public String getAllWifiInfo(){
        try {
            return service.getAllWifiInfo();
        } catch (RemoteException e) {
            e.printStackTrace();
            return null;
        }
    }

}

這個manager的作用具體是幹什麼呢?其實就對service中的方法的管理。

6. system_server 啓動管理service

frameworks/base/services/java/com/android/server/SystemServer.java

+//add by justart for debug
+import com.android.server.justart.JustArtService;

 public final class SystemServer {
        startOtherServices(){
            ....
+            //add by justart for debug
+            ServiceManager.addService(Context.JUSTART_SERVICE, new JustArtService());
            ...
    }
}

在system_server啓動時候將這個service 添加到ServiceManager統一管理,以便其他進程或者線程獲取這個service。

7. SystemServiceRegistry註冊自定義service

frameworks/base/core/java/android/app/SystemServiceRegistry.java

registerService(Context.JUSTART_SERVICE, JustArt.class,
        new CachedServiceFetcher<JustArt>() {
    @Override
    public JustArt createService(ContextImpl ctx) {
        IBinder b = ServiceManager.getService(Context.JUSTART_SERVICE);
        IJustArt service = IJustArt.Stub.asInterface(b);
        return new JustArt(ctx,service);
    }});

在SystemServiceRegistry文件中找到一個熟悉的系統service比如ActivityManagerService的register代碼字節copy,修改其中的Service名字已經對應manager類。這裏就是負責給service綁定一個manager,也就是前面的JustArt.java。

這裏代碼相關的東西就配置完成,下面需要設置相關的SeLinux權限。

8. 配置SeLinux

8.1 service.te

(1)system/sepolicy/public/service.te

type justart_service, system_api_service, system_server_service, service_manager_type;

最後一行添加上面一句話即可。(抄襲ActivityManager的配置)

Android P 中規定與該目錄保持一致的還有:

(2)system/sepolicy/prebuilts/api/28.0/public/service.te

type justart_service, system_api_service, system_server_service, service_manager_type;

所以這個裏面也要和上面service.te 內容保持一致,記住是完全一致(位置,格式...最好直接copy過來到相同位置)

8.2 service_contexts

(1)system/sepolicy/private/service_contexts

 activity                                  u:object_r:activity_service:s0
 justart                                   u:object_r:justart_service:s0
 alarm                                     u:object_r:alarm_service:s0

中間找個位置添加自己的service權限,和activity規範保持一致即可,前面寫Context.java中新建的名字。後面部分在後面追加_service。

Android P 中規定與該目錄保持一致的還有

(2)system/sepolicy/prebuilts/api/28.0/private/service_contexts

所以這個裏面也要和上面service_contexts 內容保持一致,記住是完全一致(位置,格式...最好直接copy過來到相同位置)

8.3 service定義typeattribute

(1)system/sepolicy/prebuilts/api/26.0/nonplat_sepolicy.cil

(typeattribute justart_service_26_0)
(roletype object_r justart_service_26_0)

在上面文件中添加如上兩行,(可以借鑑AMS定義)

(2)system/sepolicy/prebuilts/api/27.0/nonplat_sepolicy.cil

(typeattribute justart_service_27_0)
(roletype object_r justart_service_27_0)

在上面文件中添加如上兩行,(可以借鑑AMS定義)

8.4 配置typeattributesset

(1)system/sepolicy/private/compat/26.0/26.0.cil

(typeattributeset justart_service_26_0 (justart_service))

(2)system/sepolicy/private/compat/27.0/27.0.cil

(typeattributeset justart_service_27_0 (justart_service))

(3)system/sepolicy/prebuilts/api/28.0/private/compat/26.0/26.0.cil

(typeattributeset justart_service_26_0 (justart_service))

同(1)保持一致,格式,位置,內容完全一樣,建議都放在最後一行。

(4)system/sepolicy/prebuilts/api/28.0/private/compat/27.0/27.0.cil

(typeattributeset justart_service_27_0 (justart_service))

同(2)保持一致,格式,位置,內容完全一樣,建議都放在最後一行。

到這裏所有的selinux權限相關配置完成,不得不說android P上selinux配置東西真的多,感嘆系統越做越安全,哈哈。

android P之前都可以反射調用系統service,android P之後都被hidden了。

9. make update-api

執行make update-api 更新源碼api再編譯即可。

make update-api 

什麼時候需要執行這個編譯選項呢?

  • 添加系統API或者修改@hide的API後;

  • 修改公共api後。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章