1 /*
2 * Copyright (c) 2021-2022 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_capturer.h"
17
18 #include "audio_errors.h"
19 #ifdef OHCORE
20 #include "audio_capturer_gateway.h"
21 #else
22 #include "audio_capturer_private.h"
23 #include "audio_stream.h"
24 #endif
25 #include "audio_log.h"
26
27 namespace OHOS {
28 namespace AudioStandard {
29 AudioCapturer::~AudioCapturer() = default;
30
31 #ifndef OHCORE
32 AudioCapturerPrivate::~AudioCapturerPrivate() = default;
33 #endif
34
Create(AudioStreamType audioStreamType)35 std::unique_ptr<AudioCapturer> AudioCapturer::Create(AudioStreamType audioStreamType)
36 {
37 AppInfo appInfo = {};
38 return Create(audioStreamType, appInfo);
39 }
40
Create(AudioStreamType audioStreamType,const AppInfo & appInfo)41 std::unique_ptr<AudioCapturer> AudioCapturer::Create(AudioStreamType audioStreamType, const AppInfo &appInfo)
42 {
43 #ifdef OHCORE
44 return std::make_unique<AudioCapturerGateway>(audioStreamType, appInfo);
45 #else
46 return std::make_unique<AudioCapturerPrivate>(audioStreamType, appInfo);
47 #endif
48 }
49
Create(const AudioCapturerOptions & options)50 std::unique_ptr<AudioCapturer> AudioCapturer::Create(const AudioCapturerOptions &options)
51 {
52 AppInfo appInfo = {};
53 return Create(options, "", appInfo);
54 }
55
Create(const AudioCapturerOptions & options,const AppInfo & appInfo)56 std::unique_ptr<AudioCapturer> AudioCapturer::Create(const AudioCapturerOptions &options, const AppInfo &appInfo)
57 {
58 return Create(options, "", appInfo);
59 }
60
Create(const AudioCapturerOptions & options,const std::string cachePath)61 std::unique_ptr<AudioCapturer> AudioCapturer::Create(const AudioCapturerOptions &options, const std::string cachePath)
62 {
63 AppInfo appInfo = {};
64 return Create(options, cachePath, appInfo);
65 }
66
Create(const AudioCapturerOptions & capturerOptions,const std::string cachePath,const AppInfo & appInfo)67 std::unique_ptr<AudioCapturer> AudioCapturer::Create(const AudioCapturerOptions &capturerOptions,
68 const std::string cachePath, const AppInfo &appInfo)
69 {
70 auto sourceType = capturerOptions.capturerInfo.sourceType;
71 if (sourceType < SOURCE_TYPE_MIC || sourceType > SOURCE_TYPE_VOICE_COMMUNICATION) {
72 return nullptr;
73 }
74
75 AudioStreamType audioStreamType = STREAM_MUSIC;
76 if (sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) {
77 audioStreamType = STREAM_VOICE_CALL;
78 }
79
80 AudioCapturerParams params;
81 params.audioSampleFormat = capturerOptions.streamInfo.format;
82 params.samplingRate = capturerOptions.streamInfo.samplingRate;
83 bool isChange = false;
84 if (AudioChannel::CHANNEL_3 == capturerOptions.streamInfo.channels) {
85 params.audioChannel = AudioChannel::STEREO;
86 isChange = true;
87 } else {
88 params.audioChannel = capturerOptions.streamInfo.channels;
89 }
90 params.audioEncoding = capturerOptions.streamInfo.encoding;
91 #ifdef OHCORE
92 auto capturer = std::make_unique<AudioCapturerGateway>(audioStreamType, appInfo);
93 #else
94 auto capturer = std::make_unique<AudioCapturerPrivate>(audioStreamType, appInfo);
95 #endif
96 if (capturer == nullptr) {
97 return capturer;
98 }
99
100 if (!cachePath.empty()) {
101 AUDIO_DEBUG_LOG("Set application cache path");
102 capturer->SetApplicationCachePath(cachePath);
103 }
104
105 capturer->capturerInfo_.sourceType = sourceType;
106 capturer->capturerInfo_.capturerFlags = capturerOptions.capturerInfo.capturerFlags;
107 if (capturer->SetParams(params) != SUCCESS) {
108 capturer = nullptr;
109 }
110 if (isChange) {
111 capturer->isChannelChange_ = true;
112 }
113 return capturer;
114 }
115
116 #ifndef OHCORE
AudioCapturerPrivate(AudioStreamType audioStreamType,const AppInfo & appInfo)117 AudioCapturerPrivate::AudioCapturerPrivate(AudioStreamType audioStreamType, const AppInfo &appInfo)
118 {
119 appInfo_ = appInfo;
120 if (!(appInfo_.appPid)) {
121 appInfo_.appPid = getpid();
122 }
123
124 if (appInfo_.appUid < 0) {
125 appInfo_.appUid = static_cast<int32_t>(getuid());
126 }
127
128 audioStream_ = std::make_shared<AudioStream>(audioStreamType, AUDIO_MODE_RECORD, appInfo_.appUid);
129 if (audioStream_) {
130 AUDIO_DEBUG_LOG("AudioCapturerPrivate::Audio stream created");
131 }
132 capturerProxyObj_ = std::make_shared<AudioCapturerProxyObj>();
133 if (!capturerProxyObj_) {
134 AUDIO_ERR_LOG("AudioCapturerProxyObj Memory Allocation Failed !!");
135 }
136 }
137
GetFrameCount(uint32_t & frameCount) const138 int32_t AudioCapturerPrivate::GetFrameCount(uint32_t &frameCount) const
139 {
140 return audioStream_->GetFrameCount(frameCount);
141 }
142
SetParams(const AudioCapturerParams params)143 int32_t AudioCapturerPrivate::SetParams(const AudioCapturerParams params)
144 {
145 if (!audioStream_->VerifyClientPermission(MICROPHONE_PERMISSION, appInfo_.appTokenId, appInfo_.appUid,
146 true, AUDIO_PERMISSION_START)) {
147 AUDIO_ERR_LOG("MICROPHONE permission denied for %{public}d", appInfo_.appTokenId);
148 return ERR_PERMISSION_DENIED;
149 }
150 const AudioCapturer *capturer = this;
151 capturerProxyObj_->SaveCapturerObj(capturer);
152
153 audioStream_->SetCapturerInfo(capturerInfo_);
154
155 AudioStreamParams audioStreamParams;
156 audioStreamParams.format = params.audioSampleFormat;
157 audioStreamParams.samplingRate = params.samplingRate;
158 audioStreamParams.channels = params.audioChannel;
159 audioStreamParams.encoding = params.audioEncoding;
160
161 audioStream_->SetClientID(appInfo_.appPid, appInfo_.appUid);
162
163 return audioStream_->SetAudioStreamInfo(audioStreamParams, capturerProxyObj_);
164 }
165
SetCapturerCallback(const std::shared_ptr<AudioCapturerCallback> & callback)166 int32_t AudioCapturerPrivate::SetCapturerCallback(const std::shared_ptr<AudioCapturerCallback> &callback)
167 {
168 // If the client is using the deprecated SetParams API. SetCapturerCallback must be invoked, after SetParams.
169 // In general, callbacks can only be set after the capturer state is PREPARED.
170 CapturerState state = GetStatus();
171 if (state == CAPTURER_NEW || state == CAPTURER_RELEASED) {
172 AUDIO_DEBUG_LOG("AudioCapturerPrivate::SetCapturerCallback ncorrect state:%{public}d to register cb", state);
173 return ERR_ILLEGAL_STATE;
174 }
175 if (callback == nullptr) {
176 AUDIO_ERR_LOG("AudioCapturerPrivate::SetCapturerCallback callback param is null");
177 return ERR_INVALID_PARAM;
178 }
179
180 // Save and Set reference for stream callback. Order is important here.
181 if (audioStreamCallback_ == nullptr) {
182 audioStreamCallback_ = std::make_shared<AudioStreamCallbackCapturer>();
183 if (audioStreamCallback_ == nullptr) {
184 AUDIO_ERR_LOG("AudioCapturerPrivate::Failed to allocate memory for audioStreamCallback_");
185 return ERROR;
186 }
187 }
188 std::shared_ptr<AudioStreamCallbackCapturer> cbStream =
189 std::static_pointer_cast<AudioStreamCallbackCapturer>(audioStreamCallback_);
190 cbStream->SaveCallback(callback);
191 (void)audioStream_->SetStreamCallback(audioStreamCallback_);
192
193 return SUCCESS;
194 }
195
GetParams(AudioCapturerParams & params) const196 int32_t AudioCapturerPrivate::GetParams(AudioCapturerParams ¶ms) const
197 {
198 AudioStreamParams audioStreamParams;
199 int32_t result = audioStream_->GetAudioStreamInfo(audioStreamParams);
200 if (SUCCESS == result) {
201 params.audioSampleFormat = static_cast<AudioSampleFormat>(audioStreamParams.format);
202 params.samplingRate = static_cast<AudioSamplingRate>(audioStreamParams.samplingRate);
203 params.audioChannel = static_cast<AudioChannel>(audioStreamParams.channels);
204 params.audioEncoding = static_cast<AudioEncodingType>(audioStreamParams.encoding);
205 }
206
207 return result;
208 }
209
GetCapturerInfo(AudioCapturerInfo & capturerInfo) const210 int32_t AudioCapturerPrivate::GetCapturerInfo(AudioCapturerInfo &capturerInfo) const
211 {
212 capturerInfo = capturerInfo_;
213
214 return SUCCESS;
215 }
216
GetStreamInfo(AudioStreamInfo & streamInfo) const217 int32_t AudioCapturerPrivate::GetStreamInfo(AudioStreamInfo &streamInfo) const
218 {
219 AudioStreamParams audioStreamParams;
220 int32_t result = audioStream_->GetAudioStreamInfo(audioStreamParams);
221 if (SUCCESS == result) {
222 streamInfo.format = static_cast<AudioSampleFormat>(audioStreamParams.format);
223 streamInfo.samplingRate = static_cast<AudioSamplingRate>(audioStreamParams.samplingRate);
224 if (this->isChannelChange_) {
225 streamInfo.channels = AudioChannel::CHANNEL_3;
226 } else {
227 streamInfo.channels = static_cast<AudioChannel>(audioStreamParams.channels);
228 }
229 streamInfo.encoding = static_cast<AudioEncodingType>(audioStreamParams.encoding);
230 }
231
232 return result;
233 }
234
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)235 int32_t AudioCapturerPrivate::SetCapturerPositionCallback(int64_t markPosition,
236 const std::shared_ptr<CapturerPositionCallback> &callback)
237 {
238 if ((callback == nullptr) || (markPosition <= 0)) {
239 AUDIO_ERR_LOG("AudioCapturerPrivate::SetCapturerPositionCallback input param is invalid");
240 return ERR_INVALID_PARAM;
241 }
242
243 audioStream_->SetCapturerPositionCallback(markPosition, callback);
244
245 return SUCCESS;
246 }
247
UnsetCapturerPositionCallback()248 void AudioCapturerPrivate::UnsetCapturerPositionCallback()
249 {
250 audioStream_->UnsetCapturerPositionCallback();
251 }
252
SetCapturerPeriodPositionCallback(int64_t frameNumber,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)253 int32_t AudioCapturerPrivate::SetCapturerPeriodPositionCallback(int64_t frameNumber,
254 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
255 {
256 if ((callback == nullptr) || (frameNumber <= 0)) {
257 AUDIO_ERR_LOG("AudioCapturerPrivate::SetCapturerPeriodPositionCallback input param is invalid");
258 return ERR_INVALID_PARAM;
259 }
260
261 audioStream_->SetCapturerPeriodPositionCallback(frameNumber, callback);
262
263 return SUCCESS;
264 }
265
UnsetCapturerPeriodPositionCallback()266 void AudioCapturerPrivate::UnsetCapturerPeriodPositionCallback()
267 {
268 audioStream_->UnsetCapturerPeriodPositionCallback();
269 }
270
Start() const271 bool AudioCapturerPrivate::Start() const
272 {
273 if (!audioStream_->getUsingPemissionFromPrivacy(MICROPHONE_PERMISSION, appInfo_.appTokenId,
274 AUDIO_PERMISSION_START)) {
275 AUDIO_ERR_LOG("Start monitor permission failed");
276 }
277 return audioStream_->StartAudioStream();
278 }
279
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead) const280 int32_t AudioCapturerPrivate::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead) const
281 {
282 return audioStream_->Read(buffer, userSize, isBlockingRead);
283 }
284
GetStatus() const285 CapturerState AudioCapturerPrivate::GetStatus() const
286 {
287 return (CapturerState)audioStream_->GetState();
288 }
289
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base) const290 bool AudioCapturerPrivate::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) const
291 {
292 return audioStream_->GetAudioTime(timestamp, base);
293 }
294
Pause() const295 bool AudioCapturerPrivate::Pause() const
296 {
297 if (!audioStream_->getUsingPemissionFromPrivacy(MICROPHONE_PERMISSION, appInfo_.appTokenId,
298 AUDIO_PERMISSION_STOP)) {
299 AUDIO_ERR_LOG("Pause monitor permission failed");
300 }
301 return audioStream_->PauseAudioStream();
302 }
303
Stop() const304 bool AudioCapturerPrivate::Stop() const
305 {
306 if (!audioStream_->getUsingPemissionFromPrivacy(MICROPHONE_PERMISSION, appInfo_.appTokenId,
307 AUDIO_PERMISSION_STOP)) {
308 AUDIO_ERR_LOG("Stop monitor permission failed");
309 }
310 return audioStream_->StopAudioStream();
311 }
312
Flush() const313 bool AudioCapturerPrivate::Flush() const
314 {
315 return audioStream_->FlushAudioStream();
316 }
317
Release() const318 bool AudioCapturerPrivate::Release() const
319 {
320 if (!audioStream_->getUsingPemissionFromPrivacy(MICROPHONE_PERMISSION, appInfo_.appTokenId,
321 AUDIO_PERMISSION_STOP)) {
322 AUDIO_ERR_LOG("Release monitor permission failed");
323 }
324 return audioStream_->ReleaseAudioStream();
325 }
326
GetBufferSize(size_t & bufferSize) const327 int32_t AudioCapturerPrivate::GetBufferSize(size_t &bufferSize) const
328 {
329 return audioStream_->GetBufferSize(bufferSize);
330 }
331
GetAudioStreamId(uint32_t & sessionID) const332 int32_t AudioCapturerPrivate::GetAudioStreamId(uint32_t &sessionID) const
333 {
334 return audioStream_->GetAudioSessionID(sessionID);
335 }
336
SetBufferDuration(uint64_t bufferDuration) const337 int32_t AudioCapturerPrivate::SetBufferDuration(uint64_t bufferDuration) const
338 {
339 if (bufferDuration < MINIMUM_BUFFER_SIZE_MSEC || bufferDuration > MAXIMUM_BUFFER_SIZE_MSEC) {
340 AUDIO_ERR_LOG("Error: Please set the buffer duration between 5ms ~ 20ms");
341 return ERR_INVALID_PARAM;
342 }
343 return audioStream_->SetBufferSizeInMsec(bufferDuration);
344 }
345
SetApplicationCachePath(const std::string cachePath)346 void AudioCapturerPrivate::SetApplicationCachePath(const std::string cachePath)
347 {
348 audioStream_->SetApplicationCachePath(cachePath);
349 }
350
SaveCallback(const std::weak_ptr<AudioCapturerCallback> & callback)351 void AudioStreamCallbackCapturer::SaveCallback(const std::weak_ptr<AudioCapturerCallback> &callback)
352 {
353 callback_ = callback;
354 }
355
OnStateChange(const State state,const StateChangeCmdType cmdType)356 void AudioStreamCallbackCapturer::OnStateChange(const State state,
357 const StateChangeCmdType __attribute__((unused)) cmdType)
358 {
359 std::shared_ptr<AudioCapturerCallback> cb = callback_.lock();
360 if (cb == nullptr) {
361 AUDIO_ERR_LOG("AudioStreamCallbackCapturer::OnStateChange cb == nullptr.");
362 return;
363 }
364
365 cb->OnStateChange(static_cast<CapturerState>(state));
366 }
367
GetSupportedFormats()368 std::vector<AudioSampleFormat> AudioCapturer::GetSupportedFormats()
369 {
370 return AUDIO_SUPPORTED_FORMATS;
371 }
372
GetSupportedChannels()373 std::vector<AudioChannel> AudioCapturer::GetSupportedChannels()
374 {
375 return CAPTURER_SUPPORTED_CHANNELS;
376 }
377
GetSupportedEncodingTypes()378 std::vector<AudioEncodingType> AudioCapturer::GetSupportedEncodingTypes()
379 {
380 return AUDIO_SUPPORTED_ENCODING_TYPES;
381 }
382
GetSupportedSamplingRates()383 std::vector<AudioSamplingRate> AudioCapturer::GetSupportedSamplingRates()
384 {
385 return AUDIO_SUPPORTED_SAMPLING_RATES;
386 }
387
SetCaptureMode(AudioCaptureMode captureMode) const388 int32_t AudioCapturerPrivate::SetCaptureMode(AudioCaptureMode captureMode) const
389 {
390 return audioStream_->SetCaptureMode(captureMode);
391 }
392
GetCaptureMode() const393 AudioCaptureMode AudioCapturerPrivate::GetCaptureMode() const
394 {
395 return audioStream_->GetCaptureMode();
396 }
397
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)398 int32_t AudioCapturerPrivate::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
399 {
400 return audioStream_->SetCapturerReadCallback(callback);
401 }
402
GetBufferDesc(BufferDesc & bufDesc) const403 int32_t AudioCapturerPrivate::GetBufferDesc(BufferDesc &bufDesc) const
404 {
405 return audioStream_->GetBufferDesc(bufDesc);
406 }
407
Enqueue(const BufferDesc & bufDesc) const408 int32_t AudioCapturerPrivate::Enqueue(const BufferDesc &bufDesc) const
409 {
410 return audioStream_->Enqueue(bufDesc);
411 }
412
Clear() const413 int32_t AudioCapturerPrivate::Clear() const
414 {
415 return audioStream_->Clear();
416 }
417
GetBufQueueState(BufferQueueState & bufState) const418 int32_t AudioCapturerPrivate::GetBufQueueState(BufferQueueState &bufState) const
419 {
420 return audioStream_->GetBufQueueState(bufState);
421 }
422 #endif
423
424 } // namespace AudioStandard
425 } // namespace OHOS
426