blob: 5fd329fd9d49486bf044d3ed3a41e34b8df045d3 [file] [log] [blame]
Lei Qian7bf98232018-09-20 17:56:38 +08001/*
2**
3** Copyright 2012, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16** @author Hugo Hong
17** @version 1.0
18** @date 2018/04/01
19** @par function description:
20** - 1 bluetooth rc audio stream in base class
21*/
22
23#define LOG_TAG "AudioHAL:AudioStreamIn"
xingri.gao989a73a2022-12-28 06:58:14 +000024#include <cutils/log.h>
25
Lei Qian7bf98232018-09-20 17:56:38 +080026
27#include "AudioStreamIn.h"
28#include "AudioHardwareInput.h"
29
30#include <assert.h>
31#include <stdio.h>
32#include <string.h>
33#include <unistd.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <netinet/in.h>
38#include <sys/select.h>
39#include <sys/socket.h>
40#include <sys/un.h>
41
42#include <utils/String8.h>
43#include <media/AudioParameter.h>
44
wei.du06ada4c2021-06-24 04:04:01 -040045// for turning Remote mic on/off
46#ifdef REMOTE_CONTROL_INTERFACE
47#include <IRemoteControlService.h>
48#endif
Lei Qian7bf98232018-09-20 17:56:38 +080049
50namespace android {
51
52const audio_format_t AudioStreamIn::kAudioFormat = AUDIO_FORMAT_PCM_16_BIT;
53const uint32_t AudioStreamIn::kChannelMask = AUDIO_CHANNEL_IN_MONO;
wei.du06ada4c2021-06-24 04:04:01 -040054const char AudioStreamIn::kRemoteSocketPath[] = "/data/misc/bluedroid/.rc_ctrl";
55int AudioStreamIn::m_fd = -1;
Lei Qian7bf98232018-09-20 17:56:38 +080056bool AudioStreamIn::mStandby = true;
57
58AudioStreamIn::AudioStreamIn(AudioHardwareInput& owner)
59 : mOwnerHAL(owner)
60 , mCurrentDeviceInfo(NULL)
61 , mRequestedSampleRate(0)
62 , mDisabled(false)
63 , mInputSource(AUDIO_SOURCE_VOICE_RECOGNITION)
64 , mReadStatus(0)
65{
66 mCurrentDeviceInfo = mOwnerHAL.getBestDevice(mInputSource);
67}
68
69AudioStreamIn::~AudioStreamIn()
70{
wei.du06ada4c2021-06-24 04:04:01 -040071 if (mStandby) {
72 closeRemoteService();
73 }
Lei Qian7bf98232018-09-20 17:56:38 +080074}
75
76// Perform stream initialization that may fail.
77// Must only be called once at construction time.
78status_t AudioStreamIn::set(struct audio_stream_in *stream,
79 audio_format_t *pFormat,
80 uint32_t *pChannelMask,
81 uint32_t *pRate)
82{
83 Mutex::Autolock _l(mLock);
84
85 (void) stream;
86
87 // Respond with a request for mono if a different format is given.
88 if (*pChannelMask != kChannelMask) {
89 *pChannelMask = kChannelMask;
90 return BAD_VALUE;
91 }
92
93 if (*pFormat != kAudioFormat) {
94 *pFormat = kAudioFormat;
95 return BAD_VALUE;
96 }
97
98 mRequestedSampleRate = *pRate;
99
100 return NO_ERROR;
101}
102
103
104uint32_t AudioStreamIn::getSampleRate()
105{
106 Mutex::Autolock _l(mLock);
107 return mRequestedSampleRate;
108}
109
110status_t AudioStreamIn::setSampleRate(uint32_t rate)
111{
112 (void) rate;
113 // this is a no-op in other audio HALs
114 return NO_ERROR;
115}
116
117size_t AudioStreamIn::getBufferSize()
118{
119 Mutex::Autolock _l(mLock);
120
121 size_t size = AudioHardwareInput::calculateInputBufferSize(
122 mRequestedSampleRate, kAudioFormat, getChannelCount());
123 return size;
124}
125
126uint32_t AudioStreamIn::getChannelMask()
127{
128 return kChannelMask;
129}
130
131audio_format_t AudioStreamIn::getFormat()
132{
133 return kAudioFormat;
134}
135
136status_t AudioStreamIn::setFormat(audio_format_t format)
137{
138 (void) format;
139 // other audio HALs fail any call to this API (even if the format matches
140 // the current format)
141 return INVALID_OPERATION;
142}
143
144status_t AudioStreamIn::standby()
145{
146 Mutex::Autolock _l(mLock);
147 return standby_l();
148}
149
150status_t AudioStreamIn::dump(int fd)
151{
152 (void) fd;
153 return NO_ERROR;
154}
155
156status_t AudioStreamIn::setParameters(struct audio_stream* stream,
157 const char* kvpairs)
158{
159 (void) stream;
160 (void) kvpairs;
161
162 return NO_ERROR;
163}
164
165char* AudioStreamIn::getParameters(const char* keys)
166{
167 (void) keys;
168 return strdup("");
169}
170
171status_t AudioStreamIn::setGain(float gain)
172{
173 (void) gain;
174 // In other HALs, this is a no-op and returns success.
175 return NO_ERROR;
176}
177
178uint32_t AudioStreamIn::getInputFramesLost()
179{
180 return 0;
181}
182
183status_t AudioStreamIn::addAudioEffect(effect_handle_t effect)
184{
185 (void) effect;
186 // In other HALs, this is a no-op and returns success.
187 return 0;
188}
189
190status_t AudioStreamIn::removeAudioEffect(effect_handle_t effect)
191{
192 (void) effect;
193 // In other HALs, this is a no-op and returns success.
194 return 0;
195}
196
197ssize_t AudioStreamIn::read(void* buffer, size_t bytes)
198{
199 Mutex::Autolock _l(mLock);
200
201 status_t status = NO_ERROR;
202
203 (void) buffer;
204
205 if (mStandby) {
206 status = startInputStream_l();
207 // Only try to start once to prevent pointless spew.
208 // If mic is not available then read will return silence.
209 // This is needed to prevent apps from hanging.
210 mStandby = false;
211 if (status != NO_ERROR) {
212 mDisabled = true;
213 }
214 }
215
216 return bytes;
217}
218
wei.du06ada4c2021-06-24 04:04:01 -0400219void AudioStreamIn::setRemoteControlMicEnabled(bool flag)
220{
221#ifdef REMOTE_CONTROL_INTERFACE
222 sp<IRemoteControlService> service = IRemoteControlService::getService();
223 if (service == NULL) {
224 ALOGE("%s: No RemoteControl service detected, ignoring\n", __func__);
225 return;
226 }
227 service->setMicEnable(flag == true ? 1 : 0);
228#else
229 m_fd = openRemoteService();
230 if (m_fd > 0) {
231 char status = (flag == true ? 1 : 0);
232 send(m_fd, &status, sizeof(status), MSG_NOSIGNAL);
233 }
234#endif
235}
236
Lei Qian7bf98232018-09-20 17:56:38 +0800237status_t AudioStreamIn::startInputStream_l()
238{
239 // Get the most appropriate device for the given input source, eg VOICE_RECOGNITION
240 const AudioHotplugThread::DeviceInfo *deviceInfo = mOwnerHAL.getBestDevice(mInputSource);
241 if (deviceInfo == NULL) {
242 return INVALID_OPERATION;
243 }
244
245 ALOGD("AudioStreamIn::startInputStream_l, mRequestedSampleRate = %d", mRequestedSampleRate);
246
247 // Turn on RemoteControl MIC if we are recording from it.
248 if (deviceInfo->forVoiceRecognition) {
wei.du06ada4c2021-06-24 04:04:01 -0400249 setRemoteControlMicEnabled(true);
Lei Qian7bf98232018-09-20 17:56:38 +0800250 }
251
252 mCurrentDeviceInfo = deviceInfo;
253
254 return NO_ERROR;
255}
256
257status_t AudioStreamIn::standby_l()
258{
259 if (mStandby) {
260 return NO_ERROR;
261 }
262
263 // Turn OFF Remote MIC if we were recording from Remote.
264 if (mCurrentDeviceInfo != NULL) {
265 if (mCurrentDeviceInfo->forVoiceRecognition) {
wei.du06ada4c2021-06-24 04:04:01 -0400266 setRemoteControlMicEnabled(false);
Lei Qian7bf98232018-09-20 17:56:38 +0800267 }
268 }
269
270 mCurrentDeviceInfo = NULL;
271 mStandby = true;
272 mDisabled = false;
273
274 return NO_ERROR;
275}
276
wei.du06ada4c2021-06-24 04:04:01 -0400277int AudioStreamIn::openRemoteService()
278{
279#ifdef REMOTE_CONTROL_INTERFACE
280 return 0;
281#else
282 int ret = -1;
283 int fd = m_fd;
284 socklen_t alen;
285 size_t namelen;
286 struct sockaddr_un addr;
287
288 if (fd > 0) return fd;
289
290 ALOGD("%s connect socket%s",__FUNCTION__, kRemoteSocketPath);
291
292 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
293
294 namelen = strlen(kRemoteSocketPath);
295 if ((namelen + 1) > sizeof(addr.sun_path))
296 goto done;
297
298 /*
299 * Note: The path in this case is *not* supposed to be
300 */
301 addr.sun_path[0] = 0;
302 memcpy(addr.sun_path + 1, kRemoteSocketPath, namelen);
303 addr.sun_family = AF_LOCAL;
304 alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
305 ret = connect(fd, (struct sockaddr *)&addr, alen);
306 if (ret < 0) {
307 ALOGE("connect failed:%d", errno);
308 goto done;
309 }
310
311 ALOGD("%s: fd=%d, ret=%d", __func__, fd, ret);
312done:
313 if (ret < 0) {
314 if (fd > 0) close(fd);
315 fd = -1;
316 }
317 return fd;
318#endif
319}
320
321void AudioStreamIn::closeRemoteService() {
322#ifdef REMOTE_CONTROL_INTERFACE
323 //do nothing
324#else
325 ALOGD("%s: fd=%d", __func__, m_fd);
326 if (m_fd > 0) {
327 close(m_fd);
328 m_fd = -1;
329 }
330#endif
331}
332
Lei Qian7bf98232018-09-20 17:56:38 +0800333}; // namespace android