Android P Auto版本evs_app解析之二:evs_app启动和运行

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

最近在调试Android Auto版本的evs_app程序。

evs_app相关参考:
《Android P Auto版本evs_app解析之一:evs_app代码架构和通信机制》
《Android P Auto版本evs_app解析之二:evs_app启动和运行》

一、检查摄像头设备

驱动层生成的摄像头设备节点在dev下面查看。adb进入系统目录dev下,ls -l查看摄像头;
生成的摄像头为:dev/video0,dev/video1,dev/video2,dev/video3;
我做实验这里有四个摄像头。

二、运行evs_app程序报错

evs_app是可执行的二进制文件,在system/bin目录下。
adb shell进入系统目录,执行start evs_app启动evs_app.

1、驱动层代码报错

看下面的打印,没有权限对video*设备进行访问。所以没有找到有效的摄像头设备

2019-06-13 18:14:16.420 1909-1963/? I/EvsDriver: Starting dev/video* enumeration
2019-06-13 18:14:16.428 1909-1909/? W/VideoFile-Poll-: type=1400 audit(0.0:2044): avc: denied { read write } for name="video3" dev="tmpfs" ino=9980 scontext=u:r:hal_evs_driver:s0 tcontext=u:object_r:ad_camera_device:s0 tclass=chr_file permissive=0
2019-06-13 18:14:16.428 1909-1909/? W/VideoFile-Poll-: type=1400 audit(0.0:2045): avc: denied { read write } for name="video2" dev="tmpfs" ino=9979 scontext=u:r:hal_evs_driver:s0 tcontext=u:object_r:ad_camera_device:s0 tclass=chr_file permissive=0
2019-06-13 18:14:16.428 1909-1909/? W/VideoFile-Poll-: type=1400 audit(0.0:2046): avc: denied { read write } for name="video1" dev="tmpfs" ino=9978 scontext=u:r:hal_evs_driver:s0 tcontext=u:object_r:ad_camera_device:s0 tclass=chr_file permissive=0
2019-06-13 18:14:16.428 1909-1909/? W/VideoFile-Poll-: type=1400 audit(0.0:2047): avc: denied { read write } for name="video0" dev="tmpfs" ino=20016 scontext=u:r:hal_evs_driver:s0 tcontext=u:object_r:ad_camera_device:s0 tclass=chr_file permissive=0
2019-06-13 18:14:16.431 1909-1963/? I/EvsDriver: enum name:mxc_isi.0.m2m
     path:/dev/video4
2019-06-13 18:14:16.434 1909-1963/? I/EvsDriver: Found 1 qualified video capture devices of 7 checked

2、evs_app应用层也报错提示没有找到摄像头

2019-06-13 18:53:38.331 1909-1909/? D/EvsDriver: openCamera
2019-06-13 18:53:38.331 1909-1909/? E/EvsDriver: Requested camera mxc_isi.0.capture not found
2019-06-13 18:53:38.332 3272-3274/? E/EvsApp: Failed to allocate new EVS Camera interface for mxc_isi.0.capture
2019-06-13 18:53:38.332 3272-3274/? E/EvsApp: Failed to set up video texture for mxc_isi.0.capture (reverse,park)
2019-06-13 18:53:38.332 3272-3274/? E/EvsApp: New renderer failed to activate
2019-06-13 18:53:38.332 3272-3274/? E/EvsApp: selectStateForCurrentConditions failed so we're going to die
2019-06-13 18:53:38.332 3272-3274/? W/EvsApp: EvsStateControl update loop ending
2019-06-13 18:53:38.332 3272-3274/? E/EvsApp: KILLING THE APP FROM THE EvsStateControl LOOP ON DRAW FAILURE!!!
2019-06-13 18:53:38.346 1909-1909/? D/EvsDriver: EvsDisplay being destroyed
2019-06-13 18:53:38.346 1909-1909/? D/EvsDriver: EvsDisplay forceShutdown

三、修改驱动层代码

代码路径:packages\services\Car\evs\sampleDriver\EvsEnumerator.cpp
sampleDriver是android提供的示例驱动,运行evs_app之前,要保证驱动程序先正常运行,驱动程序也在system/bin目录下。

修改一下代码:

