diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index 6a2189d5571b7d5d4bb2b0c515fd37b2ec0a7e33..073dbef9264273b437eb5dc7f4ecaa30c8f78c93 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -253,6 +253,7 @@ private: sptr capturerStateChangelistenerStub_ = nullptr; sptr clientTrackerCbStub_ = nullptr; static std::unordered_map> rendererCBMap_; + bool rendererStateChangeRegistered = false; }; } // namespce AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 0417db502798d2516e1fcee0c251e1f2a59a66b3..9a914fb8f069a65160195bf7bb7f8e333c2b4b41 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -89,6 +89,7 @@ public: AudioEffectMode GetAudioEffectMode() const override; int64_t GetFramesWritten() const override; int32_t SetAudioEffectMode(AudioEffectMode effectMode) const override; + void SetAudioRendererErrorCallback(std::shared_ptr errorCallback) override; static inline AudioStreamParams ConvertToAudioStreamParams(const AudioRendererParams params) { @@ -107,10 +108,22 @@ public: std::string cachePath_; explicit AudioRendererPrivate(AudioStreamType audioStreamType, const AppInfo &appInfo, bool createStream = true); + ~AudioRendererPrivate(); + friend class AudioRendererStateChangeCallbackImpl; + +protected: + // Method for switching between normal and low latency paths + void SwitchStream(bool isLowLatencyDevice); + private: int32_t InitAudioInterruptCallback(); + void SetSwitchInfo(IAudioStream::SwitchInfo info, std::shared_ptr audioStream); + bool SwitchToTargetStream(IAudioStream::StreamClass targetClass); + void SetSelfRendererStateCallback(); + void InitDumpInfo(); + std::shared_ptr audioStream_; std::shared_ptr audioInterruptCallback_ = nullptr; std::shared_ptr audioStreamCallback_ = nullptr; @@ -123,7 +136,10 @@ private: FILE *dcp_ = nullptr; #endif std::shared_ptr audioDeviceChangeCallback_ = nullptr; + std::shared_ptr audioRendererErrorCallback_ = nullptr; DeviceInfo currentDeviceInfo = {}; + bool isFastRenderer_ = false; + bool isSwitching_ = false; }; class AudioRendererInterruptCallbackImpl : public AudioInterruptCallback { diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index f722ad69c3c70704fc536d4ca7be9c9256f07f23..25d829500a0246ff3cfd604ad1d78767e999b569 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -66,6 +66,9 @@ AudioRendererPrivate::~AudioRendererPrivate() if (state != RENDERER_RELEASED && state != RENDERER_NEW) { Release(); } + + // Unregister the renderer event callaback in policy server + (void)AudioPolicyManager::GetInstance().UnregisterAudioRendererEventListener(appInfo_.appPid); #ifdef DUMP_CLIENT_PCM if (dcp_) { fclose(dcp_); @@ -273,6 +276,7 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) if (IAudioStream::IsStreamSupported(rendererInfo_.rendererFlags, audioStreamParams)) { AUDIO_INFO_LOG("Create stream with STREAM_FLAG_FAST"); streamClass = IAudioStream::FAST_STREAM; + isFastRenderer_ = true; } else { AUDIO_ERR_LOG("Unsupported parameter, try to create a normal stream"); streamClass = IAudioStream::PA_STREAM; @@ -283,7 +287,7 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) if (audioStream_ == nullptr) { audioStream_ = IAudioStream::GetPlaybackStream(streamClass, audioStreamParams, audioStreamType, appInfo_.appUid); - CHECK_AND_RETURN_RET_LOG(audioStream_ != nullptr, ERR_INVALID_PARAM, "SetParams GetPlayBackStream faied."); + CHECK_AND_RETURN_RET_LOG(audioStream_ != nullptr, ERR_INVALID_PARAM, "SetParams GetPlayBackStream failed."); AUDIO_INFO_LOG("IAudioStream::GetStream success"); audioStream_->SetApplicationCachePath(cachePath_); } @@ -303,6 +307,14 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) } AUDIO_INFO_LOG("AudioRendererPrivate::SetParams SetAudioStreamInfo Succeeded"); + SetSelfRendererStateCallback(); + InitDumpInfo(); + + return InitAudioInterruptCallback(); +} + +void AudioRendererPrivate::InitDumpInfo() +{ #ifdef DUMP_CLIENT_PCM uint32_t streamId = 0; GetAudioStreamId(streamId); @@ -318,8 +330,6 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) AUDIO_ERR_LOG("Error opening pcm test file!"); } #endif - - return InitAudioInterruptCallback(); } int32_t AudioRendererPrivate::GetParams(AudioRendererParams ¶ms) const @@ -441,6 +451,11 @@ bool AudioRendererPrivate::Start(StateChangeCmdType cmdType) const return false; } + if (isSwitching_) { + AUDIO_ERR_LOG("AudioRenderer::Start failed. Switching state: %{public}d", isSwitching_); + return false; + } + AUDIO_INFO_LOG("AudioRenderer::Start::interruptMode: %{public}d, streamType: %{public}d, sessionID: %{public}d", audioInterrupt_.mode, audioInterrupt_.audioFocusType.streamType, audioInterrupt_.sessionID); @@ -497,6 +512,11 @@ bool AudioRendererPrivate::Flush() const bool AudioRendererPrivate::Pause(StateChangeCmdType cmdType) const { AUDIO_INFO_LOG("AudioRenderer::Pause"); + if (isSwitching_) { + AUDIO_ERR_LOG("AudioRenderer::Pause failed. Switching state: %{public}d", isSwitching_); + return false; + } + if (audioInterrupt_.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { // When the cellular call stream is pausing, only need to deactivate audio interrupt. if (AudioPolicyManager::GetInstance().DeactivateAudioInterrupt(audioInterrupt_) != 0) { @@ -525,6 +545,10 @@ bool AudioRendererPrivate::Pause(StateChangeCmdType cmdType) const bool AudioRendererPrivate::Stop() const { AUDIO_INFO_LOG("AudioRenderer::Stop"); + if (isSwitching_) { + AUDIO_ERR_LOG("AudioRenderer::Stop failed. Switching state: %{public}d", isSwitching_); + return false; + } if (audioInterrupt_.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { // When the cellular call stream is stopping, only need to deactivate audio interrupt. if (AudioPolicyManager::GetInstance().DeactivateAudioInterrupt(audioInterrupt_) != 0) { @@ -913,6 +937,12 @@ uint32_t AudioRendererPrivate::GetUnderflowCount() const return audioStream_->GetUnderflowCount(); } + +void AudioRendererPrivate::SetAudioRendererErrorCallback(std::shared_ptr errorCallback) +{ + audioRendererErrorCallback_ = errorCallback; +} + int32_t AudioRendererPrivate::RegisterAudioRendererEventListener(const int32_t clientPid, const std::shared_ptr &callback) { @@ -1008,6 +1038,112 @@ void AudioRendererStateChangeCallbackImpl::setAudioRendererObj(AudioRendererPriv renderer = rendererObj; } +void AudioRendererPrivate::SetSwitchInfo(IAudioStream::SwitchInfo info, std::shared_ptr audioStream) +{ + if (!audioStream) { + AUDIO_ERR_LOG("stream is nullptr"); + return; + } + audioStream->SetStreamTrackerState(info.streamTrackerRegistered); + audioStream->SetAudioStreamInfo(info.params, rendererProxyObj_); + audioStream->SetApplicationCachePath(info.cachePath); + audioStream->SetRenderMode(info.renderMode); + audioStream->SetRendererInfo(info.rendererInfo); + audioStream->SetCapturerInfo(info.capturerInfo); + audioStream->SetClientID(info.clientPid, info.clientUid); + audioStream->SetAudioEffectMode(info.effectMode); + audioStream->SetPrivacyType(info.privacyType); + audioStream->SetVolume(info.volume); + + // set callback + if ((info.renderPositionCb != nullptr) && (info.frameMarkPosition > 0)) { + audioStream->SetRendererPositionCallback(info.frameMarkPosition, info.renderPositionCb); + } + + if ((info.capturePositionCb != nullptr) && (info.frameMarkPosition > 0)) { + audioStream->SetCapturerPositionCallback(info.frameMarkPosition, info.capturePositionCb); + } + + if ((info.renderPeriodPositionCb != nullptr) && (info.framePeriodNumber > 0)) { + audioStream->SetRendererPeriodPositionCallback(info.framePeriodNumber, info.renderPeriodPositionCb); + } + + if ((info.capturePeriodPositionCb != nullptr) && (info.framePeriodNumber > 0)) { + audioStream->SetCapturerPeriodPositionCallback(info.framePeriodNumber, info.capturePeriodPositionCb); + } + + audioStream->SetStreamCallback(info.audioStreamCallback); + audioStream->SetRendererWriteCallback(info.rendererWriteCallback); +} + +bool AudioRendererPrivate::SwitchToTargetStream(IAudioStream::StreamClass targetClass) +{ + bool switchResult = false; + if (audioStream_) { + Trace trace("SwitchToTargetStream"); + isSwitching_ = true; + RendererState previousState = GetStatus(); + if (previousState == RENDERER_RUNNING) { + // stop old stream + switchResult = audioStream_->StopAudioStream(); + CHECK_AND_RETURN_RET_LOG(switchResult, false, "StopAudioStream failed."); + } + // switch new stream + IAudioStream::SwitchInfo info; + audioStream_->GetSwitchInfo(info); + std::shared_ptr newAudioStream = IAudioStream::GetPlaybackStream(targetClass, info.params, + info.eStreamType, appInfo_.appPid); + CHECK_AND_RETURN_RET_LOG(newAudioStream != nullptr, false, "SetParams GetPlayBackStream failed."); + AUDIO_INFO_LOG("Get new stream success!"); + + // set new stream info + SetSwitchInfo(info, newAudioStream); + + // release old stream and restart audio stream + switchResult = audioStream_->ReleaseAudioStream(); + CHECK_AND_RETURN_RET_LOG(switchResult, false, "release old stream failed."); + + if (previousState == RENDERER_RUNNING) { + // restart audio stream + switchResult = newAudioStream->StartAudioStream(); + CHECK_AND_RETURN_RET_LOG(switchResult, false, "start new stream failed."); + } + audioStream_ = newAudioStream; + isSwitching_ = false; + switchResult= true; + } + return switchResult; +} + +void AudioRendererPrivate::SwitchStream(bool isLowLatencyDevice) +{ + // switch stream for fast renderer only + if (audioStream_ != nullptr && isFastRenderer_ && !isSwitching_) { + bool needSwitch = false; + IAudioStream::StreamClass currentClass = audioStream_->GetStreamClass(); + IAudioStream::StreamClass targetClass = IAudioStream::PA_STREAM; + if (currentClass == IAudioStream::FAST_STREAM && !isLowLatencyDevice) { + needSwitch = true; + rendererInfo_.rendererFlags = 0; // Normal renderer type + } + if (currentClass == IAudioStream::PA_STREAM && isLowLatencyDevice) { + // Jumping from normal stream to low latency stream is not supported yet. + needSwitch = false; + rendererInfo_.rendererFlags = STREAM_FLAG_FAST; + targetClass = IAudioStream::FAST_STREAM; + } + if (needSwitch) { + if (!SwitchToTargetStream(targetClass) && !audioRendererErrorCallback_) { + audioRendererErrorCallback_->OnError(ERROR_SYSTEM); + } + } else { + AUDIO_ERR_LOG("need not SwitchStream!"); + } + } else { + AUDIO_INFO_LOG("Do not SwitchStream , is low latency renderer: %{public}d!", isFastRenderer_); + } +} + bool AudioRendererPrivate::IsDeviceChanged(DeviceInfo &newDeviceInfo) { bool deviceUpdated = false; @@ -1032,13 +1168,17 @@ void AudioRendererStateChangeCallbackImpl::OnRendererStateChange( const std::vector> &audioRendererChangeInfos) { std::shared_ptr cb = callback_.lock(); - if (cb == nullptr) { - AUDIO_ERR_LOG("AudioRendererStateChangeCallbackImpl::OnStateChange cb == nullptr."); - return; - } AUDIO_INFO_LOG("AudioRendererStateChangeCallbackImpl OnRendererStateChange"); DeviceInfo deviceInfo = {}; if (renderer->IsDeviceChanged(deviceInfo)) { + if (deviceInfo.deviceType != DEVICE_TYPE_NONE && deviceInfo.deviceType != DEVICE_TYPE_INVALID) { + // switch audio channel + renderer->SwitchStream(deviceInfo.isLowLatencyDevice); + } + if (cb == nullptr) { + AUDIO_ERR_LOG("AudioRendererStateChangeCallbackImpl::OnStateChange cb == nullptr."); + return; + } cb->OnStateChange(deviceInfo); } } @@ -1057,5 +1197,29 @@ int32_t AudioRendererPrivate::SetAudioEffectMode(AudioEffectMode effectMode) con { return audioStream_->SetAudioEffectMode(effectMode); } + +void AudioRendererPrivate::SetSelfRendererStateCallback() +{ + if (GetCurrentOutputDevices(currentDeviceInfo) != SUCCESS) { + AUDIO_ERR_LOG("get current device info failed"); + } + + int32_t clientPid = getpid(); + if (!audioDeviceChangeCallback_) { + audioDeviceChangeCallback_ = std::make_shared(); + if (!audioDeviceChangeCallback_) { + AUDIO_ERR_LOG("AudioRendererPrivate: Memory Allocation Failed !!"); + } + } + + int32_t ret = AudioPolicyManager::GetInstance().RegisterAudioRendererEventListener(clientPid, + audioDeviceChangeCallback_); + if (ret != 0) { + AUDIO_ERR_LOG("AudioRendererPrivate::RegisterAudioRendererEventListener failed"); + } + + audioDeviceChangeCallback_->setAudioRendererObj(this); + AUDIO_INFO_LOG("AudioRendererPrivate::RegisterAudioRendererEventListener successful!"); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiostream/include/audio_stream.h b/frameworks/native/audiostream/include/audio_stream.h index 9889ba331b6a9a47ff1f9d2bd1d91c7097a4e4b5..92e994225c1c3ad8c1f5fda86512681a349b8c44 100644 --- a/frameworks/native/audiostream/include/audio_stream.h +++ b/frameworks/native/audiostream/include/audio_stream.h @@ -94,7 +94,11 @@ public: // Recording related APIs int32_t Read(uint8_t &buffer, size_t userSize, bool isBlockingRead) override; + void SetStreamTrackerState(bool trackerRegisteredState) override; + void GetSwitchInfo(SwitchInfo& info) override; + private: + void RegisterTracker(const std::shared_ptr &proxyObj); AudioStreamType eStreamType_; AudioMode eMode_; State state_; @@ -123,6 +127,8 @@ private: std::mutex bufferQueueLock_; std::condition_variable bufferQueueCV_; + + bool streamTrackerRegistered_ = false; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiostream/include/fast_audio_stream.h b/frameworks/native/audiostream/include/fast_audio_stream.h index 56c2376f74bdce89852e35e602d1179e68e3b1b8..7e9860288c338963a055404549c787c1b9ff5b1e 100644 --- a/frameworks/native/audiostream/include/fast_audio_stream.h +++ b/frameworks/native/audiostream/include/fast_audio_stream.h @@ -31,12 +31,14 @@ namespace AudioStandard { class FastAudioStreamRenderCallback : public AudioDataCallback { public: FastAudioStreamRenderCallback(const std::shared_ptr &callback) - : renderCallback_(callback) {}; + : rendererWriteCallback_(callback) {}; virtual ~FastAudioStreamRenderCallback() = default; void OnHandleData(size_t length) override; + std::shared_ptr GetRendererWriteCallback() const; + private: - std::shared_ptr renderCallback_ = nullptr; + std::shared_ptr rendererWriteCallback_ = nullptr; }; class FastAudioStreamCaptureCallback : public AudioDataCallback { @@ -133,6 +135,11 @@ public: int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec) override; void SetApplicationCachePath(const std::string cachePath) override; + void SetStreamTrackerState(bool trackerRegisteredState) override; + void GetSwitchInfo(IAudioStream::SwitchInfo& info) override; + + IAudioStream::StreamClass GetStreamClass() override; + private: AudioStreamType eStreamType_; AudioMode eMode_; @@ -153,6 +160,7 @@ private: AudioRendererRate renderRate_ = RENDER_RATE_NORMAL; int32_t clientPid_ = 0; int32_t clientUid_ = 0; + bool streamTrackerRegistered_ = false; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index f0ff97795776ea996afc69dec2ff256829b0e49d..fb6d440c724172e704b9d2b93081f7c8be1008fb 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -43,6 +43,47 @@ public: FAST_STREAM, }; + struct SwitchInfo { + AudioStreamParams params; + AudioStreamType eStreamType; + int32_t appUid; + AudioRendererInfo rendererInfo; + AudioCapturerInfo capturerInfo; + State state; + uint32_t sessionId; + std::string cachePath = ""; + uint32_t rendererSampleRate; + uint32_t underFlowCount; + AudioEffectMode effectMode; + AudioRenderMode renderMode; + AudioCaptureMode captureMode; + AudioRendererRate renderRate; + int32_t clientPid = 0; + int32_t clientUid = 0; + std::shared_ptr proxyObj; + AudioPrivacyType privacyType; + float volume; + + bool streamTrackerRegistered = false; + + uint64_t frameMarkPosition = 0; + uint64_t framePeriodNumber = 0; + + uint64_t totalBytesWritten = 0; + uint64_t framePeriodWritten = 0; + std::shared_ptr renderPositionCb; + std::shared_ptr renderPeriodPositionCb; + + uint64_t totalBytesRead = 0; + uint64_t framePeriodRead = 0; + std::shared_ptr capturePositionCb; + std::shared_ptr capturePeriodPositionCb; + + // callback info + std::shared_ptr audioStreamCallback; + std::shared_ptr rendererWriteCallback; + }; + virtual ~IAudioStream() = default; static bool IsStreamSupported(int32_t streamFlags, const AudioStreamParams ¶ms); @@ -142,6 +183,10 @@ public: virtual uint32_t GetRendererSamplingRate() = 0; virtual int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec) = 0; virtual void SetApplicationCachePath(const std::string cachePath) = 0; + + virtual IAudioStream::StreamClass GetStreamClass() = 0; + virtual void SetStreamTrackerState(bool trackerRegisteredState) = 0; + virtual void GetSwitchInfo(SwitchInfo& info) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.cpp b/frameworks/native/ohaudio/OHAudioRenderer.cpp index 63dea5ffe00ee0ad60d426103419fe37ef0453ff..b6ddcf882ba3406569cd60318e11c3dd33ca77f4 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.cpp +++ b/frameworks/native/ohaudio/OHAudioRenderer.cpp @@ -353,6 +353,10 @@ void OHAudioRenderer::SetRendererCallback(OH_AudioRenderer_Callbacks callbacks, std::make_shared(callbacks, (OH_AudioRenderer*)this, userData); int32_t clientPid = getpid(); audioRenderer_->RegisterAudioPolicyServerDiedCb(clientPid, callback); + + std::shared_ptr errorCallback = + std::make_shared(callbacks, (OH_AudioRenderer*)this, userData); + audioRenderer_->SetAudioRendererErrorCallback(errorCallback); } else { AUDIO_ERR_LOG("audio error callback is nullptr"); } @@ -397,5 +401,27 @@ void OHServiceDiedCallback::OnAudioPolicyServiceDied() OH_AudioStream_Result error = AUDIOSTREAM_ERROR_SYSTEM; callbacks_.OH_AudioRenderer_OnError(ohAudioRenderer_, userData_, error); } + +OH_AudioStream_Result OHAudioRendererErrorCallback::GetErrorResult(AudioErrors errorCode) const +{ + switch (errorCode) { + case ERROR_ILLEGAL_STATE: + return AUDIOSTREAM_ERROR_ILLEGAL_STATE; + case ERROR_INVALID_PARAM: + return AUDIOSTREAM_ERROR_INVALID_PARAM; + case ERROR_SYSTEM: + return AUDIOSTREAM_ERROR_SYSTEM; + default: + return AUDIOSTREAM_ERROR_SYSTEM; + } +} + +void OHAudioRendererErrorCallback::OnError(AudioErrors errorCode) +{ + CHECK_AND_RETURN_LOG(ohAudioRenderer_ != nullptr && callbacks_.OH_AudioRenderer_OnError != nullptr, + "renderer client or error callback funtion is nullptr"); + OH_AudioStream_Result error = GetErrorResult(errorCode); + callbacks_.OH_AudioRenderer_OnError(ohAudioRenderer_, userData_, error); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.h b/frameworks/native/ohaudio/OHAudioRenderer.h index c4c569347699b0870c559273bfff6aa2d201adb7..aed61a9a3caa2605b11a0d08a32b1e1fb881dfaa 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.h +++ b/frameworks/native/ohaudio/OHAudioRenderer.h @@ -79,6 +79,23 @@ public: void OnAudioPolicyServiceDied() override; +private: + OH_AudioRenderer_Callbacks callbacks_; + OH_AudioRenderer* ohAudioRenderer_; + void* userData_; +}; + +class OHAudioRendererErrorCallback : public AudioRendererErrorCallback { +public: + OHAudioRendererErrorCallback(OH_AudioRenderer_Callbacks callbacks, OH_AudioRenderer* audioRenderer, + void* userData) : callbacks_(callbacks), ohAudioRenderer_(audioRenderer), userData_(userData) + { + } + + void OnError(AudioErrors errorCode) override; + + OH_AudioStream_Result GetErrorResult(AudioErrors errorCode) const; + private: OH_AudioRenderer_Callbacks callbacks_; OH_AudioRenderer* ohAudioRenderer_; diff --git a/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp b/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp index fc8a5cd3fe5e13901d5113ffe62a7808b66a8be2..01cf8c790a7bb99cad39a53a8e105038f6fbc7dc 100644 --- a/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp +++ b/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp @@ -30,6 +30,7 @@ namespace AudioTestConstants { constexpr int32_t FIRST_ARG_IDX = 1; constexpr int32_t SECOND_ARG_IDX = 2; constexpr int32_t THIRD_ARG_IDX = 3; + constexpr int32_t FOUR_ARG_IDX = 4; constexpr int32_t WAIT_INTERVAL = 1000; } @@ -38,6 +39,7 @@ FILE* g_file = nullptr; bool g_readEnd = false; int32_t g_samplingRate = 48000; int32_t g_channelCount = 2; +int32_t g_latencyMode = 0; static int32_t AudioRendererOnWriteData(OH_AudioRenderer* capturer, void* userData, @@ -70,6 +72,7 @@ void PlayerTest(char *argv[]) // 2. set params and callbacks OH_AudioStreamBuilder_SetSamplingRate(builder, g_samplingRate); OH_AudioStreamBuilder_SetChannelCount(builder, g_channelCount); + OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_latencyMode); OH_AudioRenderer_Callbacks callbacks; callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData; @@ -93,11 +96,11 @@ void PlayerTest(char *argv[]) std::this_thread::sleep_for(std::chrono::milliseconds(AudioTestConstants::WAIT_INTERVAL)); int64_t frames; OH_AudioRenderer_GetFramesWritten(audioRenderer, &frames); - printf("Wait for the audio to finish playing.(..%d s) frames:%lld\n", ++timer, frames); + printf("Wait for the audio to finish playing.(..%d s) frames:%ld\n", ++timer, frames); int64_t framePosition; int64_t timestamp; OH_AudioRenderer_GetTimestamp(audioRenderer, CLOCK_MONOTONIC, &framePosition, ×tamp); - printf("framePosition %lld timestamp:%lld\n", framePosition, timestamp); + printf("framePosition %ld timestamp:%ld\n", framePosition, timestamp); } // 5. stop and release client ret = OH_AudioRenderer_Stop(audioRenderer); @@ -114,18 +117,21 @@ int main(int argc, char *argv[]) { printf("start \n"); if ((argv == nullptr) || (argc < AudioTestConstants::THIRD_ARG_IDX)) { - printf("input parms wrong. input format: filePath samplingRate channelCount \n"); - printf("input demo: ./oh_audio_renderer_test ./oh_test_audio.pcm 48000 2 \n"); + printf("input parms wrong. input format: filePath samplingRate channelCount latencyMode\n"); + printf("input demo: ./oh_audio_renderer_test ./oh_test_audio.pcm 48000 2 1 \n"); return 0; } printf("argc=%d ", argc); - printf("argv[1]=%s ", argv[AudioTestConstants::FIRST_ARG_IDX]); - printf("argv[2]=%s ", argv[AudioTestConstants::SECOND_ARG_IDX]); - printf("argv[3]=%s \n", argv[AudioTestConstants::THIRD_ARG_IDX]); + printf("file path =%s ", argv[AudioTestConstants::FIRST_ARG_IDX]); + printf("sample rate =%s ", argv[AudioTestConstants::SECOND_ARG_IDX]); + printf("channel count =%s \n", argv[AudioTestConstants::THIRD_ARG_IDX]); + printf("latency mode =%s \n", argv[AudioTestConstants::FOUR_ARG_IDX]); + g_filePath = argv[AudioTestConstants::FIRST_ARG_IDX]; g_samplingRate = atoi(argv[AudioTestConstants::SECOND_ARG_IDX]); g_channelCount = atoi(argv[AudioTestConstants::THIRD_ARG_IDX]); - g_filePath = argv[AudioTestConstants::FIRST_ARG_IDX]; + g_latencyMode = atoi(argv[AudioTestConstants::FOUR_ARG_IDX]); + printf("filePATH: %s \n", g_filePath.c_str()); g_file = fopen(g_filePath.c_str(), "rb"); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index 587aa84309ad149ae6031a342e925599a49b5b4c..92938d274b40850a3adb6995c470eee827e8345d 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -1026,6 +1026,7 @@ struct DeviceInfo { std::string displayName; int32_t interruptGroupId; int32_t volumeGroupId; + bool isLowLatencyDevice; }; enum StreamSetState { diff --git a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h index bfcc9bc43923c70bd636dbf43814351bdad32073..3f0baf3a4d7173cc42e32c5e43e0f40d3f15506d 100644 --- a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h @@ -118,6 +118,19 @@ public: virtual void RemoveAllCallbacks() = 0; }; +class AudioRendererErrorCallback { +public: + virtual ~AudioRendererErrorCallback() = default; + + /** + * Called when an unrecoverable exception occurs in the renderer + * + * @param errorCode Indicates error code of the exception. + * since 10 + */ + virtual void OnError(AudioErrors errorCode) = 0; +}; + /** * @brief Provides functions for applications to implement audio rendering. * @since 8 @@ -722,6 +735,14 @@ public: */ virtual int32_t SetAudioEffectMode(AudioEffectMode effectMode) const = 0; + /** + * @brief Registers the renderer error event callback listener. + * + * @param errorCallback Error callback pointer + * @since 10 + */ + virtual void SetAudioRendererErrorCallback(std::shared_ptr errorCallback) = 0; + /** * @brief Registers the renderer event callback listener. * @@ -769,6 +790,7 @@ public: * @since 10 */ virtual void DestroyAudioRendererStateCallback() = 0; + virtual ~AudioRenderer(); private: static std::mutex createRendererMutex_; diff --git a/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h b/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h index 989efa6ad588fb1366ff32205479b39508dd4056..a2a949bb0de5e017159c10fde63d5201772d6365 100644 --- a/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h +++ b/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h @@ -34,7 +34,7 @@ public: private: void ReadAudioRendererChangeInfo(MessageParcel &data, std::unique_ptr &rendererChangeInfo); - std::weak_ptr callback_; + std::vector> callbacks_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp b/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp index 9f0aff7d875a84c25fd6b73af67f1e5d78f95294..4d3017d162f8b365c5128dce53ee67bef9c6c0ac 100644 --- a/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp +++ b/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp @@ -59,6 +59,7 @@ void AudioCapturerStateChangeListenerStub::ReadAudioCapturerChangeInfo(MessagePa capturerChangeInfo->inputDeviceInfo.networkId = data.ReadString(); capturerChangeInfo->inputDeviceInfo.interruptGroupId = data.ReadInt32(); capturerChangeInfo->inputDeviceInfo.volumeGroupId = data.ReadInt32(); + capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice = data.ReadBool(); AUDIO_DEBUG_LOG("AudioCapturerStateChangeListenerStub, sessionid = %{public}d", capturerChangeInfo->sessionId); AUDIO_DEBUG_LOG("AudioCapturerStateChangeListenerStub, capturerState = %{public}d", diff --git a/services/audio_policy/client/src/audio_policy_manager.cpp b/services/audio_policy/client/src/audio_policy_manager.cpp index fe5c0c8f77245084d427bb1828bd4b1b7a80ab44..b83f8dee0463cdec39b6772a3c7e7859332f7edf 100644 --- a/services/audio_policy/client/src/audio_policy_manager.cpp +++ b/services/audio_policy/client/src/audio_policy_manager.cpp @@ -805,10 +805,12 @@ int32_t AudioPolicyManager::RegisterAudioRendererEventListener(const int32_t cli } std::unique_lock lock(stateChangelistenerStubMutex_); - rendererStateChangelistenerStub_ = new(std::nothrow) AudioRendererStateChangeListenerStub(); - if (rendererStateChangelistenerStub_ == nullptr) { - AUDIO_ERR_LOG("RegisterAudioRendererEventListener: object null"); - return ERROR; + if (!rendererStateChangelistenerStub_ && !rendererStateChangeRegistered) { + rendererStateChangelistenerStub_ = new(std::nothrow) AudioRendererStateChangeListenerStub(); + if (rendererStateChangelistenerStub_ == nullptr) { + AUDIO_ERR_LOG("RegisterAudioRendererEventListener: object null"); + return ERROR; + } } rendererStateChangelistenerStub_->SetCallback(callback); @@ -820,7 +822,11 @@ int32_t AudioPolicyManager::RegisterAudioRendererEventListener(const int32_t cli } lock.unlock(); - return gsp->RegisterAudioRendererEventListener(clientPid, object); + if (!rendererStateChangeRegistered) { + gsp->RegisterAudioRendererEventListener(clientPid, object); + rendererStateChangeRegistered = true; + } + return SUCCESS; } int32_t AudioPolicyManager::UnregisterAudioRendererEventListener(const int32_t clientPid) @@ -831,7 +837,13 @@ int32_t AudioPolicyManager::UnregisterAudioRendererEventListener(const int32_t c AUDIO_ERR_LOG("UnregisterAudioRendererEventListener: audio policy manager proxy is NULL."); return ERROR; } - return gsp->UnregisterAudioRendererEventListener(clientPid); + + int32_t ret = ERROR; + ret = gsp->UnregisterAudioRendererEventListener(clientPid); + if (ret == SUCCESS) { + rendererStateChangeRegistered = false; + } + return ret; } int32_t AudioPolicyManager::RegisterAudioCapturerEventListener(const int32_t clientPid, diff --git a/services/audio_policy/client/src/audio_policy_proxy.cpp b/services/audio_policy/client/src/audio_policy_proxy.cpp index 332d42e360353f17a765d61867cb0fc2d205f7cb..5e0c619e5a1a38a1f24bbaa5abcd1036ad4de50b 100644 --- a/services/audio_policy/client/src/audio_policy_proxy.cpp +++ b/services/audio_policy/client/src/audio_policy_proxy.cpp @@ -1721,6 +1721,7 @@ void AudioPolicyProxy::ReadAudioRendererChangeInfo(MessageParcel &reply, rendererChangeInfo->outputDeviceInfo.networkId = reply.ReadString(); rendererChangeInfo->outputDeviceInfo.interruptGroupId = reply.ReadInt32(); rendererChangeInfo->outputDeviceInfo.volumeGroupId = reply.ReadInt32(); + rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice = reply.ReadBool(); } void AudioPolicyProxy::ReadAudioCapturerChangeInfo(MessageParcel &reply, @@ -1748,6 +1749,7 @@ void AudioPolicyProxy::ReadAudioCapturerChangeInfo(MessageParcel &reply, capturerChangeInfo->inputDeviceInfo.networkId = reply.ReadString(); capturerChangeInfo->inputDeviceInfo.interruptGroupId = reply.ReadInt32(); capturerChangeInfo->inputDeviceInfo.volumeGroupId = reply.ReadInt32(); + capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice = reply.ReadBool(); } int32_t AudioPolicyProxy::GetCurrentRendererChangeInfos( diff --git a/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp b/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp index 96016963b646996ec95befd4effedadcb9794689..be2f1ffed83ea7d4a1c9056b6b8234dd89ef1ae5 100644 --- a/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp +++ b/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp @@ -62,6 +62,7 @@ void AudioRendererStateChangeListenerStub::ReadAudioRendererChangeInfo(MessagePa rendererChangeInfo->outputDeviceInfo.networkId = data.ReadString(); rendererChangeInfo->outputDeviceInfo.interruptGroupId = data.ReadInt32(); rendererChangeInfo->outputDeviceInfo.volumeGroupId = data.ReadInt32(); + rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice = data.ReadBool(); AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub, sessionid = %{public}d", rendererChangeInfo->sessionId); AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub, rendererState = %{public}d", @@ -108,20 +109,22 @@ void AudioRendererStateChangeListenerStub::OnRendererStateChange( const vector> &audioRendererChangeInfos) { AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub OnRendererStateChange"); - shared_ptr cb = callback_.lock(); - if (cb == nullptr) { - AUDIO_ERR_LOG("AudioRendererStateChangeListenerStub: callback_ is nullptr"); - return; - } - cb->OnRendererStateChange(audioRendererChangeInfos); + for (const auto& callback : callbacks_) { + shared_ptr cb = callback.lock(); + if (cb == nullptr) { + AUDIO_ERR_LOG("AudioRendererStateChangeListenerStub: callback_ is nullptr"); + } else { + cb->OnRendererStateChange(audioRendererChangeInfos); + } + } return; } void AudioRendererStateChangeListenerStub::SetCallback(const weak_ptr &callback) { AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub SetCallback"); - callback_ = callback; + callbacks_.push_back(callback); } } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp b/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp index 4aef6e90a32e69926ca9ad7e33dbbdc5613a6504..3c34e6e1a93e26ef46ba6fa16a045c8b8040f9ef 100644 --- a/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp +++ b/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp @@ -56,6 +56,7 @@ void AudioCapturerStateChangeListenerProxy::WriteCapturerChangeInfo(MessageParce data.WriteString(capturerChangeInfo->inputDeviceInfo.networkId); data.WriteInt32(capturerChangeInfo->inputDeviceInfo.interruptGroupId); data.WriteInt32(capturerChangeInfo->inputDeviceInfo.volumeGroupId); + data.WriteBool(capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice); } void AudioCapturerStateChangeListenerProxy::OnCapturerStateChange( diff --git a/services/audio_policy/server/src/audio_policy_manager_stub.cpp b/services/audio_policy/server/src/audio_policy_manager_stub.cpp index 611ba010b0029c2d11a16ff99e3088ba4da448ba..d37c4064f4c55defb008c59b47f7517ec4928195 100644 --- a/services/audio_policy/server/src/audio_policy_manager_stub.cpp +++ b/services/audio_policy/server/src/audio_policy_manager_stub.cpp @@ -800,6 +800,7 @@ void AudioPolicyManagerStub::GetRendererChangeInfosInternal(MessageParcel &data, reply.WriteString(rendererChangeInfo->outputDeviceInfo.networkId); reply.WriteInt32(rendererChangeInfo->outputDeviceInfo.interruptGroupId); reply.WriteInt32(rendererChangeInfo->outputDeviceInfo.volumeGroupId); + reply.WriteBool(rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice); } AUDIO_DEBUG_LOG("AudioPolicyManagerStub:Renderer change info internal exit"); @@ -844,6 +845,7 @@ void AudioPolicyManagerStub::GetCapturerChangeInfosInternal(MessageParcel &data, reply.WriteString(capturerChangeInfo->inputDeviceInfo.networkId); reply.WriteInt32(capturerChangeInfo->inputDeviceInfo.interruptGroupId); reply.WriteInt32(capturerChangeInfo->inputDeviceInfo.volumeGroupId); + reply.WriteBool(capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice); } AUDIO_DEBUG_LOG("AudioPolicyManagerStub:Capturer change info internal exit"); } diff --git a/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp b/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp index e60fe80eef379341b5c455465f80f4d27001e66d..8d7a091520eed69549d9588c37a3563391943e68 100644 --- a/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp +++ b/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp @@ -59,6 +59,7 @@ void AudioRendererStateChangeListenerProxy::WriteRendererChangeInfo(MessageParce data.WriteString(rendererChangeInfo->outputDeviceInfo.networkId); data.WriteInt32(rendererChangeInfo->outputDeviceInfo.interruptGroupId); data.WriteInt32(rendererChangeInfo->outputDeviceInfo.volumeGroupId); + data.WriteBool(rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice); } void AudioRendererStateChangeListenerProxy::OnRendererStateChange( diff --git a/services/audio_policy/server/src/service/audio_policy_service.cpp b/services/audio_policy/server/src/service/audio_policy_service.cpp index 821951e74e3a95458f87e2ccf6af7b4dcc07f545..424b80abc8c3a0a15fb22e7a06aed59b7cd42600 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -2589,6 +2589,29 @@ static void UpdateCapturerInfoWhenNoPermission(const unique_ptr &desc, bool hasBTPermission, bool hasSystemPermission) { @@ -2606,6 +2629,9 @@ static void UpdateDeviceInfo(DeviceInfo &deviceInfo, const sptrnetworkId_ != LOCAL_NETWORK_ID); + if (hasSystemPermission) { deviceInfo.networkId = desc->networkId_; deviceInfo.volumeGroupId = desc->volumeGroupId_; diff --git a/services/audio_service/client/include/audio_service_client.h b/services/audio_service/client/include/audio_service_client.h index d93e00c889f8828b128af573f1c06317b03eef24..ac0cd6b34e9efaf0d4845d0f651718c2d17a76f0 100644 --- a/services/audio_service/client/include/audio_service_client.h +++ b/services/audio_service/client/include/audio_service_client.h @@ -513,6 +513,9 @@ public: void SetClientID(int32_t clientPid, int32_t clientUid) override; + IAudioStream::StreamClass GetStreamClass() override; + void GetStreamSwitchInfo(SwitchInfo& info); + protected: virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; void SendWriteBufferRequestEvent(); @@ -619,6 +622,8 @@ private: std::map sourceOutputs; std::map clientInfo; + IAudioStream::StreamClass streamClass_; + ASClientType eAudioClientType; uint32_t underFlowCount; diff --git a/services/audio_service/client/src/audio_process_in_client.cpp b/services/audio_service/client/src/audio_process_in_client.cpp index 865aecff5d632195d942073597b292023a5ad733..9013f64c32714247bd68ff729e6e1f08867395f8 100644 --- a/services/audio_service/client/src/audio_process_in_client.cpp +++ b/services/audio_service/client/src/audio_process_in_client.cpp @@ -280,7 +280,7 @@ int32_t AudioProcessInClientInner::OnEndpointChange(int32_t status) int32_t AudioProcessInClientInner::GetSessionID(uint32_t &sessionID) { // note: Get the session id from server. - int32_t pid = processConfig_.appInfo.appUid; + int32_t pid = processConfig_.appInfo.appPid; if (pid < 0) { AUDIO_ERR_LOG("GetSessionID failed:%{public}d", pid); return ERR_OPERATION_FAILED; @@ -383,6 +383,7 @@ void AudioProcessInClientInner::SetApplicationCachePath(const std::string &cache cachePath_ = cachePath; } + bool AudioProcessInClientInner::InitAudioBuffer() { CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr, false, "Init failed with null ipcProxy."); diff --git a/services/audio_service/client/src/audio_service_client.cpp b/services/audio_service/client/src/audio_service_client.cpp index 703f103c0df8ca1b13d62884a3f24ed6b534e853..564af5697b2ef1a0ede284b843440c69812fdc87 100644 --- a/services/audio_service/client/src/audio_service_client.cpp +++ b/services/audio_service/client/src/audio_service_client.cpp @@ -1639,6 +1639,35 @@ void AudioServiceClient::SetClientID(int32_t clientPid, int32_t clientUid) clientUid_ = clientUid; } +IAudioStream::StreamClass AudioServiceClient::GetStreamClass() +{ + return streamClass_; +} + +void AudioServiceClient::GetStreamSwitchInfo(SwitchInfo& info) +{ + info.cachePath = cachePath_; + info.rendererSampleRate = rendererSampleRate; + info.underFlowCount = underFlowCount; + info.effectMode = effectMode; + info.renderMode = renderMode_; + info.captureMode = captureMode_; + info.renderRate = renderRate; + info.clientPid = clientPid_; + info.clientUid = clientUid_; + info.volume = mVolumeFactor; + + info.frameMarkPosition = mFrameMarkPosition; + info.renderPositionCb = mRenderPositionCb; + info.capturePositionCb = mCapturePositionCb; + + info.framePeriodNumber = mFramePeriodNumber; + info.renderPeriodPositionCb = mRenderPeriodPositionCb; + info.capturePeriodPositionCb = mCapturePeriodPositionCb; + + info.rendererWriteCallback = writeCallback_; +} + void AudioServiceClient::HandleCapturePositionCallbacks(size_t bytesRead) { mTotalBytesRead += bytesRead; diff --git a/services/audio_service/client/src/audio_stream.cpp b/services/audio_service/client/src/audio_stream.cpp index 88df7b2557929290499a8548d705471741ddd53d..58aebd19916e250893459c40edeb574157276c3d 100644 --- a/services/audio_service/client/src/audio_stream.cpp +++ b/services/audio_service/client/src/audio_stream.cpp @@ -237,11 +237,22 @@ int32_t AudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo) return SUCCESS; } +void AudioStream::RegisterTracker(const std::shared_ptr &proxyObj) +{ + if (audioStreamTracker_ && audioStreamTracker_.get() && !streamTrackerRegistered_) { + (void)GetSessionID(sessionId_); + AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_); + audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj); + streamTrackerRegistered_ = true; + } +} + int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info, const std::shared_ptr &proxyObj) { AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d," - " stream type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_); + " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format, + eStreamType_, info.encoding); if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) { AUDIO_ERR_LOG("AudioStream: Unsupported audio parameter"); @@ -284,12 +295,7 @@ int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info, } state_ = PREPARED; AUDIO_DEBUG_LOG("AudioStream:Set stream Info SUCCESS"); - - if (audioStreamTracker_ && audioStreamTracker_.get()) { - (void)GetSessionID(sessionId_); - AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_); - audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj); - } + RegisterTracker(proxyObj); return SUCCESS; } @@ -925,5 +931,25 @@ int64_t AudioStream::GetFramesRead() { return GetStreamFramesRead(); } + +void AudioStream::SetStreamTrackerState(bool trackerRegisteredState) +{ + streamTrackerRegistered_ = trackerRegisteredState; +} + +void AudioStream::GetSwitchInfo(SwitchInfo& info) +{ + GetAudioStreamParams(info.params); + + info.rendererInfo = rendererInfo_; + info.capturerInfo = capturerInfo_; + info.eStreamType = eStreamType_; + info.renderMode = renderMode_; + info.state = state_; + info.sessionId = sessionId_; + info.streamTrackerRegistered = streamTrackerRegistered_; + GetStreamSwitchInfo(info); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp index 42429b999601e9288ca3c4f0ff732d84f9887490..a427e7883510da6823cb0c5f2ece6395dca75823 100644 --- a/services/audio_service/client/src/fast_audio_stream.cpp +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -289,7 +289,7 @@ int32_t FastAudioStream::SetCapturerReadCallback(const std::shared_ptrGetRendererWriteCallback(); + } +} + void FastAudioStreamRenderCallback::OnHandleData(size_t length) { - CHECK_AND_RETURN_LOG(renderCallback_!= nullptr, "OnHandleData failed: renderCallback_ is null."); - renderCallback_->OnWriteData(length); + CHECK_AND_RETURN_LOG(rendererWriteCallback_!= nullptr, "OnHandleData failed: rendererWriteCallback_ is null."); + rendererWriteCallback_->OnWriteData(length); +} + +std::shared_ptr FastAudioStreamRenderCallback::GetRendererWriteCallback() const +{ + return rendererWriteCallback_; } void FastAudioStreamCaptureCallback::OnHandleData(size_t length) diff --git a/services/audio_service/client/src/policy_provider_stub.cpp b/services/audio_service/client/src/policy_provider_stub.cpp index eeb2791c0921e09358f93c42b2bb4bd670c16a64..2796af3366e2076346beb043af36d96a17cc367c 100644 --- a/services/audio_service/client/src/policy_provider_stub.cpp +++ b/services/audio_service/client/src/policy_provider_stub.cpp @@ -69,6 +69,7 @@ int32_t PolicyProviderStub::HandleGetProcessDeviceInfo(MessageParcel &data, Mess reply.WriteString(deviceInfo.displayName); reply.WriteInt32(deviceInfo.interruptGroupId); reply.WriteInt32(deviceInfo.volumeGroupId); + reply.WriteBool(deviceInfo.isLowLatencyDevice); return AUDIO_OK; } diff --git a/services/audio_service/server/src/policy_provider_proxy.cpp b/services/audio_service/server/src/policy_provider_proxy.cpp index 7adbf397995633f176d394ea63f3bd077ac6b37b..578fe0e24cb7695c085896b11acc75e0b1efab04 100644 --- a/services/audio_service/server/src/policy_provider_proxy.cpp +++ b/services/audio_service/server/src/policy_provider_proxy.cpp @@ -59,6 +59,7 @@ int32_t PolicyProviderProxy::GetProcessDeviceInfo(const AudioProcessConfig &conf deviceInfo.displayName = reply.ReadString(); deviceInfo.interruptGroupId = reply.ReadInt32(); deviceInfo.volumeGroupId = reply.ReadInt32(); + deviceInfo.isLowLatencyDevice = reply.ReadBool(); return SUCCESS; }