ネイティブ サービス作成プロセス - Android 12 S コード分析に基づく

通常、カスタム システム サービスを作成するためのコード ディレクトリは次のとおりです。

フレームワーク/ネイティブ/サービス/

新しいディレクトリ名:カスタマイズ

カスタマイズの下にディレクトリ include を追加して、ヘッダー ファイルを保存します。

カスタマイズ下のディレクトリ構造は次のとおりです。
CustomizeManagerService.cpp
ICustomizeManagerService.cpp
include/CustomizeManagerService.h
include/ICustomizeManagerService.h

Android.bp

次のコンテンツを include/ICustomizeManagerService.h に追加します。

#ifndef ICustomizeManagerService_H
#define ICustomizeManagerService_H
#include <binder/IInterface.h>
#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <binder/Parcel.h>
#include <utils/String8.h>

namespace android
{
//IInterface:定义的接口,在bp以及bn都要按这个函数去实现,不允许出现多余的入参或者不同的返回值
class ICustomizeManagerService: public IInterface
{
public:
    //关联server端的实现类
    DECLARE_META_INTERFACE(CustomizeManagerService);
    //纯虚函数
    virtual int customeize() = 0;
};

//BnInterface: Server 端类
class BnCustomizeManagerService : public BnInterface<ICustomizeManagerService>
{
public:
    virtual status_t onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags = 0);
};

}; //namespace android

#endif

ICustomizeManagerService.cpp に次のコンテンツを追加します。

#undef LOG_TAG
#define LOG_TAG "ICustomizeManagerService"
#include <binder/Parcel.h>
#include <fcntl.h>
#include "ICustomizeManagerService.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <stdint.h>
#include <utils/Log.h>
#include <utils/String8.h>

namespace android {
    enum{
        CREATE = IBinder::FIRST_CALL_TRANSACTION,
        CUSTOMIZE,
    };
#define NATIVESERVICE_NAME "customizemanagerservice"
//Client 端
class BpCustomizeManagerService : public BpInterface<ICustomizeManagerService>
{
public:
    explicit BpCustomizeManagerService(const sp<IBinder>& impl)
      : BpInterface <ICustomizeManagerService>(impl)
    {
        ALOGD("create Service \n");
    }

    int customeize(){
        //client和server端的参数或者返回值传递通过Parcel
        Parcel data, reply;
        data.writeInterfaceToken(ICustomizeManagerService::getInterfaceDescriptor());
        remote()->transact(CUSTOMIZE, data, &reply);
        return reply.readInt32();
    }
};

IMPLEMENT_META_INTERFACE(CustomizeManagerService, NATIVESERVICE_NAME);
//Server 端
status_t BnCustomizeManagerService ::onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags){
    switch (code)
    {
        case CUSTOMIZE:
        {
            CHECK_INTERFACE(ICustomizeManagerService, data, reply);
            //此处方法必须和Interface中保持一致,实现是在CustomizeManagerService.cpp中实现的
            int ret = customeize();
            reply->writeInt32(ret);
            return NO_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);
     };
}
};  //namespace android


include/CustomizeManagerService.h に次の内容を追加します。

#ifndef CustomizeManagerService_H
#define CustomizeManagerService_H
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include "ICustomizeManagerService.h"
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <utils/String8.h>

namespace android {
using namespace android;

class CustomizeManagerService : public BnCustomizeManagerService  {
public:

    CustomizeManagerService();
    ~CustomizeManagerService();
    int customeize();
};
};
#endif

CustomizeManagerService.cpp に次の内容を追加します。

#undef LOG_TAG
#define LOG_TAG "CustomizeManagerService"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "CustomizeManagerService .h"
#include <utils/Log.h>
#include <utils/String8.h>
#include <android-base/properties.h>
#include <cutils/properties.h>

namespace android {
CustomizeManagerService ::CustomizeManagerService () {
    bindHidlService();
}

CustomizeManagerService ::~CustomizeManagerService () {
}


int CustomizeManagerService ::customeize() {
    int ret = 100;
    return ret;
}

};

Bn と Bp が実装される場合、IInterface の純粋な仮想メソッドはまったく同じである必要があることに注意してください。

Android 12 がネイティブ サービスをカスタマイズする場合は、次のファイルに独自のサービス名を追加する必要があることに注意してください。追加しないとエラーが報告されます。

エラー: 要件 'internal::allowedManualInterface("xxx")' により static_assert が失敗しました: 手動で作成されたバインダー インターフェイスはエラーが発生しやすいと考えられており、頻繁にバグがあります。インターフェイスを追加するための推奨される方法は、.aidl ファイルを定義してインターフェイスを自動生成することです。インターフェースを手動で記述する必要がある場合は、その名前をホワイトリストに追加してください。」

フレームワーク/ネイティブ/libs/binder/include/binder/IInterface.h

kManualInterfaces に独自のサービス名を追加するだけです。


namespace internal {
constexpr const char* const kManualInterfaces[] = {
  "android.app.IActivityManager",
  "android.app.IUidObserver",
  "android.drm.IDrm",
......
+ "customizemanagerserver",
  nullptr,
};

Android.bp

hal サービスと Ahandler へのアクセスに関連するコードが多数あります。

cc_library_shared {
    name: "libcustomizemanagerserver",

    srcs: [
        "CustomizeManagerService.cpp",
        "ICustomizeManagerService.cpp",
    ],

    shared_libs: [
        "libcutils",
        "libbinder",
        "liblog",
        "libutils",
        "libhidltransport",
        "libhidlbase",
        "[email protected]",
        "libstagefright_foundation",
        "libstagefright",
        "libmedia",
        "libmedia_codeclist",
    ],

    cflags: [
        "-Werror",
        "-Wno-error=deprecated-declarations",
        "-Wno-unused-parameter",
        "-Wall",
        "-Wunused-variable",
        "-Wswitch",
    ],
    include_dirs:[
        "frameworks/native/services/customizemanagerserver/include",
        "frameworks/av/media/libstagefright/foundation/include",
        "frameworks/av/media/libstagefright/foundation/include/media/stagefright/foundation",
    ],
    header_libs: [
        "libaudiohal_headers",
    ],
}

cc_binary {
    name: "customizemanagerserver",
    init_rc: ["customizemanagerserver.rc"],

    srcs: [
        "main_customizemanagerserver.cpp",
    ],
    shared_libs: [
        "libcutils",
        "libutils",
        "liblog",
        "libbinder",
        "libcustomizemanagerserver",
        "libhidlbase",
        "libbase",
        "libhidltransport",
        "[email protected]",
        "libstagefright_foundation",
        "libstagefright",
        "libmedia",
        "libmedia_codeclist",
    ],

    include_dirs:[
        "frameworks/native/services/customizemanagerserver/include",
        "frameworks/av/media/libstagefright/foundation/include",
        "frameworks/av/media/libstagefright/foundation/include/media/stagefright/foundation",
    ],
    cflags: [
        "-Werror",
        "-Wno-error=deprecated-declarations",
        "-Wno-unused-parameter",
        "-Wall",
    ],
    header_libs: [
        "libaudiohal_headers",
    ],
}

Custommanagerserver.rc は次のとおりです。

service customizemanagerserver  /system/bin/customizemanagerserver
    class main
    user system
    group system
    oneshot
on property:sys.boot_completed=1
    start customizemanagerserver

おすすめ

転載: blog.csdn.net/weixin_41028555/article/details/130322366