blob: e4adf88d515b885e5891a4f467f03f95f7aa8fbf [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"
24#include <utils/Log.h>
25
26#include "AudioStreamIn.h"
27#include "AudioHardwareInput.h"
28
29#include <assert.h>
30#include <stdio.h>
31#include <string.h>
32#include <unistd.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <fcntl.h>
36#include <netinet/in.h>
37#include <sys/select.h>
38#include <sys/socket.h>
39#include <sys/un.h>
40
41#include <utils/String8.h>
42#include <media/AudioParameter.h>
43
wei.du06ada4c2021-06-24 04:04:01 -040044// for turning Remote mic on/off
45#ifdef REMOTE_CONTROL_INTERFACE
46#include <IRemoteControlService.h>
47#endif
Lei Qian7bf98232018-09-20 17:56:38 +080048
49namespace android {
50
51const audio_format_t AudioStreamIn::kAudioFormat = AUDIO_FORMAT_PCM_16_BIT;
52const uint32_t AudioStreamIn::kChannelMask = AUDIO_CHANNEL_IN_MONO;
wei.du06ada4c2021-06-24 04:04:01 -040053const char AudioStreamIn::kRemoteSocketPath[] = "/data/misc/bluedroid/.rc_ctrl";
54int AudioStreamIn::m_fd = -1;
Lei Qian7bf98232018-09-20 17:56:38 +080055bool AudioStreamIn::mStandby = true;
56
57AudioStreamIn::AudioStreamIn(AudioHardwareInput& owner)
58 : mOwnerHAL(owner)
59 , mCurrentDeviceInfo(NULL)
60 , mRequestedSampleRate(0)
61 , mDisabled(false)
62 , mInputSource(AUDIO_SOURCE_VOICE_RECOGNITION)
63 , mReadStatus(0)
64{
65 mCurrentDeviceInfo = mOwnerHAL.getBestDevice(mInputSource);
66}
67
68AudioStreamIn::~AudioStreamIn()
69{
wei.du06ada4c2021-06-24 04:04:01 -040070 if (mStandby) {
71 closeRemoteService();
72 }
Lei Qian7bf98232018-09-20 17:56:38 +080073}
74
75// Perform stream initialization that may fail.
76// Must only be called once at construction time.
77status_t AudioStreamIn::set(struct audio_stream_in *stream,
78 audio_format_t *pFormat,
79 uint32_t *pChannelMask,
80 uint32_t *pRate)
81{
82 Mutex::Autolock _l(mLock);
83
84 (void) stream;
85
86 // Respond with a request for mono if a different format is given.
87 if (*pChannelMask != kChannelMask) {
88 *pChannelMask = kChannelMask;
89 return BAD_VALUE;
90 }
91
92 if (*pFormat != kAudioFormat) {
93 *pFormat = kAudioFormat;
94 return BAD_VALUE;
95 }
96
97 mRequestedSampleRate = *pRate;
98
99 return NO_ERROR;
100}
101
102
103uint32_t AudioStreamIn::getSampleRate()
104{
105 Mutex::Autolock _l(mLock);
106 return mRequestedSampleRate;
107}
108
109status_t AudioStreamIn::setSampleRate(uint32_t rate)
110{
111 (void) rate;
112 // this is a no-op in other audio HALs
113 return NO_ERROR;
114}
115
116size_t AudioStreamIn::getBufferSize()
117{
118 Mutex::Autolock _l(mLock);
119
120 size_t size = AudioHardwareInput::calculateInputBufferSize(
121 mRequestedSampleRate, kAudioFormat, getChannelCount());
122 return size;
123}
124
125uint32_t AudioStreamIn::getChannelMask()
126{
127 return kChannelMask;
128}
129
130audio_format_t AudioStreamIn::getFormat()
131{
132 return kAudioFormat;
133}
134
135status_t AudioStreamIn::setFormat(audio_format_t format)
136{
137 (void) format;
138 // other audio HALs fail any call to this API (even if the format matches
139 // the current format)
140 return INVALID_OPERATION;
141}
142
143status_t AudioStreamIn::standby()
144{
145 Mutex::Autolock _l(mLock);
146 return standby_l();
147}
148
149status_t AudioStreamIn::dump(int fd)
150{
151 (void) fd;
152 return NO_ERROR;
153}
154
155status_t AudioStreamIn::setParameters(struct audio_stream* stream,
156 const char* kvpairs)
157{
158 (void) stream;
159 (void) kvpairs;
160
161 return NO_ERROR;
162}
163
164char* AudioStreamIn::getParameters(const char* keys)
165{
166 (void) keys;
167 return strdup("");
168}
169
170status_t AudioStreamIn::setGain(float gain)
171{
172 (void) gain;
173 // In other HALs, this is a no-op and returns success.
174 return NO_ERROR;
175}
176
177uint32_t AudioStreamIn::getInputFramesLost()
178{
179 return 0;
180}
181
182status_t AudioStreamIn::addAudioEffect(effect_handle_t effect)
183{
184 (void) effect;
185 // In other HALs, this is a no-op and returns success.
186 return 0;
187}
188
189status_t AudioStreamIn::removeAudioEffect(effect_handle_t effect)
190{
191 (void) effect;
192 // In other HALs, this is a no-op and returns success.
193 return 0;
194}
195
196ssize_t AudioStreamIn::read(void* buffer, size_t bytes)
197{
198 Mutex::Autolock _l(mLock);
199
200 status_t status = NO_ERROR;
201
202 (void) buffer;
203
204 if (mStandby) {
205 status = startInputStream_l();
206 // Only try to start once to prevent pointless spew.
207 // If mic is not available then read will return silence.
208 // This is needed to prevent apps from hanging.
209 mStandby = false;
210 if (status != NO_ERROR) {
211 mDisabled = true;
212 }
213 }
214
215 return bytes;
216}
217
wei.du06ada4c2021-06-24 04:04:01 -0400218void AudioStreamIn::setRemoteControlMicEnabled(bool flag)
219{
220#ifdef REMOTE_CONTROL_INTERFACE
221 sp<IRemoteControlService> service = IRemoteControlService::getService();
222 if (service == NULL) {
223 ALOGE("%s: No RemoteControl service detected, ignoring\n", __func__);
224 return;
225 }
226 service->setMicEnable(flag == true ? 1 : 0);
227#else
228 m_fd = openRemoteService();
229 if (m_fd > 0) {
230 char status = (flag == true ? 1 : 0);
231 send(m_fd, &status, sizeof(status), MSG_NOSIGNAL);
232 }
233#endif
234}
235
Lei Qian7bf98232018-09-20 17:56:38 +0800236status_t AudioStreamIn::startInputStream_l()
237{
238 // Get the most appropriate device for the given input source, eg VOICE_RECOGNITION
239 const AudioHotplugThread::DeviceInfo *deviceInfo = mOwnerHAL.getBestDevice(mInputSource);
240 if (deviceInfo == NULL) {
241 return INVALID_OPERATION;
242 }
243
244 ALOGD("AudioStreamIn::startInputStream_l, mRequestedSampleRate = %d", mRequestedSampleRate);
245
246 // Turn on RemoteControl MIC if we are recording from it.
247 if (deviceInfo->forVoiceRecognition) {
wei.du06ada4c2021-06-24 04:04:01 -0400248 setRemoteControlMicEnabled(true);
Lei Qian7bf98232018-09-20 17:56:38 +0800249 }
250
251 mCurrentDeviceInfo = deviceInfo;
252
253 return NO_ERROR;
254}
255
256status_t AudioStreamIn::standby_l()
257{
258 if (mStandby) {
259 return NO_ERROR;
260 }
261
262 // Turn OFF Remote MIC if we were recording from Remote.
263 if (mCurrentDeviceInfo != NULL) {
264 if (mCurrentDeviceInfo->forVoiceRecognition) {
wei.du06ada4c2021-06-24 04:04:01 -0400265 setRemoteControlMicEnabled(false);
Lei Qian7bf98232018-09-20 17:56:38 +0800266 }
267 }
268
269 mCurrentDeviceInfo = NULL;
270 mStandby = true;
271 mDisabled = false;
272
273 return NO_ERROR;
274}
275
wei.du06ada4c2021-06-24 04:04:01 -0400276int AudioStreamIn::openRemoteService()
277{
278#ifdef REMOTE_CONTROL_INTERFACE
279 return 0;
280#else
281 int ret = -1;
282 int fd = m_fd;
283 socklen_t alen;
284 size_t namelen;
285 struct sockaddr_un addr;
286
287 if (fd > 0) return fd;
288
289 ALOGD("%s connect socket%s",__FUNCTION__, kRemoteSocketPath);
290
291 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
292
293 namelen = strlen(kRemoteSocketPath);
294 if ((namelen + 1) > sizeof(addr.sun_path))
295 goto done;
296
297 /*
298 * Note: The path in this case is *not* supposed to be
299 */
300 addr.sun_path[0] = 0;
301 memcpy(addr.sun_path + 1, kRemoteSocketPath, namelen);
302 addr.sun_family = AF_LOCAL;
303 alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
304 ret = connect(fd, (struct sockaddr *)&addr, alen);
305 if (ret < 0) {
306 ALOGE("connect failed:%d", errno);
307 goto done;
308 }
309
310 ALOGD("%s: fd=%d, ret=%d", __func__, fd, ret);
311done:
312 if (ret < 0) {
313 if (fd > 0) close(fd);
314 fd = -1;
315 }
316 return fd;
317#endif
318}
319
320void AudioStreamIn::closeRemoteService() {
321#ifdef REMOTE_CONTROL_INTERFACE
322 //do nothing
323#else
324 ALOGD("%s: fd=%d", __func__, m_fd);
325 if (m_fd > 0) {
326 close(m_fd);
327 m_fd = -1;
328 }
329#endif
330}
331
Lei Qian7bf98232018-09-20 17:56:38 +0800332}; // namespace android