• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
47 static cJSON *g_cJsonObj = NULL;
48 
AudioPathSelGetConfToJsonObj(void)49 int32_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 
AudioPathSelGetDeviceType(enum AudioPortPin pin)99 static 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 
AudioPathSelGetUseCase(enum AudioCategory type)127 static 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 
SetRenderPathDefaultValue(cJSON * renderSwObj,struct AudioHwRenderParam * renderParam)143 static 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 
SetCapturePathDefaultValue(cJSON * captureSwObj,struct AudioHwCaptureParam * captureParam)185 static 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 
SetRenderPathValue(int32_t tpins,cJSON * renderObj,struct AudioHwRenderParam * renderParam,int32_t value)226 static 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     int32_t devNum = renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum;
234     const char *renderDeviceType = AudioPathSelGetDeviceType(tpins);
235     if (renderDeviceType == NULL) {
236         AUDIO_FUNC_LOGE("DeviceType not found.");
237         return HDF_FAILURE;
238     }
239     /* pins = 0, parse default value */
240     if (strcasecmp(renderDeviceType, renderObj->string) == 0) {
241         int32_t pathNum = cJSON_GetArraySize(renderObj);
242         if (pathNum < 0 || pathNum > HDF_PATH_NUM_MAX) {
243             AUDIO_FUNC_LOGE("pathNum is invalid!");
244             return HDF_FAILURE;
245         }
246         for (int32_t i = 0; i < pathNum; i++) {
247             cJSON *tmpValue = cJSON_GetArrayItem(renderObj, i);
248             if (tmpValue == NULL) {
249                 AUDIO_FUNC_LOGE("tmpValue is null.");
250                 return HDF_FAILURE;
251             }
252             cJSON *swName = tmpValue->child;
253             cJSON *swVal = swName->next;
254 
255             if (swName->valuestring == NULL) {
256                 AUDIO_FUNC_LOGE("ValueString is null!");
257                 return HDF_FAILURE;
258             }
259 
260             char *devKey = swName->valuestring;
261             (void)memset_s(renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch,
262                 PATHPLAN_LEN, 0, PATHPLAN_LEN);
263             int32_t ret =
264                 strncpy_s(renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch,
265                     PATHPLAN_COUNT, devKey, strlen(devKey) + 1);
266             if (ret != 0) {
267                 AUDIO_FUNC_LOGE("strcpy_s failed!");
268                 return HDF_FAILURE;
269             }
270             if (swVal->valueint > AUDIO_DEV_ON) {
271                 /* alsa Adaptation */
272                 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = swVal->valueint;
273             } else {
274                 renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = value;
275             }
276             devNum++;
277         }
278         renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum = devNum;
279     }
280     return HDF_SUCCESS;
281 }
282 
SetMatchRenderDevicePath(int32_t tpins,struct AudioHwRenderParam * renderParam,cJSON * cJsonObj,const char * deviceType,int32_t value)283 static int32_t SetMatchRenderDevicePath(
284     int32_t tpins, struct AudioHwRenderParam *renderParam, cJSON *cJsonObj, const char *deviceType, int32_t value)
285 {
286     if (cJsonObj == NULL || renderParam == NULL) {
287         AUDIO_FUNC_LOGE("param Is NULL");
288         return HDF_ERR_INVALID_PARAM;
289     }
290     if (strcasecmp(cJsonObj->string, deviceType) == 0) {
291         int32_t ret = SetRenderPathValue(tpins, cJsonObj, renderParam, value);
292         if (ret != HDF_SUCCESS) {
293             AUDIO_FUNC_LOGE("set value failed!");
294             return ret;
295         }
296     }
297     return HDF_SUCCESS;
298 }
299 
SetMatchRenderDefaultDevicePath(struct AudioHwRenderParam * renderParam,cJSON * cJsonObj)300 static int32_t SetMatchRenderDefaultDevicePath(struct AudioHwRenderParam *renderParam, cJSON *cJsonObj)
301 {
302     int32_t ret;
303     if (cJsonObj == NULL || renderParam == NULL) {
304         AUDIO_FUNC_LOGE("param Is NULL");
305         return HDF_ERR_INVALID_PARAM;
306     }
307     for (uint32_t i = PIN_OUT_SPEAKER; i <= PIN_OUT_EARPIECE; i = i << 1) {
308         const char *deviceType = AudioPathSelGetDeviceType((int32_t)i);
309         if (deviceType == NULL) {
310             AUDIO_FUNC_LOGE("DeviceType not found.");
311             return HDF_FAILURE;
312         }
313         if (strcasecmp(deviceType, cJsonObj->string) == 0) {
314             ret = SetRenderPathDefaultValue(cJsonObj, renderParam);
315             if (ret != HDF_SUCCESS) {
316                 AUDIO_FUNC_LOGE("set default value failed!");
317                 return ret;
318             }
319             break;
320         }
321     }
322     return HDF_SUCCESS;
323 }
324 
SetMatchRenderOtherDevicePath(int32_t tpins,struct AudioHwRenderParam * renderParam,cJSON * cJsonObj,int32_t value)325 static int32_t SetMatchRenderOtherDevicePath(
326     int32_t tpins, struct AudioHwRenderParam *renderParam, cJSON *cJsonObj, int32_t value)
327 {
328     int32_t ret;
329     if (cJsonObj == NULL || renderParam == NULL) {
330         AUDIO_FUNC_LOGE("param Is NULL");
331         return HDF_ERR_INVALID_PARAM;
332     }
333     for (uint32_t j = PIN_OUT_SPEAKER; j <= PIN_OUT_EARPIECE; j = j << 1) {
334         if ((j & tpins) == j) {
335             ret = SetRenderPathValue((int32_t)j, cJsonObj, renderParam, AUDIO_DEV_ON);
336             if (ret != HDF_SUCCESS) {
337                 AUDIO_FUNC_LOGW("set value failed!");
338                 continue;
339             }
340         }
341     }
342     return HDF_SUCCESS;
343 }
344 
AudioRenderParseDevice(struct AudioHwRenderParam * renderParam,cJSON * cJsonObj)345 static int32_t AudioRenderParseDevice(struct AudioHwRenderParam *renderParam, cJSON *cJsonObj)
346 {
347     int32_t ret;
348     if (cJsonObj == NULL || renderParam == NULL) {
349         AUDIO_FUNC_LOGE("param Is NULL");
350         return HDF_ERR_INVALID_PARAM;
351     }
352     uint32_t pins = renderParam->renderMode.hwInfo.deviceDescript.pins;
353 
354     int32_t tpins = pins & OUTPUT_MASK;
355     if ((pins >> OUTPUT_OFFSET) != 0) {
356         AUDIO_FUNC_LOGE("pins: %d, error!\n", pins);
357         return HDF_FAILURE;
358     }
359 
360     if (strcasecmp(cJsonObj->string, MIC) == 0 || strcasecmp(cJsonObj->string, HS_MIC) == 0 ||
361         strcasecmp(cJsonObj->string, BLUETOOTH_SCO_HEADSET) == 0) {
362         return HDF_SUCCESS;
363     }
364 
365     switch (tpins) {
366         case PIN_NONE:
367             /* pins = 0, parse default value */
368             ret = SetMatchRenderDefaultDevicePath(renderParam, cJsonObj);
369             break;
370         case PIN_OUT_SPEAKER:
371         case PIN_OUT_BLUETOOTH_A2DP:
372             /* 1.open speaker */
373             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, SPEAKER, AUDIO_DEV_ON);
374 #ifndef ALSA_LIB_MODE
375             /* 2.close headphones */
376             ret |= SetMatchRenderDevicePath(PIN_OUT_HEADSET, renderParam, cJsonObj, HEADPHONES, AUDIO_DEV_OFF);
377 #endif
378             break;
379         case PIN_OUT_HEADSET:
380             /* 1、open headphone */
381             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, HEADPHONES, AUDIO_DEV_ON);
382 #ifndef ALSA_LIB_MODE
383             /* 2、close speaker */
384             ret |= SetMatchRenderDevicePath(PIN_OUT_SPEAKER, renderParam, cJsonObj, SPEAKER, AUDIO_DEV_OFF);
385 #endif
386             break;
387         case PIN_OUT_EARPIECE:
388             /* 1、open earpiece */
389             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, EARPIECE, AUDIO_DEV_ON);
390             break;
391         case PIN_OUT_BLUETOOTH_SCO:
392             /* 1、open bluetooth */
393             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, BLUETOOTH_SCO, AUDIO_DEV_ON);
394             break;
395         default:
396             ret = SetMatchRenderOtherDevicePath(tpins, renderParam, cJsonObj, AUDIO_DEV_ON);
397             break;
398     }
399 
400     return ret;
401 }
402 
AudioRenderParseUsecase(struct AudioHwRenderParam * renderParam,const char * useCase)403 static int32_t AudioRenderParseUsecase(struct AudioHwRenderParam *renderParam, const char *useCase)
404 {
405     /* reset path numbers */
406     renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum = 0;
407 
408     cJSON *cardNode = cJSON_GetObjectItem(g_cJsonObj, renderParam->renderMode.hwInfo.cardServiceName);
409     if (cardNode == NULL) {
410         AUDIO_FUNC_LOGE(
411             "failed to check item when [%{public}s] gets object!", renderParam->renderMode.hwInfo.cardServiceName);
412         return HDF_FAILURE;
413     }
414     cJSON *cardList = cardNode->child;
415     if (cardList == NULL) {
416         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", renderParam->renderMode.hwInfo.cardServiceName);
417         return HDF_FAILURE;
418     }
419 
420     cJSON *useCaseNode = cJSON_GetObjectItem(cardList, useCase);
421     if (useCaseNode == NULL) {
422         AUDIO_FUNC_LOGE("failed to check item when [%{public}s] gets object!", useCase);
423         return HDF_FAILURE;
424     }
425 
426     cJSON *useCaseList = useCaseNode->child;
427     if (useCaseList == NULL) {
428         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", useCase);
429         return HDF_FAILURE;
430     }
431 
432     int32_t len = cJSON_GetArraySize(useCaseList);
433     if (len < 0 || len > HDF_PATH_NUM_MAX) {
434         AUDIO_FUNC_LOGE("len is invalid!");
435         return HDF_FAILURE;
436     }
437     for (int32_t i = 0; i < len; i++) {
438         cJSON *tmpValue = cJSON_GetArrayItem(useCaseList, i);
439         /* Each device in the incoming scene */
440         int32_t ret = AudioRenderParseDevice(renderParam, tmpValue);
441         if (ret != HDF_SUCCESS) {
442             return ret;
443         }
444     }
445     return HDF_SUCCESS;
446 }
447 
AudioPathSelGetPlanRender(struct AudioHwRenderParam * renderParam)448 static int32_t AudioPathSelGetPlanRender(struct AudioHwRenderParam *renderParam)
449 {
450     if (renderParam == NULL) {
451         AUDIO_FUNC_LOGE("param Is NULL");
452         return HDF_ERR_INVALID_PARAM;
453     }
454     const char *useCase = AudioPathSelGetUseCase(renderParam->frameRenderMode.attrs.type);
455     if (useCase == NULL) {
456         AUDIO_FUNC_LOGE("useCase not support!");
457         return HDF_FAILURE;
458     }
459     return AudioRenderParseUsecase(renderParam, useCase);
460 }
461 
SetCapturePathValue(int32_t tpins,cJSON * captureSwitchObj,struct AudioHwCaptureParam * captureParam,int32_t value)462 static int32_t SetCapturePathValue(
463     int32_t tpins, cJSON *captureSwitchObj, struct AudioHwCaptureParam *captureParam, int32_t value)
464 {
465     if (captureParam == NULL || captureSwitchObj == NULL) {
466         AUDIO_FUNC_LOGE("param Is NULL");
467         return HDF_ERR_INVALID_PARAM;
468     }
469     const char *captureDeviceType = AudioPathSelGetDeviceType(tpins);
470     if (captureDeviceType == NULL) {
471         AUDIO_FUNC_LOGE("DeviceType not found.");
472         return HDF_FAILURE;
473     }
474 
475     int32_t devNum = captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum;
476     if (strcasecmp(captureDeviceType, captureSwitchObj->string) == 0) {
477         int32_t pathNum = cJSON_GetArraySize(captureSwitchObj);
478         if (pathNum < 0 || pathNum > HDF_PATH_NUM_MAX) {
479             AUDIO_FUNC_LOGE("pathNum is invalid!");
480             return HDF_FAILURE;
481         }
482         for (int32_t i = 0; i < pathNum; i++) {
483             cJSON *captureTmpValue = cJSON_GetArrayItem(captureSwitchObj, i);
484             if (captureTmpValue == NULL) {
485                 AUDIO_FUNC_LOGE("captureTmpValue is null.");
486                 return HDF_FAILURE;
487             }
488             cJSON *swName = captureTmpValue->child;
489             cJSON *swVal = swName->next;
490 
491             if (swName->valuestring == NULL) {
492                 AUDIO_FUNC_LOGE("ValueString is null!");
493                 return HDF_FAILURE;
494             }
495 
496             (void)memset_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch,
497                 PATHPLAN_LEN, 0, PATHPLAN_LEN);
498             int32_t ret =
499                 strncpy_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch,
500                     PATHPLAN_COUNT, swName->valuestring, strlen(swName->valuestring) + 1);
501             if (ret != 0) {
502                 AUDIO_FUNC_LOGE("strcpy_s failed!");
503                 return HDF_FAILURE;
504             }
505             if (swVal->valueint > AUDIO_DEV_ON) {
506                 /* alsa Adaptation */
507                 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = swVal->valueint;
508             } else {
509                 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = value;
510             }
511 
512             devNum++;
513         }
514         captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = devNum;
515     }
516     return HDF_SUCCESS;
517 }
518 
SetMatchCaptureDevicePath(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj,int32_t tpins,char * deviceType,int32_t value)519 static int32_t SetMatchCaptureDevicePath(
520     struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj, int32_t tpins, char *deviceType, int32_t value)
521 {
522     if (captureParam == NULL || cJsonObj == NULL) {
523         AUDIO_FUNC_LOGE("param Is NULL");
524         return HDF_ERR_INVALID_PARAM;
525     }
526     if (strcasecmp(cJsonObj->string, deviceType) == 0) {
527         int32_t ret = SetCapturePathValue(tpins, cJsonObj, captureParam, value);
528         if (ret != HDF_SUCCESS) {
529             AUDIO_FUNC_LOGE("set value failed!");
530             return ret;
531         }
532     }
533     return HDF_SUCCESS;
534 }
535 
SetMatchCaptureDefaultDevicePath(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj)536 static int32_t SetMatchCaptureDefaultDevicePath(struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj)
537 {
538     int32_t ret;
539     if (captureParam == NULL || cJsonObj == NULL) {
540         AUDIO_FUNC_LOGE("param Is NULL");
541         return HDF_ERR_INVALID_PARAM;
542     }
543     for (uint32_t i = PIN_IN_MIC; i <= PIN_IN_BLUETOOTH_SCO_HEADSET;
544          i = (1 << INPUT_OFFSET) | ((i & OUTPUT_MASK) << 1)) {
545         const char *deviceType = AudioPathSelGetDeviceType((int32_t)i);
546         if (deviceType == NULL) {
547             AUDIO_FUNC_LOGE("DeviceType not found.");
548             return HDF_FAILURE;
549         }
550 
551         if (strcasecmp(deviceType, cJsonObj->string) == 0) {
552             ret = SetCapturePathDefaultValue(cJsonObj, captureParam);
553             if (ret != HDF_SUCCESS) {
554                 AUDIO_FUNC_LOGE("set default value failed!");
555                 return ret;
556             }
557             break;
558         }
559     }
560     return HDF_SUCCESS;
561 }
562 
SetMatchCaptureOtherDevicePath(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj,int32_t tpins,int32_t value)563 static int32_t SetMatchCaptureOtherDevicePath(
564     struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj, int32_t tpins, int32_t value)
565 {
566     int32_t ret;
567     uint32_t i;
568     if (captureParam == NULL || cJsonObj == NULL) {
569         AUDIO_FUNC_LOGE("param Is NULL");
570         return HDF_ERR_INVALID_PARAM;
571     }
572     for (i = PIN_IN_MIC; i <= PIN_IN_BLUETOOTH_SCO_HEADSET; i = (1 << INPUT_OFFSET) | ((i & OUTPUT_MASK) << 1)) {
573         if ((i & tpins) == i) { /* Select which device to open and get the pin of which device */
574             ret = SetCapturePathValue((int32_t)i, cJsonObj, captureParam, value);
575             if (ret != HDF_SUCCESS) {
576                 AUDIO_FUNC_LOGE("set value failed!");
577                 continue;
578             }
579         }
580     }
581     return HDF_SUCCESS;
582 }
583 
AudioCaptureParseDevice(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj)584 static int32_t AudioCaptureParseDevice(struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj)
585 {
586     int32_t ret;
587     if (captureParam == NULL || cJsonObj == NULL) {
588         AUDIO_FUNC_LOGE("param Is NULL");
589         return HDF_ERR_INVALID_PARAM;
590     }
591     uint32_t pins = captureParam->captureMode.hwInfo.deviceDescript.pins;
592 
593     if (!((pins >> INPUT_OFFSET) & 0x01)) {
594         AUDIO_FUNC_LOGE("pins: %{public}d, error!", pins);
595         return HDF_FAILURE;
596     }
597 
598     if (strcasecmp(cJsonObj->string, SPEAKER) == 0 || strcasecmp(cJsonObj->string, HEADPHONES) == 0 ||
599         strcasecmp(cJsonObj->string, EARPIECE) == 0  || strcasecmp(cJsonObj->string, BLUETOOTH_SCO) == 0) {
600         return HDF_SUCCESS;
601     }
602 
603     int32_t tpins = pins & INPUT_MASK;
604     switch (tpins) {
605         case (1 << INPUT_OFFSET):
606             /* pins = 0, parse default value */
607             ret = SetMatchCaptureDefaultDevicePath(captureParam, cJsonObj);
608             break;
609         case PIN_IN_MIC:
610             /* 1.open main mic */
611             ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, MIC, AUDIO_DEV_ON);
612 #ifndef ALSA_LIB_MODE
613             /* 2.close headset mic */
614             ret |= SetMatchCaptureDevicePath(captureParam, cJsonObj, PIN_IN_HS_MIC, HS_MIC, AUDIO_DEV_OFF);
615 #endif
616             break;
617         case PIN_IN_HS_MIC:
618             /* 1、open headset mic */
619             ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, HS_MIC, AUDIO_DEV_ON);
620 #ifndef ALSA_LIB_MODE
621             /* 2、close main mic */
622             ret |= SetMatchCaptureDevicePath(captureParam, cJsonObj, PIN_IN_MIC, MIC, AUDIO_DEV_OFF);
623 #endif
624             break;
625         case PIN_IN_BLUETOOTH_SCO_HEADSET:
626             /* 1、open bluetooth sco headset mic */
627             ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, BLUETOOTH_SCO_HEADSET, AUDIO_DEV_ON);
628             break;
629         default:
630             ret = SetMatchCaptureOtherDevicePath(captureParam, cJsonObj, tpins, AUDIO_DEV_ON);
631             break;
632     }
633     return ret;
634 }
635 
AudioCaptureParseUsecase(struct AudioHwCaptureParam * captureParam,const char * useCase)636 static int32_t AudioCaptureParseUsecase(struct AudioHwCaptureParam *captureParam, const char *useCase)
637 {
638     if (captureParam == NULL || useCase == NULL) {
639         AUDIO_FUNC_LOGE("param Is NULL");
640         return HDF_ERR_INVALID_PARAM;
641     }
642     /* reset path numbers */
643     captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = 0;
644 
645     cJSON *cardNode = cJSON_GetObjectItem(g_cJsonObj, captureParam->captureMode.hwInfo.cardServiceName);
646     if (cardNode == NULL) {
647         AUDIO_FUNC_LOGE(
648             "failed to check item when [%{public}s] gets object!", captureParam->captureMode.hwInfo.cardServiceName);
649         return HDF_FAILURE;
650     }
651     cJSON *cardList = cardNode->child;
652     if (cardList == NULL) {
653         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", captureParam->captureMode.hwInfo.cardServiceName);
654         return HDF_FAILURE;
655     }
656 
657     cJSON *useCaseNode = cJSON_GetObjectItem(cardList, useCase);
658     if (useCaseNode == NULL) {
659         AUDIO_FUNC_LOGE("failed to check item when [%{public}s] gets object!", useCase);
660         return HDF_FAILURE;
661     }
662     cJSON *useCaseList = useCaseNode->child;
663     if (useCaseList == NULL) {
664         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", useCase);
665         return HDF_FAILURE;
666     }
667 
668     int32_t len = cJSON_GetArraySize(useCaseList);
669     if (len < 0 || len > HDF_PATH_NUM_MAX) {
670         AUDIO_FUNC_LOGE("len is invalid!");
671         return HDF_FAILURE;
672     }
673     for (int32_t i = 0; i < len; i++) {
674         cJSON *tmpValue = cJSON_GetArrayItem(useCaseList, i);
675         int32_t ret = AudioCaptureParseDevice(captureParam, tmpValue);
676         if (ret != HDF_SUCCESS) {
677             return ret;
678         }
679     }
680     return HDF_SUCCESS;
681 }
682 
AudioPathSelGetPlanCapture(struct AudioHwCaptureParam * captureParam)683 static int32_t AudioPathSelGetPlanCapture(struct AudioHwCaptureParam *captureParam)
684 {
685     enum AudioCategory type = captureParam->frameCaptureMode.attrs.type;
686 
687     if (type == AUDIO_IN_RINGTONE) {
688         AUDIO_FUNC_LOGE("useCase not support!");
689         return HDF_ERR_NOT_SUPPORT;
690     }
691 
692     if (type == AUDIO_MMAP_NOIRQ) {
693         AUDIO_FUNC_LOGE("useCase set as AUDIO_IN_MEDIA");
694         type = AUDIO_IN_MEDIA;
695     }
696 
697     const char *useCase = AudioPathSelGetUseCase(type);
698     if (useCase == NULL) {
699         AUDIO_FUNC_LOGE("useCase not support!");
700         return HDF_FAILURE;
701     }
702 
703     return AudioCaptureParseUsecase(captureParam, useCase);
704 }
705 
AudioPathSelRenderChkScene(struct AudioHwRenderParam * renderSceneParam)706 static int32_t AudioPathSelRenderChkScene(struct AudioHwRenderParam *renderSceneParam)
707 {
708     return AudioPathSelGetPlanRender(renderSceneParam);
709 }
710 
AudioPathSelCaptureChkScene(struct AudioHwCaptureParam * captureSceneParam)711 static int32_t AudioPathSelCaptureChkScene(struct AudioHwCaptureParam *captureSceneParam)
712 {
713     return AudioPathSelGetPlanCapture(captureSceneParam);
714 }
715 
AudioPathSelAnalysisJson(const AudioHandle adapterParam,enum AudioAdaptType adaptType)716 int32_t AudioPathSelAnalysisJson(const AudioHandle adapterParam, enum AudioAdaptType adaptType)
717 {
718     AUDIO_FUNC_LOGI();
719     if (adaptType < 0 || adapterParam == NULL) {
720         AUDIO_FUNC_LOGE("Param Invaild!");
721         return HDF_ERR_INVALID_PARAM;
722     }
723     struct AudioHwRenderParam *renderParam = NULL;
724     struct AudioHwCaptureParam *captureParam = NULL;
725     struct AudioHwRenderParam *renderSceneCheck = NULL;
726     struct AudioHwCaptureParam *captureScenceCheck = NULL;
727     switch (adaptType) {
728         case RENDER_PATH_SELECT:
729             renderParam = (struct AudioHwRenderParam *)adapterParam;
730             if (strcasecmp(renderParam->renderMode.hwInfo.adapterName, USB) == 0 ||
731                 strcasecmp(renderParam->renderMode.hwInfo.adapterName, HDMI) == 0) {
732                 return HDF_SUCCESS;
733             }
734             return (AudioPathSelGetPlanRender(renderParam));
735         case CAPTURE_PATH_SELECT:
736             captureParam = (struct AudioHwCaptureParam *)adapterParam;
737             if (strcasecmp(captureParam->captureMode.hwInfo.adapterName, USB) == 0 ||
738                 strcasecmp(captureParam->captureMode.hwInfo.adapterName, HDMI) == 0) {
739                 return HDF_SUCCESS;
740             }
741             return (AudioPathSelGetPlanCapture(captureParam));
742         /* Scene is supported */
743         case CHECKSCENE_PATH_SELECT:
744             renderSceneCheck = (struct AudioHwRenderParam *)adapterParam;
745             if (strcasecmp(renderSceneCheck->renderMode.hwInfo.adapterName, USB) == 0 ||
746                 strcasecmp(renderSceneCheck->renderMode.hwInfo.adapterName, HDMI) == 0) {
747                 return HDF_SUCCESS;
748             }
749             return (AudioPathSelRenderChkScene(renderSceneCheck));
750         case CHECKSCENE_PATH_SELECT_CAPTURE:
751             captureScenceCheck = (struct AudioHwCaptureParam *)adapterParam;
752             if (strcasecmp(captureScenceCheck->captureMode.hwInfo.adapterName, USB) == 0 ||
753                 strcasecmp(captureScenceCheck->captureMode.hwInfo.adapterName, HDMI) == 0) {
754                 return HDF_SUCCESS;
755             }
756             return (AudioPathSelCaptureChkScene(captureScenceCheck));
757         default:
758             AUDIO_FUNC_LOGE("Path select mode invalid");
759             break;
760     }
761     return HDF_FAILURE;
762 }
763