1 /*
2  * Copyright (c) 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioInputThread"
17 #endif
18 
19 #include "audio_input_thread.h"
20 
21 #include <fcntl.h>
22 #include <poll.h>
23 #include <unistd.h>
24 
25 #include "audio_errors.h"
26 #include "audio_policy_log.h"
27 
28 namespace OHOS {
29 namespace AudioStandard {
30 using namespace std;
31 int32_t g_inputDevCnt = 0;
32 pollfd g_fdSets[INPUT_EVT_MAX_CNT];
33 
34 AudioEvent AudioInputThread::audioInputEvent_ = {
35     .eventType = AUDIO_EVENT_UNKNOWN,
36     .deviceType = AUDIO_DEVICE_UNKNOWN,
37 };
38 
AudioAnalogHeadsetDeviceCheck(input_event evt)39 int32_t AudioInputThread::AudioAnalogHeadsetDeviceCheck(input_event evt)
40 {
41     audioInputEvent_.eventType = (evt.value == 0) ? AUDIO_DEVICE_REMOVE : AUDIO_DEVICE_ADD;
42     switch (evt.code) {
43         case SW_HEADPHONE_INSERT:
44             audioInputEvent_.deviceType = AUDIO_HEADPHONE;
45             break;
46         case SW_MICROPHONE_INSERT:
47             audioInputEvent_.deviceType = AUDIO_HEADSET;
48             break;
49         case SW_LINEOUT_INSERT:
50             audioInputEvent_.deviceType = AUDIO_LINEOUT;
51             break;
52         default: // SW_JACK_PHYSICAL_INSERT = 0x7, SW_LINEIN_INSERT = 0xd and other.
53             AUDIO_ERR_LOG("not surpport code = 0x%{public}x\n", evt.code);
54             return ERROR;
55     }
56     return SUCCESS;
57 }
58 
AudioPnpInputPollAndRead()59 int32_t AudioInputThread::AudioPnpInputPollAndRead()
60 {
61     int32_t num;
62     int32_t ret;
63     int32_t inputNum = g_inputDevCnt;
64     input_event evt;
65 
66     ret = poll(g_fdSets, (nfds_t)inputNum, -1);
67     if (ret < 0) {
68         AUDIO_ERR_LOG("[poll] failed, %{public}d", errno);
69         return ERROR;
70     }
71 
72     for (num = 0; num < inputNum; num++) {
73         if ((uint32_t)g_fdSets[num].revents & POLLIN) {
74             if (read(g_fdSets[num].fd, (void *)&evt, sizeof(evt)) < 0) {
75                 AUDIO_ERR_LOG("[read] failed, %{public}d", errno);
76                 return ERROR;
77             }
78             switch (evt.type) {
79                 case EV_SYN:
80                     AUDIO_DEBUG_LOG("evt.type = EV_SYN code = 0x%{public}d, value = %{public}d",
81                         evt.code, evt.value);
82                     break;
83                 case EV_SW:
84                     AUDIO_DEBUG_LOG("evt.type = EV_SW5, code = 0x%{public}d, value = %{public}d\n",
85                         evt.code, evt.value);
86                     AudioAnalogHeadsetDeviceCheck(evt);
87                     break;
88                 case EV_KEY:
89                     AUDIO_DEBUG_LOG("evt.type = EV_KEY, code = 0x%{public}x, value = %{public}d.",
90                         evt.code, evt.value);
91                     break;
92                 case EV_REL: // mouse move event.
93                 case EV_MSC:
94                 default:
95                     AUDIO_DEBUG_LOG("evt.type = EV_REL or EV_MSC code = 0x%{public}d, value = %{public}d",
96                         evt.code, evt.value);
97                     break;
98             }
99         }
100     }
101     return SUCCESS;
102 }
103 
AudioPnpInputOpen()104 int32_t AudioInputThread::AudioPnpInputOpen()
105 {
106     int32_t num;
107     int32_t fdNum = 0;
108     const char *devices[INPUT_EVT_MAX_CNT] = {
109         "/dev/input/event1",
110         "/dev/input/event2",
111         "/dev/input/event3",
112         "/dev/input/event4"
113     };
114 
115     for (num = 0; num < INPUT_EVT_MAX_CNT; num++) {
116         g_fdSets[fdNum].fd = open(devices[num], O_RDONLY);
117         if (g_fdSets[fdNum].fd < 0) {
118             AUDIO_ERR_LOG("[open] %{public}s failed!, fd %{public}d, errno: %{public}d",
119                 devices[num], g_fdSets[fdNum].fd, errno);
120             continue;
121         }
122         g_fdSets[fdNum].events = POLLIN;
123         fdNum++;
124     }
125     g_inputDevCnt = fdNum;
126 
127     return (fdNum == 0) ? ERROR : SUCCESS;
128 }
129 } // namespace AudioStandard
130 } // namespace OHOS