Native Service creation process - based on Android 12 S code analysis

Generally, the code directory for creating custom system services is:

frameworks/native/services/

New directory name: customize

Add a directory include under customize to store header files.

The directory structure under customize is as follows:
CustomizeManagerService.cpp
ICustomizeManagerService.cpp
include/CustomizeManagerService.h
include/ICustomizeManagerService.h

Android.bp

Add the following content in 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

Add the following content in 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


Add the following content in 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

Add the following content in 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;
}

};

It should be noted that the pure virtual method in IInterface must be exactly the same when Bn and Bp are implemented.

It should be noted that when Android 12 customizes the native service, you need to add your own service name in the following file, otherwise an error will be reported:

error: static_assert failed due to requirement 'internal::allowedManualInterface("xxx")' : Manually written binder interfaces are considered error prone and frequently have bugs. The preferred way to add interfaces is to define an .aidl file to auto-generate the interface. If an interface must be manually written, add its name to the whitelist."

frameworks/native/libs/binder/include/binder/IInterface.h

Just add your own service name in kManualInterfaces:


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

Android.bp

There are a lot of codes related to accessing hal services and 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",
    ],
}

customizemanagerserver.rc is as follows:

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

Guess you like

Origin blog.csdn.net/weixin_41028555/article/details/130322366