通过FIFO实现Android Framework/App与hal层单向通信

Android是通过HIDL实现上层与Hal层通信,当业务逻辑有通信需求时去扩展HIDL接口比较麻烦。本文介绍了通过FIFO实现Android FWK/App给hal发送消息的快捷方式。该方式是从FWK/App向Hal层发送消息。

1 Hal层实现

1.1 定义Hal层监听接口

定义FIFO的读端。

#include <utils/Thread.h>    
class CameraMSGProcess : public android::Thread {
public:
    CameraMSGProcess();
    ~CameraMSGProcess();
    virtual bool threadLoop() override;
private:
    bool mExit;
    const char* mObservePath;
    int mFd;
};

1.2 实现Hal层监听接口

#include <log/log.h>
#include <errno.h>
#include <cutils/properties.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

CameraMSGProcess::CameraMSGProcess() :
        Thread(/*canCallJava*/false),
        mExit(false),
        mObservePath("/data/local/fifo"),
        mFd(-1){
        //创建fifo,直接调用该函数创建出来的接口权限不是指定的0666。未研究原因。
        if(!mkfifo(mObservePath, 0666)) {
            ALOGI("create fifo OK");
            //通过写属性的方式在.rc文件修改节点权限
            property_set("sys.myfifo.hal.fifo_read", "1");
        }
}

CameraMSGProcess::~CameraMSGProcess() {
    //析构时以写的方式打开写入退出标识
    int fd = open(mObservePath, O_WRONLY|O_NONBLOCK);
    if(fd != -1) {
        write(mFd, "q", 1);
        close(fd);
    }
    mExit = true;
}

bool CameraMSGProcess::threadLoop() {
    ALOGI("start to monitor");
    while (!mExit) {
        //在调试过程中发现每次监听需要重新打开一次。否者下次select函数直接返回。这和linux上不同,未深入研究原因。
        mFd = open(mObservePath, O_RDONLY|O_NONBLOCK); //以只读方式打开
        if(mFd < 0) {
            ALOGE("open %s failed! %s", mObservePath, strerror(errno));
            usleep(50000);
            return true;
        }
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(this->mFd, &fds);

        int ret = select(this->mFd + 1, &fds, NULL, NULL, NULL);
        if(ret < 0) {
            ALOGE("select %s failed! %s", mObservePath, strerror(errno));
        } else {
            char value[100] = {0};
            ret = read(mFd, value, 100);
            if(ret > 0) {
                ALOGI("read %s", value);

               //退出监听
                if(!strncmp(value, "q", 1)) break;

                //消息处理
                if(!strcmp(value, "doPTZ")) {
                    //Call doPTZ
                } else if(!strcmp(value, "doAWB")) {
                    //Call doAWB
                }
            }
        }
        close(mFd);
        mFd = -1;
    }

    unlink(mObservePath);
    return false;
}

void startFIFO() {
    sp<CameraMSGProcess>  mCameraMSGProcess = new CameraMSGProcess();
    mCameraMSGProcess.run("msg_process", PRIORITY_BACKGROUND);
}

1.3 修改fifo节点权限

mkfifo第二个参数指定的权限不生效,可以通过.rc文件修改。因为我是在camera hal中使用,所以在cameraProvider的rc文件添加如下代码。

on property:sys.myfifo.hal.fifo_read=1
    chmod 0666 /data/local/fifo

2 在FWK或App中写入消息

写入消息。

void sendMsg() {
    android.util.FileUtils.writeFile("/data/local/fifo", "xxx");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值