目录
1、需求分析
项目中需要监听gpio改变的事件,驱动测上报Input事件,需要在framework添加逻辑通知给app,为了解耦,考虑能够更好的移植,app单独监听该input事件。
2、接口实现
1、APP注册 callback给 Hidl Service
2、Hidl Service监听相关文件节点后回调 APP Callback
参考之前Hidl 学习总结1
3、代码编写
APP代码编写
package com.example.test2;
import androidx.appcompat.app.AppCompatActivity;
import vendor.hardware.test.V1_0.ITest;
import vendor.hardware.test.V1_0.ITestCmdCallback;
import android.hidl.base.V1_0.DebugInfo;
import android.os.Bundle;
import android.os.IHwBinder;
import android.os.NativeHandle;
import android.os.RemoteException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private TestCmdCallback mCallback;
ITest mTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
mTest = ITest.getService(false);
mCallback = new TestCmdCallback();
android.util.Log.i("zmao","get services success **** !");
int ret = mTest.registCallback(mCallback);
android.util.Log.i("zmao","register callback ret = " + ret);
} catch(Exception e) {
android.util.Log.i("zmao","exception " + e);
}
}
@Override
protected void onResume() {
super.onResume();
}
public class TestCmdCallback extends ITestCmdCallback.Stub {
public void callback(String rsp) {
android.util.Log.i("zmao","TestCmdCallback rsp = " + rsp);
}
}
}
Hidl 服务代码编写
void EventObserver::startObserver(void *observer){
int fd;
/*需要轮询的fds*/
fd_set readfds;
/*需要轮询的fds数量*/
int maxfds;
struct input_event event;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
EventCallback* mObserver = (EventCallback*)observer;
fd = open("/dev/input/event3", O_RDWR | O_NONBLOCK);
if(fd < 0){
ALOGE("startObserver error");
} else {
ALOGE("startObserver success");
}
//清零
FD_ZERO(&readfds);
/*将标准输入的文件描述符添加到集合中, 如果是多个添加多个文件描述符*/
FD_SET(fd, &readfds);
maxfds = fd + 1; //最大文件描述符fd + 1
while(1){
int ret = select(maxfds, &readfds, NULL, NULL, NULL);
if(ret > 0){
/*只有发生过的fd才会在文件readfds中*/
if(FD_ISSET(fd, &readfds)){
while(read(fd, &event, sizeof(event)) == sizeof(event)){
ALOGE("get envent: type = 0x%x, Code = 0x%x value = 0x%x \n",event.type, event.code, event.value);
//ALOGE("get envent: type = %s, Code = %s value = 0x%x \n",eventTypeToString(event.type), eventCodeToString(event.code), event.value);
if(mObserver->mCallback != nullptr){
mObserver->mCallback->callback("gpio is change");
ALOGE("mCallback is called");
}
}
}
//将文件描述符重置
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
} else if (ret == 0){
if(FD_ISSET(fd, &readfds)){
ALOGE("select time out \n");
}
} else {
ALOGE("poll err \n");
}
}
}
关闭Selinux 调试Log 如下
Line 70180: 04-10 18:38:32.399 443 443 E SELinux : avc: denied { find } for interface=vendor.hardware.test::ITest sid=u:r:untrusted_app_32:s0:c238,c256,c512,c768 pid=9203 scontext=u:r:untrusted_app_32:s0:c238,c256,c512,c768 tcontext=u:object_r:default_android_hwservice:s0 tclass=hwservice_manager permissive=1
Line 70181: 04-10 18:38:32.399 443 443 I auditd : avc: denied { find } for interface=vendor.hardware.test::ITest sid=u:r:untrusted_app_32:s0:c238,c256,c512,c768 pid=9203 scontext=u:r:untrusted_app_32:s0:c238,c256,c512,c768 tcontext=u:object_r:default_android_hwservice:s0 tclass=hwservice_manager permissive=1
Line 70183: 04-10 18:38:32.400 9203 9203 I android_os_HwBinder: HwBinder: Starting thread pool for getting: vendor.hardware.test@1.0::ITest/default
Line 70185: 04-10 18:38:32.401 9203 9203 I zmao : get services success **** !
Line 70186: 04-10 18:38:32.401 16251 16251 E vendor.hardware.test@1.0-service: zmao registCallback success!
Line 70186: 04-10 18:38:32.401 16251 16251 E vendor.hardware.test@1.0-service: zmao registCallback success!
Line 70187: 04-10 18:38:32.401 16251 16251 E vendor.hardware.test@1.0-service: registCallback sucess
Line 70188: 04-10 18:38:32.402 9203 9203 I zmao : register callback ret = 0
Line 115875: 04-10 18:39:00.883 16251 16252 E vendor.hardware.test@1.0-service: get envent: type = 0x1, Code = 0x1 value = 0x1
Line 115879: 04-10 18:39:00.884 16251 16252 E vendor.hardware.test@1.0-service: mCallback is called
Line 115880: 04-10 18:39:00.884 16251 16252 E vendor.hardware.test@1.0-service: get envent: type = 0x1, Code = 0x1 value = 0x0
Line 115881: 04-10 18:39:00.884 16251 16252 E vendor.hardware.test@1.0-service: mCallback is called
Line 115882: 04-10 18:39:00.884 16251 16252 E vendor.hardware.test@1.0-service: get envent: type = 0x0, Code = 0x0 value = 0x0
Line 115883: 04-10 18:39:00.885 16251 16252 E vendor.hardware.test@1.0-service: mCallback is called
Line 115898: 04-10 18:39:00.886 9203 19019 I zmao : TestCmdCallback rspgpio is change
Line 115905: 04-10 18:39:00.887 9203 19019 I zmao : TestCmdCallback rspgpio is change
Line 115906: 04-10 18:39:00.887 9203 19019 I zmao : TestCmdCallback rspgpio is change
4、调试过程中遇到的坑
std:thread的join函数会阻塞主线程,需要使用detach函数。导致服务一直无法获取