【MSM8937】【倒车影像】代码流程分析



一、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()

  1. 在构造函数中,调用 initFunc()进行初始化

  2. 将当前状态设置为 STATE_HIDE ,即 OFF 状态

  3. 初始化 reverse_video 对象,用于控制 Camera 的开关,
    保存在全局变量 reverse_video* reverse_video::sInstance = 0;

  4. 初始化 UIController 对象,用于控制 UI 的显示
    保存在全局变量 UIController* UIController::mInstance = 0;

  5. 初始化 reverse_control 线程,用于监听和控制 Camera 的状态
    保存在全局变量 reverse_control* reverse_control::sInstance = 0;

  6. 初始化 dls_task_thread 线程,用于控制进入和退出dls,
    保存在全局变量 dls_task_thread* dls_task_thread::sInstance = 0;

  7. 初始化 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(),主要工作如下:

  1. 初始化 pateo uevent, 绑这下netlink socket,设备描述符保存在 d_sig_fd_sets.sigdet_uevent_fd
  2. 并打开 "dev/sigdet0" 节点 ,把设备描述符保存在 d_sig_fd_sets.sigdet_get_fd
  3. 调用 initReverseDataByIoctl()
  4. 获取车机 acc ,baterry, pdc, Can board,reverseState 这些信息,根投当前车机状态来更新倒车影像的 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()

  1. 创建 NETLINK socket, protocol 协议为 NETLINK_CIS_SIGDET
  2. 配置 socket receve buff size128 * 1024
  3. 绑定 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()

  1. 变量初始化
  2. "dev/sigdet0" 发送 SIGDET_GET_ACC_STATE 命令 获取 ACC 状态,保存在 m_acc_state
  3. "dev/sigdet0" 发送 SIGDET_GET_REVERSE_STATE 命令获取倒车影像的状态,状态保存在 m_reverse_gear_state
  4. "dev/sigdet0" 发送 SIGDET_GET_CANB_STATE 命令获取 Can board 状态,保存在 m_canb_state
  5. "dev/sigdet0" 发送 SIGDET_GET_BATTERY_STATE 命令 get battery state,保存在 m_battery_state
  6. "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()

  1. 根据当前车机状态向更新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 初始化成功后,就开始监听系统消息了

  1. 调用 pateo_uevent_next_event() 开始循环poll 监听 NETLINK_CIS_SIGDET 的socket event 事件 event 消息

  2. 一个调试demon
    如果接收到CAN 消息, mEventData[0] = 0x85, mEventData[0]=4, 则说时是进入倒车影像
    根据 mEventData[3] 判断开还是关倒车影像

  3. 根据监听到的socket event 事件做相关处理,我们此处重点看下 CMD_REVERSE_CAN_STATE
    当有状态更新时,调用updateReverseCondition() 来更新倒车影像状态
    事件包括:
    CMD_ACC_STATECMD_FRONT_PDC_VALUECMD_REAR_PDC_VALUE
    CMD_REVERSE_CAN_STATECMD_BATTERY_STATECMD_PASWORK_STATE
    CMD_SPEED_VALUECMD_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 线程自循环

  1. 等待mCommandQueue 事件到
  2. 处理事件
@ 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()

  1. mStateManager->notifyEnterPreReverseState()
    通过 BpReverseClient 代理调用 BnReverseClientonPrepareReverseChange()
    onPrepareReverseChange() 函数定义在 class IReverseClient 中,定义在include/IReverseClient.h
    class BnReverseClient 继承自 class IReverseClient
    接下来看下,谁继承了 BnReverseClient ,就知道onPrepareReverseChange()函数实际处理的地方。

  2. 调用BnReverseClientonPrepareReverseChange(),参数传递 PRE_STATE_ENTERPRE_STATE_EXIT

  3. 调用 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()

  1. 创建pthread ,运行函数 reverse_video::threadLoop()
  2. 阻塞等待Camera 初始化完毕 mCameraInitDoneCondition.wait(mCameraInitDoneLock);
  3. 等待 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, &param);
	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()

  1. 实例化 RearCamera() 对象,将 mCameraInitDone 标志位设置为 false

  2. 通过 binder 获取 名为 "media.camera" 的CameraService服务,调用getNumberOfCameras() 获取 Camera 个数,下发参数 CAMERA_TYPE_ALL

  3. 调用 cameraRear->mCameraService->connectLegacy() 函数开始连接Camera, 获得 CameraDevice 的设备操作函数

  4. 调用getParameters()获得当前Camera 参数

  5. 配置对焦模式,接着调用 setParameters() 下发参数

  6. 配置 Display 宽高,根据 preview size 创建 Surface

  7. 在配置好对应的参数后,开始调用 startPreview(), 成功后,发送mCameraInitDoneCondition.broadcast() 广播

  8. start to monitor vdloss, 开始正常显示camera

  9. 等待 camera 退出信号

  10. stop monitor

  11. 调用 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)来降低优先级。



发布了355 篇原创文章 · 获赞 81 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/Ciellee/article/details/105735455