• 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(uint32_t tpins,cJSON * renderObj,struct AudioHwRenderParam * renderParam,int32_t value)226 static int32_t SetRenderPathValue(
227     uint32_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(uint32_t tpins,struct AudioHwRenderParam * renderParam,cJSON * cJsonObj,const char * deviceType,int32_t value)283 static int32_t SetMatchRenderDevicePath(
284     uint32_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(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(uint32_t tpins,struct AudioHwRenderParam * renderParam,cJSON * cJsonObj,int32_t value)325 static int32_t SetMatchRenderOtherDevicePath(
326     uint32_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     uint32_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             if (SetMatchRenderDevicePath(PIN_OUT_HEADSET, renderParam, cJsonObj, HEADPHONES, AUDIO_DEV_OFF) !=
377                 HDF_SUCCESS) {
378                 ret = HDF_FAILURE;
379             }
380 #endif
381             break;
382         case PIN_OUT_HEADSET:
383             /* 1、open headphone */
384             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, HEADPHONES, AUDIO_DEV_ON);
385 #ifndef ALSA_LIB_MODE
386             /* 2、close speaker */
387             if (SetMatchRenderDevicePath(PIN_OUT_SPEAKER, renderParam, cJsonObj, SPEAKER, AUDIO_DEV_OFF) !=
388                 HDF_SUCCESS) {
389                 ret = HDF_FAILURE;
390             }
391 #endif
392             break;
393         case PIN_OUT_EARPIECE:
394             /* 1、open earpiece */
395             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, EARPIECE, AUDIO_DEV_ON);
396             break;
397         case PIN_OUT_BLUETOOTH_SCO:
398             /* 1、open bluetooth */
399             ret = SetMatchRenderDevicePath(tpins, renderParam, cJsonObj, BLUETOOTH_SCO, AUDIO_DEV_ON);
400             break;
401         default:
402             ret = SetMatchRenderOtherDevicePath(tpins, renderParam, cJsonObj, AUDIO_DEV_ON);
403             break;
404     }
405 
406     return ret;
407 }
408 
AudioRenderParseUsecase(struct AudioHwRenderParam * renderParam,const char * useCase)409 static int32_t AudioRenderParseUsecase(struct AudioHwRenderParam *renderParam, const char *useCase)
410 {
411     /* reset path numbers */
412     renderParam->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum = 0;
413 
414     cJSON *cardNode = cJSON_GetObjectItem(g_cJsonObj, renderParam->renderMode.hwInfo.cardServiceName);
415     if (cardNode == NULL) {
416         AUDIO_FUNC_LOGE(
417             "failed to check item when [%{public}s] gets object!", renderParam->renderMode.hwInfo.cardServiceName);
418         return HDF_FAILURE;
419     }
420     cJSON *cardList = cardNode->child;
421     if (cardList == NULL) {
422         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", renderParam->renderMode.hwInfo.cardServiceName);
423         return HDF_FAILURE;
424     }
425 
426     cJSON *useCaseNode = cJSON_GetObjectItem(cardList, useCase);
427     if (useCaseNode == NULL) {
428         AUDIO_FUNC_LOGE("failed to check item when [%{public}s] gets object!", useCase);
429         return HDF_FAILURE;
430     }
431 
432     cJSON *useCaseList = useCaseNode->child;
433     if (useCaseList == NULL) {
434         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", useCase);
435         return HDF_FAILURE;
436     }
437 
438     int32_t len = cJSON_GetArraySize(useCaseList);
439     if (len < 0 || len > HDF_PATH_NUM_MAX) {
440         AUDIO_FUNC_LOGE("len is invalid!");
441         return HDF_FAILURE;
442     }
443     for (int32_t i = 0; i < len; i++) {
444         cJSON *tmpValue = cJSON_GetArrayItem(useCaseList, i);
445         /* Each device in the incoming scene */
446         int32_t ret = AudioRenderParseDevice(renderParam, tmpValue);
447         if (ret != HDF_SUCCESS) {
448             return ret;
449         }
450     }
451     return HDF_SUCCESS;
452 }
453 
AudioPathSelGetPlanRender(struct AudioHwRenderParam * renderParam)454 static int32_t AudioPathSelGetPlanRender(struct AudioHwRenderParam *renderParam)
455 {
456     if (renderParam == NULL) {
457         AUDIO_FUNC_LOGE("param Is NULL");
458         return HDF_ERR_INVALID_PARAM;
459     }
460     const char *useCase = AudioPathSelGetUseCase(renderParam->frameRenderMode.attrs.type);
461     if (useCase == NULL) {
462         AUDIO_FUNC_LOGE("useCase not support!");
463         return HDF_FAILURE;
464     }
465     return AudioRenderParseUsecase(renderParam, useCase);
466 }
467 
SetCapturePathValue(uint32_t tpins,cJSON * captureSwitchObj,struct AudioHwCaptureParam * captureParam,int32_t value)468 static int32_t SetCapturePathValue(
469     uint32_t tpins, cJSON *captureSwitchObj, struct AudioHwCaptureParam *captureParam, int32_t value)
470 {
471     if (captureParam == NULL || captureSwitchObj == NULL) {
472         AUDIO_FUNC_LOGE("param Is NULL");
473         return HDF_ERR_INVALID_PARAM;
474     }
475     const char *captureDeviceType = AudioPathSelGetDeviceType(tpins);
476     if (captureDeviceType == NULL) {
477         AUDIO_FUNC_LOGE("DeviceType not found.");
478         return HDF_FAILURE;
479     }
480 
481     int32_t devNum = captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum;
482     if (strcasecmp(captureDeviceType, captureSwitchObj->string) == 0) {
483         int32_t pathNum = cJSON_GetArraySize(captureSwitchObj);
484         if (pathNum < 0 || pathNum > HDF_PATH_NUM_MAX) {
485             AUDIO_FUNC_LOGE("pathNum is invalid!");
486             return HDF_FAILURE;
487         }
488         for (int32_t i = 0; i < pathNum; i++) {
489             cJSON *captureTmpValue = cJSON_GetArrayItem(captureSwitchObj, i);
490             if (captureTmpValue == NULL) {
491                 AUDIO_FUNC_LOGE("captureTmpValue is null.");
492                 return HDF_FAILURE;
493             }
494             cJSON *swName = captureTmpValue->child;
495             cJSON *swVal = swName->next;
496 
497             if (swName->valuestring == NULL) {
498                 AUDIO_FUNC_LOGE("ValueString is null!");
499                 return HDF_FAILURE;
500             }
501 
502             (void)memset_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch,
503                 PATHPLAN_LEN, 0, PATHPLAN_LEN);
504             int32_t ret =
505                 strncpy_s(captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].deviceSwitch,
506                     PATHPLAN_COUNT, swName->valuestring, strlen(swName->valuestring) + 1);
507             if (ret != 0) {
508                 AUDIO_FUNC_LOGE("strcpy_s failed!");
509                 return HDF_FAILURE;
510             }
511             if (swVal->valueint > AUDIO_DEV_ON) {
512                 /* alsa Adaptation */
513                 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = swVal->valueint;
514             } else {
515                 captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[devNum].value = value;
516             }
517 
518             devNum++;
519         }
520         captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = devNum;
521     }
522     return HDF_SUCCESS;
523 }
524 
SetMatchCaptureDevicePath(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj,uint32_t tpins,char * deviceType,int32_t value)525 static int32_t SetMatchCaptureDevicePath(
526     struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj, uint32_t tpins, char *deviceType, int32_t value)
527 {
528     if (captureParam == NULL || cJsonObj == NULL) {
529         AUDIO_FUNC_LOGE("param Is NULL");
530         return HDF_ERR_INVALID_PARAM;
531     }
532     if (strcasecmp(cJsonObj->string, deviceType) == 0) {
533         int32_t ret = SetCapturePathValue(tpins, cJsonObj, captureParam, value);
534         if (ret != HDF_SUCCESS) {
535             AUDIO_FUNC_LOGE("set value failed!");
536             return ret;
537         }
538     }
539     return HDF_SUCCESS;
540 }
541 
SetMatchCaptureDefaultDevicePath(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj)542 static int32_t SetMatchCaptureDefaultDevicePath(struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj)
543 {
544     int32_t ret;
545     if (captureParam == NULL || cJsonObj == NULL) {
546         AUDIO_FUNC_LOGE("param Is NULL");
547         return HDF_ERR_INVALID_PARAM;
548     }
549     for (uint32_t i = PIN_IN_MIC; i <= PIN_IN_BLUETOOTH_SCO_HEADSET;
550          i = (1 << INPUT_OFFSET) | ((i & OUTPUT_MASK) << 1)) {
551         const char *deviceType = AudioPathSelGetDeviceType((int32_t)i);
552         if (deviceType == NULL) {
553             AUDIO_FUNC_LOGE("DeviceType not found.");
554             return HDF_FAILURE;
555         }
556 
557         if (strcasecmp(deviceType, cJsonObj->string) == 0) {
558             ret = SetCapturePathDefaultValue(cJsonObj, captureParam);
559             if (ret != HDF_SUCCESS) {
560                 AUDIO_FUNC_LOGE("set default value failed!");
561                 return ret;
562             }
563             break;
564         }
565     }
566     return HDF_SUCCESS;
567 }
568 
SetMatchCaptureOtherDevicePath(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj,uint32_t tpins,int32_t value)569 static int32_t SetMatchCaptureOtherDevicePath(
570     struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj, uint32_t tpins, int32_t value)
571 {
572     int32_t ret;
573     uint32_t i;
574     if (captureParam == NULL || cJsonObj == NULL) {
575         AUDIO_FUNC_LOGE("param Is NULL");
576         return HDF_ERR_INVALID_PARAM;
577     }
578     for (i = PIN_IN_MIC; i <= PIN_IN_BLUETOOTH_SCO_HEADSET; i = (1 << INPUT_OFFSET) | ((i & OUTPUT_MASK) << 1)) {
579         if ((i & tpins) == i) { /* Select which device to open and get the pin of which device */
580             ret = SetCapturePathValue((int32_t)i, cJsonObj, captureParam, value);
581             if (ret != HDF_SUCCESS) {
582                 AUDIO_FUNC_LOGE("set value failed!");
583                 continue;
584             }
585         }
586     }
587     return HDF_SUCCESS;
588 }
589 
AudioCaptureParseDevice(struct AudioHwCaptureParam * captureParam,cJSON * cJsonObj)590 static int32_t AudioCaptureParseDevice(struct AudioHwCaptureParam *captureParam, cJSON *cJsonObj)
591 {
592     int32_t ret;
593     if (captureParam == NULL || cJsonObj == NULL) {
594         AUDIO_FUNC_LOGE("param Is NULL");
595         return HDF_ERR_INVALID_PARAM;
596     }
597     uint32_t pins = captureParam->captureMode.hwInfo.deviceDescript.pins;
598 
599     if (!((pins >> INPUT_OFFSET) & 0x01)) {
600         AUDIO_FUNC_LOGE("pins: %{public}d, error!", pins);
601         return HDF_FAILURE;
602     }
603 
604     if (strcasecmp(cJsonObj->string, SPEAKER) == 0 || strcasecmp(cJsonObj->string, HEADPHONES) == 0 ||
605         strcasecmp(cJsonObj->string, EARPIECE) == 0  || strcasecmp(cJsonObj->string, BLUETOOTH_SCO) == 0) {
606         return HDF_SUCCESS;
607     }
608 
609     uint32_t tpins = pins & INPUT_MASK;
610     switch (tpins) {
611         case (1 << INPUT_OFFSET):
612             /* pins = 0, parse default value */
613             ret = SetMatchCaptureDefaultDevicePath(captureParam, cJsonObj);
614             break;
615         case PIN_IN_MIC:
616             /* 1.open main mic */
617             ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, MIC, AUDIO_DEV_ON);
618 #ifndef ALSA_LIB_MODE
619             /* 2.close headset mic */
620             if (SetMatchCaptureDevicePath(captureParam, cJsonObj, PIN_IN_HS_MIC, HS_MIC, AUDIO_DEV_OFF) ==
621                 HDF_SUCCESS) {
622                 ret = HDF_SUCCESS;
623             }
624 #endif
625             break;
626         case PIN_IN_HS_MIC:
627             /* 1、open headset mic */
628             ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, HS_MIC, AUDIO_DEV_ON);
629 #ifndef ALSA_LIB_MODE
630             /* 2、close main mic */
631             if (SetMatchCaptureDevicePath(captureParam, cJsonObj, PIN_IN_MIC, MIC, AUDIO_DEV_OFF) ==
632                 HDF_SUCCESS) {
633                 ret = HDF_SUCCESS;
634             }
635 #endif
636             break;
637         case PIN_IN_BLUETOOTH_SCO_HEADSET:
638             /* 1、open bluetooth sco headset mic */
639             ret = SetMatchCaptureDevicePath(captureParam, cJsonObj, tpins, BLUETOOTH_SCO_HEADSET, AUDIO_DEV_ON);
640             break;
641         default:
642             ret = SetMatchCaptureOtherDevicePath(captureParam, cJsonObj, tpins, AUDIO_DEV_ON);
643             break;
644     }
645     return ret;
646 }
647 
AudioCaptureParseUsecase(struct AudioHwCaptureParam * captureParam,const char * useCase)648 static int32_t AudioCaptureParseUsecase(struct AudioHwCaptureParam *captureParam, const char *useCase)
649 {
650     if (captureParam == NULL || useCase == NULL) {
651         AUDIO_FUNC_LOGE("param Is NULL");
652         return HDF_ERR_INVALID_PARAM;
653     }
654     /* reset path numbers */
655     captureParam->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum = 0;
656 
657     cJSON *cardNode = cJSON_GetObjectItem(g_cJsonObj, captureParam->captureMode.hwInfo.cardServiceName);
658     if (cardNode == NULL) {
659         AUDIO_FUNC_LOGE(
660             "failed to check item when [%{public}s] gets object!", captureParam->captureMode.hwInfo.cardServiceName);
661         return HDF_FAILURE;
662     }
663     cJSON *cardList = cardNode->child;
664     if (cardList == NULL) {
665         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", captureParam->captureMode.hwInfo.cardServiceName);
666         return HDF_FAILURE;
667     }
668 
669     cJSON *useCaseNode = cJSON_GetObjectItem(cardList, useCase);
670     if (useCaseNode == NULL) {
671         AUDIO_FUNC_LOGE("failed to check item when [%{public}s] gets object!", useCase);
672         return HDF_FAILURE;
673     }
674     cJSON *useCaseList = useCaseNode->child;
675     if (useCaseList == NULL) {
676         AUDIO_FUNC_LOGE("no child when [%{public}s] gets object!", useCase);
677         return HDF_FAILURE;
678     }
679 
680     int32_t len = cJSON_GetArraySize(useCaseList);
681     if (len < 0 || len > HDF_PATH_NUM_MAX) {
682         AUDIO_FUNC_LOGE("len is invalid!");
683         return HDF_FAILURE;
684     }
685     for (int32_t i = 0; i < len; i++) {
686         cJSON *tmpValue = cJSON_GetArrayItem(useCaseList, i);
687         int32_t ret = AudioCaptureParseDevice(captureParam, tmpValue);
688         if (ret != HDF_SUCCESS) {
689             return ret;
690         }
691     }
692     return HDF_SUCCESS;
693 }
694 
AudioPathSelGetPlanCapture(struct AudioHwCaptureParam * captureParam)695 static int32_t AudioPathSelGetPlanCapture(struct AudioHwCaptureParam *captureParam)
696 {
697     enum AudioCategory type = captureParam->frameCaptureMode.attrs.type;
698 
699     if (type == AUDIO_IN_RINGTONE) {
700         AUDIO_FUNC_LOGE("useCase not support!");
701         return HDF_ERR_NOT_SUPPORT;
702     }
703 
704     if (type == AUDIO_MMAP_NOIRQ) {
705         AUDIO_FUNC_LOGE("useCase set as AUDIO_IN_MEDIA");
706         type = AUDIO_IN_MEDIA;
707     }
708 
709     const char *useCase = AudioPathSelGetUseCase(type);
710     if (useCase == NULL) {
711         AUDIO_FUNC_LOGE("useCase not support!");
712         return HDF_FAILURE;
713     }
714 
715     return AudioCaptureParseUsecase(captureParam, useCase);
716 }
717 
AudioPathSelRenderChkScene(struct AudioHwRenderParam * renderSceneParam)718 static int32_t AudioPathSelRenderChkScene(struct AudioHwRenderParam *renderSceneParam)
719 {
720     return AudioPathSelGetPlanRender(renderSceneParam);
721 }
722 
AudioPathSelCaptureChkScene(struct AudioHwCaptureParam * captureSceneParam)723 static int32_t AudioPathSelCaptureChkScene(struct AudioHwCaptureParam *captureSceneParam)
724 {
725     return AudioPathSelGetPlanCapture(captureSceneParam);
726 }
727 
AudioPathSelAnalysisJson(const AudioHandle adapterParam,enum AudioAdaptType adaptType)728 int32_t AudioPathSelAnalysisJson(const AudioHandle adapterParam, enum AudioAdaptType adaptType)
729 {
730     AUDIO_FUNC_LOGI();
731     if (adaptType < 0 || adapterParam == NULL) {
732         AUDIO_FUNC_LOGE("Param Invaild!");
733         return HDF_ERR_INVALID_PARAM;
734     }
735     struct AudioHwRenderParam *renderParam = NULL;
736     struct AudioHwCaptureParam *captureParam = NULL;
737     struct AudioHwRenderParam *renderSceneCheck = NULL;
738     struct AudioHwCaptureParam *captureScenceCheck = NULL;
739     switch (adaptType) {
740         case RENDER_PATH_SELECT:
741             renderParam = (struct AudioHwRenderParam *)adapterParam;
742             if (strcasecmp(renderParam->renderMode.hwInfo.adapterName, USB) == 0 ||
743                 strcasecmp(renderParam->renderMode.hwInfo.adapterName, HDMI) == 0) {
744                 return HDF_SUCCESS;
745             }
746             return (AudioPathSelGetPlanRender(renderParam));
747         case CAPTURE_PATH_SELECT:
748             captureParam = (struct AudioHwCaptureParam *)adapterParam;
749             if (strcasecmp(captureParam->captureMode.hwInfo.adapterName, USB) == 0 ||
750                 strcasecmp(captureParam->captureMode.hwInfo.adapterName, HDMI) == 0) {
751                 return HDF_SUCCESS;
752             }
753             return (AudioPathSelGetPlanCapture(captureParam));
754         /* Scene is supported */
755         case CHECKSCENE_PATH_SELECT:
756             renderSceneCheck = (struct AudioHwRenderParam *)adapterParam;
757             if (strcasecmp(renderSceneCheck->renderMode.hwInfo.adapterName, USB) == 0 ||
758                 strcasecmp(renderSceneCheck->renderMode.hwInfo.adapterName, HDMI) == 0) {
759                 return HDF_SUCCESS;
760             }
761             return (AudioPathSelRenderChkScene(renderSceneCheck));
762         case CHECKSCENE_PATH_SELECT_CAPTURE:
763             captureScenceCheck = (struct AudioHwCaptureParam *)adapterParam;
764             if (strcasecmp(captureScenceCheck->captureMode.hwInfo.adapterName, USB) == 0 ||
765                 strcasecmp(captureScenceCheck->captureMode.hwInfo.adapterName, HDMI) == 0) {
766                 return HDF_SUCCESS;
767             }
768             return (AudioPathSelCaptureChkScene(captureScenceCheck));
769         default:
770             AUDIO_FUNC_LOGE("Path select mode invalid");
771             break;
772     }
773     return HDF_FAILURE;
774 }
775