1/* 2 * Copyright (c) 2021-2023 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 16#include "audio_pathselect.h" 17#include "audio_uhdf_log.h" 18#include "cJSON.h" 19#include "osal_mem.h" 20#include "securec.h" 21 22#ifdef IDL_MODE 23#define HDF_LOG_TAG AUDIO_HDI_IMPL 24#else 25#define HDF_LOG_TAG HDF_AUDIO_HAL_IMPL 26#endif 27 28#define SPEAKER "Speaker" 29#define HEADPHONES "Headphones" 30#define MIC "MIC" 31#define HS_MIC "micHs" 32#define EARPIECE "earpiece" 33#define BLUETOOTH_SCO "Bluetooth" 34#define BLUETOOTH_SCO_HEADSET "Bluetooth_SCO_Headset" 35#define JSON_UNPRINT 1 36 37#define OUTPUT_MASK 0xFFF 38#define OUTPUT_OFFSET 12 39#define INPUT_MASK 0x80000FF 40#define INPUT_OFFSET 27 41 42#define AUDIO_DEV_ON 1 43#define AUDIO_DEV_OFF 0 44 45#define HDF_PATH_NUM_MAX 32 46 47static cJSON *g_cJsonObj = NULL; 48 49int32_t AudioPathSelGetConfToJsonObj(void) 50{ 51 FILE *fpJson = NULL; 52 char *pJsonStr = NULL; 53 if (g_cJsonObj != NULL) { 54 return HDF_SUCCESS; 55 } 56 fpJson = fopen(CJSONFILE_CONFIG_PATH, "r"); 57 if (fpJson == NULL) { 58 AUDIO_FUNC_LOGE("open %{pulbic}s fail!", CJSONFILE_CONFIG_PATH); 59 return HDF_FAILURE; 60 } 61 if (fseek(fpJson, 0, SEEK_END) != HDF_SUCCESS) { 62 AUDIO_FUNC_LOGE("fseek fail!"); 63 (void)fclose(fpJson); 64 return HDF_FAILURE; 65 } 66 int32_t jsonStrSize = ftell(fpJson); 67 rewind(fpJson); 68 if (jsonStrSize <= 0) { 69 (void)fclose(fpJson); 70 return HDF_FAILURE; 71 } 72 pJsonStr = (char *)OsalMemCalloc(jsonStrSize + 1); 73 if (pJsonStr == NULL) { 74 (void)fclose(fpJson); 75 return HDF_FAILURE; 76 } 77 if (fread(pJsonStr, jsonStrSize, 1, fpJson) != 1) { 78 AUDIO_FUNC_LOGE("read to file fail!"); 79 (void)fclose(fpJson); 80 fpJson = NULL; 81 OsalMemFree(pJsonStr); 82 return HDF_FAILURE; 83 } 84 (void)fclose(fpJson); 85 fpJson = NULL; 86#ifndef JSON_UNPRINT 87 AUDIO_FUNC_LOGI("pJsonStr = %{public}s", pJsonStr); 88#endif 89 g_cJsonObj = cJSON_Parse(pJsonStr); 90 if (g_cJsonObj == NULL) { 91 AUDIO_FUNC_LOGE("cJSON_GetErrorPtr() = %{public}s", cJSON_GetErrorPtr()); 92 OsalMemFree(pJsonStr); 93 return HDF_FAILURE; 94 } 95 OsalMemFree(pJsonStr); 96 return HDF_SUCCESS; 97} 98 99static const char *AudioPathSelGetDeviceType(enum AudioPortPin pin) 100{ 101 if (pin < PIN_OUT_SPEAKER || pin > PIN_IN_BLUETOOTH_SCO_HEADSET) { 102 return NULL; 103 } 104 switch (pin) { 105 case PIN_OUT_SPEAKER: 106 case PIN_OUT_BLUETOOTH_A2DP: 107 return SPEAKER; 108 case PIN_OUT_HEADSET: 109 return HEADPHONES; 110 case PIN_IN_MIC: 111 return MIC; 112 case PIN_IN_HS_MIC: 113 return HS_MIC; 114 case PIN_OUT_EARPIECE: 115 return EARPIECE; 116 case PIN_OUT_BLUETOOTH_SCO: 117 return BLUETOOTH_SCO; 118 case PIN_IN_BLUETOOTH_SCO_HEADSET: 119 return BLUETOOTH_SCO_HEADSET; 120 default: 121 AUDIO_FUNC_LOGE("UseCase not support!"); 122 break; 123 } 124 return NULL; 125} 126 127static const char *AudioPathSelGetUseCase(enum AudioCategory type) 128{ 129 static const char *usecaseType[AUDIO_MMAP_NOIRQ + 1] = { 130 [AUDIO_IN_MEDIA] = "deep-buffer-playback", 131 [AUDIO_IN_COMMUNICATION] = "low-latency-communication", 132 [AUDIO_IN_RINGTONE] = "ringtone-playback", 133 [AUDIO_IN_CALL] = "voice-call", 134 [AUDIO_MMAP_NOIRQ] = "low-latency-noirq-playback", 135 }; 136 137 if (type < 0 || type > AUDIO_MMAP_NOIRQ) { 138 return NULL; 139 } 140 return usecaseType[type]; 141} 142 143static int32_t SetRenderPathDefaultValue(cJSON *renderSwObj, struct AudioHwRenderParam *renderParam) 144{ 145 if (renderSwObj == NULL || renderParam == NULL) { 146 AUDIO_FUNC_LOGE("param Is NULL"); 147 return HDF_ERR_INVALID_PARAM; 148 } 149 char *devKey = NULL; 150 int32_t renderDevNum; 151 152 renderDevNum = renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum; 153 int32_t renderPathNum = cJSON_GetArraySize(renderSwObj); 154 if (renderPathNum < 0 || renderPathNum > HDF_PATH_NUM_MAX) { 155 AUDIO_FUNC_LOGE("renderPathNum is invalid!"); 156 return HDF_FAILURE; 157 } 158 for (int32_t i = 0; i < renderPathNum; i++) { 159 cJSON *tmpValue = cJSON_GetArrayItem(renderSwObj, i); 160 cJSON *renderSwName = tmpValue->child; 161 cJSON *renderSwVal = renderSwName->next; 162 if (renderSwName->valuestring == NULL) { 163 AUDIO_FUNC_LOGE("renderSwName->valuestring is null!"); 164 return HDF_FAILURE; 165 } 166 167 devKey = renderSwName->valuestring; 168 (void)memset_s(renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[renderDevNum].deviceSwitch, 169 PATHPLAN_LEN, 0, PATHPLAN_LEN); 170 int32_t ret = 171 strncpy_s(renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[renderDevNum].deviceSwitch, 172 PATHPLAN_COUNT, devKey, strlen(devKey) + 1); 173 if (ret != 0) { 174 AUDIO_FUNC_LOGE("strcpy_s failed!"); 175 return HDF_FAILURE; 176 } 177 178 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[renderDevNum].value = renderSwVal->valueint; 179 renderDevNum++; 180 } 181 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum = renderDevNum; 182 return HDF_SUCCESS; 183} 184 185static int32_t SetCapturePathDefaultValue(cJSON *captureSwObj, struct AudioHwCaptureParam *captureParam) 186{ 187 if (captureSwObj == NULL || captureParam == NULL) { 188 AUDIO_FUNC_LOGE("param Is NULL"); 189 return HDF_ERR_INVALID_PARAM; 190 } 191 char *devKey = NULL; 192 193 int32_t devNum = captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum; 194 int32_t pathNum = cJSON_GetArraySize(captureSwObj); 195 if (pathNum < 0 || pathNum > HDF_PATH_NUM_MAX) { 196 AUDIO_FUNC_LOGE("pathNum is invalid!"); 197 return HDF_FAILURE; 198 } 199 for (int32_t i = 0; i < pathNum; i++) { 200 cJSON *tmpValue = cJSON_GetArrayItem(captureSwObj, i); 201 cJSON *captureSwName = tmpValue->child; 202 cJSON *captureSwVal = captureSwName->next; 203 if (captureSwName->valuestring == NULL) { 204 AUDIO_FUNC_LOGE("captureSwName->valuestring is null!"); 205 return HDF_FAILURE; 206 } 207 208 devKey = captureSwName->valuestring; 209 (void)memset_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch, 210 PATHPLAN_LEN, 0, PATHPLAN_LEN); 211 int32_t ret = 212 strncpy_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch, 213 PATHPLAN_COUNT, devKey, strlen(devKey) + 1); 214 if (ret != 0) { 215 AUDIO_FUNC_LOGE("strcpy_s failed!"); 216 return HDF_FAILURE; 217 } 218 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = captureSwVal->valueint; 219 220 devNum++; 221 } 222 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = devNum; 223 return HDF_SUCCESS; 224} 225 226static int32_t SetRenderPathValue( 227 int32_t tpins, cJSON *renderObj, struct AudioHwRenderParam *renderParam, int32_t value) 228{ 229 if (renderObj == NULL || renderParam == NULL) { 230 AUDIO_FUNC_LOGE("param Is NULL"); 231 return HDF_ERR_INVALID_PARAM; 232 } 233 char *devKey = NULL; 234 int32_t devNum; 235 const char *renderDeviceType = AudioPathSelGetDeviceType(tpins); 236 if (renderDeviceType == NULL) { 237 AUDIO_FUNC_LOGE("DeviceType not found."); 238 return HDF_FAILURE; 239 } 240 devNum = renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum; 241 /* pins = 0, parse default value */ 242 if (strcasecmp(renderDeviceType, renderObj->string) == 0) { 243 int32_t pathNum = cJSON_GetArraySize(renderObj); 244 if (pathNum < 0 || pathNum > HDF_PATH_NUM_MAX) { 245 AUDIO_FUNC_LOGE("pathNum is invalid!"); 246 return HDF_FAILURE; 247 } 248 for (int32_t i = 0; i < pathNum; i++) { 249 cJSON *tmpValue = cJSON_GetArrayItem(renderObj, i); 250 cJSON *swName = tmpValue->child; 251 cJSON *swVal = swName->next; 252 if (swName->valuestring == NULL) { 253 AUDIO_FUNC_LOGE("ValueString is null!"); 254 return HDF_FAILURE; 255 } 256 257 devKey = swName->valuestring; 258 (void)memset_s(renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch, 259 PATHPLAN_LEN, 0, PATHPLAN_LEN); 260 int32_t ret = 261 strncpy_s(renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch, 262 PATHPLAN_COUNT, devKey, strlen(devKey) + 1); 263 if (ret != 0) { 264 AUDIO_FUNC_LOGE("strcpy_s failed!"); 265 return HDF_FAILURE; 266 } 267 if (swVal->valueint > AUDIO_DEV_ON) { 268 /* alsa Adaptation */ 269 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = swVal->valueint; 270 } else { 271 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = value; 272 } 273 devNum++; 274 } 275 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum = devNum; 276 } 277 return HDF_SUCCESS; 278} 279 280static int32_t SetMatchRenderDevicePath( 281 int32_t tpins, struct AudioHwRenderParam *renderParam, cJSON *cJsonObj, const char *deviceType, int32_t value) 282{ 283 if (cJsonObj == NULL || renderParam == NULL) { 284 AUDIO_FUNC_LOGE("param Is NULL"); 285 return HDF_ERR_INVALID_PARAM; 286 } 287 if (strcasecmp(cJsonObj->string, deviceType) == 0) { 288 int32_t ret = SetRenderPathValue(tpins, cJsonObj, renderParam, value); 289 if (ret != HDF_SUCCESS) { 290 AUDIO_FUNC_LOGE("set value failed!"); 291 return ret; 292 } 293 } 294 return HDF_SUCCESS; 295} 296 297static int32_t SetMatchRenderDefaultDevicePath(struct AudioHwRenderParam *renderParam, cJSON *cJsonObj) 298{ 299 int32_t ret; 300 if (cJsonObj == NULL || renderParam == NULL) { 301 AUDIO_FUNC_LOGE("param Is NULL"); 302 return HDF_ERR_INVALID_PARAM; 303 } 304 for (uint32_t i = PIN_OUT_SPEAKER; i <= PIN_OUT_EARPIECE; i = i << 1) { 305 const char *deviceType = AudioPathSelGetDeviceType((int32_t)i); 306 if (deviceType == NULL) { 307 AUDIO_FUNC_LOGE("DeviceType not found."); 308 return HDF_FAILURE; 309 } 310 if (strcasecmp(deviceType, cJsonObj->string) == 0) { 311 ret = SetRenderPathDefaultValue(cJsonObj, renderParam); 312 if (ret != HDF_SUCCESS) { 313 AUDIO_FUNC_LOGE("set default value failed!"); 314 return ret; 315 } 316 break; 317 } 318 } 319 return HDF_SUCCESS; 320} 321 322static int32_t SetMatchRenderOtherDevicePath( 323 int32_t tpins, struct AudioHwRenderParam *renderParam, cJSON *cJsonObj, int32_t value) 324{ 325 int32_t ret; 326 if (cJsonObj == NULL || renderParam == NULL) { 327 AUDIO_FUNC_LOGE("param Is NULL"); 328 return HDF_ERR_INVALID_PARAM; 329 } 330 for (uint32_t j = PIN_OUT_SPEAKER; j <= PIN_OUT_EARPIECE; j = j << 1) { 331 if ((j & tpins) == j) { 332 ret = SetRenderPathValue((int32_t)j, cJsonObj, renderParam, AUDIO_DEV_ON); 333 if (ret != HDF_SUCCESS) { 334 AUDIO_FUNC_LOGW("set value failed!"); 335 continue; 336 } 337 } 338 } 339 return HDF_SUCCESS; 340} 341 342static int32_t AudioRenderParseDevice(struct AudioHwRenderParam *renderParam, cJSON *cJsonObj) 343{ 344 int32_t ret; 345 if (cJsonObj == NULL || renderParam == NULL) { 346 AUDIO_FUNC_LOGE("param Is NULL"); 347 return HDF_ERR_INVALID_PARAM; 348 } 349 uint32_t pins = renderParam->renderMode.hwInfo.deviceDescript.pins; 350 351 int32_t tpins = pins & OUTPUT_MASK; 352 if ((pins >> OUTPUT_OFFSET) != 0) { 353 AUDIO_FUNC_LOGE("pins: %d, error!\n", pins); 354 return HDF_FAILURE; 355 } 356 357 if (strcasecmp(cJsonObj->string, MIC) == 0 || strcasecmp(cJsonObj->string, HS_MIC) == 0 || 358 strcasecmp(cJsonObj->string, BLUETOOTH_SCO_HEADSET) == 0) { 359 return HDF_SUCCESS; 360 } 361 362 switch (tpins) { 363 case PIN_NONE: 364 /* pins = 0, parse default value */ 365 ret = SetMatchRenderDefaultDevicePath(renderParam, cJsonObj); 366 break; 367 case PIN_OUT_SPEAKER: 368 case PIN_OUT_BLUETOOTH_A2DP: 369 /* 1.open speaker */ 370 ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, SPEAKER, AUDIO_DEV_ON); 371#ifndef ALSA_LIB_MODE 372 /* 2.close headphones */ 373 ret |= SetMatchRenderDevicePath(PIN_OUT_HEADSET, renderParam, cJsonObj, HEADPHONES, AUDIO_DEV_OFF); 374#endif 375 break; 376 case PIN_OUT_HEADSET: 377 /* 1、open headphone */ 378 ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, HEADPHONES, AUDIO_DEV_ON); 379#ifndef ALSA_LIB_MODE 380 /* 2、close speaker */ 381 ret |= SetMatchRenderDevicePath(PIN_OUT_SPEAKER, renderParam, cJsonObj, SPEAKER, AUDIO_DEV_OFF); 382#endif 383 break; 384 case PIN_OUT_EARPIECE: 385 /* 1、open earpiece */ 386 ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, EARPIECE, AUDIO_DEV_ON); 387 break; 388 case PIN_OUT_BLUETOOTH_SCO: 389 /* 1、open bluetooth */ 390 ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, BLUETOOTH_SCO, AUDIO_DEV_ON); 391 break; 392 default: 393 ret = SetMatchRenderOtherDevicePath(tpins, renderParam, cJsonObj, AUDIO_DEV_ON); 394 break; 395 } 396 397 return ret; 398} 399 400static int32_t AudioRenderParseUsecase(struct AudioHwRenderParam *renderParam, const char *useCase) 401{ 402 /* reset path numbers */ 403 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum = 0; 404 405 cJSON *cardNode = cJSON_GetObjectItem(g_cJsonObj, renderParam->renderMode.hwInfo.cardServiceName); 406 if (cardNode == NULL) { 407 AUDIO_FUNC_LOGE( 408 "failed to check item when [%{public}s] gets object!", renderParam->renderMode.hwInfo.cardServiceName); 409 return HDF_FAILURE; 410 } 411 cJSON *cardList = cardNode->child; 412 if (cardList == NULL) { 413 AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", renderParam->renderMode.hwInfo.cardServiceName); 414 return HDF_FAILURE; 415 } 416 417 cJSON *useCaseNode = cJSON_GetObjectItem(cardList, useCase); 418 if (useCaseNode == NULL) { 419 AUDIO_FUNC_LOGE("failed to check item when [%{public}s] gets object!", useCase); 420 return HDF_FAILURE; 421 } 422 423 cJSON *useCaseList = useCaseNode->child; 424 if (useCaseList == NULL) { 425 AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", useCase); 426 return HDF_FAILURE; 427 } 428 429 int32_t len = cJSON_GetArraySize(useCaseList); 430 if (len < 0 || len > HDF_PATH_NUM_MAX) { 431 AUDIO_FUNC_LOGE("len is invalid!"); 432 return HDF_FAILURE; 433 } 434 for (int32_t i = 0; i < len; i++) { 435 cJSON *tmpValue = cJSON_GetArrayItem(useCaseList, i); 436 /* Each device in the incoming scene */ 437 int32_t ret = AudioRenderParseDevice(renderParam, tmpValue); 438 if (ret != HDF_SUCCESS) { 439 return ret; 440 } 441 } 442 return HDF_SUCCESS; 443} 444 445static int32_t AudioPathSelGetPlanRender(struct AudioHwRenderParam *renderParam) 446{ 447 if (renderParam == NULL) { 448 AUDIO_FUNC_LOGE("param Is NULL"); 449 return HDF_ERR_INVALID_PARAM; 450 } 451 const char *useCase = AudioPathSelGetUseCase(renderParam->frameRenderMode.attrs.type); 452 if (useCase == NULL) { 453 AUDIO_FUNC_LOGE("useCase not support!"); 454 return HDF_FAILURE; 455 } 456 return AudioRenderParseUsecase(renderParam, useCase); 457} 458 459static int32_t SetCapturePathValue( 460 int32_t tpins, cJSON *captureSwitchObj, struct AudioHwCaptureParam *captureParam, int32_t value) 461{ 462 if (captureParam == NULL || captureSwitchObj == NULL) { 463 AUDIO_FUNC_LOGE("param Is NULL"); 464 return HDF_ERR_INVALID_PARAM; 465 } 466 const char *captureDeviceType = AudioPathSelGetDeviceType(tpins); 467 if (captureDeviceType == NULL) { 468 AUDIO_FUNC_LOGE("DeviceType not found."); 469 return HDF_FAILURE; 470 } 471 472 int32_t devNum = captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum; 473 if (strcasecmp(captureDeviceType, captureSwitchObj->string) == 0) { 474 int32_t pathNum = cJSON_GetArraySize(captureSwitchObj); 475 if (pathNum < 0 || pathNum > HDF_PATH_NUM_MAX) { 476 AUDIO_FUNC_LOGE("pathNum is invalid!"); 477 return HDF_FAILURE; 478 } 479 for (int32_t i = 0; i < pathNum; i++) { 480 cJSON *captureTmpValue = cJSON_GetArrayItem(captureSwitchObj, i); 481 cJSON *swName = captureTmpValue->child; 482 cJSON *swVal = swName->next; 483 if (swName->valuestring == NULL) { 484 AUDIO_FUNC_LOGE("ValueString is null!"); 485 return HDF_FAILURE; 486 } 487 488 (void)memset_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch, 489 PATHPLAN_LEN, 0, PATHPLAN_LEN); 490 int32_t ret = 491 strncpy_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch, 492 PATHPLAN_COUNT, swName->valuestring, strlen(swName->valuestring) + 1); 493 if (ret != 0) { 494 AUDIO_FUNC_LOGE("strcpy_s failed!"); 495 return HDF_FAILURE; 496 } 497 if (swVal->valueint > AUDIO_DEV_ON) { 498 /* alsa Adaptation */ 499 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = swVal->valueint; 500 } else { 501 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = value; 502 } 503 504 devNum++; 505 } 506 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = devNum; 507 } 508 return HDF_SUCCESS; 509} 510 511static int32_t SetMatchCaptureDevicePath( 512 struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj, int32_t tpins, char *deviceType, int32_t value) 513{ 514 if (captureParam == NULL || cJsonObj == NULL) { 515 AUDIO_FUNC_LOGE("param Is NULL"); 516 return HDF_ERR_INVALID_PARAM; 517 } 518 if (strcasecmp(cJsonObj->string, deviceType) == 0) { 519 int32_t ret = SetCapturePathValue(tpins, cJsonObj, captureParam, value); 520 if (ret != HDF_SUCCESS) { 521 AUDIO_FUNC_LOGE("set value failed!"); 522 return ret; 523 } 524 } 525 return HDF_SUCCESS; 526} 527 528static int32_t SetMatchCaptureDefaultDevicePath(struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj) 529{ 530 int32_t ret; 531 if (captureParam == NULL || cJsonObj == NULL) { 532 AUDIO_FUNC_LOGE("param Is NULL"); 533 return HDF_ERR_INVALID_PARAM; 534 } 535 for (uint32_t i = PIN_IN_MIC; i <= PIN_IN_BLUETOOTH_SCO_HEADSET; 536 i = (1 << INPUT_OFFSET) | ((i & OUTPUT_MASK) << 1)) { 537 const char *deviceType = AudioPathSelGetDeviceType((int32_t)i); 538 if (deviceType == NULL) { 539 AUDIO_FUNC_LOGE("DeviceType not found."); 540 return HDF_FAILURE; 541 } 542 543 if (strcasecmp(deviceType, cJsonObj->string) == 0) { 544 ret = SetCapturePathDefaultValue(cJsonObj, captureParam); 545 if (ret != HDF_SUCCESS) { 546 AUDIO_FUNC_LOGE("set default value failed!"); 547 return ret; 548 } 549 break; 550 } 551 } 552 return HDF_SUCCESS; 553} 554 555static int32_t SetMatchCaptureOtherDevicePath( 556 struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj, int32_t tpins, int32_t value) 557{ 558 int32_t ret; 559 uint32_t i; 560 if (captureParam == NULL || cJsonObj == NULL) { 561 AUDIO_FUNC_LOGE("param Is NULL"); 562 return HDF_ERR_INVALID_PARAM; 563 } 564 for (i = PIN_IN_MIC; i <= PIN_IN_BLUETOOTH_SCO_HEADSET; i = (1 << INPUT_OFFSET) | ((i & OUTPUT_MASK) << 1)) { 565 if ((i & tpins) == i) { /* Select which device to open and get the pin of which device */ 566 ret = SetCapturePathValue((int32_t)i, cJsonObj, captureParam, value); 567 if (ret != HDF_SUCCESS) { 568 AUDIO_FUNC_LOGE("set value failed!"); 569 continue; 570 } 571 } 572 } 573 return HDF_SUCCESS; 574} 575 576static int32_t AudioCaptureParseDevice(struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj) 577{ 578 int32_t ret; 579 if (captureParam == NULL || cJsonObj == NULL) { 580 AUDIO_FUNC_LOGE("param Is NULL"); 581 return HDF_ERR_INVALID_PARAM; 582 } 583 uint32_t pins = captureParam->captureMode.hwInfo.deviceDescript.pins; 584 585 if (!((pins >> INPUT_OFFSET) & 0x01)) { 586 AUDIO_FUNC_LOGE("pins: %{public}d, error!", pins); 587 return HDF_FAILURE; 588 } 589 590 if (strcasecmp(cJsonObj->string, SPEAKER) == 0 || strcasecmp(cJsonObj->string, HEADPHONES) == 0 || 591 strcasecmp(cJsonObj->string, EARPIECE) == 0 || strcasecmp(cJsonObj->string, BLUETOOTH_SCO) == 0) { 592 return HDF_SUCCESS; 593 } 594 595 int32_t tpins = pins & INPUT_MASK; 596 switch (tpins) { 597 case (1 << INPUT_OFFSET): 598 /* pins = 0, parse default value */ 599 ret = SetMatchCaptureDefaultDevicePath(captureParam, cJsonObj); 600 break; 601 case PIN_IN_MIC: 602 /* 1.open main mic */ 603 ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, MIC, AUDIO_DEV_ON); 604#ifndef ALSA_LIB_MODE 605 /* 2.close headset mic */ 606 ret |= SetMatchCaptureDevicePath(captureParam, cJsonObj, PIN_IN_HS_MIC, HS_MIC, AUDIO_DEV_OFF); 607#endif 608 break; 609 case PIN_IN_HS_MIC: 610 /* 1、open headset mic */ 611 ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, HS_MIC, AUDIO_DEV_ON); 612#ifndef ALSA_LIB_MODE 613 /* 2、close main mic */ 614 ret |= SetMatchCaptureDevicePath(captureParam, cJsonObj, PIN_IN_MIC, MIC, AUDIO_DEV_OFF); 615#endif 616 break; 617 case PIN_IN_BLUETOOTH_SCO_HEADSET: 618 /* 1、open bluetooth sco headset mic */ 619 ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, BLUETOOTH_SCO_HEADSET, AUDIO_DEV_ON); 620 break; 621 default: 622 ret = SetMatchCaptureOtherDevicePath(captureParam, cJsonObj, tpins, AUDIO_DEV_ON); 623 break; 624 } 625 return ret; 626} 627 628static int32_t AudioCaptureParseUsecase(struct AudioHwCaptureParam *captureParam, const char *useCase) 629{ 630 if (captureParam == NULL || useCase == NULL) { 631 AUDIO_FUNC_LOGE("param Is NULL"); 632 return HDF_ERR_INVALID_PARAM; 633 } 634 /* reset path numbers */ 635 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = 0; 636 637 cJSON *cardNode = cJSON_GetObjectItem(g_cJsonObj, captureParam->captureMode.hwInfo.cardServiceName); 638 if (cardNode == NULL) { 639 AUDIO_FUNC_LOGE( 640 "failed to check item when [%{public}s] gets object!", captureParam->captureMode.hwInfo.cardServiceName); 641 return HDF_FAILURE; 642 } 643 cJSON *cardList = cardNode->child; 644 if (cardList == NULL) { 645 AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", captureParam->captureMode.hwInfo.cardServiceName); 646 return HDF_FAILURE; 647 } 648 649 cJSON *useCaseNode = cJSON_GetObjectItem(cardList, useCase); 650 if (useCaseNode == NULL) { 651 AUDIO_FUNC_LOGE("failed to check item when [%{public}s] gets object!", useCase); 652 return HDF_FAILURE; 653 } 654 cJSON *useCaseList = useCaseNode->child; 655 if (useCaseList == NULL) { 656 AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", useCase); 657 return HDF_FAILURE; 658 } 659 660 int32_t len = cJSON_GetArraySize(useCaseList); 661 if (len < 0 || len > HDF_PATH_NUM_MAX) { 662 AUDIO_FUNC_LOGE("len is invalid!"); 663 return HDF_FAILURE; 664 } 665 for (int32_t i = 0; i < len; i++) { 666 cJSON *tmpValue = cJSON_GetArrayItem(useCaseList, i); 667 int32_t ret = AudioCaptureParseDevice(captureParam, tmpValue); 668 if (ret != HDF_SUCCESS) { 669 return ret; 670 } 671 } 672 return HDF_SUCCESS; 673} 674 675static int32_t AudioPathSelGetPlanCapture(struct AudioHwCaptureParam *captureParam) 676{ 677 enum AudioCategory type = captureParam->frameCaptureMode.attrs.type; 678 679 if (type == AUDIO_IN_RINGTONE) { 680 AUDIO_FUNC_LOGE("useCase not support!"); 681 return HDF_ERR_NOT_SUPPORT; 682 } 683 684 if (type == AUDIO_MMAP_NOIRQ) { 685 AUDIO_FUNC_LOGE("useCase set as AUDIO_IN_MEDIA"); 686 type = AUDIO_IN_MEDIA; 687 } 688 689 const char *useCase = AudioPathSelGetUseCase(type); 690 if (useCase == NULL) { 691 AUDIO_FUNC_LOGE("useCase not support!"); 692 return HDF_FAILURE; 693 } 694 695 return AudioCaptureParseUsecase(captureParam, useCase); 696} 697 698static int32_t AudioPathSelRenderChkScene(struct AudioHwRenderParam *renderSceneParam) 699{ 700 return AudioPathSelGetPlanRender(renderSceneParam); 701} 702 703static int32_t AudioPathSelCaptureChkScene(struct AudioHwCaptureParam *captureSceneParam) 704{ 705 return AudioPathSelGetPlanCapture(captureSceneParam); 706} 707 708int32_t AudioPathSelAnalysisJson(const AudioHandle adapterParam, enum AudioAdaptType adaptType) 709{ 710 AUDIO_FUNC_LOGI(); 711 if (adaptType < 0 || adapterParam == NULL) { 712 AUDIO_FUNC_LOGE("Param Invaild!"); 713 return HDF_ERR_INVALID_PARAM; 714 } 715 struct AudioHwRenderParam *renderParam = NULL; 716 struct AudioHwCaptureParam *captureParam = NULL; 717 struct AudioHwRenderParam *renderSceneCheck = NULL; 718 struct AudioHwCaptureParam *captureScenceCheck = NULL; 719 switch (adaptType) { 720 case RENDER_PATH_SELECT: 721 renderParam = (struct AudioHwRenderParam *)adapterParam; 722 if (strcasecmp(renderParam->renderMode.hwInfo.adapterName, USB) == 0 || 723 strcasecmp(renderParam->renderMode.hwInfo.adapterName, HDMI) == 0) { 724 return HDF_SUCCESS; 725 } 726 return (AudioPathSelGetPlanRender(renderParam)); 727 case CAPTURE_PATH_SELECT: 728 captureParam = (struct AudioHwCaptureParam *)adapterParam; 729 if (strcasecmp(captureParam->captureMode.hwInfo.adapterName, USB) == 0 || 730 strcasecmp(captureParam->captureMode.hwInfo.adapterName, HDMI) == 0) { 731 return HDF_SUCCESS; 732 } 733 return (AudioPathSelGetPlanCapture(captureParam)); 734 /* Scene is supported */ 735 case CHECKSCENE_PATH_SELECT: 736 renderSceneCheck = (struct AudioHwRenderParam *)adapterParam; 737 if (strcasecmp(renderSceneCheck->renderMode.hwInfo.adapterName, USB) == 0 || 738 strcasecmp(renderSceneCheck->renderMode.hwInfo.adapterName, HDMI) == 0) { 739 return HDF_SUCCESS; 740 } 741 return (AudioPathSelRenderChkScene(renderSceneCheck)); 742 case CHECKSCENE_PATH_SELECT_CAPTURE: 743 captureScenceCheck = (struct AudioHwCaptureParam *)adapterParam; 744 if (strcasecmp(captureScenceCheck->captureMode.hwInfo.adapterName, USB) == 0 || 745 strcasecmp(captureScenceCheck->captureMode.hwInfo.adapterName, HDMI) == 0) { 746 return HDF_SUCCESS; 747 } 748 return (AudioPathSelCaptureChkScene(captureScenceCheck)); 749 default: 750 AUDIO_FUNC_LOGE("Path select mode invalid"); 751 break; 752 } 753 return HDF_FAILURE; 754} 755