DarkSoda
DarkSoda

Reputation: 93

How can a C++ client bind to AIDL service on Android?

This is what I want to achieve

I used aidl binary to generate some .cpp and .h from my IMyService.aidl, but when trying to compile them with my C++ program, these generated C++ files refer to some other header files such as "<binder/IBinder.h>" which are not part of NDK. Instead, they are part of AOSP framework. I am new to AOSP framework, so my question is how to build a C++ standalone program with reference to AOSP framework? How do I set up the build environment so my build can find those files in AOSP framework?

I did some research and found this article, but still I cannot find my answers after reading it.

Thanks!

Upvotes: 4

Views: 667

Answers (1)

Lakindu
Lakindu

Reputation: 950

Let's take a look at the logcat system service to understand how to bind to a Java service from a C++ standalone program.

Use https://cs.android.com/android to search for the actual code in AOSP.

AIDL

frameworks/base/core/java/android/os/logcat/ILogcatManagerService.aidl

interface ILogcatManagerService {
    void startThread(in int uid, in int gid, in int pid, in int fd);
    void finishThread(in int uid, in int gid, in int pid, in int fd);
}

Java system service

frameworks/base/services/core/java/com/android/server/logcat/LogcatManagerService.java

import com.android.server.SystemService;
import android.os.logcat.ILogcatManagerService;

public final class LogcatManagerService extends SystemService {
    // Service implementation
    private final class BinderService extends ILogcatManagerService.Stub {
        @Override
        public void startThread(int uid, int gid, int pid, int fd) { ... }

        @Override
        public void finishThread(int uid, int gid, int pid, int fd) { ... }
    }

    public LogcatManagerService(Context context, ...) {
        super(context);
        mBinderService = new BinderService();
    }

    @Override
    public void onStart() {
        // Publish the binder service
        publishBinderService("logcat", mBinderService);
    }
}

C++ standalone program

system/logging/logd/LogReaderList.cpp

#include <android/os/logcat/ILogcatManagerService.h>
#include <binder/IServiceManager.h>

using android::defaultServiceManager;
using android::sp;

sp<ILogcatManagerService> logcat_service = android::interface_cast<ILogcatManagerService>(
    defaultServiceManager()->waitForService(String16("logcat"))
);

logcat_service->startThread(...);
logcat_service->finishThread(...);

Build configuration of the Java system service

frameworks/base/core/java/Android.bp

aidl_library {
    name: "ILogcatManagerService_aidl",
    srcs: ["android/os/logcat/ILogcatManagerService.aidl"],
}

frameworks/base/services/Android.bp

// All system services are packages into the services.jar
java_library {
    name: "services",
    srcs: [":services-main-sources"],
}

filegroup {
    name: "services-main-sources",
    srcs: [
        "java/**/*.java",
        "java/**/package.html",
    ],
    path: "java",
    visibility: ["//visibility:private"],
}

Build configuration of the C++ standalone program

system/logging/logd/Android.bp

cc_binary {
    name: "logd",
    // logd standalone program is executed at system startup via init.rc
    init_rc: ["logd.rc"],

    srcs: [
        "main.cpp",
        ...
    ],

    static_libs: [
        "liblogd",
        ...
    ],

    aidl: {
        libs: [
            "ILogcatManagerService_aidl",
        ]
    }
}

cc_library_static {
    name: "liblogd",
    srcs: [
        "LogReaderList.cpp",
        ...
    ],

    aidl: {
        libs: [
            "ILogcatManagerService_aidl",
        ],
    },
}

You may have to define SELiux policies as well for your services.

Upvotes: 0

Related Questions