【倒车影像】代码流程分析
- 一、Service初始化 dls_reverse_svr
- 二、倒车影像控制线程 reverse_control
- 2.1 线程初始化 reverse_control::readyToRun()
- 2.2 线程自循环 reverse_control::threadLoop()
- 三、线程 dls_task_thread
- 四、CameraService 服务初始化
- 五、MessageQueue
- 三、知识扩展
一、Service初始化 dls_reverse_svr
先来看下Android.mk。
@ /hardware/libhardware/modules/reverse/reversing_video/Android.mk
LOCAL_SRC_FILES:= \
reverse_service/dls_reverse_svr_main.cpp \
reverse_service/DLSVehicleSignalService.cpp \
reverse_service/IDLSVehicleSignalService.cpp \
reverse_service/IReverseClient.cpp \
reverse_service/IDLSAnimationClient.cpp \
reverse_service/dls_message_queue.cpp \
reverse_service/dls_thread.cpp \
reverse_service/dls_task_thread.cpp \
reverse_service/touch_ev.cpp \
# version is msm8937_32go
LOCAL_CFLAGS += -D_ANDROID_8_1_
LOCAL_MODULE:= dls_reverse_svr
include $(BUILD_EXECUTABLE)
可以看到整个倒车影像服务是以可执行程序执行的,名字为 /system/bin/dls_reverse_svr
接下来,我们进入它的 main( ) ,来看下干了啥。
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_service/dls_reverse_svr_main.cpp
#include <utils/RefBase.h>
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <binder/BinderService.h>
#include "include/DLSVehicleSignalService.h"
#include <pthread.h>
#include <sys/resource.h>
using namespace pateo_dls;
using namespace android;
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
// 1. 将当前process 线程设定为 UI主线程,value=-4
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
sp<ProcessState> proc(ProcessState::self());
// 2. 获取系统默认的 ServiceManager
sp<IServiceManager> sm(defaultServiceManager());
// 3. 注册一个名为 dls_vehicle_signal_service 的service
sm->addService(String16(DLSVehicleSignalService::getServiceName()), new DLSVehicleSignalService);
========>
return "dls_vehicle_signal_service";
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
1.1 服务初始化 DLSVehicleSignalService()
-
在构造函数中,调用
initFunc()
进行初始化 -
将当前状态设置为
STATE_HIDE
,即 OFF 状态 -
初始化
reverse_video
对象,用于控制 Camera 的开关,
保存在全局变量reverse_video* reverse_video::sInstance = 0;
中 -
初始化
UIController
对象,用于控制 UI 的显示
保存在全局变量UIController* UIController::mInstance = 0;
中 -
初始化
reverse_control
线程,用于监听和控制 Camera 的状态
保存在全局变量reverse_control* reverse_control::sInstance = 0;
中 -
初始化
dls_task_thread
线程,用于控制进入和退出dls,
保存在全局变量dls_task_thread* dls_task_thread::sInstance = 0;
中 -
初始化 UI Windows 显示
@ libhardware/modules/reverse/reversing_video/reverse_service/DLSVehicleSignalService.cpp
DLSVehicleSignalService::DLSVehicleSignalService()
{
initFunc();
DLSVehicleSignalService::sInstance = this;
}
/******************************************************************
* use: init the vehicle service
**********/
void DLSVehicleSignalService::initFunc()
{
ALOGI("2019-1-11 DLSVehicleSignalService is starting ");
loadVehicleConfig();
//Step 0:
reverseControlByJava = false;
mReverseClient = NULL;
// 1. 将当前状态设置为 STATE_HIDE ,即 OFF 状态
mConditionState = ReverseStateManager::STATE_HIDE;
// Step 1: In this order to create threads
// 2. 初始化 `reverse_video` 对象,用于控制 Camera 的开关,
// 保存在全局变量 `reverse_video* reverse_video::sInstance = 0;` 中
reverse_video::getInstance();
// 3. 初始化 `UIController` 对象,用于控制 UI 的显示,
// 保存在全局变量 `UIController* UIController::mInstance = 0;` 中
UIController::getController();
// Step 2: In this order to start threads
// 4. 初始化 reverse_control 线程,用于监听和控制 Camera 的状态。
// 保存在全局变量 reverse_control* reverse_control::sInstance = 0; 中
mController = reverse_control::createController();
==============>
+ void reverse_control::onFirstRef(){
+ ALOGD("onFirstRef reverse_control");
+ run("DLS_MessageReceiver", PRIORITY_DISPLAY);
+ }
<==============
// 5. 初始化 dls_task_thread 线程,用于控制进入和退出dls,
// 保存在全局变量 dls_task_thread* dls_task_thread::sInstance = 0; 中
mReverseTask = dls_task_thread::getReverseTask();
==============>
+ void dls_task_thread::onFirstRef()
+ {
+ ALOGD("onFirstRef dls_task_thread");
+ run("DLS_ReverseTask", PRIORITY_DISPLAY);
+ }
<==============
// 6. 初始化 UI Windows 显示
UIController::getController()->initAllWindows();
/*Trigger boot animation tmprialy*/
//property_set("ctl.start", "dls_bootanim");
//mReverseTask->addTask(dls_task_thread::CMD_TEST_MODE);
ALOGI("DLSVehicleSignalService started over.");
}
1.1.1 初始化倒车影像UI 显示 UIController::initAllWindows()
@ libhardware/modules/reverse/reversing_video/reverse_pdc/wl_32go/UIController_32go.cpp
void UIController::initAllWindows()
{
if (RADAR_SHOW_STYLE_CN202S_1920x720 == mShowStyle)
{
mErrorWindow = new ErrorWindow(WIN_ERROR_ID, (char*)"ErrorWindow");
mWindowManager->addWindow(mErrorWindow, WIN_ERROR_ID);
mRvcSDWindow = new RvcSDWindow(WIN_SD_RVC_ID, (char*)"RvcSDWindow");
mWindowManager->addWindow(mRvcSDWindow, WIN_SD_RVC_ID);
mRadarWindow = new RadarWindow(WIN_RADAR_ID, (char*)"RadarWindow");
mWindowManager->addWindow(mRadarWindow, WIN_RADAR_ID);
}
else if (RADAR_SHOW_STYLE_CN202S_800x480 == mShowStyle)
{
mErrorWindow_800x480 = new ErrorWindow_800x480(WIN_ERROR_ID, (char*)"ErrorWindow");
mWindowManager->addWindow(mErrorWindow_800x480, WIN_ERROR_ID);
mRvcSDWindow_800x480 = new RvcSDWindow_800x480(WIN_SD_RVC_ID, (char*)"RvcSDWindow");
mWindowManager->addWindow(mRvcSDWindow_800x480, WIN_SD_RVC_ID);
mRadarWindow_800x480 = new RadarWindow_800x480(WIN_RADAR_ID, (char*)"RadarWindow");
mWindowManager->addWindow(mRadarWindow_800x480, WIN_RADAR_ID);
}
mWindowManager->showWindow(WIN_SD_RVC_ID);
}
1.1.2 绘制 UI 显示控件 createWindowContent()
绘制 UI 显示控件,并对这些控件设置监听函数 setOnClickListener()
void RadarWindow::createWindowContent()
{
int car_x = (DLS_LCD_WIDTH - CAR_VIEW_WIDTH) / 2;
int car_y = 270 - 20;//(DLS_APP_HEIGHT - CAR_VIEW_HEIGHT) / 2;
int radarView_x = (DLS_LCD_WIDTH - DLS_APP_WIDTH) / 2;
carView = new ImageView(car_x, car_y, CAR_VIEW_WIDTH, CAR_VIEW_HEIGHT, (char*)"CarView", ID_CARVIEW);
carView->setImageSrc((char*)"images/32go/pateo_32go_car_left.png", ImageResource::PIC_INDEX_CAR);
radarTipsView = new TextView(DLS_APP_WIDTH + DLS_CAMERA_WIDTH, 0, 240, 720, (char*)"Tips");
radarTipsView->setImageZHSrc((char*)"images/32go/pateo_32go_radar_repair_tip_cn.png",
ImageResource::PIC_INDEX_RADAR_TIPS);
radarTipsView->setImageENSrc((char*)"images/32go/pateo_32go_radar_repair_tip_en.png",
ImageResource::PIC_INDEX_RADAR_TIPS_EN);
radarView = new RadarView(radarView_x, 0, DLS_APP_WIDTH, DLS_APP_HEIGHT, ID_RADAR_VIEW, 0, 0, (300+660), (350 - 20));
radarView->setZoneBgColor(0x29, 0x2A, 0x2E);
xkeyButton = new ImageButton(50, (DLS_LCD_HEIGHT - 150), 100, 100, ID_XKEY_BUTTON, (char*)"XKeyButton");
xkeyButton->setNormalImageSrc((char*)"images/32go/pateo_32go_xbutton_normal.png",
ImageResource::PIC_INDEX_XBUTTON_NORMAL);
xkeyButton->setPressImageSrc((char*)"images/32go/pateo_32go_xbutton_pressed.png",
ImageResource::PIC_INDEX_XBUTTON_PRESSED);
xkeyButton->setOnClickListener(this);
addView(xkeyButton);
addView(carView);
carView->setOnClickListener(this);
addView(radarTipsView);
radarTipsView->setVisibility(false);
addView(radarView);
//front left
pdcFrontL_AreaAlertView = new ImageView(0, 0, RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT,
(char*)"pdcFrontL_AreaAlertView");
pdcFrontL_AreaAlertView->setImageSrc((char*)"images/32go/pateo_32go_radar_fail_alert.png",
ImageResource::PIC_INDEX_RADAR_FAIL_ALERT);
//front right
pdcFrontR_AreaAlertView = new ImageView(0, 0, RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT,
(char*)"pdcFrontR_AreaAlertView");
pdcFrontR_AreaAlertView->setImageSrc((char*)"images/32go/pateo_32go_radar_fail_alert.png",
ImageResource::PIC_INDEX_RADAR_FAIL_ALERT);
//rear left
pdcRearL_AreaAlertView = new ImageView((698-30+7), (DLS_LCD_HEIGHT - 512 - 40),
RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearL_AreaAlertView");
pdcRearL_AreaAlertView->setImageSrc((char*)"images/32go/pateo_32go_radar_fail_alert.png",
ImageResource::PIC_INDEX_RADAR_FAIL_ALERT);
//rear right
pdcRearR_AreaAlertView = new ImageView((948-20-3), (DLS_LCD_HEIGHT - 512 - 40),
RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearR_AreaAlertView");
pdcRearR_AreaAlertView->setImageSrc((char*)"images/32go/pateo_32go_radar_fail_alert.png",
ImageResource::PIC_INDEX_RADAR_FAIL_ALERT);
//rear left middle
pdcRearLM_AreaAlertView = new ImageView((773 - 28), (DLS_LCD_HEIGHT - 568 - 62),
RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearLM_AreaAlertView");
pdcRearLM_AreaAlertView->setImageSrc((char*)"images/32go/pateo_32go_radar_fail_alert.png",
ImageResource::PIC_INDEX_RADAR_FAIL_ALERT);
//rear right middle
pdcRearRM_AreaAlertView = new ImageView((870 - 10), (DLS_LCD_HEIGHT - 568 - 62),
RADAR_ALERT_VIEW_WIDTH, RADAR_ALERT_VIEW_HEIGHT, (char*)"pdcRearRM_AreaAlertView");
pdcRearRM_AreaAlertView->setImageSrc((char*)"images/32go/pateo_32go_radar_fail_alert.png",
ImageResource::PIC_INDEX_RADAR_FAIL_ALERT);
addView(pdcFrontL_AreaAlertView);
addView(pdcFrontR_AreaAlertView);
addView(pdcRearL_AreaAlertView);
addView(pdcRearLM_AreaAlertView);
addView(pdcRearRM_AreaAlertView);
addView(pdcRearR_AreaAlertView);
pdcFrontL_AreaAlertView->setVisibility(false);
pdcFrontR_AreaAlertView->setVisibility(false);
pdcRearL_AreaAlertView->setVisibility(false);
pdcRearR_AreaAlertView->setVisibility(false);
pdcRearLM_AreaAlertView->setVisibility(false);
pdcRearRM_AreaAlertView->setVisibility(false);
}
二、倒车影像控制线程 reverse_control
2.1 线程初始化 reverse_control::readyToRun()
在线程初始化完毕,开始进入 threadLoop()
前,会调用 reverse_control::readyToRun()
,主要工作如下:
- 初始化
pateo uevent
, 绑这下netlink socket,设备描述符保存在d_sig_fd_sets.sigdet_uevent_fd
中 - 并打开
"dev/sigdet0"
节点 ,把设备描述符保存在d_sig_fd_sets.sigdet_get_fd
中 - 调用
initReverseDataByIoctl()
- 获取车机
acc ,baterry, pdc, Can board,reverseStat
e 这些信息,根投当前车机状态来更新倒车影像的mMessageQueue
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cpp
status_t reverse_control::readyToRun()
{
ALOGD("reverse_control readyToRun");
initReceiver();
=====================>
+ // 1. 初始化 pateo uevent,相关设备描述符保存在 d_sig_fd_sets.sigdet_uevent_fd 中
+ d_sig_fd_sets.sigdet_uevent_fd = pateo_uevent_init(NETLINK_CIS_SIGDET);
+ // 2. 打开 "dev/sigdet0" 节点 ,把设备描述符保存在 d_sig_fd_sets.sigdet_get_fd 中
+ d_sig_fd_sets.sigdet_get_fd = open(SIGDET_FD_PATH,O_RDWR);
+ ALOGD("reverse_control init ===sigdet_get_fd : %d, sigdet_uevent_fd: %d",
+ d_sig_fd_sets.sigdet_get_fd, d_sig_fd_sets.sigdet_uevent_fd);
<=====================
// 3. 获取车机 acc ,baterry, pdc, Can board,reverseState 这些信息,根投当前车机状态来更新倒车影像的 mMessageQueue
initReverseDataByIoctl();
return NO_ERROR;
}
2.1.1 Event Socket 初始化 pateo_uevent_init()
- 创建
NETLINK socket
,protocol
协议为NETLINK_CIS_SIGDET
- 配置
socket receve buff size
为128 * 1024
- 绑定 socket
@ libhardware/modules/libpateouevent/pateo_uevent.c
int pateo_uevent_init(int protocol)
{
struct sockaddr_nl addr;
int sz = 128 * 1024;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid();
addr.nl_groups = 1;
// addr.nl_groups = getpid();
ALOGD("protocol=%d, addr.nl_pid=%d \n", protocol, addr.nl_pid);
// 1. 创建 NETLINK socket, protocol 为 NETLINK_CIS_SIGDET
s = socket(PF_NETLINK, SOCK_DGRAM, protocol);
// 2. 配置 socket receve buff size 为 128 * 1024
setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));
// 3. 绑定 socket
ret = bind(s, (struct sockaddr *) &addr, sizeof(addr));
return s;
}
2.1.2 更新倒车影像状态 initReverseDataByIoctl()
- 变量初始化
- 向
"dev/sigdet0"
发送SIGDET_GET_ACC_STATE
命令 获取ACC
状态,保存在m_acc_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_REVERSE_STATE
命令获取倒车影像的状态,状态保存在m_reverse_gear_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_CANB_STATE
命令获取 Can board 状态,保存在m_canb_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_BATTERY_STATE
命令 get battery state,保存在m_battery_state
中 - 向
"dev/sigdet0"
发送SIGDET_GET_BATTERY_STATE
命令 get PDC state
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cpp
void reverse_control::initReverseDataByIoctl()
{
// 1. 变量初始化
resetDataModel();
// 2. 如果打开 "dev/sigdet0" 节点成功的话
if (-1 != d_sig_fd_sets.sigdet_get_fd)
{
unsigned char accState[2] = {0x00, 0x00};
// 2.1 向"dev/sigdet0" 发送 SIGDET_GET_ACC_STATE 命令 获取 ACC 状态
// get ACC state
if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_ACC_STATE, accState)) == 0){
if(accState[0] == 1){
m_acc_state = accState[1];
m_acc_state_valid = true;
ALOGE("%s - SIGDET_GET_ACC_STATE , ACC State = %d", __FUNCTION__,m_acc_state);
}
}
// 2.2 向"dev/sigdet0" 发送 SIGDET_GET_REVERSE_STATE 命令获取倒车影像的状态 get reverse state
unsigned char reverseState[2] = {0x01, 0x07};
if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_REVERSE_STATE, reverseState)) == 0){
ALOGD("%s - get reverse state reverseState[0]:%d, reverseState[1]:%d", __FUNCTION__,
reverseState[0], reverseState[1]);
if(reverseState[0] == 1){
m_reverse_gear_state = reverseState[1];
m_reverse_gear_state_valid = true;
}
}
// get can board state
// 2.3 向"dev/sigdet0" 发送 SIGDET_GET_CANB_STATE 命令获取 Can board 状态,保存在 m_canb_state 中
unsigned char canbState[2] = {0x0};
m_canb_state = 0; //init value
m_canb_state_valid = false;
for(i=0; i<3; i++){
if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_CANB_STATE, canbState)) == 0){
if(canbState[0] == 1){
m_canb_state = canbState[1];
m_canb_state_valid = true;
}
break;
}
ALOGW("%s - SIGDET_GET_CANB_STATE %d", __FUNCTION__, m_canb_state);
// 2.4 向"dev/sigdet0" 发送 SIGDET_GET_BATTERY_STATE 命令 get battery state
ret = -1;
unsigned char batteryState[2] = {0x00, 0x00};
if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_BATTERY_STATE, batteryState)) == 0)
{
if(batteryState[0] == 1)
{
m_battery_state = batteryState[1];
m_battery_state_valid = true;
}
}
// 2.5 向"dev/sigdet0" 发送 SIGDET_GET_BATTERY_STATE 命令 get PDC state
ret = -1;
unsigned char pdcState[3] = {0x02, 0x02, 0x00};
if ((ret = ioctl(d_sig_fd_sets.sigdet_get_fd, SIGDET_GET_FRONT_PDC, pdcState)) == 0)
{
ALOGW("%s - SIGDET_GET_PDC_STATE success, ret = %d", __FUNCTION__, ret);
}
}
// on first boot; default battery normal
//comment it by vence @20190118 for test demo
updateReverseCondition(true);
=====================>
+ accState = m_acc_state;
+ gearState = m_reverse_gear_state;
+ batteryState = m_battery_state;
+
+ bool condition_acc_test_result = (accState >= STATE_CARKEY_ACC);
+ bool condition_gear_test_result = (gearState == GEAR_R_OR_REVERSE_ON);
+ bool condition_battery_test_result = (batteryState == BATTERY_NORMAL_LEVEL1);
+
+ mLastAccCondition = condition_acc_test_result;
+ mLastBatteryCondition = condition_battery_test_result;
+ mLastGearCondition = condition_gear_test_result;
+ judgReverseCondition();
<=====================
}
2.1.2.1 judgReverseCondition()
- 根据当前车机状态向更新mMessageQueue中的消息,从而更新倒车影像的状态
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cpp
bool reverse_control::judgReverseCondition()
{
int temp_reverseState = mIsInReverse;
int temp_condition_acc = mLastAccCondition;
bool temp_condition_gear = mLastGearCondition;//true mean reverse gear is on
int temp_condition_battery = mLastBatteryCondition;
bool actions_processed = false;
if (ReverseConfig::CAMERA_TYPE_ORIGINAL == ReverseConfig::getConfigs()->getCameraSelect()) {
//tmpDelayTime = DELAY_TIME_FOR_REVERSE_IN_ORIGNAL;
//ALOGW("Using orignal camera...");
}
// 1. 根据当前车机状态向更新mMessageQueue中的消息,从而更新倒车影像的状态
///////////////////////////////////////////////////////
///////pre test
if(mMessageQueue->hasMessage(mHandler, MSG_ENTER_REVERSE)){
if(!temp_condition_acc || !temp_condition_battery || !temp_condition_gear){
ALOGD("%s ... Cancel ... [ENTER REVERSE] From MessageQueue", __FUNCTION__);
mMessageQueue->removeMessages(mHandler, MSG_ENTER_REVERSE);
}
}
if(mMessageQueue->hasMessage(mHandler, MSG_EXIT_REVERSE)){
if(temp_condition_acc && temp_condition_battery && temp_condition_gear){
ALOGD("%s ... Cancel ... [EXIT REVERSE] From MessageQueue", __FUNCTION__);
mMessageQueue->removeMessages(mHandler, MSG_EXIT_REVERSE);
}
}
///////////////////////////////////////////////////////
///actions take
if((!temp_condition_acc || !temp_condition_gear || !temp_condition_battery ) && mIsInReverse){
ALOGD("%s Condition :: [EXIT REVERSE]", __FUNCTION__);
if(!mMessageQueue->hasMessage(mHandler, MSG_EXIT_REVERSE)){
mMessageQueue->sendMessageDelay(450, MSG_EXIT_REVERSE, mHandler);
actions_processed = true;
}
}
if((!temp_condition_acc || !temp_condition_gear || !temp_condition_battery ) && false == mIsInReverse && true == mRunningEnterReverseProcess){
//meet exit-reverse condition, and in non-reverse state, but an enter-reverse process is running
ALOGD("%s Condition-patch :: [EXIT REVERSE]", __FUNCTION__);
if(!mMessageQueue->hasMessage(mHandler, MSG_EXIT_REVERSE))
{
mMessageQueue->sendMessageDelay(450, MSG_EXIT_REVERSE, mHandler);//200
actions_processed = true;
}
}
if(temp_condition_acc && temp_condition_battery && temp_condition_gear && !mIsInReverse){
ALOGD("%s Condition :: [ENTER REVERSE]", __FUNCTION__);
onResetDataByEnterReverse();
if(!mMessageQueue->hasMessage(mHandler, MSG_ENTER_REVERSE)){
mMessageQueue->sendMessageDelay(450, MSG_ENTER_REVERSE, mHandler);//200
actions_processed = true;
}
}
if(temp_condition_acc && temp_condition_battery && temp_condition_gear && true == mIsInReverse
&& true == mRunningExitReverseProcess)
{
//meet reverse condition, and in reverse state, but an exit-reverse process is running
ALOGD("%s Condition-patch :: [ENTER REVERSE]", __FUNCTION__);
onResetDataByEnterReverse();
if(!mMessageQueue->hasMessage(mHandler, MSG_ENTER_REVERSE))
{
mMessageQueue->sendMessageDelay(450, MSG_ENTER_REVERSE, mHandler);//200
actions_processed = true;
}
}
return true;
}
2.2 线程自循环 reverse_control::threadLoop()
在 service 初始化成功后,就开始监听系统消息了
-
调用
pateo_uevent_next_event()
开始循环poll 监听NETLINK_CIS_SIGDET
的socket event 事件 event 消息 -
一个调试demon
如果接收到CAN 消息,mEventData[0] = 0x85
,mEventData[0]=4
, 则说时是进入倒车影像
根据mEventData[3]
判断开还是关倒车影像 -
根据监听到的socket event 事件做相关处理,我们此处重点看下
CMD_REVERSE_CAN_STATE
当有状态更新时,调用updateReverseCondition()
来更新倒车影像状态
事件包括:
CMD_ACC_STATE
、CMD_FRONT_PDC_VALUE
、CMD_REAR_PDC_VALUE
、
CMD_REVERSE_CAN_STATE
、CMD_BATTERY_STATE
、CMD_PASWORK_STATE
、
CMD_SPEED_VALUE
、CMD_SWA_STATE
@ libhardware/modules/reverse/reversing_video/reverse_service/wl_32go/reverse_control_32go.cpp
bool reverse_control::threadLoop()
{
memset(mEventData, 0, BUFFER_LENGTH);
// 1. 调用 `pateo_uevent_next_event()` 开始循环poll 监听 `NETLINK_CIS_SIGDET` 的socket event 事件 event 消息
ret = pateo_uevent_next_event(mEventData, BUFFER_LENGTH, d_sig_fd_sets.sigdet_uevent_fd);
ALOGI("[PATEO_UEVENT_EVENT] 0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x",
mEventData[0], mEventData[1], mEventData[2], mEventData[3], mEventData[4],
mEventData[5], mEventData[6], mEventData[7], mEventData[8], mEventData[9]);
#if 0
{ // 2. 一个调试demon, for demo only
if(ret > 2){
int mCmdID = mEventData[0];
// 2.1 如果接收到CAN 消息, mEventData[0] = 0x85, mEventData[0]=4, 则说时是进入倒车影像
if (CMD_REVERSE_CAN_STATE == mCmdID)
{ //0x85-0x4-0x0-0x0-0x2-0x4-0x0-0x0-0x0-0x0 normal 2gear
//0x85-0x4-0x0-0x1-0x13-0x4-0x0-0x0-0x0-0x0 reverse
if(4 == mEventData[1]) {
unsigned char reverse_state = mEventData[3];
// 2.2 根据 mEventData[3] 判断开还是关倒车影像
if (GEAR_R_OR_REVERSE_ON == reverse_state){
ALOGD("%s test mode: switch Camera View ON",__FUNCTION__);
dls_task_thread::getReverseTask()->addTask(dls_task_thread::CMD_TEST_MODE);
}else{
ALOGD("%s test mode: switch Camera View OFF",__FUNCTION__);
dls_task_thread::getReverseTask()->addTask(dls_task_thread::CMD_TEST_MODE_2);
}
}
}
}
}
#endif
if(ret > 2)
{
int mCmdID = mEventData[0];
// 3. 根据 mEventData[0] 第一个字节 判断event 命令
switch(mCmdID) //cmd id
{
case CMD_ACC_STATE: // 0x01
{ /* 0x1-0x1- 0x3-0x0-0x0-0x0-0x0-0x0-0x0-0x0 START
0x1-0x1- 0x1-0x0-0x0-0x0-0x0-0x0-0x0-0x0 ACC */
//ACC State
if(mEventData[1] == 1){ //length
switch(mEventData[2]){ //acc value
case STATE_CARKEY_OFF:
case STATE_CARKEY_ACC:
case STATE_CARKEY_RUN:
case STATE_CARKEY_START:
ALOGD("%s : got acc state %d",__FUNCTION__, mEventData[2]);
m_acc_state = mEventData[2];
m_acc_state_valid = true;
updateReverseCondition(true); //更新倒车影像状态
break;
}
}
break;
case CMD_FRONT_PDC_VALUE: //0x86
processPDCData(DISPLAY_INDEX_FRONT);
UIController::getController()->updatePdcInfo(mEventData, DISPLAY_INDEX_FRONT);
break;
case CMD_REAR_PDC_VALUE: // 0x87
processPDCData(DISPLAY_INDEX_REAR);
UIController::getController()->updatePdcInfo(mEventData, DISPLAY_INDEX_REAR);
break;
case CMD_REVERSE_CAN_STATE: // 0x85 // 倒车影像CAN 消息
{ /**********************************************************
0x85-0x4- 0x0-0x0-0x2-0x4-0x0-0x0-0x0-0x0 normal 2gear
0x85-0x4- 0x0-0x1-0x13-0x4-0x0-0x0-0x0-0x0 reverse
gear position valid (1byte) + reverse state (1byte)+ gear pos(1byte) + gear select mode (1byte)
************************************************************/
if(4 == mEventData[1]){ //length match
unsigned char reverse_state = mEventData[3];
if (GEAR_R_OR_REVERSE_ON == reverse_state){ // 0 -- false 1 ---- true
ALOGD("%s : reverse gear is ON",__FUNCTION__);
m_reverse_gear_state = GEAR_R_OR_REVERSE_ON;
}else{
ALOGD("%s : reverse gear is OFF",__FUNCTION__);
m_reverse_gear_state = GEAR_P_OR_REVERSE_OFF;
}
m_reverse_gear_state_valid = true;
updateReverseCondition(true);
//test
//UIController::getController()->updateDegreeInfo(20);
}
}
break;
case CMD_BATTERY_STATE:{ //Battery State 0x03
/**********************************************************
0x3-0x1 -0x0-0x0-0x0-0x0-0x0-0x0-0x0-0x0
************************************************************/
if(mEventData[1] == 1) {
m_battery_state = mEventData[2];
m_battery_state_valid = true;
}
updateReverseCondition(false);
}
break;
case CMD_PASWORK_STATE: //PASWorkCmd State
#if 0
m_pas_work_state = mEventData[2];
m_pas_work_state_valid = true;
updateReverseCondition(true);
#endif
break;
case CMD_SPEED_VALUE: { // 0x81
/** speed factor:0.015625
0x81-0x07-0x00-0x0c-0x80-0x01-0x00-0x00-0x00-0x00
(50km/h)
**/
if(mEventData[1] == 7){
if (0x00 == mEventData[2]){
//speed field is valid
unsigned short speed;
speed = (mEventData[3] << 8) | mEventData[4];
float speed_f = (float)speed;
speed_f *= 0.015625f;
m_vehicle_speed = (int)speed_f;
m_vehicle_speed_valid = true;
ALOGD("%s : got speed is %d",__FUNCTION__, m_vehicle_speed);
/** for test
updateReverseCondition(true);
**/
}
}
}
break;
case CMD_SWA_STATE:{
/** Steer Wheel Angle factor:0.0625
0x83-0x3-0x0-0x01-0x23-0x0-0x0-0x0-0x0-0x0
(-2047.9375 ~ + 2047.9375) **/
if(mEventData[1] == 3){
if(mEventData[2] == 0){
//swa field is valid
short swa_value;
swa_value = (mEventData[3] << 8) | mEventData[4];
float swa_f = (float)swa_value;
swa_f *= 0.0625f;
m_swa_value = swa_f;
ALOGD("%s : got swa is %f",__FUNCTION__, m_swa_value);
if (m_swa_value > 554.4 )//2047.9375
m_swa_value = 554.4;
else if (m_swa_value < -554.4)
m_swa_value = -554.4 ;
//assume max angnle is 30 deg of front wheel
//30.48 ~ 34.75
m_swa_value = (m_swa_value *30.48f)/554.4f;
m_swa_value_valid = true;
int swa_val_int = (int)m_swa_value;
swa_val_int = -swa_val_int;//exchange +- Jira: L0001M-2888
ALOGD("%s : final calced swa angle is %f, pass to low layer is %d",__FUNCTION__, m_swa_value, swa_val_int);
UIController::getController()->updateDegreeInfo(swa_val_int);
=====> mRvcSDWindow->updateDegree(degree);
}
}
}
break;
default:
onMessageReceive(mEventData);
break;
}
}
return true;//return true, mean this function will be called again.
}
2.2.1 Uevent 监听 pateo_uevent_next_event
循环 poll 监听 NETLINK_CIS_SIGDET
的socket event 事件
@ libhardware/modules/libpateouevent/pateo_uevent.c
int pateo_uevent_next_event(char* buffer, int buffer_length, int fd)
{
while (1) {
struct pollfd fds;
fds.fd = fd;
fds.events = POLLIN;
fds.revents = 0;
nr = poll(&fds, 1, -1);
int i;
if(nr > 0 && fds.revents == POLLIN) {
int count = recv(fd, buffer, buffer_length, 0);
// for(i=0;i<count;i++)
// ALOGD("buff[%d]=============%d\n",i,buffer[i]);
if (count > 0) {
return count;
}
}
}
return 0;
}
三、线程 dls_task_thread
3.1 线程自循环
- 等待mCommandQueue 事件到
- 处理事件
@ libhardware/modules/reverse/reversing_video/reverse_service/dls_task_thread.cpp
bool dls_task_thread::threadLoop()
{
pthread_mutex_lock(&mTaskLock);
while (mCommandQueue.empty())
pthread_cond_wait(&mTaskCondition, &mTaskLock);
deque<int>::iterator pIter;
mRunTaskQueue.clear();
for (pIter = mCommandQueue.begin(); pIter != mCommandQueue.end(); pIter++)
{
mRunTaskQueue.push_back(*pIter);
}
// clear
mCommandQueue.clear();
pthread_mutex_unlock(&mTaskLock);
deque<int>::iterator pExecIter;
for(pExecIter = mRunTaskQueue.begin(); pExecIter != mRunTaskQueue.end(); pExecIter++)
{
switch(*pExecIter)
{
case CMD_ENTER_REVERSE: processEnterReverse(); break;
case CMD_EXIT_REVERSE: processExitReverse(); break;
case CMD_ENTER_EOL_MODE: processEnterEolMode(); break;
case CMD_EXIT_EOL_MODE: processExitEolMode(); break;
case CMD_SET_LANGUAGE_EN: ReverseConfig::getConfigs()->setLanguageEN(); break;
case CMD_SET_LANGUAGE_ZH: ReverseConfig::getConfigs()->setLanguageZH();break;
case CMD_SWITCH_TO_ERROR_PAGE: processSwitchToErrorPage(); break;
case CMD_SWITCH_TO_VIDEO_PAGE: processSwitchToVideoPage(); break;
case CMD_RESTART_CAMERA: processReStartCamera(); break;
case CMD_RESTART_CAMERA_SILENT: processReStartCameraSilent(); break;
case CMD_RESTART_CAMERA_NEXT: processReStartCameraNext(); break;
case CMD_TEST_MODE: processTestMode(); break;
case CMD_TEST_MODE_2: processTestMode2(); break;
case CMD_TEST_MODE_SHOW_CAMERA: processTestShowCamera(); break;
case CMD_TEST_MODE_HIDE_CAMERA: processTestHideCamera(); break;
case CMD_ENTER_RADAR_SHOW: processEnterRadarShow(); break;
case CMD_EXIT_RADAR_SHOW: processExitRadarShow(); break;
default: break;
}
}
return true;
}
3.2 进入倒车影像 processEnterReverse()
-
在
mStateManager->notifyEnterPreReverseState()
中
通过BpReverseClient
代理调用BnReverseClient
的onPrepareReverseChange()
onPrepareReverseChange()
函数定义在class IReverseClient
中,定义在include/IReverseClient.h
中
class BnReverseClient
继承自class IReverseClient
,
接下来看下,谁继承了BnReverseClient
,就知道onPrepareReverseChange()
函数实际处理的地方。 -
调用
BnReverseClient
的onPrepareReverseChange()
,参数传递PRE_STATE_ENTER
、PRE_STATE_EXIT
-
调用
requestCamera()
打开Camera
@ libhardware/modules/reverse/reversing_video/reverse_service/dls_task_thread.cpp
void dls_task_thread::processEnterReverse()
{
//Pre state callback policy to be compatible with previous versions of the Java layer
mStateManager->notifyEnterPreReverseState();
=====================>
+ //通过 BpReverseClient 代理调用 BnReverseClient 的 onPrepareReverseChange(),参数传递 PRE_STATE_ENTER
+ //onPrepareReverseChange() 函数定义在 class IReverseClient 中,定义在include/IReverseClient.h中
+ //class BnReverseClient 继承自 class IReverseClient,
+ //接下来看下,谁继承了 BnReverseClient ,就知道onPrepareReverseChange() 函数实际处理的地方。
+
+ //@ libhardware/modules/reverse/reversing_video/reverse_service/IReverseClient.cpp
+ class BpReverseClient: public BpInterface<IReverseClient>
+ {
+ virtual void onPrepareReverseChange(int state){
+ Parcel data, reply;
+ data.writeInterfaceToken(IReverseClient::getInterfaceDescriptor());
+ data.writeInt32(state);
+ remote()->transact(BnReverseClient::ON_PER_REVERSE_STATE_CHANGE, data, &reply);
+ }
+ status_t BnReverseClient::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+ {
+ switch(code) {
+ case ON_PER_REVERSE_STATE_CHANGE: {
+ CHECK_INTERFACE(IReverseClient, data, reply);
+ int state = data.readInt32();
+ onPrepareReverseChange(state);
+ return NO_ERROR;
+ } break;
<=====================
mStateManager->notifyExitPreReverseState();
=====================>
+ 和前同一样,通过 BpReverseClient 代理调用 BnReverseClient 的 onPrepareReverseChange(),参数传递 PRE_STATE_EXIT
<=====================
mController->setEnterReverseState();
=====> mIsInReverse = true;
mController->EnterReverseProcessDone();
=====> mRunningEnterReverseProcess = false;
if(ReverseConfig::getConfigs()->getCameraSelect() != ReverseConfig::CAMERA_TYPE_NONE){
if(ReverseConfig::getConfigs()->getCameraClarity() == ReverseConfig::CAMERA_SD){
//Standard Mode
if (ReverseConfig::getConfigs()->getReverseController() == ReverseConfig::REVERSE_DP_CONTROLLER_AVM) {
ALOGD("[AVM Mode -- SD] Enter Reverse");
}else{
ALOGD("[RVC Mode -- SD] Enter Reverse");
//mCameraStable = true;
//todo: need to check camera if is ok
// 打开 Camera
bool res = mReverseVideo->requestCamera();
============>
mCameraHideSurface = false;
return requestCameraImpl(true);
<============
if(res){
ALOGD("[UI-PAGE] SD RVC Video");
mUIController->prepareSDCameraPage();
mStateManager->enterShowWithVideoDelay();
mUIController->showGUI();
}else{
ALOGD("[UI-PAGE] SD RVC Error");
mUIController->prepareNoVideoPage();
mStateManager->enterShowWithNoVideoDelay();
mUIController->showGUI();
}
}
}
}
}
3.2.1 打开摄像头 mReverseVideo->requestCamera()
- 创建pthread ,运行函数
reverse_video::threadLoop()
- 阻塞等待Camera 初始化完毕
mCameraInitDoneCondition.wait(mCameraInitDoneLock);
- 等待 360ms ,同步 Camera thread 出图
@ libhardware/modules/reverse/reversing_video/reverse_video/reverse_video.cpp
// use: turn on camera, return true mean ok, false mean error
bool reverse_video::requestCamera(){
mCameraHideSurface = false;
return requestCameraImpl(true);
}
/***************************************************
* use: the impl of request camera
* @aWaitCameraInitDone: true ----- the function will block until camera is inited done
* false ----- not wait
* return true mean ok, false mean error
* note: if aWaitCameraInitDone is true, the return result is the camera init result.
* Otherwise only return the general result.
******/
bool reverse_video::requestCameraImpl(bool aWaitCameraInitDone)
{
ALOGI("[reverse_video] %s +++", __FUNCTION__);
if (true == mCameraThreadRunning)
return true;//thread has already in the running state.
mCameraThreadRunning = true;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr, ¶m);
mReqQuit = false;//reset it
mCameraInitDone = false;
// 创建pthread ,运行函数 reverse_video::threadLoop()
int ret = pthread_create(&mThreadID, &attr, reverse_video::threadLoop, this);
==============>
+ // libhardware/modules/reverse/reversing_video/reverse_video/reverse_video.cpp
+ void* reverse_video::threadLoop(void* args)
+ {
+ reverse_video* me = (reverse_video*) args;
+ me->do_jobs();
+ ==========>
+ mCameraIsPoweredOn = false;
+ do_job_of_openCamera();
+ mCameraThreadRunning = false;
+ <==========
+ return NULL;
+ }
<=============
ALOGI("[reverse_video] %s thread created ok", __FUNCTION__);
if (true == aWaitCameraInitDone)
{
// 阻塞等待Camera 初始化完毕
ALOGI("[reverse_video] %s waiting camera initing -----", __FUNCTION__);
rc = mCameraInitDoneCondition.wait(mCameraInitDoneLock);
// 等待 360ms ,同步 Camera thread 出图
usleep(360 * 1000);//sync with camea thread
ALOGI("[reverse_video] %s mCameraInitDone =%d -----", __FUNCTION__, mCameraInitDone);
return mCameraInitDone;
}
ALOGI("[reverse_video] %s -----", __FUNCTION__);
return true;
}
3.2.1.1 打开摄像头线程 do_job_of_openCamera()
-
实例化
RearCamera()
对象,将mCameraInitDone
标志位设置为 false -
通过 binder 获取 名为
"media.camera"
的CameraService服务,调用getNumberOfCameras()
获取 Camera 个数,下发参数CAMERA_TYPE_ALL
-
调用
cameraRear->mCameraService->connectLegacy()
函数开始连接Camera, 获得CameraDevice
的设备操作函数 -
调用
getParameters()
获得当前Camera 参数 -
配置对焦模式,接着调用
setParameters()
下发参数 -
配置 Display 宽高,根据 preview size 创建 Surface
-
在配置好对应的参数后,开始调用
startPreview()
, 成功后,发送mCameraInitDoneCondition.broadcast()
广播 -
start to monitor vdloss, 开始正常显示camera
-
等待 camera 退出信号
-
stop monitor
-
调用
stopPreview()
,disconnect()
, 下电
@ libhardware/modules/reverse/reversing_video/reverse_video/reverse_video.cpp
void reverse_video::do_job_of_openCamera(void)
{
ALOGI("[reverse_video] %s +++", __FUNCTION__);
::android::binder::Status rc;
ALOGV("main begin");
// 1. 实例化 RearCamera() 对象
sp<RearCamera> cameraRear = new RearCamera();
// 2. 将 mCameraInitDone 标志位设置为 false
mCameraInitDone = false;
cameraRear->SetUp();
=================>
+ // 通过 binder 获取 名为 "media.camera" 的camera service
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.camera"));
+ mCameraService = interface_cast<ICameraService>(binder);
+
+ // 调用getNumberOfCameras() 获取 Camera 个数,下发参数 CAMERA_TYPE_ALL
+ rc = mCameraService->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras);
+ ALOGV("numCameras=%d",numCameras);
+ ==============>
+ // 服务"media.camera"位于 @ /frameworks/av/services/camera/libcameraservice/CameraService.h
+ static char const* getServiceName() { return "media.camera"; }
+
+ // @ /frameworks/av/camera/cameraserver/main_cameraserver.cpp
+ CameraService::instantiate();
+ <==============
+
+ mComposerClient = new SurfaceComposerClient;
+ mComposerClient->initCheck();
+ =======> return mStatus;
<=================
int32_t cameraId = 0;
sp<Surface> previewSurface;
sp<SurfaceControl> surfaceControl;
sp<ICamera> cameraDevice;
String16 cameraIdStr = String16(String8::format("%d", cameraId));
bool isSupported = false;
rc = cameraRear->mCameraService->supportsCameraApi(cameraIdStr,hardware::ICameraService::API_VERSION_1, &isSupported);
=================>
@ av/services/camera/libcameraservice/common/CameraProviderManager.cpp
deviceVersion = getDeviceVersion(id);
<=================
int halVersion = 0x100;
// 调用 cameraRear->mCameraService->connectLegacy() 函数开始连接Camera, 获得 CameraDevice 的设备操作函数
for (int try_time = 0; try_time < 30; try_time++)
{
rc = cameraRear->mCameraService->connectLegacy(cameraRear, cameraId, halVersion,
String16("ReverseCamera"),hardware::ICameraService::USE_CALLING_UID, /*out*/&cameraDevice);
if (cameraDevice != nullptr){
ALOGD("[reverse_video] %s ---, accquire cameraDevice OK , try_times=%d!", __FUNCTION__, try_time);
break;
}
usleep(200 * 1000);
}
// 调用getParameters()获得当前Camera 参数
CameraParameters params(cameraDevice->getParameters());
// 配置对焦模式
String8 focusModes(params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
bool isAFSupported = false;
const char *focusMode = nullptr;
if (focusModes.contains(CameraParameters::FOCUS_MODE_AUTO)) {
// If supported 'auto' should be set by default
isAFSupported = true;
} else if (focusModes.contains(CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) {
isAFSupported = true;
focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
} else if (focusModes.contains(CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO)) {
isAFSupported = true;
focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
} else if (focusModes.contains(CameraParameters::FOCUS_MODE_MACRO)) {
isAFSupported = true;
focusMode = CameraParameters::FOCUS_MODE_MACRO;
}
if (nullptr != focusMode) {
params.set(CameraParameters::KEY_FOCUS_MODE, focusMode);
cameraDevice->setParameters(params.flatten());
//ASSERT_EQ(NO_ERROR, cameraDevice->setParameters(params.flatten()));
}
// 配置 Display 宽高
int32_t nDisplayWidth = DLS_CAMERA_WIDTH;
int32_t nDisplayHeight = DLS_CAMERA_HEIGHT;
/***
sp<IBinder> primaryDisplay = cameraRear->mComposerClient->getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain);
DisplayInfo displayInfo;
status_t ret = cameraRear->mComposerClient->getDisplayInfo(
primaryDisplay, &displayInfo);
nDisplayWidth = displayInfo.w;
nDisplayHeight = displayInfo.h;
***/
// 根据 preview size 创建 Surface,及配置 surface参数
int previewWidth, previewHeight;
params.getPreviewSize(&previewWidth, &previewHeight);
//ASSERT_TRUE((0 < previewWidth) && (0 < previewHeight));
ALOGV("previewWidth=%d,previewHeight=%d",previewWidth,previewHeight);
surfaceControl = cameraRear->mComposerClient->createSurface(
String8("Rear Camera Surface"),nDisplayWidth, nDisplayHeight,
CameraParameters::previewFormatToEnum(params.getPreviewFormat()),
GRALLOC_USAGE_HW_RENDER);
//ASSERT_TRUE(nullptr != surfaceControl.get());
//ASSERT_TRUE(surfaceControl->isValid());
int32_t w = 0; int32_t h = 0; int32_t x = 0; int32_t y = 0;
FixScaling(0, nDisplayWidth, nDisplayHeight, previewWidth, previewHeight, w, h, x, y);
ALOGV("surfaceControl.get()=%d,surfaceControl->isValid()=%d",nullptr != surfaceControl.get(),surfaceControl->isValid());
SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(DLS_CAMERA_SURFACE_LAYER_INDEX);
surfaceControl->setAlpha(DLS_VIDEO_ALPHA);
//set transparent are
#if 0
const Rect top_area(0, 0, DLS_LCD_WIDTH, DLS_TOP_TITLE_HEIGHT);
const Rect bottom_area(0, DLS_LCD_HEIGHT - DLS_BOTTOM_TITLE_HEIGHT, DLS_LCD_WIDTH, DLS_LCD_HEIGHT);
Region region(top_area);
region.orSelf(bottom_area);
surfaceControl->setTransparentRegionHint(region);
#endif
surfaceControl->setPosition(DLS_APP_WIDTH, y + DLS_TOP_TITLE_HEIGHT);
surfaceControl->setSize(w, h);
#ifndef FEATURE_CAMERA_VIEW_SUPPORT
if (false == mCameraHideSurface) {
ALOGI("[reverse_video] %s Create with SHOW!!", __FUNCTION__);
surfaceControl->show();
}else{
ALOGI("[reverse_video] %s Create with HIDE!!", __FUNCTION__);
surfaceControl->hide();
}
#else
surfaceControl->hide();
#endif
//ASSERT_EQ(NO_ERROR, surfaceControl->setLayer(0x7fffffff));
//ASSERT_EQ(NO_ERROR, surfaceControl->show());
SurfaceComposerClient::closeGlobalTransaction();
previewSurface = surfaceControl->getSurface();
cameraDevice->setPreviewTarget( previewSurface->getIGraphicBufferProducer());
//ASSERT_TRUE(previewSurface != NULL);
//ASSERT_EQ(NO_ERROR, cameraDevice->setPreviewTarget(
// previewSurface->getIGraphicBufferProducer()));
cameraDevice->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER);
cameraDevice->setParameters(params.flatten());
mCameraInitDoneLock.lock();
mCameraInitDone = true;
mCameraInitDoneLock.unlock();
mCameraInitDoneCondition.broadcast();
// 在配置好对应的参数后,开始调用 startPreview(), 成功后,发送mCameraInitDoneCondition.broadcast() 广播
if (NO_ERROR != cameraDevice->startPreview())
{
ALOGD("[reverse_video] %s ---, startPreview Failed!", __FUNCTION__);
mCameraInitDoneCondition.broadcast();
return ;
}
//start to monitor vdloss
VideoLossMonitor::getVideoLossMonitor()->startMonitor();
===================>
+ start_camera_NGF_Monitor();
+ =======>
+ ret = pthread_create(&pid, NULL, camera_NGF_main, NULL);
+ ------>
+ static void * camera_NGF_main(void * arg) {
+ (void)arg;
+ int ret;
+ ret = camera_NGF_init();
+ --------->
+ - epollfd = epoll_create(MAX_EPOLL_EVENTS); //4
+ - uevent_fd = uevent_open_socket(64*1024, true);
+ - fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
+ - camera_NGF_register_event(uevent_fd, camera_NGF_uevent_event, EVENT_WAKEUP_FD);
+ <---------
+ camera_NGF_mainloop();
+ return NULL;
+ }
<+===================
//cameraRear->waitForPreviewStart();
mCameraIsPoweredOn = true;//camera is poweron OK!!
mCameraSurfaceControlLock.lock();
mCameraSurfaceControl = surfaceControl;
mCameraSurfaceControlLock.unlock();
ALOGI("[reverse_video] %s Video Working!!", __FUNCTION__);
// 等待 camera 退出信号
{
status_t rc = NO_ERROR;
Mutex::Autolock l(mReqQuitLock);
while (0 == mReqQuit)
{
rc = mReqQuitCondition.wait(mReqQuitLock);
}
}
//stop monitor
VideoLossMonitor::getVideoLossMonitor()->stopMonitor();
//////////
// 调用 stopPreview(), disconnect(), 下电
cameraDevice->stopPreview();
rc = cameraDevice->disconnect();
mCameraIsPoweredOn = false; //camera is poweroff OK!!
mCameraSurfaceControlLock.lock();
mCameraSurfaceControl.clear();
mCameraSurfaceControl = NULL;
mCameraSurfaceControlLock.unlock();
cameraRear->TearDown();
cameraRear.clear();
ALOGI("[reverse_video] %s --- Quit", __FUNCTION__);
}
3.2.1.1.1 CameraService::getNumberOfCameras()
下发的 type = CAMERA_TYPE_ALL,
直接返回 mNumberOfCameras 的值,该值是在CameraService 初始化时赋值的。
@ /frameworks/av/services/camera/libcameraservice/CameraService.cpp
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
switch (type) {
case CAMERA_TYPE_BACKWARD_COMPATIBLE: *numCameras = mNumberOfNormalCameras; break;
case CAMERA_TYPE_ALL: *numCameras = mNumberOfCameras; break;
}
return Status::ok();
}
3.2.1.1.2 connectLegacy()
@ /frameworks/av/camera/Camera.cpp
status_t Camera::connectLegacy(int cameraId, int halVersion, const String16& clientPackageName,int clientUid,sp<Camera>& camera)
{
ALOGV("%s: connect legacy camera device", __FUNCTION__);
sp<Camera> c = new Camera(cameraId);
sp<::android::hardware::ICameraClient> cl = c;
status_t status = NO_ERROR;
const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService();
binder::Status ret;
if (cs != nullptr) {
ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
clientUid, /*out*/&(c->mCamera));
}
if (ret.isOk() && c->mCamera != nullptr) {
IInterface::asBinder(c->mCamera)->linkToDeath(c);
c->mStatus = NO_ERROR;
camera = c;
}
return status;
}
调用 CameraService::connectLegacy()
@ frameworks/av/services/camera/libcameraservice/CameraService.cpp
Status CameraService::connectLegacy( const sp<ICameraClient>& cameraClient,
int cameraId, int halVersion,const String16& clientPackageName,
int clientUid, /*out*/ sp<ICamera>* device)
{
ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion,
clientPackageName, clientUid, USE_CALLING_PID, API_1,
/*legacyMode*/ true, /*shimUpdateOnly*/ false,
/*out*/client);
*device = client;
return ret;
}
@/frameworks/av/services/camera/libcameraservice/CameraService.cpp
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
// give flashlight a chance to close devices if necessary.
mFlashlight->prepareDeviceOpen(cameraId);
int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,/*out*/&tmp)).isOk()) {
return ret;
}
=====================>
+ // frameworks/av/services/camera/libcameraservice/api1/
<====================
err = client->initialize(mCameraProviderManager);
=====================>
+ // frameworks/av/services/camera/libcameraservice/api1/
<====================
device = client;
return ret;
}
四、CameraService 服务初始化
这一块,详细可以参考之前写的文章:《【高通SDM660平台】Camera Init 初始化流程》
五、MessageQueue
先来看下 MessageQueue的定义。
可以看出,MessageQueue 是一个继承自 Thread 的class。
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/header/MessageQueue.h
#ifndef ANDROID_MESSAGEQUEUE_H
#define ANDROID_MESSAGEQUEUE_H
#include "ReverseLooper.h"
using namespace android;
namespace pateo_dls {
class MessageQueue: public Thread{
public:
static MessageQueue* createMessageQueue();
virtual ~MessageQueue();
void sendMessage(int msgID, const sp<MessageHandler>& messageHandler);
void sendMessageDelay(int timeout, int msgID, const sp<MessageHandler>& messageHandler);
void removeMessages(const sp<MessageHandler>& handler);
void removeMessages(const sp<MessageHandler>& handler, int what);
bool hasMessage(const sp<MessageHandler>& handler, int what);
private:
static MessageQueue* sInstance;
MessageQueue();
virtual bool threadLoop();
virtual status_t readyToRun();
virtual void onFirstRef();
sp<ReverseLooper> mLooper;
};
}
#endif //ANDROID_MESSAGEQUEUE_H
5.1 MessageQueue::onFirstRef()
在初始化 MessageQueue 对象时会自动调用 onFirstRef(),在该函数中,主要工作就是 将当前线程跑起来
@ hardware/libhardware/modules/reverse/reversing_video/reverse_utils/MessageQueue.cpp
void MessageQueue::onFirstRef(){
ALOGD("onFirstRef MessageQueue");
run("DLS_MessageQueue", PRIORITY_DISPLAY);
}
5.2 线程自循环 MessageQueue::threadLoop()
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/MessageQueue.cpp
bool MessageQueue::threadLoop(){
ALOGD("Message Queue Enter ThreadLoop to poll Message");
mLooper->pollOnce(-1);
return true;
}
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/header/ReverseLooper.h
int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
inline int pollOnce(int timeoutMillis) {
return pollOnce(timeoutMillis, NULL, NULL, NULL);
}
@ /hardware/libhardware/modules/reverse/reversing_video/reverse_utils/ReverseLooper.cpp
int ReverseLooper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
while (mResponseIndex < mResponses.size()) {
const Response& response = mResponses.itemAt(mResponseIndex++);
int ident = response.request.ident;
if (ident >= 0) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
ALOGD("%p ~ pollOnce - returning signalled identifier %d: fd=%d, events=0x%x, data=%p",
this, ident, fd, events, data);
if (outFd != NULL) *outFd = fd;
if (outEvents != NULL) *outEvents = events;
if (outData != NULL) *outData = data;
return ident;
}
}
if (result != 0) {
ALOGD("%p ~ pollOnce - returning result %d", this, result);
if (outFd != NULL) *outFd = 0;
if (outEvents != NULL) *outEvents = 0;
if (outData != NULL) *outData = NULL;
return result;
}
result = pollInner(timeoutMillis);
}
}
5.2.1 ReverseLooper::pollInner()
int ReverseLooper::pollInner(int timeoutMillis) {
ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
// Adjust the timeout based on when the next message is due.
if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
if (messageTimeoutMillis >= 0 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
timeoutMillis = messageTimeoutMillis;
}
ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d",
this, mNextMessageUptime - now, timeoutMillis);
}
// Poll.
int result = POLL_WAKE;
mResponses.clear();
mResponseIndex = 0;
// We are about to idle.
mPolling = true;
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
// No longer idling.
mPolling = false;
// Acquire lock.
mLock.lock();
// Rebuild epoll set if needed.
if (mEpollRebuildRequired) {
mEpollRebuildRequired = false;
rebuildEpollLocked();
goto Done;
}
// Handle all events.
ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
for (int i = 0; i < eventCount; i++) {
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if (fd == mWakeEventFd) {
if (epollEvents & EPOLLIN) {
awoken();
========>
TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));
}
} else {
ssize_t requestIndex = mRequests.indexOfKey(fd);
if (requestIndex >= 0) {
int events = 0;
if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
pushResponse(events, mRequests.valueAt(requestIndex));
}
}
}
Done: ;
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now) {
// Remove the envelope from the list.
// We keep a strong reference to the handler until the call to handleMessage
// finishes. Then we drop it so that the handler can be deleted *before*
// we reacquire our lock.
{ // obtain handler
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",this, handler.get(), message.what);
handler->handleMessage(message);
} // release handler
mLock.lock();
mSendingMessage = false;
result = POLL_CALLBACK;
} else {
// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
}
}
// Release lock.
mLock.unlock();
// Invoke all response callbacks.
for (size_t i = 0; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if (response.request.ident == POLL_CALLBACK) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
this, response.request.callback.get(), fd, events, data);
#endif
// Invoke the callback. Note that the file descriptor may be closed by
// the callback (and potentially even reused) before the function returns so
// we need to be a little careful when removing the file descriptor afterwards.
int callbackResult = response.request.callback->handleEvent(fd, events, data);
if (callbackResult == 0) {
removeFd(fd, response.request.seq);
}
// Clear the callback reference in the response structure promptly because we
// will not clear the response vector itself until the next poll.
response.request.callback.clear();
result = POLL_CALLBACK;
}
}
return result;
}
三、知识扩展
2.1 Android 线程优先级
ANDROID_PRIORITY_LOWEST 19 可以使用最后的
ANDROID_PRIORITY_BACKGROUND 10 用于background tasks
ANDROID_PRIORITY_NORMAL 0 大部分线程都以这个优先级运行
ANDROID_PRIORITY_FOREGROUND -2 用户正在交互的线程
ANDROID_PRIORITY_DISPLAY -4 UI主线程
ANDROID_PRIORITY_URGENT_DISPLAY -8 这个值由HAL_PRIORITY_URGENT_DISPLAY来指定,当前版本中是-8。只在部分紧急状态下使用
ANDROID_PRIORITY_AUDIO -16 正常情况下的声音线程
ANDROID_PRIORITY_URGENT_AUDIO -19 声音线程(通常情况不用)
ANDROID_PRIORITY_HIGHEST -20 最高优先级,禁止使用
ANDROID_PRIORITY_DEFAULT 0 默认情况下就是ANDROID_PRIORITY_NORMAL
ANDROID_PRIORITY_MORE_FAVORABLE -1 在上述优先级的基础上,用于加大优先级
ANDROID_PRIORITY_LESS_FAVORABLE +1 在上述优先级的基础上,用于减小优先级
数值越大的,优先级越小。因为各等级间的数值并不是连续的,
我们可以通过ANDROID_PRIORITY_MORE_FAVORABLE(-1)
来适当地提高优先级,
或者是利用ANDROID_PRIORITY_LESS_FAVORABLE(+1)
来降低优先级。