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