1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include "input_manager.h" 16#include <stdio.h> 17#include <stdlib.h> 18#include <unistd.h> 19#include <limits.h> 20#include <fcntl.h> 21#include <malloc.h> 22#include <sys/ioctl.h> 23#include <securec.h> 24#include "hdf_io_service_if.h" 25#include "osal_time.h" 26#include "input_common.h" 27 28#define TOUCH_INDEX 1 29#define PLACEHOLDER_LENGTH 2 30#define PLACEHOLDER_LIMIT 10 31 32static InputDevManager *g_devManager; 33int32_t InstanceReporterHdi(InputReporter **hdi); 34int32_t InstanceControllerHdi(InputController **hdi); 35int32_t UpdateDevFullInfo(uint32_t devIndex); 36 37InputDevManager *GetDevManager(void) 38{ 39 return g_devManager; 40} 41 42static int32_t GetInputDevice(uint32_t devIndex, InputDeviceInfo **devInfo) 43{ 44 int32_t ret; 45 int32_t count = 3; // 3 : number of attempts 46 DeviceInfoNode *pos = NULL; 47 DeviceInfoNode *next = NULL; 48 InputDevManager *manager = NULL; 49 50 if (devIndex >= MAX_INPUT_DEV_NUM || devInfo == NULL) { 51 HDF_LOGE("%s: invalid param", __func__); 52 return INPUT_INVALID_PARAM; 53 } 54 55 while ((count--) > 0) { 56 ret = UpdateDevFullInfo(devIndex); 57 if (ret == INPUT_SUCCESS) { 58 break; 59 } 60 OsalMSleep(10); // 10 : delay time 61 } 62 if (count == 0) { 63 HDF_LOGE("%s: update dev info failed", __func__); 64 return ret; 65 } 66 67 GET_MANAGER_CHECK_RETURN(manager); 68 69 pthread_mutex_lock(&manager->mutex); 70 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) { 71 if (pos->payload.devIndex != devIndex) { 72 continue; 73 } 74 *devInfo = &pos->payload; 75 pthread_mutex_unlock(&manager->mutex); 76 HDF_LOGI("%s: device%u get dev info succ", __func__, devIndex); 77 return INPUT_SUCCESS; 78 } 79 80 pthread_mutex_unlock(&manager->mutex); 81 HDF_LOGE("%s: device%u doesn't exist, can't get device info", __func__, devIndex); 82 return INPUT_FAILURE; 83} 84 85static int32_t GetInputDeviceList(uint32_t *devNum, InputDeviceInfo **deviceList, uint32_t size) 86{ 87 DeviceInfoNode *pos = NULL; 88 DeviceInfoNode *next = NULL; 89 InputDevManager *manager = NULL; 90 uint32_t tempSize = 0; 91 InputDeviceInfo **tempList = NULL; 92 93 if (devNum == NULL || deviceList == NULL) { 94 HDF_LOGE("%s: invalid param", __func__); 95 return INPUT_INVALID_PARAM; 96 } 97 tempList = deviceList; 98 GET_MANAGER_CHECK_RETURN(manager); 99 100 pthread_mutex_lock(&manager->mutex); 101 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) { 102 if (tempSize >= size) { 103 *devNum = manager->attachedDevNum; 104 pthread_mutex_unlock(&manager->mutex); 105 HDF_LOGE("%s: size is not enough, size = %u, devNum = %u", __func__, 106 size, *devNum); 107 return INPUT_FAILURE; 108 } 109 *tempList = &pos->payload; 110 tempList++; 111 tempSize++; 112 } 113 *devNum = manager->attachedDevNum; 114 pthread_mutex_unlock(&manager->mutex); 115 return INPUT_SUCCESS; 116} 117 118static int32_t CloseInputDevice(uint32_t devIndex) 119{ 120 DeviceInfoNode *pos = NULL; 121 DeviceInfoNode *next = NULL; 122 InputDevManager *manager = NULL; 123 124 GET_MANAGER_CHECK_RETURN(manager); 125 126 pthread_mutex_lock(&manager->mutex); 127 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) { 128 if (pos->payload.devIndex != devIndex) { 129 continue; 130 } 131 HdfIoServiceRecycle(pos->service); 132 DListRemove(&pos->node); 133 free(pos); 134 manager->attachedDevNum--; 135 pthread_mutex_unlock(&manager->mutex); 136 return INPUT_SUCCESS; 137 } 138 139 pthread_mutex_unlock(&manager->mutex); 140 HDF_LOGE("%s: device%u doesn't exist", __func__, devIndex); 141 return INPUT_FAILURE; 142} 143 144static int32_t AddService(uint32_t index, const struct HdfIoService *service) 145{ 146 InputDevManager *manager = NULL; 147 DeviceInfoNode *device = NULL; 148 149 GET_MANAGER_CHECK_RETURN(manager); 150 device = (DeviceInfoNode *)malloc(sizeof(DeviceInfoNode)); 151 if (device == NULL) { 152 HDF_LOGE("%s: malloc fail", __func__); 153 return INPUT_NOMEM; 154 } 155 (void)memset_s(device, sizeof(DeviceInfoNode), 0, sizeof(DeviceInfoNode)); 156 157 device->payload.devIndex = index; 158 device->service = (struct HdfIoService *)service; 159 pthread_mutex_lock(&manager->mutex); 160 DListInsertTail(&device->node, &manager->devList); 161 manager->attachedDevNum++; 162 pthread_mutex_unlock(&manager->mutex); 163 return INPUT_SUCCESS; 164} 165 166static int32_t CheckIndex(uint32_t devIndex) 167{ 168 DeviceInfoNode *pos = NULL; 169 DeviceInfoNode *next = NULL; 170 InputDevManager *manager = NULL; 171 172 if (devIndex >= MAX_INPUT_DEV_NUM) { 173 HDF_LOGE("%s: invalid param", __func__); 174 return INPUT_INVALID_PARAM; 175 } 176 177 GET_MANAGER_CHECK_RETURN(manager); 178 pthread_mutex_lock(&manager->mutex); 179 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) { 180 if (pos->payload.devIndex == devIndex) { 181 pthread_mutex_unlock(&manager->mutex); 182 HDF_LOGE("%s: the device%u has existed", __func__, devIndex); 183 return INPUT_FAILURE; 184 } 185 } 186 pthread_mutex_unlock(&manager->mutex); 187 return INPUT_SUCCESS; 188} 189 190static int32_t OpenInputDevice(uint32_t devIndex) 191{ 192 int32_t ret; 193 int32_t len; 194 struct HdfIoService *service = NULL; 195 char serviceName[SERVICE_NAME_LEN] = {0}; 196 197 if (CheckIndex(devIndex) != INPUT_SUCCESS) { 198 return INPUT_FAILURE; 199 } 200 201 len = (devIndex < PLACEHOLDER_LIMIT) ? 1 : PLACEHOLDER_LENGTH; 202 ret = snprintf_s(serviceName, SERVICE_NAME_LEN, strlen("hdf_input_event") + len, "%s%u", 203 "hdf_input_event", devIndex); 204 if (ret == -1) { 205 HDF_LOGE("%s: snprintf_s fail", __func__); 206 return INPUT_FAILURE; 207 } 208 209 service = HdfIoServiceBind(serviceName); 210 if (service == NULL) { 211 HDF_LOGE("%s: fail to get io service: %s", __func__, serviceName); 212 return INPUT_NULL_PTR; 213 } 214 215 if (AddService(devIndex, service) < 0) { 216 HDF_LOGE("%s: add device%d failed", __func__, devIndex); 217 HdfIoServiceRecycle(service); 218 return INPUT_FAILURE; 219 } 220 221 HDF_LOGI("%s: open dev%u succ, service name = %s", __func__, devIndex, serviceName); 222 return INPUT_SUCCESS; 223} 224 225static int32_t ScanInputDevice(InputDevDesc *staArr, uint32_t arrLen) 226{ 227 InputDevManager *manager = NULL; 228 struct HdfIoService *service = NULL; 229 struct HdfSBuf *reply = NULL; 230 char *data = {0}; 231 uint32_t count = 0; 232 uint32_t replayDataSize = 0; 233 int32_t ret; 234 235 GET_MANAGER_CHECK_RETURN(manager); 236 pthread_mutex_lock(&manager->mutex); 237 if (manager->hostDev.service == NULL) { 238 manager->hostDev.service = HdfIoServiceBind(DEV_MANAGER_SERVICE_NAME); 239 } 240 service = manager->hostDev.service; 241 pthread_mutex_unlock(&manager->mutex); 242 243 if (service == NULL) { 244 HDF_LOGE("%s: HdfIoServiceBind failed", __func__); 245 return INPUT_FAILURE; 246 } 247 reply = HdfSbufObtainDefaultSize(); 248 if (reply == NULL) { 249 HDF_LOGE("%s: fail to obtain sbuf data", __func__); 250 return INPUT_FAILURE; 251 } 252 253 ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply); 254 if (ret != INPUT_SUCCESS) { 255 HDF_LOGE("%s: dispatch fail", __func__); 256 HdfSbufRecycle(reply); 257 return INPUT_FAILURE; 258 } 259 260 while (count < arrLen) { 261 if (!HdfSbufReadBuffer(reply, (const void **)(&data), &replayDataSize) || 262 replayDataSize != sizeof(InputDevDesc)) { 263 HDF_LOGE("%s: sbuf read failed", __func__); 264 break; 265 } 266 if (memcpy_s(&staArr[count], sizeof(InputDevDesc), data, replayDataSize) != EOK) { 267 HDF_LOGE("%s: memcpy failed, line: %d", __func__, __LINE__); 268 HdfSbufRecycle(reply); 269 return INPUT_FAILURE; 270 } 271 HDF_LOGI("%s: type = %d, id =%d", __func__, staArr[count].devType, staArr[count].devIndex); 272 count++; 273 } 274 HdfSbufRecycle(reply); 275 return INPUT_SUCCESS; 276} 277 278static int32_t InstanceManagerHdi(InputManager **manager) 279{ 280 InputManager *managerHdi = (InputManager *)malloc(sizeof(InputManager)); 281 if (managerHdi == NULL) { 282 HDF_LOGE("%s: malloc fail", __func__); 283 return INPUT_NOMEM; 284 } 285 286 (void)memset_s(managerHdi, sizeof(InputManager), 0, sizeof(InputManager)); 287 288 managerHdi->ScanInputDevice = ScanInputDevice; 289 managerHdi->OpenInputDevice = OpenInputDevice; 290 managerHdi->CloseInputDevice = CloseInputDevice; 291 managerHdi->GetInputDevice = GetInputDevice; 292 managerHdi->GetInputDeviceList = GetInputDeviceList; 293 *manager = managerHdi; 294 return INPUT_SUCCESS; 295} 296 297static int32_t InitDevManager(void) 298{ 299 InputDevManager *manager = (InputDevManager *)malloc(sizeof(InputDevManager)); 300 if (manager == NULL) { 301 HDF_LOGE("%s: malloc fail", __func__); 302 return INPUT_NOMEM; 303 } 304 305 (void)memset_s(manager, sizeof(InputDevManager), 0, sizeof(InputDevManager)); 306 DListHeadInit(&manager->devList); 307 pthread_mutex_init(&manager->mutex, NULL); 308 manager->attachedDevNum = 0; 309 manager->evtCallbackNum = 0; 310 g_devManager = manager; 311 return INPUT_SUCCESS; 312} 313 314static void FreeInputHdi(IInputInterface **hdi) 315{ 316 if (hdi == NULL || *hdi == NULL) { 317 return; 318 } 319 if ((*hdi)->iInputManager != NULL) { 320 free((*hdi)->iInputManager); 321 (*hdi)->iInputManager = NULL; 322 } 323 324 if ((*hdi)->iInputController != NULL) { 325 free((*hdi)->iInputController); 326 (*hdi)->iInputController = NULL; 327 } 328 329 if ((*hdi)->iInputReporter != NULL) { 330 free((*hdi)->iInputReporter); 331 (*hdi)->iInputReporter = NULL; 332 } 333 free((*hdi)); 334 *hdi = NULL; 335} 336 337static IInputInterface *InstanceInputHdi(void) 338{ 339 int32_t ret; 340 IInputInterface *hdi = (IInputInterface *)malloc(sizeof(IInputInterface)); 341 if (hdi == NULL) { 342 HDF_LOGE("%s: malloc fail", __func__); 343 return NULL; 344 } 345 (void)memset_s(hdi, sizeof(IInputInterface), 0, sizeof(IInputInterface)); 346 347 ret = InstanceManagerHdi(&hdi->iInputManager); 348 if (ret != INPUT_SUCCESS) { 349 FreeInputHdi(&hdi); 350 return NULL; 351 } 352 353 ret = InstanceControllerHdi(&hdi->iInputController); 354 if (ret != INPUT_SUCCESS) { 355 FreeInputHdi(&hdi); 356 return NULL; 357 } 358 359 ret = InstanceReporterHdi(&hdi->iInputReporter); 360 if (ret != INPUT_SUCCESS) { 361 FreeInputHdi(&hdi); 362 return NULL; 363 } 364 return hdi; 365} 366 367int32_t GetInputInterface(IInputInterface **inputInterface) 368{ 369 int32_t ret; 370 IInputInterface *inputHdi = NULL; 371 372 if (inputInterface == NULL) { 373 HDF_LOGE("%s: parameter is null", __func__); 374 return INPUT_INVALID_PARAM; 375 } 376 377 inputHdi = InstanceInputHdi(); 378 if (inputHdi == NULL) { 379 HDF_LOGE("%s: failed to instance hdi", __func__); 380 return INPUT_NULL_PTR; 381 } 382 383 ret = InitDevManager(); 384 if (ret != INPUT_SUCCESS) { 385 HDF_LOGE("%s: failed to initialize manager", __func__); 386 FreeInputHdi(&inputHdi); 387 return INPUT_FAILURE; 388 } 389 390 *inputInterface = inputHdi; 391 HDF_LOGI("%s: exit succ", __func__); 392 return INPUT_SUCCESS; 393} 394 395static void FreeDevManager(InputDevManager *manager) 396{ 397 (void)HdfDeviceUnregisterEventListener(manager->hostDev.service, manager->hostDev.listener); 398 if (manager->hostDev.listener != NULL) { 399 free(manager->hostDev.listener); 400 manager->hostDev.listener = NULL; 401 manager->hostDev.hostCb = NULL; 402 } 403 (void)HdfIoServiceRecycle(manager->hostDev.service); 404 pthread_mutex_unlock(&manager->mutex); 405 pthread_mutex_destroy(&manager->mutex); 406 free(manager); 407 g_devManager = NULL; 408} 409 410void ReleaseInputInterface(IInputInterface **inputInterface) 411{ 412 DeviceInfoNode *pos = NULL; 413 DeviceInfoNode *next = NULL; 414 InputDevManager *manager = NULL; 415 416 if (inputInterface == NULL) { 417 return; 418 } 419 FreeInputHdi(inputInterface); 420 421 if (g_devManager == NULL) { 422 return; 423 } 424 manager = g_devManager; 425 pthread_mutex_lock(&manager->mutex); 426 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) { 427 (void)HdfDeviceUnregisterEventListener(pos->service, pos->listener); 428 if (pos->listener != NULL) { 429 free(pos->listener); 430 pos->listener = NULL; 431 pos->eventCb = NULL; 432 } 433 (void)HdfIoServiceRecycle(pos->service); 434 DListRemove(&pos->node); 435 free(pos); 436 } 437 FreeDevManager(manager); 438}