• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <chrono>
17 #include <thread>
18 #include <vector>
19 
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 
23 #include "audio_stream.h"
24 
25 using namespace std;
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 const unsigned long long TIME_CONVERSION_US_S = 1000000ULL; /* us to s */
30 const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to us */
31 const unsigned long long TIME_CONVERSION_NS_S = 1000000000ULL; /* ns to s */
32 constexpr int32_t WRITE_RETRY_DELAY_IN_US = 500;
33 constexpr int32_t READ_WRITE_WAIT_TIME_IN_US = 500;
34 constexpr int32_t CB_WRITE_BUFFERS_WAIT_IN_MS = 80;
35 constexpr int32_t CB_READ_BUFFERS_WAIT_IN_US = 500;
36 
37 const map<pair<ContentType, StreamUsage>, AudioStreamType> AudioStream::streamTypeMap_ = AudioStream::CreateStreamMap();
38 
CreateStreamMap()39 map<pair<ContentType, StreamUsage>, AudioStreamType> AudioStream::CreateStreamMap()
40 {
41     map<pair<ContentType, StreamUsage>, AudioStreamType> streamMap;
42 
43     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
44     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
45     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
46     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
47     streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
48 
49     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
50     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_MEDIA)] = STREAM_VOICE_ASSISTANT;
51     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_VOICE_CALL;
52     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
53     streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
54 
55     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
56     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
57     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
58     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
59     streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
60 
61     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_UNKNOWN)] = STREAM_MEDIA;
62     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_MEDIA)] = STREAM_MEDIA;
63     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
64     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
65     streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
66 
67     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_UNKNOWN)] = STREAM_NOTIFICATION;
68     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_MEDIA)] = STREAM_NOTIFICATION;
69     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
70     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
71     streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
72 
73     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_UNKNOWN)] = STREAM_RING;
74     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_MEDIA)] = STREAM_RING;
75     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
76     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
77     streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
78 
79     return streamMap;
80 }
81 
AudioStream(AudioStreamType eStreamType,AudioMode eMode,int32_t appUid)82 AudioStream::AudioStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid)
83     : eStreamType_(eStreamType),
84       eMode_(eMode),
85       state_(NEW),
86       isReadInProgress_(false),
87       isWriteInProgress_(false),
88       resetTime_(false),
89       resetTimestamp_(0),
90       renderMode_(RENDER_MODE_NORMAL),
91       captureMode_(CAPTURE_MODE_NORMAL),
92       isReadyToWrite_(false),
93       isReadyToRead_(false),
94       isFirstRead_(false),
95       isFirstWrite_(false)
96 {
97     AUDIO_DEBUG_LOG("AudioStream ctor, appUID = %{public}d", appUid);
98     audioStreamTracker_ =  std::make_unique<AudioStreamTracker>(eMode, appUid);
99     AUDIO_DEBUG_LOG("AudioStreamTracker created");
100 }
101 
~AudioStream()102 AudioStream::~AudioStream()
103 {
104     isReadyToWrite_ = false;
105     isReadyToRead_ = false;
106 
107     if (writeThread_ && writeThread_->joinable()) {
108         writeThread_->join();
109     }
110 
111     if (readThread_ && readThread_->joinable()) {
112         readThread_->join();
113     }
114 
115     if (state_ != RELEASED && state_ != NEW) {
116         ReleaseAudioStream(false);
117     }
118 
119     if (audioStreamTracker_ && audioStreamTracker_.get()) {
120         AUDIO_DEBUG_LOG("AudioStream:~AudioStream:Calling update tracker");
121         AudioRendererInfo rendererInfo = {};
122         AudioCapturerInfo capturerInfo = {};
123         state_ = RELEASED;
124         audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo, capturerInfo);
125     }
126 }
127 
SetRendererInfo(const AudioRendererInfo & rendererInfo)128 void AudioStream::SetRendererInfo(const AudioRendererInfo &rendererInfo)
129 {
130     rendererInfo_ = rendererInfo;
131 }
132 
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)133 void AudioStream::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
134 {
135     capturerInfo_ = capturerInfo;
136 }
137 
GetState()138 State AudioStream::GetState()
139 {
140     return state_;
141 }
142 
GetAudioSessionID(uint32_t & sessionID)143 int32_t AudioStream::GetAudioSessionID(uint32_t &sessionID)
144 {
145     if ((state_ == RELEASED) || (state_ == NEW)) {
146         return ERR_ILLEGAL_STATE;
147     }
148 
149     if (GetSessionID(sessionID) != 0) {
150         return ERR_INVALID_INDEX;
151     }
152 
153     sessionId_ = sessionID;
154 
155     return SUCCESS;
156 }
157 
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)158 bool AudioStream::GetAudioTime(Timestamp &timestamp, Timestamp::Timestampbase base)
159 {
160     if (state_ == STOPPED) {
161         return false;
162     }
163     uint64_t paTimeStamp = 0;
164     if (GetCurrentTimeStamp(paTimeStamp) == SUCCESS) {
165         if (resetTime_) {
166             AUDIO_INFO_LOG("AudioStream::GetAudioTime resetTime_ %{public}d", resetTime_);
167             resetTime_ = false;
168             resetTimestamp_ = paTimeStamp;
169         }
170 
171         timestamp.time.tv_sec = static_cast<time_t>((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S);
172         timestamp.time.tv_nsec
173             = static_cast<time_t>(((paTimeStamp - resetTimestamp_) - (timestamp.time.tv_sec * TIME_CONVERSION_US_S))
174                                   * TIME_CONVERSION_NS_US);
175         timestamp.time.tv_sec += baseTimestamp_.tv_sec;
176         timestamp.time.tv_nsec += baseTimestamp_.tv_nsec;
177         timestamp.time.tv_sec += (timestamp.time.tv_nsec / TIME_CONVERSION_NS_S);
178         timestamp.time.tv_nsec = (timestamp.time.tv_nsec % TIME_CONVERSION_NS_S);
179 
180         return true;
181     }
182     return false;
183 }
184 
GetBufferSize(size_t & bufferSize) const185 int32_t AudioStream::GetBufferSize(size_t &bufferSize) const
186 {
187     AUDIO_INFO_LOG("AudioStream: Get Buffer size");
188     if (GetMinimumBufferSize(bufferSize) != 0) {
189         return ERR_OPERATION_FAILED;
190     }
191 
192     return SUCCESS;
193 }
194 
GetFrameCount(uint32_t & frameCount) const195 int32_t AudioStream::GetFrameCount(uint32_t &frameCount) const
196 {
197     AUDIO_INFO_LOG("AudioStream: Get frame count");
198     if (GetMinimumFrameCount(frameCount) != 0) {
199         return ERR_OPERATION_FAILED;
200     }
201 
202     return SUCCESS;
203 }
204 
GetLatency(uint64_t & latency)205 int32_t AudioStream::GetLatency(uint64_t &latency)
206 {
207     if (GetAudioLatency(latency) != SUCCESS) {
208         return ERR_OPERATION_FAILED;
209     } else {
210         return SUCCESS;
211     }
212 }
213 
GetSupportedFormats() const214 vector<AudioSampleFormat> AudioStream::GetSupportedFormats() const
215 {
216     return AUDIO_SUPPORTED_FORMATS;
217 }
218 
GetSupportedEncodingTypes() const219 vector<AudioEncodingType> AudioStream::GetSupportedEncodingTypes() const
220 {
221     return AUDIO_SUPPORTED_ENCODING_TYPES;
222 }
223 
GetSupportedSamplingRates() const224 vector<AudioSamplingRate> AudioStream::GetSupportedSamplingRates() const
225 {
226     return AUDIO_SUPPORTED_SAMPLING_RATES;
227 }
228 
IsFormatValid(uint8_t format)229 bool IsFormatValid(uint8_t format)
230 {
231     bool isValidFormat = (find(AUDIO_SUPPORTED_FORMATS.begin(), AUDIO_SUPPORTED_FORMATS.end(), format)
232                           != AUDIO_SUPPORTED_FORMATS.end());
233     AUDIO_DEBUG_LOG("AudioStream: IsFormatValid: %{public}s", isValidFormat ? "true" : "false");
234     return isValidFormat;
235 }
236 
IsRendererChannelValid(uint8_t channel)237 bool IsRendererChannelValid(uint8_t channel)
238 {
239     bool isValidChannel = (find(RENDERER_SUPPORTED_CHANNELS.begin(), RENDERER_SUPPORTED_CHANNELS.end(), channel)
240                            != RENDERER_SUPPORTED_CHANNELS.end());
241     AUDIO_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
242     return isValidChannel;
243 }
244 
IsCapturerChannelValid(uint8_t channel)245 bool IsCapturerChannelValid(uint8_t channel)
246 {
247     bool isValidChannel = (find(CAPTURER_SUPPORTED_CHANNELS.begin(), CAPTURER_SUPPORTED_CHANNELS.end(), channel)
248                            != CAPTURER_SUPPORTED_CHANNELS.end());
249     AUDIO_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
250     return isValidChannel;
251 }
252 
IsEncodingTypeValid(uint8_t encodingType)253 bool IsEncodingTypeValid(uint8_t encodingType)
254 {
255     bool isValidEncodingType
256             = (find(AUDIO_SUPPORTED_ENCODING_TYPES.begin(), AUDIO_SUPPORTED_ENCODING_TYPES.end(), encodingType)
257                != AUDIO_SUPPORTED_ENCODING_TYPES.end());
258     AUDIO_DEBUG_LOG("AudioStream: IsEncodingTypeValid: %{public}s", isValidEncodingType ? "true" : "false");
259     return isValidEncodingType;
260 }
261 
IsSamplingRateValid(uint32_t samplingRate)262 bool IsSamplingRateValid(uint32_t samplingRate)
263 {
264     bool isValidSamplingRate
265             = (find(AUDIO_SUPPORTED_SAMPLING_RATES.begin(), AUDIO_SUPPORTED_SAMPLING_RATES.end(), samplingRate)
266                != AUDIO_SUPPORTED_SAMPLING_RATES.end());
267     AUDIO_DEBUG_LOG("AudioStream: IsSamplingRateValid: %{public}s", isValidSamplingRate ? "true" : "false");
268     return isValidSamplingRate;
269 }
270 
GetAudioStreamInfo(AudioStreamParams & audioStreamInfo)271 int32_t AudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo)
272 {
273     AUDIO_INFO_LOG("AudioStream: GetAudioStreamInfo");
274     if (GetAudioStreamParams(audioStreamInfo) != 0) {
275         return ERR_OPERATION_FAILED;
276     }
277 
278     return SUCCESS;
279 }
280 
VerifyClientPermission(const std::string & permissionName,uint32_t appTokenId,int32_t appUid,bool privacyFlag,AudioPermissionState state)281 bool AudioStream::VerifyClientPermission(const std::string &permissionName, uint32_t appTokenId, int32_t appUid,
282     bool privacyFlag, AudioPermissionState state)
283 {
284     return AudioServiceClient::VerifyClientPermission(permissionName, appTokenId, appUid, privacyFlag, state);
285 }
286 
getUsingPemissionFromPrivacy(const std::string & permissionName,uint32_t appTokenId,AudioPermissionState state)287 bool AudioStream::getUsingPemissionFromPrivacy(const std::string &permissionName, uint32_t appTokenId,
288     AudioPermissionState state)
289 {
290     return AudioServiceClient::getUsingPemissionFromPrivacy(permissionName, appTokenId, state);
291 }
292 
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj)293 int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info,
294     const std::shared_ptr<AudioClientTracker> &proxyObj)
295 {
296     AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d,"
297         " stream type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_);
298 
299     if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
300         AUDIO_ERR_LOG("AudioStream: Unsupported audio parameter");
301         return ERR_NOT_SUPPORTED;
302     }
303     if (state_ != NEW) {
304         AUDIO_INFO_LOG("AudioStream: State is not new, release existing stream");
305         StopAudioStream();
306         ReleaseAudioStream(false);
307     }
308     int32_t ret = 0;
309     switch (eMode_) {
310         case AUDIO_MODE_PLAYBACK:
311             AUDIO_DEBUG_LOG("AudioStream: Initialize playback");
312             if (!IsRendererChannelValid(info.channels)) {
313                 AUDIO_ERR_LOG("AudioStream: Invalid sink channel %{public}d", info.channels);
314                 return ERR_NOT_SUPPORTED;
315             }
316             ret = Initialize(AUDIO_SERVICE_CLIENT_PLAYBACK);
317             break;
318         case AUDIO_MODE_RECORD:
319             AUDIO_DEBUG_LOG("AudioStream: Initialize recording");
320             if (!IsCapturerChannelValid(info.channels)) {
321                 AUDIO_ERR_LOG("AudioStream: Invalid source channel %{public}d", info.channels);
322                 return ERR_NOT_SUPPORTED;
323             }
324             ret = Initialize(AUDIO_SERVICE_CLIENT_RECORD);
325             break;
326         default:
327             return ERR_INVALID_OPERATION;
328     }
329 
330     if (ret) {
331         AUDIO_DEBUG_LOG("AudioStream: Error initializing!");
332         return ret;
333     }
334     if (CreateStream(info, eStreamType_) != SUCCESS) {
335         AUDIO_ERR_LOG("AudioStream:Create stream failed");
336         return ERROR;
337     }
338     state_ = PREPARED;
339     AUDIO_INFO_LOG("AudioStream:Set stream Info SUCCESS");
340 
341     if (audioStreamTracker_ && audioStreamTracker_.get()) {
342         (void)GetSessionID(sessionId_);
343         AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_);
344         audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj);
345     }
346     return SUCCESS;
347 }
348 
StartAudioStream(StateChangeCmdType cmdType)349 bool AudioStream::StartAudioStream(StateChangeCmdType cmdType)
350 {
351     if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
352         AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
353         return false;
354     }
355 
356     int32_t ret = StartStream(cmdType);
357     if (ret != SUCCESS) {
358         AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret);
359         return false;
360     }
361 
362     resetTime_ = true;
363     int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
364     if (retCode != 0) {
365         AUDIO_ERR_LOG("AudioStream::StartAudioStream get system elapsed time failed: %d", retCode);
366     }
367 
368     isFirstRead_ = true;
369     isFirstWrite_ = true;
370     state_ = RUNNING;
371 
372     if (renderMode_ == RENDER_MODE_CALLBACK) {
373         isReadyToWrite_ = true;
374         writeThread_ = std::make_unique<std::thread>(&AudioStream::WriteCbTheadLoop, this);
375     } else if (captureMode_ == CAPTURE_MODE_CALLBACK) {
376         isReadyToRead_ = true;
377         readThread_ = std::make_unique<std::thread>(&AudioStream::ReadCbThreadLoop, this);
378     }
379 
380     AUDIO_INFO_LOG("StartAudioStream SUCCESS");
381 
382     if (audioStreamTracker_ && audioStreamTracker_.get()) {
383         AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Running");
384         audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
385     }
386     return true;
387 }
388 
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)389 int32_t AudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
390 {
391     if (userSize <= 0) {
392         AUDIO_ERR_LOG("Invalid userSize:%{public}zu", userSize);
393         return ERR_INVALID_PARAM;
394     }
395 
396     if (state_ != RUNNING) {
397         AUDIO_ERR_LOG("Read: State is not RUNNNIG. Illegal  state:%{public}u", state_);
398         return ERR_ILLEGAL_STATE;
399     }
400 
401     if (isFirstRead_) {
402         FlushAudioStream();
403         isFirstRead_ = false;
404     }
405 
406     StreamBuffer stream;
407     stream.buffer = &buffer;
408     stream.bufferLen = userSize;
409     isReadInProgress_ = true;
410     int32_t readLen = ReadStream(stream, isBlockingRead);
411     isReadInProgress_ = false;
412     if (readLen < 0) {
413         AUDIO_ERR_LOG("ReadStream fail,ret:%{public}d", readLen);
414         return ERR_INVALID_READ;
415     }
416 
417     return readLen;
418 }
419 
Write(uint8_t * buffer,size_t buffer_size)420 size_t AudioStream::Write(uint8_t *buffer, size_t buffer_size)
421 {
422     if (renderMode_ == RENDER_MODE_CALLBACK) {
423         AUDIO_ERR_LOG("AudioStream::Write not supported. RenderMode is callback");
424         return ERR_INCORRECT_MODE;
425     }
426 
427     if ((buffer == nullptr) || (buffer_size <= 0)) {
428         AUDIO_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size);
429         return ERR_INVALID_PARAM;
430     }
431 
432     if (state_ != RUNNING) {
433         AUDIO_ERR_LOG("Write: Illegal  state:%{public}u", state_);
434         // To allow context switch for APIs running in different thread contexts
435         std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US));
436         return ERR_ILLEGAL_STATE;
437     }
438 
439     int32_t writeError;
440     StreamBuffer stream;
441     stream.buffer = buffer;
442     stream.bufferLen = buffer_size;
443     isWriteInProgress_ = true;
444 
445     if (isFirstWrite_) {
446         if (RenderPrebuf(stream.bufferLen)) {
447             return ERR_WRITE_FAILED;
448         }
449         isFirstWrite_ = false;
450     }
451 
452     size_t bytesWritten = WriteStream(stream, writeError);
453     isWriteInProgress_ = false;
454     if (writeError != 0) {
455         AUDIO_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError);
456         return ERR_WRITE_FAILED;
457     }
458     return bytesWritten;
459 }
460 
PauseAudioStream(StateChangeCmdType cmdType)461 bool AudioStream::PauseAudioStream(StateChangeCmdType cmdType)
462 {
463     if (state_ != RUNNING) {
464         AUDIO_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
465         return false;
466     }
467     State oldState = state_;
468     // Update state to stop write thread
469     state_ = PAUSED;
470 
471     if (captureMode_ == CAPTURE_MODE_CALLBACK) {
472         isReadyToRead_ = false;
473         if (readThread_ && readThread_->joinable()) {
474             readThread_->join();
475         }
476     }
477 
478     // Ends the WriteCb thread
479     if (renderMode_ == RENDER_MODE_CALLBACK) {
480         isReadyToWrite_ = false;
481         // wake write thread to make pause faster
482         bufferQueueCV_.notify_all();
483         if (writeThread_ && writeThread_->joinable()) {
484             writeThread_->join();
485         }
486     }
487 
488     while (isReadInProgress_ || isWriteInProgress_) {
489         std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
490     }
491 
492     AUDIO_DEBUG_LOG("AudioStream::PauseAudioStream:renderMode_ : %{public}d state_: %{public}d", renderMode_, state_);
493 
494     int32_t ret = PauseStream(cmdType);
495     if (ret != SUCCESS) {
496         AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret);
497         state_ = oldState;
498         return false;
499     }
500 
501     AUDIO_INFO_LOG("PauseAudioStream SUCCESS");
502 
503     // flush stream after stream paused
504     FlushAudioStream();
505 
506     if (audioStreamTracker_ && audioStreamTracker_.get()) {
507         AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Pause");
508         audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
509     }
510     return true;
511 }
512 
StopAudioStream()513 bool AudioStream::StopAudioStream()
514 {
515     AUDIO_INFO_LOG("AudioStream: begin StopAudioStream for sessionId %{public}d", sessionId_);
516     if (state_ == PAUSED) {
517         state_ = STOPPED;
518         AUDIO_INFO_LOG("StopAudioStream SUCCESS");
519         return true;
520     }
521 
522     if (state_ != RUNNING) {
523         AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
524         return false;
525     }
526     State oldState = state_;
527     state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
528 
529     if (captureMode_ == CAPTURE_MODE_CALLBACK) {
530         isReadyToRead_ = false;
531         if (readThread_ && readThread_->joinable()) {
532             readThread_->join();
533         }
534     }
535 
536     if (renderMode_ == RENDER_MODE_CALLBACK) {
537         isReadyToWrite_ = false;
538         if (writeThread_ && writeThread_->joinable()) {
539             writeThread_->join();
540         }
541     }
542 
543     while (isReadInProgress_ || isWriteInProgress_) {
544         std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
545     }
546 
547     int32_t ret = StopStream();
548     if (ret != SUCCESS) {
549         AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret);
550         state_ = oldState;
551         return false;
552     }
553 
554     AUDIO_INFO_LOG("StopAudioStream SUCCESS");
555 
556     if (audioStreamTracker_ && audioStreamTracker_.get()) {
557         AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for stop");
558         audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
559     }
560     return true;
561 }
562 
FlushAudioStream()563 bool AudioStream::FlushAudioStream()
564 {
565     if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
566         AUDIO_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
567         return false;
568     }
569 
570     int32_t ret = FlushStream();
571     if (ret != SUCCESS) {
572         AUDIO_DEBUG_LOG("Flush stream fail,ret:%{public}d", ret);
573         return false;
574     }
575 
576     AUDIO_INFO_LOG("Flush stream SUCCESS");
577     return true;
578 }
579 
DrainAudioStream()580 bool AudioStream::DrainAudioStream()
581 {
582     if (state_ != RUNNING) {
583         AUDIO_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal  state:%{public}u", state_);
584         return false;
585     }
586 
587     int32_t ret = DrainStream();
588     if (ret != SUCCESS) {
589         AUDIO_DEBUG_LOG("Drain stream fail,ret:%{public}d", ret);
590         return false;
591     }
592 
593     AUDIO_INFO_LOG("Drain stream SUCCESS");
594     return true;
595 }
596 
ReleaseAudioStream(bool releaseRunner)597 bool AudioStream::ReleaseAudioStream(bool releaseRunner)
598 {
599     if (state_ == RELEASED || state_ == NEW) {
600         AUDIO_ERR_LOG("Illegal state: state = %{public}u", state_);
601         return false;
602     }
603     // If state_ is RUNNING try to Stop it first and Release
604     if (state_ == RUNNING) {
605         StopAudioStream();
606     }
607 
608     ReleaseStream(releaseRunner);
609     state_ = RELEASED;
610     AUDIO_INFO_LOG("ReleaseAudiostream SUCCESS");
611 
612     if (audioStreamTracker_ && audioStreamTracker_.get()) {
613         AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for release");
614         audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
615     }
616     return true;
617 }
618 
GetStreamType(ContentType contentType,StreamUsage streamUsage)619 AudioStreamType AudioStream::GetStreamType(ContentType contentType, StreamUsage streamUsage)
620 {
621     AudioStreamType streamType = STREAM_MUSIC;
622     auto pos = streamTypeMap_.find(make_pair(contentType, streamUsage));
623     if (pos != streamTypeMap_.end()) {
624         streamType = pos->second;
625     }
626 
627     if (streamType == STREAM_MEDIA) {
628         streamType = STREAM_MUSIC;
629     }
630 
631     return streamType;
632 }
633 
SetAudioStreamType(AudioStreamType audioStreamType)634 int32_t AudioStream::SetAudioStreamType(AudioStreamType audioStreamType)
635 {
636     return SetStreamType(audioStreamType);
637 }
638 
SetVolume(float volume)639 int32_t AudioStream::SetVolume(float volume)
640 {
641     return SetStreamVolume(volume);
642 }
643 
GetVolume()644 float AudioStream::GetVolume()
645 {
646     return GetStreamVolume();
647 }
648 
SetRenderRate(AudioRendererRate renderRate)649 int32_t AudioStream::SetRenderRate(AudioRendererRate renderRate)
650 {
651     return SetStreamRenderRate(renderRate);
652 }
653 
GetRenderRate()654 AudioRendererRate AudioStream::GetRenderRate()
655 {
656     return GetStreamRenderRate();
657 }
658 
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)659 int32_t AudioStream::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
660 {
661     if (callback == nullptr) {
662         AUDIO_ERR_LOG("AudioStream::SetStreamCallback failed. callback == nullptr");
663         return ERR_INVALID_PARAM;
664     }
665 
666     SaveStreamCallback(callback);
667 
668     return SUCCESS;
669 }
670 
SetRenderMode(AudioRenderMode renderMode)671 int32_t AudioStream::SetRenderMode(AudioRenderMode renderMode)
672 {
673     int32_t ret = SetAudioRenderMode(renderMode);
674     if (ret) {
675         AUDIO_ERR_LOG("AudioStream::SetRenderMode: renderMode: %{public}d failed", renderMode);
676         return ERR_OPERATION_FAILED;
677     }
678     renderMode_ = renderMode;
679 
680     lock_guard<mutex> lock(bufferQueueLock_);
681 
682     for (int32_t i = 0; i < MAX_WRITECB_NUM_BUFFERS; ++i) {
683         size_t length;
684         GetMinimumBufferSize(length);
685         AUDIO_INFO_LOG("AudioServiceClient:: GetMinimumBufferSize: %{public}zu", length);
686 
687         writeBufferPool_[i] = std::make_unique<uint8_t[]>(length);
688         if (writeBufferPool_[i] == nullptr) {
689             AUDIO_INFO_LOG(
690             "AudioServiceClient::GetBufferDescriptor writeBufferPool_[i]==nullptr. Allocate memory failed.");
691             return ERR_OPERATION_FAILED;
692         }
693 
694         BufferDesc bufDesc {};
695         bufDesc.buffer = writeBufferPool_[i].get();
696         bufDesc.bufLength = length;
697         freeBufferQ_.emplace(bufDesc);
698     }
699 
700     return SUCCESS;
701 }
702 
GetRenderMode()703 AudioRenderMode AudioStream::GetRenderMode()
704 {
705     return GetAudioRenderMode();
706 }
707 
SetCaptureMode(AudioCaptureMode captureMode)708 int32_t AudioStream::SetCaptureMode(AudioCaptureMode captureMode)
709 {
710     int32_t ret = SetAudioCaptureMode(captureMode);
711     if (ret) {
712         AUDIO_ERR_LOG("AudioStream::SetCaptureMode: captureMode: %{public}d failed", captureMode);
713         return ERR_OPERATION_FAILED;
714     }
715     captureMode_ = captureMode;
716 
717     lock_guard<mutex> lock(bufferQueueLock_);
718 
719     for (int32_t i = 0; i < MAX_READCB_NUM_BUFFERS; ++i) {
720         size_t length;
721         GetMinimumBufferSize(length);
722         AUDIO_INFO_LOG("AudioStream::SetCaptureMode: length %{public}zu", length);
723 
724         readBufferPool_[i] = std::make_unique<uint8_t[]>(length);
725         if (readBufferPool_[i] == nullptr) {
726             AUDIO_INFO_LOG("AudioStream::SetCaptureMode readBufferPool_[i]==nullptr. Allocate memory failed.");
727             return ERR_OPERATION_FAILED;
728         }
729 
730         BufferDesc bufDesc {};
731         bufDesc.buffer = readBufferPool_[i].get();
732         bufDesc.bufLength = length;
733         freeBufferQ_.emplace(bufDesc);
734     }
735 
736     return SUCCESS;
737 }
738 
GetCaptureMode()739 AudioCaptureMode AudioStream::GetCaptureMode()
740 {
741     return GetAudioCaptureMode();
742 }
743 
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)744 int32_t AudioStream::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
745 {
746     if (renderMode_ != RENDER_MODE_CALLBACK) {
747         AUDIO_ERR_LOG("AudioStream::SetRendererWriteCallback not supported. Render mode is not callback.");
748         return ERR_INCORRECT_MODE;
749     }
750 
751     if (!callback) {
752         AUDIO_ERR_LOG("SetRendererWriteCallback callback is nullptr");
753         return ERR_INVALID_PARAM;
754     }
755     return AudioServiceClient::SetRendererWriteCallback(callback);
756 }
757 
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)758 int32_t AudioStream::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
759 {
760     if (captureMode_ != CAPTURE_MODE_CALLBACK) {
761         AUDIO_ERR_LOG("AudioStream::SetCapturerReadCallback not supported. Capture mode is not callback.");
762         return ERR_INCORRECT_MODE;
763     }
764 
765     int32_t ret = SaveReadCallback(callback);
766     if (ret) {
767         AUDIO_ERR_LOG("AudioStream::SetCapturerReadCallback: failed.");
768         return ERR_INVALID_PARAM;
769     }
770 
771     return SUCCESS;
772 }
773 
GetBufferDesc(BufferDesc & bufDesc)774 int32_t AudioStream::GetBufferDesc(BufferDesc &bufDesc)
775 {
776     if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
777         AUDIO_ERR_LOG("AudioStream::GetBufferDesc not supported. Render or Capture mode is not callback.");
778         return ERR_INCORRECT_MODE;
779     }
780 
781     lock_guard<mutex> lock(bufferQueueLock_);
782 
783     if (renderMode_ == RENDER_MODE_CALLBACK) {
784         if (!freeBufferQ_.empty()) {
785             bufDesc.buffer = freeBufferQ_.front().buffer;
786             bufDesc.bufLength = freeBufferQ_.front().bufLength;
787             bufDesc.dataLength = freeBufferQ_.front().dataLength;
788             freeBufferQ_.pop();
789         } else {
790             bufDesc.buffer = nullptr;
791             AUDIO_INFO_LOG("AudioStream::GetBufferDesc freeBufferQ_.empty()");
792             return ERR_OPERATION_FAILED;
793         }
794     }
795 
796     if (captureMode_ == CAPTURE_MODE_CALLBACK) {
797         if (!filledBufferQ_.empty()) {
798             bufDesc.buffer = filledBufferQ_.front().buffer;
799             bufDesc.bufLength = filledBufferQ_.front().bufLength;
800             bufDesc.dataLength = filledBufferQ_.front().dataLength;
801             filledBufferQ_.pop();
802         } else {
803             bufDesc.buffer = nullptr;
804             AUDIO_INFO_LOG("AudioStream::GetBufferDesc filledBufferQ_.empty()");
805             return ERR_OPERATION_FAILED;
806         }
807     }
808     return SUCCESS;
809 }
810 
GetBufQueueState(BufferQueueState & bufState)811 int32_t AudioStream::GetBufQueueState(BufferQueueState &bufState)
812 {
813     if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
814         AUDIO_ERR_LOG("AudioStream::GetBufQueueState not supported. Render or Capture mode is not callback.");
815         return ERR_INCORRECT_MODE;
816     }
817 
818     lock_guard<mutex> lock(bufferQueueLock_);
819 
820     if (renderMode_ == RENDER_MODE_CALLBACK) {
821         bufState.numBuffers = filledBufferQ_.size();
822     }
823 
824     if (captureMode_ == CAPTURE_MODE_CALLBACK) {
825         bufState.numBuffers = freeBufferQ_.size();
826     }
827 
828     return SUCCESS;
829 }
830 
Enqueue(const BufferDesc & bufDesc)831 int32_t AudioStream::Enqueue(const BufferDesc &bufDesc)
832 {
833     AUDIO_INFO_LOG("AudioStream::Enqueue");
834     if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
835         AUDIO_ERR_LOG("AudioStream::Enqueue not supported. Render or capture mode is not callback.");
836         return ERR_INCORRECT_MODE;
837     }
838 
839     if (bufDesc.buffer == nullptr) {
840         AUDIO_ERR_LOG("AudioStream::Enqueue: failed. bufDesc.buffer == nullptr.");
841         return ERR_INVALID_PARAM;
842     }
843 
844     unique_lock<mutex> lock(bufferQueueLock_);
845 
846     if (renderMode_ == RENDER_MODE_CALLBACK) {
847         AUDIO_DEBUG_LOG("AudioStream::Enqueue: filledBuffer length: %{public}zu.", bufDesc.bufLength);
848         filledBufferQ_.emplace(bufDesc);
849     }
850 
851     if (captureMode_ == CAPTURE_MODE_CALLBACK) {
852         AUDIO_DEBUG_LOG("AudioStream::Enqueue: freeBuffer length: %{public}zu.", bufDesc.bufLength);
853         freeBufferQ_.emplace(bufDesc);
854     }
855 
856     bufferQueueCV_.notify_all();
857 
858     return SUCCESS;
859 }
860 
Clear()861 int32_t AudioStream::Clear()
862 {
863     if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
864         AUDIO_ERR_LOG("AudioStream::Clear not supported. Render or capture mode is not callback.");
865         return ERR_INCORRECT_MODE;
866     }
867 
868     lock_guard<mutex> lock(bufferQueueLock_);
869 
870     while (!filledBufferQ_.empty()) {
871         freeBufferQ_.emplace(filledBufferQ_.front());
872         filledBufferQ_.pop();
873     }
874 
875     return SUCCESS;
876 }
877 
WriteCbTheadLoop()878 void AudioStream::WriteCbTheadLoop()
879 {
880     AUDIO_INFO_LOG("AudioStream::WriteCb thread start");
881     StreamBuffer stream;
882     size_t bytesWritten;
883     int32_t writeError;
884 
885     if (isReadyToWrite_) {
886         // send write events for application to fill all free buffers at the beginning
887         SubmitAllFreeBuffers();
888 
889         while (true) {
890             if (state_ != RUNNING) {
891                 AUDIO_INFO_LOG("Write: not running state: %{public}u", state_);
892                 isReadyToWrite_ = false;
893                 break;
894             }
895 
896             unique_lock<mutex> lock(bufferQueueLock_);
897 
898             if (filledBufferQ_.empty()) {
899                 // wait signal with timeout
900                 bufferQueueCV_.wait_for(lock, chrono::milliseconds(CB_WRITE_BUFFERS_WAIT_IN_MS));
901                 continue;
902             }
903             stream.buffer = filledBufferQ_.front().buffer;
904             stream.bufferLen = filledBufferQ_.front().bufLength;
905 
906             if (stream.buffer == nullptr) {
907                 AUDIO_ERR_LOG("AudioStream::WriteCb stream.buffer is nullptr return");
908                 break;
909             }
910             bytesWritten = WriteStreamInCb(stream, writeError);
911             if (writeError != 0) {
912                 AUDIO_ERR_LOG("AudioStream::WriteStreamInCb fail, writeError:%{public}d", writeError);
913             } else {
914                 AUDIO_DEBUG_LOG("AudioStream::WriteCb WriteStream, bytesWritten:%{public}zu", bytesWritten);
915                 freeBufferQ_.emplace(filledBufferQ_.front());
916                 filledBufferQ_.pop();
917                 SendWriteBufferRequestEvent();
918             }
919         }
920     }
921     AUDIO_INFO_LOG("AudioStream::WriteCb thread end");
922 }
923 
ReadCbThreadLoop()924 void AudioStream::ReadCbThreadLoop()
925 {
926     AUDIO_INFO_LOG("AudioStream::ReadCb thread start");
927     StreamBuffer stream;
928     int32_t readLen;
929     bool isBlockingRead = true;
930 
931     while (isReadyToRead_) {
932         while (!freeBufferQ_.empty()) {
933             if (state_ != RUNNING) {
934                 AUDIO_ERR_LOG("AudioStream::ReadCb Read: Illegal  state:%{public}u", state_);
935                 isReadyToRead_ = false;
936                 return;
937             }
938 
939             stream.buffer = freeBufferQ_.front().buffer;
940             stream.bufferLen = freeBufferQ_.front().bufLength;
941             AUDIO_DEBUG_LOG("AudioStream::ReadCb requested stream.bufferLen:%{public}d", stream.bufferLen);
942 
943             if (stream.buffer == nullptr) {
944                 AUDIO_ERR_LOG("AudioStream::ReadCb stream.buffer == nullptr return");
945                 return;
946             }
947             readLen = ReadStream(stream, isBlockingRead);
948             if (readLen < 0) {
949                 AUDIO_ERR_LOG("AudioStream::ReadCb ReadStream fail, ret: %{public}d", readLen);
950             } else {
951                 AUDIO_DEBUG_LOG("AudioStream::ReadCb ReadStream, bytesRead:%{public}d", readLen);
952                 freeBufferQ_.front().dataLength = readLen;
953                 filledBufferQ_.emplace(freeBufferQ_.front());
954                 freeBufferQ_.pop();
955             }
956         }
957         std::this_thread::sleep_for(std::chrono::microseconds(CB_READ_BUFFERS_WAIT_IN_US));
958     }
959 
960     AUDIO_INFO_LOG("AudioStream::ReadCb thread end");
961 }
962 
SetLowPowerVolume(float volume)963 int32_t AudioStream::SetLowPowerVolume(float volume)
964 {
965     return SetStreamLowPowerVolume(volume);
966 }
967 
GetLowPowerVolume()968 float AudioStream::GetLowPowerVolume()
969 {
970     return GetStreamLowPowerVolume();
971 }
972 
GetSingleStreamVolume()973 float AudioStream::GetSingleStreamVolume()
974 {
975     return GetSingleStreamVol();
976 }
977 
SubmitAllFreeBuffers()978 void AudioStream::SubmitAllFreeBuffers()
979 {
980     lock_guard<mutex> lock(bufferQueueLock_);
981     for (size_t i = 0; i < freeBufferQ_.size(); ++i) {
982         SendWriteBufferRequestEvent();
983     }
984 }
985 } // namespace AudioStandard
986 } // namespace OHOS
987