Skip to content

Instantly share code, notes, and snippets.

@spiritedRunning
Last active January 14, 2024 15:35
Show Gist options
  • Save spiritedRunning/654c4f61989a9c7205341c788b95a74c to your computer and use it in GitHub Desktop.
Save spiritedRunning/654c4f61989a9c7205341c788b95a74c to your computer and use it in GitHub Desktop.
C++ binder demo
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/Binder.h>
//#include <utils/Log.h>
using namespace android;
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "BINDER_SERVICE"
#define BINDER_SERVICE "binder_server_end"
#define BINDER_CALLBACK "binder_callback"
#define FIRST_CODE 1
#define CALLBACK_CODE 2
class ClientCallback : public BBinder
{
public:
ClientCallback()
{
ALOGE("zach ClientCallback initialized");
desc = String16(BINDER_CALLBACK);
}
virtual ~ClientCallback() {}
virtual const String16& getInterfaceDescriptor() const {
return desc;
}
protected:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) {
ALOGD("zach Client onTransact, line: %d, code: %d", __LINE__, code);
int v1, v2, v3;
String8 s1, s2, s3;
switch (code)
{
case CALLBACK_CODE:
v1 = data.readInt32();
v2 = data.readInt32();
v3 = data.readInt32();
ALOGE("zach Client %d, read v1: %d", __LINE__, v1);
ALOGE("zach Client %d, read v2: %d", __LINE__, v2);
ALOGE("zach Client %d, read v3: %d", __LINE__, v3);
s1 = data.readString8();
s2 = data.readString8();
s3 = data.readString8();
ALOGE("zach Client %d, read String s1: %s", __LINE__, s1.string());
ALOGE("zach Client %d, read String s2: %s", __LINE__, s2.string());
ALOGE("zach Client %d, read String s3: %s", __LINE__, s3.string());
break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
return 0;
}
private:
String16 desc;
};
int main() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> iBinder = sm->getService(String16(BINDER_SERVICE));
if (iBinder == nullptr) {
ALOGW("zach Can't find binder service");
return -1;
}
Parcel _data, _reply;
ClientCallback *callback = new ClientCallback();
_data.writeStrongBinder(sp<IBinder>(callback));
_data.writeInterfaceToken(String16(BINDER_CALLBACK));
int ret = iBinder->transact(FIRST_CODE, _data, &_reply, 0);
ALOGI("zach Client transact ret: %d", ret);
IPCThreadState::self()->joinThreadPool();
ALOGI("zach Client joinThreadPool complete");
return 0;
}
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
//#include <utils/Log.h>
using namespace android;
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "BINDER_SERVICE"
#define BINDER_SERVICE "binder_server_end"
#define BINDER_CALLBACK "binder_callback"
#define FIRST_CODE 1
#define CALLBACK_CODE 2
class BinderService : public BBinder {
public:
BinderService() {
ALOGE("zach BinderService server started");
desc = String16(BINDER_SERVICE);
}
virtual ~BinderService() {}
virtual const String16& getInterfaceDescriptor() const {
return desc;
}
protected:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) {
ALOGD("zach Server onTrancat, line = %d, code = %d", __LINE__, code);
switch (code)
{
case FIRST_CODE:
callback = data.readStrongBinder();
if (callback != NULL) {
Parcel _data, _reply;
_data.writeInt32(1);
_data.writeInt32(3);
_data.writeInt32(5);
_data.writeString8(String8("I"));
_data.writeString8(String8("am"));
_data.writeString8(String8("here"));
int ret = callback->transact(CALLBACK_CODE, _data, &_reply, 0);
ALOGI("zach Server callback transact ret: %d", ret);
}
data.enforceInterface(u"binder_callback", true); // corresponding to writeInterfaceToken()
ALOGD("zach Service write callback to client, line: %d", __LINE__);
break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
return 0;
}
private:
String16 desc;
sp<IBinder> callback;
};
int main() {
sp<IServiceManager> sm = defaultServiceManager();
BinderService* binderServer = new BinderService();
status_t ret = sm->addService(String16(BINDER_SERVICE), binderServer);
ALOGD("zach add Binder service to service manager, ret = %d", ret);
IPCThreadState::self()->joinThreadPool(true);
ALOGD("zach IPCThreadState joinThreadPool end");
return 0;
}
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := binder_client.cpp
LOCAL_SHARED_LIBRARIES := liblog libcutils libbinder libutils
LOCAL_MODULE := binder_client
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := binder_server.cpp
LOCAL_SHARED_LIBRARIES := liblog libcutils libbinder libutils
LOCAL_MODULE := binder_server
include $(BUILD_EXECUTABLE)
adb shell logcat -c ; adb shell logcat |grep BINDER_SERVICE
11-26 11:04:23.719 4876 4876 E BINDER_SERVICE: zach BinderService server started
11-26 11:04:23.720 4876 4876 D BINDER_SERVICE: zach add Binder service to service manager, ret = 0
11-26 11:04:30.581 4889 4889 E BINDER_SERVICE: zach ClientCallback initialized
11-26 11:04:30.589 4876 4876 D BINDER_SERVICE: zach Server onTrancat, line = 38, code = 1
11-26 11:04:30.589 4889 4889 D BINDER_SERVICE: zach Client onTransact, line: 43, code: 2
11-26 11:04:30.589 4889 4889 E BINDER_SERVICE: zach Client 55, read v1: 1
11-26 11:04:30.589 4889 4889 E BINDER_SERVICE: zach Client 56, read v2: 3
11-26 11:04:30.589 4889 4889 E BINDER_SERVICE: zach Client 57, read v3: 5
11-26 11:04:30.589 4889 4889 E BINDER_SERVICE: zach Client 63, read String s1: I
11-26 11:04:30.589 4889 4889 E BINDER_SERVICE: zach Client 64, read String s2: am
11-26 11:04:30.589 4889 4889 E BINDER_SERVICE: zach Client 65, read String s3: here
11-26 11:04:30.589 4876 4876 I BINDER_SERVICE: zach Server callback transact ret: 0
11-26 11:04:30.589 4876 4876 D BINDER_SERVICE: zach Service write callback to client, line: 59
11-26 11:04:30.589 4889 4889 I BINDER_SERVICE: zach Client transact ret: 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment