• 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 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