Files
drivers_framework/model/input/driver/hdf_input_device_manager.c
T
lianghua 6b1bbd0e46 fix input code warning
Signed-off-by: lianghua <lianghua14@huawei.com>
2022-03-07 02:03:57 -08:00

484 lines
14 KiB
C

/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_input_device_manager.h"
#include <securec.h>
#include "event_hub.h"
#include "hdf_base.h"
#include "hdf_device_object.h"
#include "hdf_log.h"
#include "osal_mem.h"
#define NODE_MODE 0660
#define SERVICE_NAME_LEN 24
#define INPUT_DEV_EXIST 1
#define INPUT_DEV_NOT_EXIST 0
#define INPUTDEV_FIRST_ID 2
#define FILLER_FLAG 1
#define PLACEHOLDER_LENGTH 2
#define PLACEHOLDER_LIMIT 10
static InputManager *g_inputManager;
InputManager* GetInputManager(void)
{
return g_inputManager;
}
static bool IsHidDevice(uint32_t devType)
{
if ((devType > INDEV_TYPE_HID_BEGIN_POS) && (devType < INDEV_TYPE_UNKNOWN)) {
return true;
#ifdef CONFIG_ARCH_ROCKCHIP
} else if (devType == INDEV_TYPE_KEY) {
return true;
#endif
}
return false;
}
static struct HdfDeviceObject *HidRegisterHdfDevice(InputDevice *inputDev)
{
char svcName[SERVICE_NAME_LEN] = {0};
const char *moduleName = "HDF_HID";
struct HdfDeviceObject *hdfDev = NULL;
int32_t len = (inputDev->devId < PLACEHOLDER_LIMIT) ? 1 : PLACEHOLDER_LENGTH;
int32_t ret = snprintf_s(svcName, SERVICE_NAME_LEN, strlen("hdf_input_event") + len, "%s%u",
"hdf_input_event", inputDev->devId);
if (ret < 0) {
HDF_LOGE("%s: snprintf_s failed", __func__);
return NULL;
}
hdfDev = HdfDeviceObjectAlloc(g_inputManager->hdfDevObj, moduleName);
if (hdfDev == NULL) {
HDF_LOGE("%s: failed to alloc device object", __func__);
return NULL;
}
ret = HdfDeviceObjectRegister(hdfDev);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: failed to regitst device %s", __func__, moduleName);
HdfDeviceObjectRelease(hdfDev);
return NULL;
}
ret = HdfDeviceObjectPublishService(hdfDev, svcName, SERVICE_POLICY_CAPACITY, 0664); // 0664:permission setting
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: failed to regitst device %s", __func__, moduleName);
HdfDeviceObjectRelease(hdfDev);
return NULL;
}
inputDev->hdfDevObj = hdfDev;
HDF_LOGI("%s: svcName is %s, devName = %s", __func__, svcName, inputDev->devName);
return hdfDev;
}
static void HotPlugNotify(const InputDevice *inputDev, uint32_t status)
{
HotPlugEvent event = {0};
int32_t ret;
if (inputDev->eventBuf == NULL) {
HDF_LOGE("%s: event buffer is null", __func__);
return;
}
event.devId = inputDev->devId;
event.devType = inputDev->devType;
event.status = status;
if (!HdfSbufWriteBuffer(inputDev->eventBuf, &event, sizeof(HotPlugEvent))) {
HDF_LOGE("%s: write buffer failed", __func__);
HdfSbufFlush(inputDev->eventBuf);
return;
}
ret = HdfDeviceSendEvent(g_inputManager->hdfDevObj, 0, inputDev->eventBuf);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: send event failed", __func__);
}
HdfSbufFlush(inputDev->eventBuf);
}
static int32_t CreateDeviceNode(InputDevice *inputDev)
{
if (IsHidDevice(inputDev->devType)) {
HDF_LOGI("%s: prepare to register hdf device", __func__);
inputDev->hdfDevObj = HidRegisterHdfDevice(inputDev);
if (inputDev->hdfDevObj == NULL) {
return HDF_DEV_ERR_NO_DEVICE;
}
inputDev->hdfDevObj->priv = (void *)inputDev;
}
HDF_LOGI("%s: create node succ, devId is %d ", __func__, inputDev->devId);
return HDF_SUCCESS;
}
static void DeleteDeviceNode(InputDevice *inputDev)
{
if (IsHidDevice(inputDev->devType)) {
HDF_LOGI("remove input device: hdf_input_event%u", inputDev->devId);
HdfDeviceObjectRelease(inputDev->hdfDevObj);
}
HDF_LOGI("%s: delete node succ, devId is %d", __func__, inputDev->devId);
}
static void AddInputDevice(InputDevice *inputDev)
{
InputDevice *tmpDev = NULL;
if (g_inputManager->inputDevList == NULL) {
g_inputManager->inputDevList = inputDev;
(g_inputManager->inputDevList)->next = NULL;
} else {
tmpDev = g_inputManager->inputDevList;
while (tmpDev != NULL) {
if (tmpDev->next == NULL) {
tmpDev->next = inputDev;
inputDev->next = NULL;
break;
}
tmpDev = tmpDev->next;
}
}
g_inputManager->devCount++;
HotPlugNotify(inputDev, ONLINE);
}
static int32_t CheckInputDevice(InputDevice *inputDev)
{
InputDevice *tmpDev = NULL;
if (g_inputManager->inputDevList == NULL) {
return HDF_SUCCESS;
} else {
tmpDev = g_inputManager->inputDevList;
while (tmpDev != NULL) {
if (tmpDev->devId == inputDev->devId) {
HDF_LOGE("%s: device%d registered", __func__, inputDev->devId);
return INPUT_DEV_EXIST;
}
tmpDev = tmpDev->next;
}
}
return INPUT_DEV_NOT_EXIST;
}
static int32_t DeleteInputDevice(InputDevice *inputDev)
{
if (g_inputManager->inputDevList == NULL) {
return HDF_FAILURE;
} else {
if ((g_inputManager->inputDevList)->devId == inputDev->devId) {
g_inputManager->inputDevList = g_inputManager->inputDevList->next;
goto EXIT;
}
InputDevice *preNode = g_inputManager->inputDevList;
InputDevice *tmpDev = preNode->next;
while (tmpDev != NULL) {
if (tmpDev->devId == inputDev->devId) {
preNode->next = tmpDev->next;
goto EXIT;
}
preNode = tmpDev;
tmpDev = tmpDev->next;
}
HDF_LOGE("%s: device%d not exist", __func__, inputDev->devId);
return HDF_FAILURE;
}
EXIT:
g_inputManager->devCount--;
HotPlugNotify(inputDev, OFFLINE);
return HDF_SUCCESS;
}
#define DEFAULT_TOUCH_BUF_PKG_NUM 50
#define DEFAULT_KEY_BUF_PKG_NUM 10
#define DEFAULT_MOUSE_BUF_PKG_NUM 30
#define DEFAULT_KEYBOARD_BUF_PKG_NUM 20
#define DEFAULT_CROWN_BUF_PKG_NUM 20
#define DEFAULT_ENCODER_BUF_PKG_NUM 20
#define DEFAULT_ROCKER_BUF_PKG_NUM 40
#define DEFAULT_TRACKBALL_BUF_PKG_NUM 30
static int32_t AllocPackageBuffer(InputDevice *inputDev)
{
uint16_t pkgNum;
switch (inputDev->devType) {
case INDEV_TYPE_TOUCH:
pkgNum = DEFAULT_TOUCH_BUF_PKG_NUM;
break;
case INDEV_TYPE_KEY:
pkgNum = DEFAULT_KEY_BUF_PKG_NUM;
break;
case INDEV_TYPE_MOUSE:
pkgNum = DEFAULT_MOUSE_BUF_PKG_NUM;
break;
case INDEV_TYPE_KEYBOARD:
pkgNum = DEFAULT_KEYBOARD_BUF_PKG_NUM;
break;
case INDEV_TYPE_CROWN:
pkgNum = DEFAULT_CROWN_BUF_PKG_NUM;
break;
case INDEV_TYPE_ENCODER:
pkgNum = DEFAULT_ENCODER_BUF_PKG_NUM;
break;
case INDEV_TYPE_ROCKER:
pkgNum = DEFAULT_ROCKER_BUF_PKG_NUM;
break;
case INDEV_TYPE_TRACKBALL:
pkgNum = DEFAULT_TRACKBALL_BUF_PKG_NUM;
break;
default:
HDF_LOGE("%s: devType not exist", __func__);
return HDF_FAILURE;
}
inputDev->pkgBuf = HdfSbufObtain(sizeof(EventPackage) * pkgNum);
if (inputDev->pkgBuf == NULL) {
HDF_LOGE("%s: malloc sbuf failed", __func__);
return HDF_ERR_MALLOC_FAIL;
}
inputDev->eventBuf = HdfSbufObtain(sizeof(HotPlugEvent));
if (inputDev->eventBuf == NULL) {
HDF_LOGE("%s: malloc sbuf failed", __func__);
return HDF_ERR_MALLOC_FAIL;
}
inputDev->pkgNum = pkgNum;
return HDF_SUCCESS;
}
static int32_t AllocDeviceID(InputDevice *inputDev)
{
InputDevice *tmpDev = g_inputManager->inputDevList;
uint32_t idList[MAX_INPUT_DEV_NUM + 1];
uint32_t id;
int32_t ret;
ret = memset_s(idList, (MAX_INPUT_DEV_NUM + 1) * sizeof(uint32_t), 0,
(MAX_INPUT_DEV_NUM + 1) * sizeof(uint32_t));
if (ret != 0) {
HDF_LOGE("%s: memset_s is failed", __func__);
return HDF_FAILURE;
}
while (tmpDev != NULL) {
if (idList[tmpDev->devId] == 0) {
idList[tmpDev->devId] = FILLER_FLAG;
}
tmpDev = tmpDev->next;
}
if (inputDev->devType == INDEV_TYPE_TOUCH) {
inputDev->devId = 1;
return HDF_SUCCESS;
}
for (id = INPUTDEV_FIRST_ID; id < MAX_INPUT_DEV_NUM + 1; id++) {
if (idList[id] == 0) {
inputDev->devId = id;
return HDF_SUCCESS;
}
}
HDF_LOGE("%s: alloc device id failed", __func__);
return HDF_FAILURE;
}
int32_t RegisterInputDevice(InputDevice *inputDev)
{
int32_t ret;
HDF_LOGI("%s: enter", __func__);
if (inputDev == NULL) {
HDF_LOGE("%s: inputdev is null", __func__);
return HDF_ERR_INVALID_PARAM;
}
if ((g_inputManager == NULL) || (g_inputManager->initialized == false)) {
HDF_LOGE("%s: dev manager is null or initialized failed", __func__);
return HDF_FAILURE;
}
OsalMutexLock(&g_inputManager->mutex);
ret = AllocDeviceID(inputDev);
if (ret != HDF_SUCCESS) {
goto EXIT;
}
ret = CreateDeviceNode(inputDev);
if (ret != HDF_SUCCESS) {
goto EXIT1;
}
ret = AllocPackageBuffer(inputDev);
if (ret != HDF_SUCCESS) {
goto EXIT1;
}
AddInputDevice(inputDev);
OsalMutexUnlock(&g_inputManager->mutex);
HDF_LOGI("%s: exit succ, devCount is %d", __func__, g_inputManager->devCount);
return HDF_SUCCESS;
EXIT1:
DeleteDeviceNode(inputDev);
EXIT:
OsalMutexUnlock(&g_inputManager->mutex);
return ret;
}
void UnregisterInputDevice(InputDevice *inputDev)
{
int32_t ret;
HDF_LOGI("%s: enter", __func__);
if (inputDev == NULL) {
HDF_LOGE("%s: inputdev is null", __func__);
return;
}
if ((g_inputManager == NULL) || (g_inputManager->initialized == false)) {
HDF_LOGE("%s: dev manager is null or initialized failed", __func__);
return;
}
OsalMutexLock(&g_inputManager->mutex);
if (CheckInputDevice(inputDev) == INPUT_DEV_NOT_EXIST) {
HDF_LOGE("%s: dev%d not exist", __func__, inputDev->devId);
goto EXIT;
}
DeleteDeviceNode(inputDev);
HdfSbufRecycle(inputDev->pkgBuf);
inputDev->pkgBuf = NULL;
ret = DeleteInputDevice(inputDev);
if (ret != HDF_SUCCESS) {
goto EXIT;
}
HdfSbufRecycle(inputDev->eventBuf);
inputDev->eventBuf = NULL;
OsalMemFree(inputDev);
OsalMutexUnlock(&g_inputManager->mutex);
HDF_LOGI("%s: exit succ, devCount is %d", __func__, g_inputManager->devCount);
return;
EXIT:
OsalMutexUnlock(&g_inputManager->mutex);
return;
}
static uint32_t GetDeviceCount(void)
{
HDF_LOGI("%s: devCount = %d", __func__, g_inputManager->devCount);
return g_inputManager->devCount;
}
static int32_t ScanAllDev(struct HdfSBuf *reply)
{
DevDesc sta;
InputDevice *tmpDev = g_inputManager->inputDevList;
while (tmpDev != NULL) {
sta.devType = tmpDev->devType;
sta.devId = tmpDev->devId;
if (!HdfSbufWriteBuffer(reply, &sta, sizeof(DevDesc))) {
HDF_LOGE("%s: HdfSbufWriteBuffer failed", __func__);
return HDF_FAILURE;
}
tmpDev = tmpDev->next;
}
HdfSbufWriteBuffer(reply, NULL, 0); // end flag
return HDF_SUCCESS;
}
static int32_t ScanDevice(struct HdfDeviceIoClient *client, int32_t cmd,
struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)cmd;
int32_t ret;
if ((client == NULL) || (data == NULL) || (reply == NULL)) {
HDF_LOGE("%s: param is null", __func__);
return HDF_FAILURE;
}
ret = ScanAllDev(reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: scan all dev failed", __func__);
}
return ret;
}
static int32_t HdfInputManagerBind(struct HdfDeviceObject *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_PARAM;
}
static IInputManagerService managerService = {
.getDeviceCount = GetDeviceCount,
.ioService.Dispatch = ScanDevice,
};
device->service = &managerService.ioService;
return HDF_SUCCESS;
}
static InputManager *InputManagerInstance(void)
{
InputManager *manager = (InputManager *)OsalMemAlloc(sizeof(InputManager));
if (manager == NULL) {
HDF_LOGE("%s: instance input manager failed", __func__);
return NULL;
}
(void)memset_s(manager, sizeof(InputManager), 0, sizeof(InputManager));
return manager;
}
static int32_t HdfInputManagerInit(struct HdfDeviceObject *device)
{
HDF_LOGI("%s: enter", __func__);
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return HDF_ERR_INVALID_PARAM;
}
g_inputManager = InputManagerInstance();
if (g_inputManager == NULL) {
return HDF_ERR_MALLOC_FAIL;
}
if (OsalMutexInit(&g_inputManager->mutex) != HDF_SUCCESS) {
HDF_LOGE("%s: mutex init failed", __func__);
OsalMemFree(g_inputManager);
g_inputManager = NULL;
return HDF_FAILURE;
}
g_inputManager->initialized = true;
g_inputManager->hdfDevObj = device;
HDF_LOGI("%s: exit succ", __func__);
return HDF_SUCCESS;
}
static void HdfInputManagerRelease(struct HdfDeviceObject *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is null", __func__);
return;
}
if (g_inputManager != NULL) {
OsalMutexDestroy(&g_inputManager->mutex);
OsalMemFree(g_inputManager);
g_inputManager = NULL;
}
}
struct HdfDriverEntry g_hdfInputEntry = {
.moduleVersion = 1,
.moduleName = "HDF_INPUT_MANAGER",
.Bind = HdfInputManagerBind,
.Init = HdfInputManagerInit,
.Release = HdfInputManagerRelease,
};
HDF_INIT(g_hdfInputEntry);