bool EvsEnumerator::EnumAvailableVideo() {
    unsigned videoCount   = 0;
    unsigned captureCount = 0;
    bool videoReady = false;

    int enableFake = property_get_int32(EVS_FAKE_PROP, 0);
    if (enableFake != 0) {
        sCameraList.emplace_back(EVS_FAKE_SENSOR, EVS_FAKE_NAME);
        captureCount++;
    }

    // For every video* entry in the dev folder, see if it reports suitable capabilities
    // WARNING:  Depending on the driver implementations this could be slow, especially if
    //           there are timeouts or round trips to hardware required to collect the needed
    //           information.  Platform implementers should consider hard coding this list of
    //           known good devices to speed up the startup time of their EVS implementation.
    //           For example, this code might be replaced with nothing more than:
    //                   sCameraList.emplace_back("/dev/video0");
    //                   sCameraList.emplace_back("/dev/video1");
    ALOGI("Starting dev/video* enumeration");
    
    /*由于没有video*的访问权限,导致了该驱动没有找到摄像头设备
    /*解决方法:1、在SElinux赋给驱动层权限,以便访问video*设备
		       2、注释掉这段代码,直接给sCameraList.emplace_back("/dev/video0")方式添加设备
	
    /*********delete start*********/
    /*
    DIR* dir = opendir("/dev");
    if (!dir) {
        LOG_FATAL("Failed to open /dev folder\n");
    }
    struct dirent* entry;
    FILE *fp = NULL;
    char devPath[HWC_PATH_LENGTH];
    char value[HWC_PATH_LENGTH];
    while ((entry = readdir(dir)) != nullptr) {
        // We're only looking for entries starting with 'video'
        if (strncmp(entry->d_name, "video", 5) == 0) {
            std::string deviceName("/dev/");
            deviceName += entry->d_name;
            videoCount++;
            if (qualifyCaptureDevice(deviceName.c_str())) {
                snprintf(devPath, HWC_PATH_LENGTH,
                    "/sys/class/video4linux/%s/name", entry->d_name);
                if ((fp = fopen(devPath, "r")) == nullptr) {
                    ALOGE("can't open %s", devPath);
                    continue;
                }
                if(fgets(value, sizeof(value), fp) == nullptr) {
                    fclose(fp);
                    ALOGE("can't read %s", devPath);
                    continue;
                }
                fclose(fp);
                ALOGI("enum name:%s path:%s", value, deviceName.c_str());
                sCameraList.emplace_back(value, deviceName.c_str());
                captureCount++;
            }
        }
    }*/
    /*********delete end*********/
    
    /*********add start*********/
    sCameraList.emplace_back("mxc_isi.0.capture","/dev/video0");
    sCameraList.emplace_back("mxc_isi.1.capture","/dev/video1");
    sCameraList.emplace_back("mxc_isi.2.capture","/dev/video2");
    sCameraList.emplace_back("mxc_isi.3.capture","/dev/video3");
    captureCount = 4;
    videoCount = 4;
    /*********add end*********/
    
    if (captureCount != 0) {
        videoReady = true;
        if (property_set(EVS_VIDEO_READY, "1") < 0)
            ALOGE("Can not set property %s", EVS_VIDEO_READY);
    }
	//delete
    //closedir(dir);
    ALOGI("Found %d qualified video capture devices of %d checked\n", captureCount, videoCount);
    return videoReady;
}

修改上面代码为直接增加摄像头,当然最好的办法是给驱动赋予权限。
sCameraList.emplace_back(“mxc_isi.1.capture”,"/dev/video1");

mxc_isi.1.capture为packages\services\Car\evs\app\config.json中对应的camer_id
video1为我们一直的摄像头。

编译驱动程序放进系统中,重启,可以看到驱动启动的打印:

打印正常,找到4个摄像头设备,EvsEnumeratorHw is ready.

扫描二维码关注公众号,回复: 6753941 查看本文章
1970-01-01 08:00:10.818 1908-1908/? I/EvsDriver: EVS Hardware Enumerator service is starting
1970-01-01 08:00:10.818 1908-1908/? D/EvsDriver: EvsEnumerator created
1970-01-01 08:00:10.818 1908-1908/? I/EvsDriver: Starting dev/video* enumeration
1970-01-01 08:00:10.842 1908-1908/? I/EvsDriver: Found 4 qualified video capture devices of 4 checked
1970-01-01 08:00:10.843 1908-1908/? I/ServiceManagement: Removing namespace from process name [email protected] to [email protected].
1970-01-01 08:00:10.845 1908-1908/? D/EvsDriver: EvsEnumeratorHw is ready.

四、再次运行evs_app,赋予权限

再次运行evs_app,开始提示 (13 = Permission denied),说明驱动没有对摄像头的读写权限。
提示没有权限打开设备

2019-06-13 18:16:26.756 1908-1908/? D/EvsDriver: openCamera
2019-06-13 18:16:26.756 1908-1908/? D/EvsDriver: EvsCamera instantiated
2019-06-13 18:16:26.756 1908-1908/? E/EvsDriver: failed to open device /dev/video0 (13 = Permission denied)
2019-06-13 18:16:26.756 1908-1908/? E/EvsDriver: Failed to open v4l device /dev/video0

SELinux权限问题请参考:
https://blog.csdn.net/Sunxiaolin2016/article/details/91039775

关闭SeLinux防火墙:setenforce 0

再次运行evs_app,进入摄像头画面,evs运行成功。

运行stop evs_app退出evs程序。

猜你喜欢

转载自blog.csdn.net/Sunxiaolin2016/article/details/94021288