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