Android内核之Binder消息处理:binder_transaction用法实例(七十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🌻1.前言

本篇目的:Android内核之Binder消息处理:binder_transaction用法实例

🌻2.Android内核binder_transaction介绍

  • binder_transaction 函数是 Android Binder 驱动中的一个核心函数,它用于在 Binder 机制中实现客户端向服务端发送请求并接收响应的过程。以下是对 binder_transaction 函数作用的详细介绍:

  • 消息传递: 在 Android 中,Binder 机制允许不同的应用程序或系统组件之间进行进程间通信(IPC)。当一个客户端应用程序想要向一个服务端应用程序发送请求时,它会通过 Binder 机制将请求封装成一个消息,并发送给服务端。binder_transaction 函数负责将这个消息从客户端传递到服务端。

  • 消息解析: 一旦消息到达服务端,binder_transaction 函数会负责解析消息的内容,提取出请求的具体信息,例如请求调用的函数或方法名称、参数等。这个过程是非常关键的,因为服务端需要根据这些信息来执行相应的操作。

  • 请求处理: 服务端收到消息后,会根据消息中的内容执行相应的操作,并生成一个响应消息。binder_transaction 函数在服务端负责处理这个请求,调用相应的服务端函数或方法,并传递请求所需的参数。

  • 响应返回: 当服务端完成请求处理后,会生成一个响应消息,并通过 binder_transaction 函数将这个响应消息传递回客户端。客户端收到响应后,可以继续执行相应的操作,例如更新用户界面或者执行下一步操作。

  • 线程同步和错误处理: 在消息传递和处理的过程中,可能会涉及到线程同步和错误处理等问题。binder_transaction 函数需要确保消息的传递和处理是按照正确的顺序进行的,并且能够处理各种可能出现的错误情况,例如超时、服务端崩溃等。

  • binder_transaction 函数是 Android Binder 驱动中非常重要的一个函数,负责实现客户端与服务端之间的消息传递和请求处理过程。它的正确和高效运行对于 Android 系统的稳定性和性能至关重要。

🌻3.代码实例

🐓3.1 Binder 服务端接收请求并回复

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/binder.h>

#define BINDER_TEST_SERVICE 1

static int binder_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    struct binder_thread *thread = current->binder;
    struct binder_transaction_data *txn = (struct binder_transaction_data *)arg;
    int ret;

    if (cmd == BINDER_TRANSACTION) {
        // 处理客户端请求,并生成响应
        // 在这里可以执行相应的功能
        // 然后构造响应消息并发送
        struct binder_transaction_data reply;
        reply.target.handle = txn->sender_pid; // 客户端的PID
        reply.target.ptr = NULL;
        reply.code = 0; // 响应码
        reply.flags = 0;
        ret = binder_transaction(thread, &reply, sizeof(reply), NULL, 0);
        return ret;
    }

    return -ENOTTY;
}

static const struct file_operations binder_test_fops = {
    .owner = THIS_MODULE,
    .unlocked_ioctl = binder_test_ioctl,
};

static int __init binder_test_init(void)
{
    if (binderfs_create_file("binder_test", &binder_test_fops) != 0)
        return -ENOMEM;

    return 0;
}

static void __exit binder_test_exit(void)
{
    binderfs_remove_file("binder_test");
}

module_init(binder_test_init);
module_exit(binder_test_exit);

🐓3.2 Binder 客户端向服务端发送请求

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/binder.h>

#define BINDER_TEST_SERVICE 1

static int binder_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    struct binder_thread *thread = current->binder;
    struct binder_transaction_data txn;
    int ret;

    if (cmd == BINDER_TRANSACTION) {
        // 构造客户端请求消息
        txn.target.handle = BINDER_TEST_SERVICE; // 服务端的 handle
        txn.code = 0; // 请求码
        txn.flags = 0; // 请求标志
        // 可以添加其他请求数据

        // 发送请求并等待响应
        ret = binder_transaction(thread, &txn, sizeof(txn), NULL, 0);
        return ret;
    }

    return -ENOTTY;
}

static const struct file_operations binder_test_fops = {
    .owner = THIS_MODULE,
    .unlocked_ioctl = binder_test_ioctl,
};

static int __init binder_test_init(void)
{
    if (binderfs_create_file("binder_test", &binder_test_fops) != 0)
        return -ENOMEM;

    return 0;
}

static void __exit binder_test_exit(void)
{
    binderfs_remove_file("binder_test");
}

module_init(binder_test_init);
module_exit(binder_test_exit);
MODULE_LICENSE("GPL");

🐓3.3 Binder 驱动中实现事务处理

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/binder.h>

#define BINDER_TEST_SERVICE 1

static int binder_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    struct binder_thread *thread = current->binder;
    struct binder_transaction_data *txn = (struct binder_transaction_data *)arg;
    int ret;

    if (cmd == BINDER_TRANSACTION) {
        // 在这里根据请求参数执行相应的功能
        // 并构造响应消息
        struct binder_transaction_data reply;
        reply.target.handle = txn->sender_pid; // 客户端的PID
        reply.target.ptr = NULL;
        reply.code = 0; // 响应码
        reply.flags = 0;
        ret = binder_transaction(thread, &reply, sizeof(reply), NULL, 0);
        return ret;
    }

    return -ENOTTY;
}

static const struct file_operations binder_test_fops = {
    .owner = THIS_MODULE,
    .unlocked_ioctl = binder_test_ioctl,
};

static int __init binder_test_init(void)
{
    if (binderfs_create_file("binder_test", &binder_test_fops) != 0)
        return -ENOMEM;

    return 0;
}

static void __exit binder_test_exit(void)
{
    binderfs_remove_file("binder_test");
}

module_init(binder_test_init);
module_exit(binder_test_exit);
MODULE_LICENSE("GPL");

相关推荐

  1. Android Binder——Parcel数据处理流程(二二)

    2024-05-09 12:18:05       29 阅读
  2. Android Binder——数据传输限制(二

    2024-05-09 12:18:05       33 阅读
  3. Android Binder——Kernel层介绍(

    2024-05-09 12:18:05       31 阅读
  4. Android Binder——APP中的Binder通信(八)

    2024-05-09 12:18:05       29 阅读
  5. android binder如何实现异步

    2024-05-09 12:18:05       21 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-09 12:18:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-09 12:18:05       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-09 12:18:05       82 阅读
  4. Python语言-面向对象

    2024-05-09 12:18:05       91 阅读

热门阅读

  1. Ubuntu 20.04 安装 Ansible

    2024-05-09 12:18:05       33 阅读
  2. EasyExcel自定义数据格式化

    2024-05-09 12:18:05       29 阅读
  3. docker部署微服务项目

    2024-05-09 12:18:05       33 阅读
  4. 前端每日一题day1

    2024-05-09 12:18:05       33 阅读
  5. 轻型钢结构工程设计专项资质办理周期

    2024-05-09 12:18:05       29 阅读