From 1811c8def5783b90b1c1654f05ee2c8af3e93dda Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 19:47:38 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- .../audiorenderer/napi_audio_renderer.cpp | 31 ++++ .../napi/audiorenderer/napi_audio_renderer.h | 1 + frameworks/js/napi/common/napi_audio_enum.cpp | 16 ++ .../include/audio_policy_manager.h | 3 + .../include/audio_renderer_private.h | 2 + .../audiorenderer/src/audio_renderer.cpp | 11 ++ frameworks/native/ohaudio/OHAudioRenderer.cpp | 19 ++ frameworks/native/ohaudio/OHAudioRenderer.h | 1 + .../audiocommon/include/audio_stream_info.h | 7 + .../audiorenderer/include/audio_renderer.h | 7 + .../c/audio_renderer/native_audiorenderer.h | 18 ++ .../client/include/audio_policy_base.h | 3 + .../include/audio_policy_manager_stub.h | 1 + .../client/include/audio_policy_proxy.h | 3 + .../client/src/audio_policy_manager.cpp | 8 + .../include/audio_policy_ipc_interface_code.h | 3 +- .../server/include/audio_policy_server.h | 3 + .../server/include/audio_stream_collector.h | 1 + .../include/service/audio_device_manager.h | 14 ++ .../include/service/audio_policy_service.h | 4 + .../server/src/audio_policy_manager_stub.cpp | 13 ++ .../server/src/audio_policy_server.cpp | 6 + .../server/src/audio_stream_collector.cpp | 11 ++ .../src/service/audio_device_manager.cpp | 166 ++++++++++++++++++ .../src/service/audio_policy_service.cpp | 29 +++ .../src/service/routers/default_router.cpp | 11 +- 26 files changed, 388 insertions(+), 4 deletions(-) diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp index bc824c208b..1b32f42673 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp @@ -103,6 +103,7 @@ napi_status NapiAudioRenderer::InitNapiAudioRenderer(napi_env env, napi_value &c DECLARE_NAPI_FUNCTION("off", Off), DECLARE_NAPI_FUNCTION("setSilentModeAndMixWithOthers", SetSilentModeAndMixWithOthers), DECLARE_NAPI_FUNCTION("getSilentModeAndMixWithOthers", GetSilentModeAndMixWithOthers), + DECLARE_NAPI_FUNCTION("setDefaultOutputDevice", SetDefaultOutputDevice), }; napi_status status = napi_define_class(env, NAPI_AUDIO_RENDERER_CLASS_NAME.c_str(), @@ -1569,6 +1570,36 @@ napi_value NapiAudioRenderer::GetSilentModeAndMixWithOthers(napi_env env, napi_c return result; } +napi_value NapiAudioRenderer::SetDefaultOutputDevice(napi_env env, napi_callback_info info) +{ + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value argv[ARGS_ONE] = {}; + auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv); + CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID, + "mandatory parameters are left unspecified"), "argcCount invaild"); + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[PARAM0], &valueType); + CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID, + "incorrect parameter types: The type of mode must be number"), "valueType params"); + + int32_t deviceType; + NapiParamUtils::GetValueInt32(env, deviceType, argv[PARAM0]); + CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentOutputDeviceType(deviceType), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM, + "parameter verification failed: The param of mode must be enum deviceType"), "unsupport params"); + + CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr"); + CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr"); + int32_t ret = + napiAudioRenderer->audioRenderer_->SetDefaultOutputDevice(static_cast(deviceType)); + CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE, + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE), "err illegal state"); + + return result; +} + napi_value NapiAudioRenderer::RegisterCallback(napi_env env, napi_value jsThis, napi_value *argv, const std::string &cbName) { diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.h b/frameworks/js/napi/audiorenderer/napi_audio_renderer.h index 16afb204d2..d87bd38628 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.h +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.h @@ -127,6 +127,7 @@ private: static napi_value Off(napi_env env, napi_callback_info info); static napi_value SetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info); static napi_value GetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info); + static napi_value SetDefaultOutputDevice(napi_env env, napi_callback_info info); static napi_status WriteArrayBufferToNative(std::shared_ptr context); diff --git a/frameworks/js/napi/common/napi_audio_enum.cpp b/frameworks/js/napi/common/napi_audio_enum.cpp index 4747bdc432..e56ae78c79 100644 --- a/frameworks/js/napi/common/napi_audio_enum.cpp +++ b/frameworks/js/napi/common/napi_audio_enum.cpp @@ -1198,6 +1198,22 @@ bool NapiAudioEnum::IsLegalInputArgumentDeviceType(int32_t deviceType) return result; } +bool NapiAudioEnum::IsLegalInputArgumentOutputDeviceType(int32_t deviceType) +{ + bool result = false; + switch (deviceType) { + case DeviceType::DEVICE_TYPE_EARPIECE: + case DeviceType::DEVICE_TYPE_SPEAKER: + case DeviceType::DEVICE_TYPE_DEFAULT: + result = true; + break; + default: + result = false; + break; + } + return result; +} + int32_t NapiAudioEnum::GetJsAudioVolumeType(AudioStreamType volumeType) { int32_t result = MEDIA; diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index 3d9e5dda0e..6cc494c964 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -417,6 +417,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId); + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + private: AudioPolicyManager() {} ~AudioPolicyManager() {} diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 2c1d95e3ac..fe5b940b9c 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -128,6 +128,8 @@ public: void EnableVoiceModemCommunicationStartStream(bool enable) override; + int32_t SetDefaultOutputDevice(DeviceType deviceType) override; + static inline AudioStreamParams ConvertToAudioStreamParams(const AudioRendererParams params) { AudioStreamParams audioStreamParams; diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index 908464c47c..0250c0decf 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -1846,5 +1846,16 @@ void AudioRendererPrivate::EnableVoiceModemCommunicationStartStream(bool enable) { isEnableVoiceModemCommunicationStartStream_ = enable; } + +int32_t AudioRendererPrivate::SetDefaultOutputDevice(DeviceType deviceType) +{ + bool isSupportedStreamUsage = (find(AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES.begin(), + AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES.end(), rendererInfo_.streamUsage) != + AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES.end()); + CHECK_AND_RETURN_RET_LOG(isSupportedStreamUsage, ERR_NOT_SUPPORTED, "stream usage not supported"); + int32_t ret = AudioPolicyManager::GetInstance().SetDefaultOutputDevice(deviceType, sessionID_, + rendererInfo_.streamUsage, GetStatus() == RENDERER_RUNNING); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "select default output device failed"); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.cpp b/frameworks/native/ohaudio/OHAudioRenderer.cpp index 456a86327a..1fb6cc2d02 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.cpp +++ b/frameworks/native/ohaudio/OHAudioRenderer.cpp @@ -337,6 +337,19 @@ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( return AUDIOSTREAM_SUCCESS; } +OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice( + OH_AudioRenderer* renderer, DeviceType deviceType) +{ + OHOS::AudioStandard::OHAudioRenderer *audioRenderer = convertRenderer(renderer); + CHECK_AND_RETURN_RET_LOG(audioRenderer != nullptr, AUDIOSTREAM_ERROR_INVALID_PARAM, "convert renderer failed"); + bool result = (deviceType == DEVICE_TYPE_EARPIECE || deviceType == DEVICE_TYPE_SPEAKER || + deviceType == DEVICE_TYPE_DEFAULT) ? true : false; + CHECK_AND_RETURN_RET_LOG(result != true, AUDIOSTREAM_ERROR_ILLEGAL_STATE, "unsupport params"); + int32_t ret = audioRenderer->SetDefaultOutputDevice(deviceType); + CHECK_AND_RETURN_RET_LOG(ret != AUDIOSTREAM_SUCCESS, AUDIOSTREAM_ERROR_INVALID_PARAM, "err illegal state"); + return AUDIOSTREAM_SUCCESS; +} + namespace OHOS { namespace AudioStandard { OHAudioRenderer::OHAudioRenderer() @@ -783,6 +796,12 @@ bool OHAudioRenderer::GetSilentModeAndMixWithOthers() return audioRenderer_->GetSilentModeAndMixWithOthers(); } +int32_t OHAudioRenderer::SetDefaultOutputDevice(DeviceType deviceType) +{ + CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "renderer client is nullptr"); + return audioRenderer_->SetDefaultOutputDevice(deviceType); +} + void OHAudioRenderer::SetRendererCallbackType(WriteDataCallbackType writeDataCallbackType) { writeDataCallbackType_ = writeDataCallbackType; diff --git a/frameworks/native/ohaudio/OHAudioRenderer.h b/frameworks/native/ohaudio/OHAudioRenderer.h index d80703b83a..c682da7fe0 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.h +++ b/frameworks/native/ohaudio/OHAudioRenderer.h @@ -201,6 +201,7 @@ class OHAudioRenderer { void SetInterruptMode(InterruptMode mode); void SetSilentModeAndMixWithOthers(bool on); bool GetSilentModeAndMixWithOthers(); + void SetDefaultOutputDevice(DeviceType deviceType); void SetRendererCallbackType(WriteDataCallbackType writeDataCallbackType); WriteDataCallbackType GetRendererCallbackType(); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h index 1ccc53d73d..ef5c3af135 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h @@ -601,6 +601,13 @@ const std::unordered_map STREAM_USAGE_MAP = { {"STREAM_USAGE_VOICE_RINGTONE", STREAM_USAGE_VOICE_RINGTONE}, }; +const std::vector AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES { + STREAM_USAGE_VOICE_COMMUNICATION, + STREAM_USAGE_VOICE_MESSAGE, + STREAM_USAGE_VIDEO_COMMUNICATION, + STREAM_USAGE_VOICE_MODEM_COMMUNICATION, +}; + struct BufferDesc { uint8_t *buffer; size_t bufLength; diff --git a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h index bb7b933378..7b8305d5f6 100644 --- a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h @@ -930,6 +930,13 @@ public: virtual void EnableVoiceModemCommunicationStartStream(bool enable) = 0; + /** + * @brief Temporarily changes the current audio route. + * @param deviceType to set. The available deviceTypes are EARPIECE/SPEAKER/DEFAULT. + * @since 12 + */ + virtual int32_t SetDefaultOutputDevice(DeviceType deviceType) = 0; + private: static int32_t CreateCheckParam(const AudioRendererOptions &rendererOptions, const AppInfo &appInfo); diff --git a/interfaces/kits/c/audio_renderer/native_audiorenderer.h b/interfaces/kits/c/audio_renderer/native_audiorenderer.h index a31ceddd97..586fd45416 100644 --- a/interfaces/kits/c/audio_renderer/native_audiorenderer.h +++ b/interfaces/kits/c/audio_renderer/native_audiorenderer.h @@ -386,6 +386,24 @@ OH_AudioStream_Result OH_AudioRenderer_SetSilentModeAndMixWithOthers( */ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( OH_AudioRenderer* renderer, bool* on); + +/** + * Temporarily changes the current audio route. + * This function can only apply on audiorenderers whose streamUsage is + * STREAM_USAGE_VOICE_COMMUNICATION/STREAM_USAGE_VIDEO_COMMUNICATION/STREAM_USAGE_VOICE_MESSAGE + * Setting the device will only take effect if no other accessory such as headphones are in use + * + * @since 13 + * + * @param renderer Renderer generated by OH_AudioStreamBuilder_GenerateRenderer() + * @param deviceType the available deviceTypes is EARPIECE/SPEAKER/DEFAULT + * EARPIECE: Built-in earpiece + * SPEAKER: Built-in speaker + * DEFAULT: system default output device + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice( + OH_AudioRenderer* renderer, DeviceType devicetype); #ifdef __cplusplus } #endif diff --git a/services/audio_policy/client/include/audio_policy_base.h b/services/audio_policy/client/include/audio_policy_base.h index ae54029198..523caa71cd 100644 --- a/services/audio_policy/client/include/audio_policy_base.h +++ b/services/audio_policy/client/include/audio_policy_base.h @@ -330,6 +330,9 @@ public: virtual int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) = 0; + virtual int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + public: DECLARE_INTERFACE_DESCRIPTOR(u"IAudioPolicy"); }; diff --git a/services/audio_policy/client/include/audio_policy_manager_stub.h b/services/audio_policy/client/include/audio_policy_manager_stub.h index 02180e3592..a05c187e28 100644 --- a/services/audio_policy/client/include/audio_policy_manager_stub.h +++ b/services/audio_policy/client/include/audio_policy_manager_stub.h @@ -166,6 +166,7 @@ private: void DeactivateAudioSessionInternal(MessageParcel &data, MessageParcel &reply); void IsAudioSessionActivatedInternal(MessageParcel &data, MessageParcel &reply); void LoadSplitModuleInternal(MessageParcel &data, MessageParcel &reply); + void SetDefaultOutputDeviceInternal(MessageParcel &data, MessageParcel &reply); void OnMiddleNinRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); void OnMiddleEigRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/audio_policy/client/include/audio_policy_proxy.h b/services/audio_policy/client/include/audio_policy_proxy.h index df9c98f27c..7b61db170f 100644 --- a/services/audio_policy/client/include/audio_policy_proxy.h +++ b/services/audio_policy/client/include/audio_policy_proxy.h @@ -316,6 +316,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) override; + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) override; + private: static inline BrokerDelegator mDdelegator; void WriteStreamChangeInfo(MessageParcel &data, const AudioMode &mode, diff --git a/services/audio_policy/client/src/audio_policy_manager.cpp b/services/audio_policy/client/src/audio_policy_manager.cpp index ac6851c697..bfba0d9d5d 100644 --- a/services/audio_policy/client/src/audio_policy_manager.cpp +++ b/services/audio_policy/client/src/audio_policy_manager.cpp @@ -1916,6 +1916,14 @@ int32_t AudioPolicyManager::LoadSplitModule(const std::string &splitArgs, const return gsp->LoadSplitModule(splitArgs, networkId); } +int32_t AudioPolicyManager::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, -1, "audio policy manager proxy is NULL."); + return gsp->SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); +} + AudioPolicyManager& AudioPolicyManager::GetInstance() { static AudioPolicyManager policyManager; diff --git a/services/audio_policy/common/include/audio_policy_ipc_interface_code.h b/services/audio_policy/common/include/audio_policy_ipc_interface_code.h index 4500b8c169..4fdda32fff 100644 --- a/services/audio_policy/common/include/audio_policy_ipc_interface_code.h +++ b/services/audio_policy/common/include/audio_policy_ipc_interface_code.h @@ -156,7 +156,8 @@ enum class AudioPolicyInterfaceCode { DEACTIVATE_AUDIO_SESSION, IS_AUDIO_SESSION_ACTIVATED, LOAD_SPLIT_MODULE, - AUDIO_POLICY_MANAGER_CODE_MAX = LOAD_SPLIT_MODULE, + SET_DEFAULT_OUTPUT_DEVICE, + AUDIO_POLICY_MANAGER_CODE_MAX = SET_DEFAULT_OUTPUT_DEVICE, }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/include/audio_policy_server.h b/services/audio_policy/server/include/audio_policy_server.h index 8030bcadff..e15e2bafbe 100644 --- a/services/audio_policy/server/include/audio_policy_server.h +++ b/services/audio_policy/server/include/audio_policy_server.h @@ -401,6 +401,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) override; + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) override; + class RemoteParameterCallback : public AudioParameterCallback { public: RemoteParameterCallback(sptr server); diff --git a/services/audio_policy/server/include/audio_stream_collector.h b/services/audio_policy/server/include/audio_stream_collector.h index b8249ccd68..b32fb5591e 100644 --- a/services/audio_policy/server/include/audio_stream_collector.h +++ b/services/audio_policy/server/include/audio_stream_collector.h @@ -76,6 +76,7 @@ public: void ResetRendererStreamDeviceInfo(const AudioDeviceDescriptor& updatedDesc); void ResetCapturerStreamDeviceInfo(const AudioDeviceDescriptor& updatedDesc); StreamUsage GetLastestRunningCallStreamUsage(); + std::vector GetAllRendererSessionIDForUID(int32_t uid); private: std::mutex streamsInfoMutex_; std::map, int32_t> rendererStatequeue_; diff --git a/services/audio_policy/server/include/service/audio_device_manager.h b/services/audio_policy/server/include/service/audio_device_manager.h index c5f532e7d1..6a8b2620f8 100644 --- a/services/audio_policy/server/include/service/audio_device_manager.h +++ b/services/audio_policy/server/include/service/audio_device_manager.h @@ -27,6 +27,8 @@ namespace OHOS { namespace AudioStandard { using namespace std; +constexpr int32_t NEED_TO_FETCH = 1; + typedef function &desc)> IsPresentFunc; std::string GetEncryptAddr(const std::string &addr); class AudioDeviceManager { @@ -82,6 +84,12 @@ public: bool IsDeviceConnected(sptr &audioDeviceDescriptors); bool IsVirtualConnectedDevice(const sptr &selectedDesc); int32_t UpdateDeviceDescDeviceId(sptr &deviceDescriptor); + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + int32_t UpdateDefaultOutputDeviceWhenStarting(const uint32_t sessionID); + int32_t UpdateDefaultOutputDeviceWhenStopping(const uint32_t sessionID); + unique_ptr GetSelectedMediaRenderDevice(); + unique_ptr GetSelectedCallRenderDevice(); private: AudioDeviceManager(); @@ -157,6 +165,12 @@ private: sptr speaker_ = nullptr; sptr defalutMic_ = nullptr; bool hasEarpiece_ = false; + unordered_map> selectedDefaultOutputDeviceInfo_; + vector> mediaDefaultOutputDevices_; + vector> callDefaultOutputDevices_; + DeviceType selectedMediaDefaultOutputDevice_ = DEVICE_TYPE_DEFAULT; + DeviceType selectedCallDefaultOutputDevice_ = DEVICE_TYPE_DEFAULT; + std::mutex selectDefaultOutputDeviceMutex_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/include/service/audio_policy_service.h b/services/audio_policy/server/include/service/audio_policy_service.h index 96b60a7eb5..e1cd6e7fe1 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -545,6 +545,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId); + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + private: AudioPolicyService() :audioPolicyManager_(AudioPolicyManagerFactory::GetAudioPolicyManager()), @@ -995,6 +998,7 @@ private: void UpdateDeviceList(AudioDeviceDescriptor &updatedDesc, bool isConnected, std::vector> &descForCb, AudioStreamDeviceChangeReasonExt &reason); + void UpdateDefaultOutputDeviceWhenStopping(int32_t uid); bool isUpdateRouteSupported_ = true; bool isCurrentRemoteRenderer = false; 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 0e65c96274..14cae2c3af 100644 --- a/services/audio_policy/server/src/audio_policy_manager_stub.cpp +++ b/services/audio_policy/server/src/audio_policy_manager_stub.cpp @@ -1285,6 +1285,16 @@ void AudioPolicyManagerStub::ReleaseAudioInterruptZoneInternal(MessageParcel &da reply.WriteInt32(result); } +void AudioPolicyManagerStub::SetDefaultOutputDeviceInternal(MessageParcel &data, MessageParcel &reply) +{ + DeviceType deviceType = static_cast(data.ReadInt32()); + uint32_t sessionID = data.ReadUint32(); + StreamUsage streamUsage = static_cast(data.ReadInt32()); + bool isRunning = data.ReadBool(); + int32_t result = SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); + reply.WriteInt32(result); +} + void AudioPolicyManagerStub::OnMiddleNinRemoteRequest( uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { @@ -1301,6 +1311,9 @@ void AudioPolicyManagerStub::OnMiddleNinRemoteRequest( case static_cast(AudioPolicyInterfaceCode::SET_HEAD_TRACKING_ENABLED_FOR_DEVICE): SetHeadTrackingEnabledForDeviceInternal(data, reply); break; + case static_cast(AudioPolicyInterfaceCode::SET_DEFAULT_OUTPUT_DEVICE): + SetDefaultOutputDeviceInternal(data, reply); + break; default: AUDIO_ERR_LOG("default case, need check AudioPolicyManagerStub"); IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/services/audio_policy/server/src/audio_policy_server.cpp b/services/audio_policy/server/src/audio_policy_server.cpp index dd45d9875e..71ab66e7a7 100644 --- a/services/audio_policy/server/src/audio_policy_server.cpp +++ b/services/audio_policy/server/src/audio_policy_server.cpp @@ -2835,5 +2835,11 @@ int32_t AudioPolicyServer::LoadSplitModule(const std::string &splitArgs, const s return audioPolicyService_.LoadSplitModule(splitArgs, networkId); } +bool AudioPolicyServer::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + return audioPolicyService_.SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/src/audio_stream_collector.cpp b/services/audio_policy/server/src/audio_stream_collector.cpp index 6d1e9325e3..65c35201d8 100644 --- a/services/audio_policy/server/src/audio_stream_collector.cpp +++ b/services/audio_policy/server/src/audio_stream_collector.cpp @@ -1201,5 +1201,16 @@ StreamUsage AudioStreamCollector::GetLastestRunningCallStreamUsage() return STREAM_USAGE_UNKNOWN; } +std::vector AudioStreamCollector::GetAllRendererSessionIDForUID(int32_t uid) +{ + std::lock_guard lock(streamsInfoMutex_); + std::vector sessionIDSet; + for (const auto &changeInfo : audioRendererChangeInfos_) { + if (changeInfo->clientUID == uid) { + sessionIDSet.push_back(changeInfo->sessionId); + } + } + return sessionIDSet; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/src/service/audio_device_manager.cpp b/services/audio_policy/server/src/service/audio_device_manager.cpp index 2f333da8e5..efd8f23ace 100644 --- a/services/audio_policy/server/src/service/audio_device_manager.cpp +++ b/services/audio_policy/server/src/service/audio_device_manager.cpp @@ -1104,6 +1104,172 @@ int32_t AudioDeviceManager::UpdateDeviceDescDeviceId(sptr deviceDescriptor->deviceId_ = (*itr)->deviceId_; return SUCCESS; } + +int32_t AudioDeviceManager::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + selectedDefaultOutputDeviceInfo_[sessionID] = std::make_pair(streamUsage, deviceType); + if (!isRunning) { + AUDIO_INFO_LOG("no need to set default output device since current stream has not started"); + return SUCCESS; + } + AUDIO_INFO_LOG("stream %{public}u with usage %{public}d selects output device %{public}d", + sessionID, streamUsage, deviceType); + if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { + // select media default output device + auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), + [&sessionID](const std::pair &mediaDefaultOutputDevice) { + return mediaDefaultOutputDevice.first == sessionID; + }); + if (it != mediaDefaultOutputDevices_.end()) { + mediaDefaultOutputDevices_.erase(it); + } + mediaDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + if (selectedMediaDefaultOutputDevice_ != deviceType) { + AUDIO_INFO_LOG("media default output device changes from %{public}d to %{public}d", + selectedMediaDefaultOutputDevice_, deviceType); + selectedMediaDefaultOutputDevice_ = deviceType; + return NEED_TO_FETCH; + } + } else if (streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION || + streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { + // select call default output device + auto it = std::find_if(callDefaultOutputDevices_.begin(), callDefaultOutputDevices_.end(), + [&sessionID](const std::pair &callDefaultOutputDevice) { + return callDefaultOutputDevice.first == sessionID; + }); + if (it != callDefaultOutputDevices_.end()) { + callDefaultOutputDevices_.erase(it); + } + callDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + if (selectedCallDefaultOutputDevice_ != deviceType) { + AUDIO_INFO_LOG("call default output device changes from %{public}d to %{public}d", + selectedCallDefaultOutputDevice_, deviceType); + selectedCallDefaultOutputDevice_ = deviceType; + return NEED_TO_FETCH; + } + } else { + AUDIO_ERR_LOG("Invalid stream usage %{public}d", streamUsage); + return ERROR; + } + return SUCCESS; +} + +int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStarting(const uint32_t sessionID) +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + if (!selectedDefaultOutputDeviceInfo_.count(sessionID)) { + AUDIO_DEBUG_LOG("no need to update default output device since current stream has not set"); + return SUCCESS; + } + StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].first; + DeviceType deviceType = selectedDefaultOutputDeviceInfo_[sessionID].second; + if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { + // select media default output device + auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), + [&sessionID](const std::pair &mediaDefaultOutputDevice) { + return mediaDefaultOutputDevice.first == sessionID; + }); + if (it != mediaDefaultOutputDevices_.end()) { + mediaDefaultOutputDevices_.erase(it); + } + mediaDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because media stream %{public}u starts", + selectedMediaDefaultOutputDevice_, deviceType, sessionID); + selectedMediaDefaultOutputDevice_ = deviceType; + } else if (streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION || + streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { + // select call default output device + auto it = std::find_if(callDefaultOutputDevices_.begin(), callDefaultOutputDevices_.end(), + [&sessionID](const std::pair &callDefaultOutputDevice) { + return callDefaultOutputDevice.first == sessionID; + }); + if (it != callDefaultOutputDevices_.end()) { + callDefaultOutputDevices_.erase(it); + } + callDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because call stream %{public}u starts", + selectedCallDefaultOutputDevice_, deviceType, sessionID); + selectedCallDefaultOutputDevice_ = deviceType; + } + return SUCCESS; +} + +int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStopping(const uint32_t sessionID) +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + if (!selectedDefaultOutputDeviceInfo_.count(sessionID)) { + AUDIO_DEBUG_LOG("no need to update default output device since current stream has not set"); + return SUCCESS; + } + StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].first; + if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { + // select media default output device + auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), + [&sessionID](const std::pair &mediaDefaultOutputDevice) { + return mediaDefaultOutputDevice.first == sessionID; + }); + if (it == mediaDefaultOutputDevices_.end()) { + return SUCCESS; + } + mediaDefaultOutputDevices_.erase(it); + DeviceType currDeviceType; + if (mediaDefaultOutputDevices_.empty()) { + currDeviceType = DEVICE_TYPE_DEFAULT; + } else { + currDeviceType = mediaDefaultOutputDevices_.back(); + } + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because media stream %{public}u stops", + selectedMediaDefaultOutputDevice_, currDeviceType, sessionID); + selectedMediaDefaultOutputDevice_ = currDeviceType; + } else if (streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION || + streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { + // select call default output device + auto it = std::find_if(callDefaultOutputDevices_.begin(), callDefaultOutputDevices_.end(), + [&sessionID](const std::pair &callDefaultOutputDevice) { + return callDefaultOutputDevice.first == sessionID; + }); + if (it == callDefaultOutputDevices_.end()) { + return SUCCESS; + } + callDefaultOutputDevices_.erase(it); + DeviceType currDeviceType; + if (callDefaultOutputDevices_.empty()) { + currDeviceType = DEVICE_TYPE_DEFAULT; + } else { + currDeviceType = callDefaultOutputDevices_.back(); + } + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because call stream %{public}u stops", + selectedCallDefaultOutputDevice_, currDeviceType, sessionID); + selectedCallDefaultOutputDevice_ = currDeviceType; + } + return SUCCESS; +} + +unique_ptr AudioDeviceManager::GetSelectedMediaRenderDevice() +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + unique_ptr devDesc = nullptr; + if (selectedMediaDefaultOutputDevice_ == DEVICE_TYPE_EARPIECE) { + devDesc = make_unique(earpiece_); + } else if (selectedMediaDefaultOutputDevice_ == DEVICE_TYPE_SPEAKER) { + devDesc = make_unique(speaker_); + } + return devDesc; +} + +unique_ptr AudioDeviceManager::GetSelectedCallRenderDevice() +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + unique_ptr devDesc = nullptr; + if (selectedCallDefaultOutputDevice_ == DEVICE_TYPE_EARPIECE) { + devDesc = make_unique(earpiece_); + } else if (selectedCallDefaultOutputDevice_ == DEVICE_TYPE_SPEAKER) { + devDesc = make_unique(speaker_); + } + return devDesc; +} // LCOV_EXCL_STOP } } 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 8957063be7..637fce3981 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -4910,6 +4910,13 @@ int32_t AudioPolicyService::UpdateTracker(AudioMode &mode, AudioStreamChangeInfo return ret; // only update tracker in new and prepared } + if (mode == AUDIO_MODE_PLAYBACK && rendererState == RENDERER_RUNNING) { + UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); + } else if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || + rendererState == RENDERER_RELEASED || rendererState == RENDERER_PAUSED)) { + UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); + } + if (rendererState == RENDERER_RELEASED && !streamCollector_.ExistStreamForPipe(PIPE_TYPE_MULTICHANNEL)) { DynamicUnloadModule(PIPE_TYPE_MULTICHANNEL); } @@ -5041,6 +5048,8 @@ void AudioPolicyService::RegisteredTrackerClientDied(pid_t uid) { std::lock_guard deviceLock(deviceStatusUpdateSharedMutex_); + UpdateDefaultOutputDeviceWhenStopping(static_cast(uid)); + RemoveAudioCapturerMicrophoneDescriptor(static_cast(uid)); streamCollector_.RegisteredTrackerClientDied(static_cast(uid)); @@ -8467,6 +8476,26 @@ int32_t AudioPolicyService::LoadSplitModule(const std::string &splitArgs, const return openRet; } +int32_t AudioPolicyService::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + CHECK_AND_RETURN_RET_LOG(hasEarpiece_, ERR_NOT_SUPPORTED, "the device has no earpiece"); + int32_t ret = audioDeviceManager_.SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); + if (ret == NEED_TO_FETCH) { + FetchDevice(true); + return SUCCESS; + } + return ret; +} + +void AudioPolicyService::UpdateDefaultOutputDeviceWhenStopping(int32_t uid) +{ + std::vector sessionIDSet = streamCollector_.GetAllRendererSessionIDForUID(uid); + for (const auto &sessionID : sessionIDSet) { + audioDeviceManager_.UpdateDefaultOutputDeviceWhenStopping(sessionID); + } +} + void AudioA2dpOffloadManager::OnA2dpPlayingStateChanged(const std::string &deviceAddress, int32_t playingState) { AUDIO_INFO_LOG("Current A2dpOffload MacAddr:%{public}s, incoming MacAddr:%{public}s, state:%{public}d", diff --git a/services/audio_policy/server/src/service/routers/default_router.cpp b/services/audio_policy/server/src/service/routers/default_router.cpp index 6275146a1d..b895e4e24e 100644 --- a/services/audio_policy/server/src/service/routers/default_router.cpp +++ b/services/audio_policy/server/src/service/routers/default_router.cpp @@ -25,7 +25,10 @@ namespace AudioStandard { unique_ptr DefaultRouter::GetMediaRenderDevice(StreamUsage streamUsage, int32_t clientUID) { - unique_ptr desc = AudioDeviceManager::GetAudioDeviceManager().GetRenderDefaultDevice(); + unique_ptr desc = AudioDeviceManager::GetAudioDeviceManager().GetSelectedMediaRenderDevice(); + if (desc == nullptr) { + desc = AudioDeviceManager::GetAudioDeviceManager().GetRenderDefaultDevice(); + } AUDIO_DEBUG_LOG("streamUsage %{public}d clientUID %{public}d fetch device %{public}d", streamUsage, clientUID, desc->deviceType_); return desc; @@ -33,8 +36,10 @@ unique_ptr DefaultRouter::GetMediaRenderDevice(StreamUsag unique_ptr DefaultRouter::GetCallRenderDevice(StreamUsage streamUsage, int32_t clientUID) { - unique_ptr desc = - AudioDeviceManager::GetAudioDeviceManager().GetCommRenderDefaultDevice(streamUsage); + unique_ptr desc = AudioDeviceManager::GetAudioDeviceManager().GetSelectedCallRenderDevice(); + if (desc == nullptr) { + desc = AudioDeviceManager::GetAudioDeviceManager().GetCommRenderDefaultDevice(streamUsage); + } AUDIO_DEBUG_LOG("streamUsage %{public}d clientUID %{public}d fetch device %{public}d", streamUsage, clientUID, desc->deviceType_); return desc; -- Gitee From 7689ad16f175826bf2e13aaa927ba031109eda9a Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 19:47:38 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- .../audiorenderer/napi_audio_renderer.cpp | 31 ++++ .../napi/audiorenderer/napi_audio_renderer.h | 1 + frameworks/js/napi/common/napi_audio_enum.cpp | 16 ++ .../include/audio_policy_manager.h | 3 + .../include/audio_renderer_private.h | 2 + .../audiorenderer/src/audio_renderer.cpp | 11 ++ frameworks/native/ohaudio/OHAudioRenderer.cpp | 19 ++ frameworks/native/ohaudio/OHAudioRenderer.h | 1 + .../audiocommon/include/audio_stream_info.h | 7 + .../audiorenderer/include/audio_renderer.h | 7 + .../c/audio_renderer/native_audiorenderer.h | 18 ++ .../client/include/audio_policy_base.h | 3 + .../include/audio_policy_manager_stub.h | 1 + .../client/include/audio_policy_proxy.h | 3 + .../client/src/audio_policy_manager.cpp | 8 + .../client/src/proxy/audio_policy_proxy.cpp | 20 +++ .../include/audio_policy_ipc_interface_code.h | 3 +- .../server/include/audio_policy_server.h | 3 + .../server/include/audio_stream_collector.h | 1 + .../include/service/audio_device_manager.h | 14 ++ .../include/service/audio_policy_service.h | 4 + .../server/src/audio_policy_manager_stub.cpp | 13 ++ .../server/src/audio_policy_server.cpp | 6 + .../server/src/audio_stream_collector.cpp | 11 ++ .../src/service/audio_device_manager.cpp | 166 ++++++++++++++++++ .../src/service/audio_policy_service.cpp | 29 +++ .../src/service/routers/default_router.cpp | 11 +- 27 files changed, 408 insertions(+), 4 deletions(-) diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp index bc824c208b..1b32f42673 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp @@ -103,6 +103,7 @@ napi_status NapiAudioRenderer::InitNapiAudioRenderer(napi_env env, napi_value &c DECLARE_NAPI_FUNCTION("off", Off), DECLARE_NAPI_FUNCTION("setSilentModeAndMixWithOthers", SetSilentModeAndMixWithOthers), DECLARE_NAPI_FUNCTION("getSilentModeAndMixWithOthers", GetSilentModeAndMixWithOthers), + DECLARE_NAPI_FUNCTION("setDefaultOutputDevice", SetDefaultOutputDevice), }; napi_status status = napi_define_class(env, NAPI_AUDIO_RENDERER_CLASS_NAME.c_str(), @@ -1569,6 +1570,36 @@ napi_value NapiAudioRenderer::GetSilentModeAndMixWithOthers(napi_env env, napi_c return result; } +napi_value NapiAudioRenderer::SetDefaultOutputDevice(napi_env env, napi_callback_info info) +{ + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value argv[ARGS_ONE] = {}; + auto *napiAudioRenderer = GetParamWithSync(env, info, argc, argv); + CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID, + "mandatory parameters are left unspecified"), "argcCount invaild"); + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[PARAM0], &valueType); + CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID, + "incorrect parameter types: The type of mode must be number"), "valueType params"); + + int32_t deviceType; + NapiParamUtils::GetValueInt32(env, deviceType, argv[PARAM0]); + CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentOutputDeviceType(deviceType), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM, + "parameter verification failed: The param of mode must be enum deviceType"), "unsupport params"); + + CHECK_AND_RETURN_RET_LOG(napiAudioRenderer!= nullptr, result, "napiAudioRenderer is nullptr"); + CHECK_AND_RETURN_RET_LOG(napiAudioRenderer->audioRenderer_ != nullptr, result, "audioRenderer_ is nullptr"); + int32_t ret = + napiAudioRenderer->audioRenderer_->SetDefaultOutputDevice(static_cast(deviceType)); + CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE, + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE), "err illegal state"); + + return result; +} + napi_value NapiAudioRenderer::RegisterCallback(napi_env env, napi_value jsThis, napi_value *argv, const std::string &cbName) { diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.h b/frameworks/js/napi/audiorenderer/napi_audio_renderer.h index 16afb204d2..d87bd38628 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.h +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.h @@ -127,6 +127,7 @@ private: static napi_value Off(napi_env env, napi_callback_info info); static napi_value SetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info); static napi_value GetSilentModeAndMixWithOthers(napi_env env, napi_callback_info info); + static napi_value SetDefaultOutputDevice(napi_env env, napi_callback_info info); static napi_status WriteArrayBufferToNative(std::shared_ptr context); diff --git a/frameworks/js/napi/common/napi_audio_enum.cpp b/frameworks/js/napi/common/napi_audio_enum.cpp index 4747bdc432..e56ae78c79 100644 --- a/frameworks/js/napi/common/napi_audio_enum.cpp +++ b/frameworks/js/napi/common/napi_audio_enum.cpp @@ -1198,6 +1198,22 @@ bool NapiAudioEnum::IsLegalInputArgumentDeviceType(int32_t deviceType) return result; } +bool NapiAudioEnum::IsLegalInputArgumentOutputDeviceType(int32_t deviceType) +{ + bool result = false; + switch (deviceType) { + case DeviceType::DEVICE_TYPE_EARPIECE: + case DeviceType::DEVICE_TYPE_SPEAKER: + case DeviceType::DEVICE_TYPE_DEFAULT: + result = true; + break; + default: + result = false; + break; + } + return result; +} + int32_t NapiAudioEnum::GetJsAudioVolumeType(AudioStreamType volumeType) { int32_t result = MEDIA; diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index 3d9e5dda0e..6cc494c964 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -417,6 +417,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId); + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + private: AudioPolicyManager() {} ~AudioPolicyManager() {} diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 2c1d95e3ac..fe5b940b9c 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -128,6 +128,8 @@ public: void EnableVoiceModemCommunicationStartStream(bool enable) override; + int32_t SetDefaultOutputDevice(DeviceType deviceType) override; + static inline AudioStreamParams ConvertToAudioStreamParams(const AudioRendererParams params) { AudioStreamParams audioStreamParams; diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index 908464c47c..0250c0decf 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -1846,5 +1846,16 @@ void AudioRendererPrivate::EnableVoiceModemCommunicationStartStream(bool enable) { isEnableVoiceModemCommunicationStartStream_ = enable; } + +int32_t AudioRendererPrivate::SetDefaultOutputDevice(DeviceType deviceType) +{ + bool isSupportedStreamUsage = (find(AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES.begin(), + AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES.end(), rendererInfo_.streamUsage) != + AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES.end()); + CHECK_AND_RETURN_RET_LOG(isSupportedStreamUsage, ERR_NOT_SUPPORTED, "stream usage not supported"); + int32_t ret = AudioPolicyManager::GetInstance().SetDefaultOutputDevice(deviceType, sessionID_, + rendererInfo_.streamUsage, GetStatus() == RENDERER_RUNNING); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "select default output device failed"); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.cpp b/frameworks/native/ohaudio/OHAudioRenderer.cpp index 456a86327a..1fb6cc2d02 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.cpp +++ b/frameworks/native/ohaudio/OHAudioRenderer.cpp @@ -337,6 +337,19 @@ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( return AUDIOSTREAM_SUCCESS; } +OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice( + OH_AudioRenderer* renderer, DeviceType deviceType) +{ + OHOS::AudioStandard::OHAudioRenderer *audioRenderer = convertRenderer(renderer); + CHECK_AND_RETURN_RET_LOG(audioRenderer != nullptr, AUDIOSTREAM_ERROR_INVALID_PARAM, "convert renderer failed"); + bool result = (deviceType == DEVICE_TYPE_EARPIECE || deviceType == DEVICE_TYPE_SPEAKER || + deviceType == DEVICE_TYPE_DEFAULT) ? true : false; + CHECK_AND_RETURN_RET_LOG(result != true, AUDIOSTREAM_ERROR_ILLEGAL_STATE, "unsupport params"); + int32_t ret = audioRenderer->SetDefaultOutputDevice(deviceType); + CHECK_AND_RETURN_RET_LOG(ret != AUDIOSTREAM_SUCCESS, AUDIOSTREAM_ERROR_INVALID_PARAM, "err illegal state"); + return AUDIOSTREAM_SUCCESS; +} + namespace OHOS { namespace AudioStandard { OHAudioRenderer::OHAudioRenderer() @@ -783,6 +796,12 @@ bool OHAudioRenderer::GetSilentModeAndMixWithOthers() return audioRenderer_->GetSilentModeAndMixWithOthers(); } +int32_t OHAudioRenderer::SetDefaultOutputDevice(DeviceType deviceType) +{ + CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "renderer client is nullptr"); + return audioRenderer_->SetDefaultOutputDevice(deviceType); +} + void OHAudioRenderer::SetRendererCallbackType(WriteDataCallbackType writeDataCallbackType) { writeDataCallbackType_ = writeDataCallbackType; diff --git a/frameworks/native/ohaudio/OHAudioRenderer.h b/frameworks/native/ohaudio/OHAudioRenderer.h index d80703b83a..c682da7fe0 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.h +++ b/frameworks/native/ohaudio/OHAudioRenderer.h @@ -201,6 +201,7 @@ class OHAudioRenderer { void SetInterruptMode(InterruptMode mode); void SetSilentModeAndMixWithOthers(bool on); bool GetSilentModeAndMixWithOthers(); + void SetDefaultOutputDevice(DeviceType deviceType); void SetRendererCallbackType(WriteDataCallbackType writeDataCallbackType); WriteDataCallbackType GetRendererCallbackType(); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h index 1ccc53d73d..ef5c3af135 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h @@ -601,6 +601,13 @@ const std::unordered_map STREAM_USAGE_MAP = { {"STREAM_USAGE_VOICE_RINGTONE", STREAM_USAGE_VOICE_RINGTONE}, }; +const std::vector AUDIO_DEFAULT_OUTPUT_DEVICE_SUPPORTED_STREAM_USAGES { + STREAM_USAGE_VOICE_COMMUNICATION, + STREAM_USAGE_VOICE_MESSAGE, + STREAM_USAGE_VIDEO_COMMUNICATION, + STREAM_USAGE_VOICE_MODEM_COMMUNICATION, +}; + struct BufferDesc { uint8_t *buffer; size_t bufLength; diff --git a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h index bb7b933378..7b8305d5f6 100644 --- a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h @@ -930,6 +930,13 @@ public: virtual void EnableVoiceModemCommunicationStartStream(bool enable) = 0; + /** + * @brief Temporarily changes the current audio route. + * @param deviceType to set. The available deviceTypes are EARPIECE/SPEAKER/DEFAULT. + * @since 12 + */ + virtual int32_t SetDefaultOutputDevice(DeviceType deviceType) = 0; + private: static int32_t CreateCheckParam(const AudioRendererOptions &rendererOptions, const AppInfo &appInfo); diff --git a/interfaces/kits/c/audio_renderer/native_audiorenderer.h b/interfaces/kits/c/audio_renderer/native_audiorenderer.h index a31ceddd97..586fd45416 100644 --- a/interfaces/kits/c/audio_renderer/native_audiorenderer.h +++ b/interfaces/kits/c/audio_renderer/native_audiorenderer.h @@ -386,6 +386,24 @@ OH_AudioStream_Result OH_AudioRenderer_SetSilentModeAndMixWithOthers( */ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( OH_AudioRenderer* renderer, bool* on); + +/** + * Temporarily changes the current audio route. + * This function can only apply on audiorenderers whose streamUsage is + * STREAM_USAGE_VOICE_COMMUNICATION/STREAM_USAGE_VIDEO_COMMUNICATION/STREAM_USAGE_VOICE_MESSAGE + * Setting the device will only take effect if no other accessory such as headphones are in use + * + * @since 13 + * + * @param renderer Renderer generated by OH_AudioStreamBuilder_GenerateRenderer() + * @param deviceType the available deviceTypes is EARPIECE/SPEAKER/DEFAULT + * EARPIECE: Built-in earpiece + * SPEAKER: Built-in speaker + * DEFAULT: system default output device + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice( + OH_AudioRenderer* renderer, DeviceType devicetype); #ifdef __cplusplus } #endif diff --git a/services/audio_policy/client/include/audio_policy_base.h b/services/audio_policy/client/include/audio_policy_base.h index ae54029198..523caa71cd 100644 --- a/services/audio_policy/client/include/audio_policy_base.h +++ b/services/audio_policy/client/include/audio_policy_base.h @@ -330,6 +330,9 @@ public: virtual int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) = 0; + virtual int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + public: DECLARE_INTERFACE_DESCRIPTOR(u"IAudioPolicy"); }; diff --git a/services/audio_policy/client/include/audio_policy_manager_stub.h b/services/audio_policy/client/include/audio_policy_manager_stub.h index 02180e3592..a05c187e28 100644 --- a/services/audio_policy/client/include/audio_policy_manager_stub.h +++ b/services/audio_policy/client/include/audio_policy_manager_stub.h @@ -166,6 +166,7 @@ private: void DeactivateAudioSessionInternal(MessageParcel &data, MessageParcel &reply); void IsAudioSessionActivatedInternal(MessageParcel &data, MessageParcel &reply); void LoadSplitModuleInternal(MessageParcel &data, MessageParcel &reply); + void SetDefaultOutputDeviceInternal(MessageParcel &data, MessageParcel &reply); void OnMiddleNinRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); void OnMiddleEigRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/audio_policy/client/include/audio_policy_proxy.h b/services/audio_policy/client/include/audio_policy_proxy.h index df9c98f27c..7b61db170f 100644 --- a/services/audio_policy/client/include/audio_policy_proxy.h +++ b/services/audio_policy/client/include/audio_policy_proxy.h @@ -316,6 +316,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) override; + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) override; + private: static inline BrokerDelegator mDdelegator; void WriteStreamChangeInfo(MessageParcel &data, const AudioMode &mode, diff --git a/services/audio_policy/client/src/audio_policy_manager.cpp b/services/audio_policy/client/src/audio_policy_manager.cpp index ac6851c697..bfba0d9d5d 100644 --- a/services/audio_policy/client/src/audio_policy_manager.cpp +++ b/services/audio_policy/client/src/audio_policy_manager.cpp @@ -1916,6 +1916,14 @@ int32_t AudioPolicyManager::LoadSplitModule(const std::string &splitArgs, const return gsp->LoadSplitModule(splitArgs, networkId); } +int32_t AudioPolicyManager::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, -1, "audio policy manager proxy is NULL."); + return gsp->SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); +} + AudioPolicyManager& AudioPolicyManager::GetInstance() { static AudioPolicyManager policyManager; diff --git a/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp b/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp index 9b47b287cc..aa85faba59 100644 --- a/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp +++ b/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp @@ -1855,5 +1855,25 @@ int32_t AudioPolicyProxy::InjectInterruption(const std::string networkId, Interr return reply.ReadInt32(); } +int32_t AudioPolicyProxy::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool ret = data.WriteInterfaceToken(GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(ret, -1, "WriteInterfaceToken failed"); + data.WriteInt32(static_cast(deviceType)); + data.WriteUint32(sessionId); + data.WriteInt32(static_cast(streamUsage)); + data.WriteBool(isRunning); + + int error = Remote()->SendRequest( + static_cast(AudioPolicyInterfaceCode::SET_DEFAULT_OUTPUT_DEVICE), data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == ERR_NONE, error, "SendRequest failed, error: %{public}d", error); + return reply.ReadInt32(); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/common/include/audio_policy_ipc_interface_code.h b/services/audio_policy/common/include/audio_policy_ipc_interface_code.h index 4500b8c169..4fdda32fff 100644 --- a/services/audio_policy/common/include/audio_policy_ipc_interface_code.h +++ b/services/audio_policy/common/include/audio_policy_ipc_interface_code.h @@ -156,7 +156,8 @@ enum class AudioPolicyInterfaceCode { DEACTIVATE_AUDIO_SESSION, IS_AUDIO_SESSION_ACTIVATED, LOAD_SPLIT_MODULE, - AUDIO_POLICY_MANAGER_CODE_MAX = LOAD_SPLIT_MODULE, + SET_DEFAULT_OUTPUT_DEVICE, + AUDIO_POLICY_MANAGER_CODE_MAX = SET_DEFAULT_OUTPUT_DEVICE, }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/include/audio_policy_server.h b/services/audio_policy/server/include/audio_policy_server.h index 8030bcadff..e15e2bafbe 100644 --- a/services/audio_policy/server/include/audio_policy_server.h +++ b/services/audio_policy/server/include/audio_policy_server.h @@ -401,6 +401,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) override; + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) override; + class RemoteParameterCallback : public AudioParameterCallback { public: RemoteParameterCallback(sptr server); diff --git a/services/audio_policy/server/include/audio_stream_collector.h b/services/audio_policy/server/include/audio_stream_collector.h index b8249ccd68..b32fb5591e 100644 --- a/services/audio_policy/server/include/audio_stream_collector.h +++ b/services/audio_policy/server/include/audio_stream_collector.h @@ -76,6 +76,7 @@ public: void ResetRendererStreamDeviceInfo(const AudioDeviceDescriptor& updatedDesc); void ResetCapturerStreamDeviceInfo(const AudioDeviceDescriptor& updatedDesc); StreamUsage GetLastestRunningCallStreamUsage(); + std::vector GetAllRendererSessionIDForUID(int32_t uid); private: std::mutex streamsInfoMutex_; std::map, int32_t> rendererStatequeue_; diff --git a/services/audio_policy/server/include/service/audio_device_manager.h b/services/audio_policy/server/include/service/audio_device_manager.h index c5f532e7d1..6a8b2620f8 100644 --- a/services/audio_policy/server/include/service/audio_device_manager.h +++ b/services/audio_policy/server/include/service/audio_device_manager.h @@ -27,6 +27,8 @@ namespace OHOS { namespace AudioStandard { using namespace std; +constexpr int32_t NEED_TO_FETCH = 1; + typedef function &desc)> IsPresentFunc; std::string GetEncryptAddr(const std::string &addr); class AudioDeviceManager { @@ -82,6 +84,12 @@ public: bool IsDeviceConnected(sptr &audioDeviceDescriptors); bool IsVirtualConnectedDevice(const sptr &selectedDesc); int32_t UpdateDeviceDescDeviceId(sptr &deviceDescriptor); + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + int32_t UpdateDefaultOutputDeviceWhenStarting(const uint32_t sessionID); + int32_t UpdateDefaultOutputDeviceWhenStopping(const uint32_t sessionID); + unique_ptr GetSelectedMediaRenderDevice(); + unique_ptr GetSelectedCallRenderDevice(); private: AudioDeviceManager(); @@ -157,6 +165,12 @@ private: sptr speaker_ = nullptr; sptr defalutMic_ = nullptr; bool hasEarpiece_ = false; + unordered_map> selectedDefaultOutputDeviceInfo_; + vector> mediaDefaultOutputDevices_; + vector> callDefaultOutputDevices_; + DeviceType selectedMediaDefaultOutputDevice_ = DEVICE_TYPE_DEFAULT; + DeviceType selectedCallDefaultOutputDevice_ = DEVICE_TYPE_DEFAULT; + std::mutex selectDefaultOutputDeviceMutex_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/include/service/audio_policy_service.h b/services/audio_policy/server/include/service/audio_policy_service.h index 96b60a7eb5..e1cd6e7fe1 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -545,6 +545,9 @@ public: int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId); + int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning); + private: AudioPolicyService() :audioPolicyManager_(AudioPolicyManagerFactory::GetAudioPolicyManager()), @@ -995,6 +998,7 @@ private: void UpdateDeviceList(AudioDeviceDescriptor &updatedDesc, bool isConnected, std::vector> &descForCb, AudioStreamDeviceChangeReasonExt &reason); + void UpdateDefaultOutputDeviceWhenStopping(int32_t uid); bool isUpdateRouteSupported_ = true; bool isCurrentRemoteRenderer = false; 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 0e65c96274..14cae2c3af 100644 --- a/services/audio_policy/server/src/audio_policy_manager_stub.cpp +++ b/services/audio_policy/server/src/audio_policy_manager_stub.cpp @@ -1285,6 +1285,16 @@ void AudioPolicyManagerStub::ReleaseAudioInterruptZoneInternal(MessageParcel &da reply.WriteInt32(result); } +void AudioPolicyManagerStub::SetDefaultOutputDeviceInternal(MessageParcel &data, MessageParcel &reply) +{ + DeviceType deviceType = static_cast(data.ReadInt32()); + uint32_t sessionID = data.ReadUint32(); + StreamUsage streamUsage = static_cast(data.ReadInt32()); + bool isRunning = data.ReadBool(); + int32_t result = SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); + reply.WriteInt32(result); +} + void AudioPolicyManagerStub::OnMiddleNinRemoteRequest( uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { @@ -1301,6 +1311,9 @@ void AudioPolicyManagerStub::OnMiddleNinRemoteRequest( case static_cast(AudioPolicyInterfaceCode::SET_HEAD_TRACKING_ENABLED_FOR_DEVICE): SetHeadTrackingEnabledForDeviceInternal(data, reply); break; + case static_cast(AudioPolicyInterfaceCode::SET_DEFAULT_OUTPUT_DEVICE): + SetDefaultOutputDeviceInternal(data, reply); + break; default: AUDIO_ERR_LOG("default case, need check AudioPolicyManagerStub"); IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/services/audio_policy/server/src/audio_policy_server.cpp b/services/audio_policy/server/src/audio_policy_server.cpp index dd45d9875e..71ab66e7a7 100644 --- a/services/audio_policy/server/src/audio_policy_server.cpp +++ b/services/audio_policy/server/src/audio_policy_server.cpp @@ -2835,5 +2835,11 @@ int32_t AudioPolicyServer::LoadSplitModule(const std::string &splitArgs, const s return audioPolicyService_.LoadSplitModule(splitArgs, networkId); } +bool AudioPolicyServer::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + return audioPolicyService_.SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/src/audio_stream_collector.cpp b/services/audio_policy/server/src/audio_stream_collector.cpp index 6d1e9325e3..65c35201d8 100644 --- a/services/audio_policy/server/src/audio_stream_collector.cpp +++ b/services/audio_policy/server/src/audio_stream_collector.cpp @@ -1201,5 +1201,16 @@ StreamUsage AudioStreamCollector::GetLastestRunningCallStreamUsage() return STREAM_USAGE_UNKNOWN; } +std::vector AudioStreamCollector::GetAllRendererSessionIDForUID(int32_t uid) +{ + std::lock_guard lock(streamsInfoMutex_); + std::vector sessionIDSet; + for (const auto &changeInfo : audioRendererChangeInfos_) { + if (changeInfo->clientUID == uid) { + sessionIDSet.push_back(changeInfo->sessionId); + } + } + return sessionIDSet; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/src/service/audio_device_manager.cpp b/services/audio_policy/server/src/service/audio_device_manager.cpp index 2f333da8e5..efd8f23ace 100644 --- a/services/audio_policy/server/src/service/audio_device_manager.cpp +++ b/services/audio_policy/server/src/service/audio_device_manager.cpp @@ -1104,6 +1104,172 @@ int32_t AudioDeviceManager::UpdateDeviceDescDeviceId(sptr deviceDescriptor->deviceId_ = (*itr)->deviceId_; return SUCCESS; } + +int32_t AudioDeviceManager::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + selectedDefaultOutputDeviceInfo_[sessionID] = std::make_pair(streamUsage, deviceType); + if (!isRunning) { + AUDIO_INFO_LOG("no need to set default output device since current stream has not started"); + return SUCCESS; + } + AUDIO_INFO_LOG("stream %{public}u with usage %{public}d selects output device %{public}d", + sessionID, streamUsage, deviceType); + if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { + // select media default output device + auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), + [&sessionID](const std::pair &mediaDefaultOutputDevice) { + return mediaDefaultOutputDevice.first == sessionID; + }); + if (it != mediaDefaultOutputDevices_.end()) { + mediaDefaultOutputDevices_.erase(it); + } + mediaDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + if (selectedMediaDefaultOutputDevice_ != deviceType) { + AUDIO_INFO_LOG("media default output device changes from %{public}d to %{public}d", + selectedMediaDefaultOutputDevice_, deviceType); + selectedMediaDefaultOutputDevice_ = deviceType; + return NEED_TO_FETCH; + } + } else if (streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION || + streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { + // select call default output device + auto it = std::find_if(callDefaultOutputDevices_.begin(), callDefaultOutputDevices_.end(), + [&sessionID](const std::pair &callDefaultOutputDevice) { + return callDefaultOutputDevice.first == sessionID; + }); + if (it != callDefaultOutputDevices_.end()) { + callDefaultOutputDevices_.erase(it); + } + callDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + if (selectedCallDefaultOutputDevice_ != deviceType) { + AUDIO_INFO_LOG("call default output device changes from %{public}d to %{public}d", + selectedCallDefaultOutputDevice_, deviceType); + selectedCallDefaultOutputDevice_ = deviceType; + return NEED_TO_FETCH; + } + } else { + AUDIO_ERR_LOG("Invalid stream usage %{public}d", streamUsage); + return ERROR; + } + return SUCCESS; +} + +int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStarting(const uint32_t sessionID) +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + if (!selectedDefaultOutputDeviceInfo_.count(sessionID)) { + AUDIO_DEBUG_LOG("no need to update default output device since current stream has not set"); + return SUCCESS; + } + StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].first; + DeviceType deviceType = selectedDefaultOutputDeviceInfo_[sessionID].second; + if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { + // select media default output device + auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), + [&sessionID](const std::pair &mediaDefaultOutputDevice) { + return mediaDefaultOutputDevice.first == sessionID; + }); + if (it != mediaDefaultOutputDevices_.end()) { + mediaDefaultOutputDevices_.erase(it); + } + mediaDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because media stream %{public}u starts", + selectedMediaDefaultOutputDevice_, deviceType, sessionID); + selectedMediaDefaultOutputDevice_ = deviceType; + } else if (streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION || + streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { + // select call default output device + auto it = std::find_if(callDefaultOutputDevices_.begin(), callDefaultOutputDevices_.end(), + [&sessionID](const std::pair &callDefaultOutputDevice) { + return callDefaultOutputDevice.first == sessionID; + }); + if (it != callDefaultOutputDevices_.end()) { + callDefaultOutputDevices_.erase(it); + } + callDefaultOutputDevices_.push_back(std::make_pair(sessionID, deviceType)); + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because call stream %{public}u starts", + selectedCallDefaultOutputDevice_, deviceType, sessionID); + selectedCallDefaultOutputDevice_ = deviceType; + } + return SUCCESS; +} + +int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStopping(const uint32_t sessionID) +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + if (!selectedDefaultOutputDeviceInfo_.count(sessionID)) { + AUDIO_DEBUG_LOG("no need to update default output device since current stream has not set"); + return SUCCESS; + } + StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].first; + if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { + // select media default output device + auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), + [&sessionID](const std::pair &mediaDefaultOutputDevice) { + return mediaDefaultOutputDevice.first == sessionID; + }); + if (it == mediaDefaultOutputDevices_.end()) { + return SUCCESS; + } + mediaDefaultOutputDevices_.erase(it); + DeviceType currDeviceType; + if (mediaDefaultOutputDevices_.empty()) { + currDeviceType = DEVICE_TYPE_DEFAULT; + } else { + currDeviceType = mediaDefaultOutputDevices_.back(); + } + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because media stream %{public}u stops", + selectedMediaDefaultOutputDevice_, currDeviceType, sessionID); + selectedMediaDefaultOutputDevice_ = currDeviceType; + } else if (streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION || + streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { + // select call default output device + auto it = std::find_if(callDefaultOutputDevices_.begin(), callDefaultOutputDevices_.end(), + [&sessionID](const std::pair &callDefaultOutputDevice) { + return callDefaultOutputDevice.first == sessionID; + }); + if (it == callDefaultOutputDevices_.end()) { + return SUCCESS; + } + callDefaultOutputDevices_.erase(it); + DeviceType currDeviceType; + if (callDefaultOutputDevices_.empty()) { + currDeviceType = DEVICE_TYPE_DEFAULT; + } else { + currDeviceType = callDefaultOutputDevices_.back(); + } + AUDIO_INFO_LOG("changes from %{public}d to %{public}d because call stream %{public}u stops", + selectedCallDefaultOutputDevice_, currDeviceType, sessionID); + selectedCallDefaultOutputDevice_ = currDeviceType; + } + return SUCCESS; +} + +unique_ptr AudioDeviceManager::GetSelectedMediaRenderDevice() +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + unique_ptr devDesc = nullptr; + if (selectedMediaDefaultOutputDevice_ == DEVICE_TYPE_EARPIECE) { + devDesc = make_unique(earpiece_); + } else if (selectedMediaDefaultOutputDevice_ == DEVICE_TYPE_SPEAKER) { + devDesc = make_unique(speaker_); + } + return devDesc; +} + +unique_ptr AudioDeviceManager::GetSelectedCallRenderDevice() +{ + std::lock_guard lock(selectDefaultOutputDeviceMutex_); + unique_ptr devDesc = nullptr; + if (selectedCallDefaultOutputDevice_ == DEVICE_TYPE_EARPIECE) { + devDesc = make_unique(earpiece_); + } else if (selectedCallDefaultOutputDevice_ == DEVICE_TYPE_SPEAKER) { + devDesc = make_unique(speaker_); + } + return devDesc; +} // LCOV_EXCL_STOP } } 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 8957063be7..637fce3981 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -4910,6 +4910,13 @@ int32_t AudioPolicyService::UpdateTracker(AudioMode &mode, AudioStreamChangeInfo return ret; // only update tracker in new and prepared } + if (mode == AUDIO_MODE_PLAYBACK && rendererState == RENDERER_RUNNING) { + UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); + } else if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || + rendererState == RENDERER_RELEASED || rendererState == RENDERER_PAUSED)) { + UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); + } + if (rendererState == RENDERER_RELEASED && !streamCollector_.ExistStreamForPipe(PIPE_TYPE_MULTICHANNEL)) { DynamicUnloadModule(PIPE_TYPE_MULTICHANNEL); } @@ -5041,6 +5048,8 @@ void AudioPolicyService::RegisteredTrackerClientDied(pid_t uid) { std::lock_guard deviceLock(deviceStatusUpdateSharedMutex_); + UpdateDefaultOutputDeviceWhenStopping(static_cast(uid)); + RemoveAudioCapturerMicrophoneDescriptor(static_cast(uid)); streamCollector_.RegisteredTrackerClientDied(static_cast(uid)); @@ -8467,6 +8476,26 @@ int32_t AudioPolicyService::LoadSplitModule(const std::string &splitArgs, const return openRet; } +int32_t AudioPolicyService::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, + const StreamUsage streamUsage, bool isRunning) +{ + CHECK_AND_RETURN_RET_LOG(hasEarpiece_, ERR_NOT_SUPPORTED, "the device has no earpiece"); + int32_t ret = audioDeviceManager_.SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); + if (ret == NEED_TO_FETCH) { + FetchDevice(true); + return SUCCESS; + } + return ret; +} + +void AudioPolicyService::UpdateDefaultOutputDeviceWhenStopping(int32_t uid) +{ + std::vector sessionIDSet = streamCollector_.GetAllRendererSessionIDForUID(uid); + for (const auto &sessionID : sessionIDSet) { + audioDeviceManager_.UpdateDefaultOutputDeviceWhenStopping(sessionID); + } +} + void AudioA2dpOffloadManager::OnA2dpPlayingStateChanged(const std::string &deviceAddress, int32_t playingState) { AUDIO_INFO_LOG("Current A2dpOffload MacAddr:%{public}s, incoming MacAddr:%{public}s, state:%{public}d", diff --git a/services/audio_policy/server/src/service/routers/default_router.cpp b/services/audio_policy/server/src/service/routers/default_router.cpp index 6275146a1d..b895e4e24e 100644 --- a/services/audio_policy/server/src/service/routers/default_router.cpp +++ b/services/audio_policy/server/src/service/routers/default_router.cpp @@ -25,7 +25,10 @@ namespace AudioStandard { unique_ptr DefaultRouter::GetMediaRenderDevice(StreamUsage streamUsage, int32_t clientUID) { - unique_ptr desc = AudioDeviceManager::GetAudioDeviceManager().GetRenderDefaultDevice(); + unique_ptr desc = AudioDeviceManager::GetAudioDeviceManager().GetSelectedMediaRenderDevice(); + if (desc == nullptr) { + desc = AudioDeviceManager::GetAudioDeviceManager().GetRenderDefaultDevice(); + } AUDIO_DEBUG_LOG("streamUsage %{public}d clientUID %{public}d fetch device %{public}d", streamUsage, clientUID, desc->deviceType_); return desc; @@ -33,8 +36,10 @@ unique_ptr DefaultRouter::GetMediaRenderDevice(StreamUsag unique_ptr DefaultRouter::GetCallRenderDevice(StreamUsage streamUsage, int32_t clientUID) { - unique_ptr desc = - AudioDeviceManager::GetAudioDeviceManager().GetCommRenderDefaultDevice(streamUsage); + unique_ptr desc = AudioDeviceManager::GetAudioDeviceManager().GetSelectedCallRenderDevice(); + if (desc == nullptr) { + desc = AudioDeviceManager::GetAudioDeviceManager().GetCommRenderDefaultDevice(streamUsage); + } AUDIO_DEBUG_LOG("streamUsage %{public}d clientUID %{public}d fetch device %{public}d", streamUsage, clientUID, desc->deviceType_); return desc; -- Gitee From 4306e253d11746902a280edd3d2ed5f76034fb1a Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 21:21:41 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- .../js/napi/audiorenderer/napi_audio_renderer.cpp | 2 +- frameworks/js/napi/common/napi_audio_enum.cpp | 2 +- frameworks/js/napi/common/napi_audio_enum.h | 1 + .../native/audiorenderer/src/audio_renderer.cpp | 1 + frameworks/native/ohaudio/OHAudioRenderer.cpp | 10 +++++----- frameworks/native/ohaudio/OHAudioRenderer.h | 2 +- .../kits/c/audio_renderer/native_audiorenderer.h | 3 ++- .../audio_policy/client/include/audio_policy_base.h | 2 +- .../client/src/proxy/audio_policy_proxy.cpp | 2 +- .../server/src/audio_policy_manager_stub.cpp | 1 + .../audio_policy/server/src/audio_policy_server.cpp | 2 +- .../server/src/service/audio_device_manager.cpp | 12 ++++++------ .../server/src/service/audio_policy_service.cpp | 4 ++-- 13 files changed, 24 insertions(+), 20 deletions(-) diff --git a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp index 1b32f42673..70cabb770d 100644 --- a/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp +++ b/frameworks/js/napi/audiorenderer/napi_audio_renderer.cpp @@ -1586,7 +1586,7 @@ napi_value NapiAudioRenderer::SetDefaultOutputDevice(napi_env env, napi_callback int32_t deviceType; NapiParamUtils::GetValueInt32(env, deviceType, argv[PARAM0]); - CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentOutputDeviceType(deviceType), + CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentDefaultOutputDeviceType(deviceType), NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM, "parameter verification failed: The param of mode must be enum deviceType"), "unsupport params"); diff --git a/frameworks/js/napi/common/napi_audio_enum.cpp b/frameworks/js/napi/common/napi_audio_enum.cpp index e56ae78c79..62d95bf584 100644 --- a/frameworks/js/napi/common/napi_audio_enum.cpp +++ b/frameworks/js/napi/common/napi_audio_enum.cpp @@ -1198,7 +1198,7 @@ bool NapiAudioEnum::IsLegalInputArgumentDeviceType(int32_t deviceType) return result; } -bool NapiAudioEnum::IsLegalInputArgumentOutputDeviceType(int32_t deviceType) +bool NapiAudioEnum::IsLegalInputArgumentDefaultOutputDeviceType(int32_t deviceType) { bool result = false; switch (deviceType) { diff --git a/frameworks/js/napi/common/napi_audio_enum.h b/frameworks/js/napi/common/napi_audio_enum.h index 51bd98a34b..f017670676 100644 --- a/frameworks/js/napi/common/napi_audio_enum.h +++ b/frameworks/js/napi/common/napi_audio_enum.h @@ -95,6 +95,7 @@ public: static bool IsLegalInputArgumentRingMode(int32_t ringMode); static bool IsLegalInputArgumentVolumeAdjustType(int32_t adjustType); static bool IsLegalInputArgumentDeviceType(int32_t deviceType); + static bool IsLegalInputArgumentDefaultOutputDeviceType(int32_t deviceType); static bool IsLegalInputArgumentDeviceFlag(int32_t deviceFlag); static bool IsLegalInputArgumentActiveDeviceType(int32_t activeDeviceFlag); static int32_t GetJsAudioVolumeType(AudioStreamType volumeType); diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index 0250c0decf..3ef2ea5d7d 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -1856,6 +1856,7 @@ int32_t AudioRendererPrivate::SetDefaultOutputDevice(DeviceType deviceType) int32_t ret = AudioPolicyManager::GetInstance().SetDefaultOutputDevice(deviceType, sessionID_, rendererInfo_.streamUsage, GetStatus() == RENDERER_RUNNING); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "select default output device failed"); + return SUCCESS; } } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.cpp b/frameworks/native/ohaudio/OHAudioRenderer.cpp index 1fb6cc2d02..ef70cdebd4 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.cpp +++ b/frameworks/native/ohaudio/OHAudioRenderer.cpp @@ -338,14 +338,14 @@ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( } OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice( - OH_AudioRenderer* renderer, DeviceType deviceType) + OH_AudioRenderer* renderer, OH_AudioDevice_Type deviceType) { OHOS::AudioStandard::OHAudioRenderer *audioRenderer = convertRenderer(renderer); CHECK_AND_RETURN_RET_LOG(audioRenderer != nullptr, AUDIOSTREAM_ERROR_INVALID_PARAM, "convert renderer failed"); - bool result = (deviceType == DEVICE_TYPE_EARPIECE || deviceType == DEVICE_TYPE_SPEAKER || - deviceType == DEVICE_TYPE_DEFAULT) ? true : false; + bool result = (deviceType == AUDIO_DEVICE_TYPE_EARPIECE || deviceType == AUDIO_DEVICE_TYPE_SPEAKER || + deviceType == AUDIO_DEVICE_TYPE_DEFAULT) ? true : false; CHECK_AND_RETURN_RET_LOG(result != true, AUDIOSTREAM_ERROR_ILLEGAL_STATE, "unsupport params"); - int32_t ret = audioRenderer->SetDefaultOutputDevice(deviceType); + int32_t ret = audioRenderer->SetDefaultOutputDevice((OHOS::AudioStandard::DeviceType)deviceType); CHECK_AND_RETURN_RET_LOG(ret != AUDIOSTREAM_SUCCESS, AUDIOSTREAM_ERROR_INVALID_PARAM, "err illegal state"); return AUDIOSTREAM_SUCCESS; } @@ -798,7 +798,7 @@ bool OHAudioRenderer::GetSilentModeAndMixWithOthers() int32_t OHAudioRenderer::SetDefaultOutputDevice(DeviceType deviceType) { - CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "renderer client is nullptr"); + CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, ERROR, "renderer client is nullptr"); return audioRenderer_->SetDefaultOutputDevice(deviceType); } diff --git a/frameworks/native/ohaudio/OHAudioRenderer.h b/frameworks/native/ohaudio/OHAudioRenderer.h index c682da7fe0..325a691e09 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.h +++ b/frameworks/native/ohaudio/OHAudioRenderer.h @@ -201,7 +201,7 @@ class OHAudioRenderer { void SetInterruptMode(InterruptMode mode); void SetSilentModeAndMixWithOthers(bool on); bool GetSilentModeAndMixWithOthers(); - void SetDefaultOutputDevice(DeviceType deviceType); + int32_t SetDefaultOutputDevice(DeviceType deviceType); void SetRendererCallbackType(WriteDataCallbackType writeDataCallbackType); WriteDataCallbackType GetRendererCallbackType(); diff --git a/interfaces/kits/c/audio_renderer/native_audiorenderer.h b/interfaces/kits/c/audio_renderer/native_audiorenderer.h index 586fd45416..7cae213b6e 100644 --- a/interfaces/kits/c/audio_renderer/native_audiorenderer.h +++ b/interfaces/kits/c/audio_renderer/native_audiorenderer.h @@ -40,6 +40,7 @@ #include #include "native_audiostream_base.h" +#include "native_audio_device_base.h" #include "multimedia/native_audio_channel_layout.h" #ifdef __cplusplus extern "C" { @@ -403,7 +404,7 @@ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. */ OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice( - OH_AudioRenderer* renderer, DeviceType devicetype); + OH_AudioRenderer* renderer, OH_AudioDevice_Type devicetype); #ifdef __cplusplus } #endif diff --git a/services/audio_policy/client/include/audio_policy_base.h b/services/audio_policy/client/include/audio_policy_base.h index 523caa71cd..1c49aec0db 100644 --- a/services/audio_policy/client/include/audio_policy_base.h +++ b/services/audio_policy/client/include/audio_policy_base.h @@ -331,7 +331,7 @@ public: virtual int32_t LoadSplitModule(const std::string &splitArgs, const std::string &networkId) = 0; virtual int32_t SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, - const StreamUsage streamUsage, bool isRunning); + const StreamUsage streamUsage, bool isRunning) = 0; public: DECLARE_INTERFACE_DESCRIPTOR(u"IAudioPolicy"); diff --git a/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp b/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp index aa85faba59..4b007473c0 100644 --- a/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp +++ b/services/audio_policy/client/src/proxy/audio_policy_proxy.cpp @@ -1865,7 +1865,7 @@ int32_t AudioPolicyProxy::SetDefaultOutputDevice(const DeviceType deviceType, co bool ret = data.WriteInterfaceToken(GetDescriptor()); CHECK_AND_RETURN_RET_LOG(ret, -1, "WriteInterfaceToken failed"); data.WriteInt32(static_cast(deviceType)); - data.WriteUint32(sessionId); + data.WriteUint32(sessionID); data.WriteInt32(static_cast(streamUsage)); data.WriteBool(isRunning); 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 14cae2c3af..3d12ef969c 100644 --- a/services/audio_policy/server/src/audio_policy_manager_stub.cpp +++ b/services/audio_policy/server/src/audio_policy_manager_stub.cpp @@ -163,6 +163,7 @@ const char *g_audioPolicyCodeStrs[] = { "DEACTIVATE_AUDIO_SESSION", "IS_AUDIO_SESSION_ACTIVATED", "LOAD_SPLIT_MODULE", + "SET_DEFAULT_OUTPUT_DEVICE", }; constexpr size_t codeNums = sizeof(g_audioPolicyCodeStrs) / sizeof(const char *); diff --git a/services/audio_policy/server/src/audio_policy_server.cpp b/services/audio_policy/server/src/audio_policy_server.cpp index 71ab66e7a7..fad7203740 100644 --- a/services/audio_policy/server/src/audio_policy_server.cpp +++ b/services/audio_policy/server/src/audio_policy_server.cpp @@ -2835,7 +2835,7 @@ int32_t AudioPolicyServer::LoadSplitModule(const std::string &splitArgs, const s return audioPolicyService_.LoadSplitModule(splitArgs, networkId); } -bool AudioPolicyServer::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, +int32_t AudioPolicyServer::SetDefaultOutputDevice(const DeviceType deviceType, const uint32_t sessionID, const StreamUsage streamUsage, bool isRunning) { return audioPolicyService_.SetDefaultOutputDevice(deviceType, sessionID, streamUsage, isRunning); diff --git a/services/audio_policy/server/src/service/audio_device_manager.cpp b/services/audio_policy/server/src/service/audio_device_manager.cpp index efd8f23ace..164a75b51d 100644 --- a/services/audio_policy/server/src/service/audio_device_manager.cpp +++ b/services/audio_policy/server/src/service/audio_device_manager.cpp @@ -1109,7 +1109,7 @@ int32_t AudioDeviceManager::SetDefaultOutputDevice(const DeviceType deviceType, const StreamUsage streamUsage, bool isRunning) { std::lock_guard lock(selectDefaultOutputDeviceMutex_); - selectedDefaultOutputDeviceInfo_[sessionID] = std::make_pair(streamUsage, deviceType); + selectedDefaultOutputDeviceInfo_[sessionID] = std::make_pair(deviceType, streamUsage); if (!isRunning) { AUDIO_INFO_LOG("no need to set default output device since current stream has not started"); return SUCCESS; @@ -1163,8 +1163,8 @@ int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStarting(const uint32_t AUDIO_DEBUG_LOG("no need to update default output device since current stream has not set"); return SUCCESS; } - StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].first; - DeviceType deviceType = selectedDefaultOutputDeviceInfo_[sessionID].second; + DeviceType deviceType = selectedDefaultOutputDeviceInfo_[sessionID].first; + StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].second; if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { // select media default output device auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), @@ -1203,7 +1203,7 @@ int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStopping(const uint32_t AUDIO_DEBUG_LOG("no need to update default output device since current stream has not set"); return SUCCESS; } - StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].first; + StreamUsage streamUsage = selectedDefaultOutputDeviceInfo_[sessionID].second; if (streamUsage == STREAM_USAGE_VOICE_MESSAGE) { // select media default output device auto it = std::find_if(mediaDefaultOutputDevices_.begin(), mediaDefaultOutputDevices_.end(), @@ -1218,7 +1218,7 @@ int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStopping(const uint32_t if (mediaDefaultOutputDevices_.empty()) { currDeviceType = DEVICE_TYPE_DEFAULT; } else { - currDeviceType = mediaDefaultOutputDevices_.back(); + currDeviceType = mediaDefaultOutputDevices_.back().second; } AUDIO_INFO_LOG("changes from %{public}d to %{public}d because media stream %{public}u stops", selectedMediaDefaultOutputDevice_, currDeviceType, sessionID); @@ -1238,7 +1238,7 @@ int32_t AudioDeviceManager::UpdateDefaultOutputDeviceWhenStopping(const uint32_t if (callDefaultOutputDevices_.empty()) { currDeviceType = DEVICE_TYPE_DEFAULT; } else { - currDeviceType = callDefaultOutputDevices_.back(); + currDeviceType = callDefaultOutputDevices_.back().second; } AUDIO_INFO_LOG("changes from %{public}d to %{public}d because call stream %{public}u stops", selectedCallDefaultOutputDevice_, currDeviceType, sessionID); 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 637fce3981..f2c50b4d2e 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -4911,10 +4911,10 @@ int32_t AudioPolicyService::UpdateTracker(AudioMode &mode, AudioStreamChangeInfo } if (mode == AUDIO_MODE_PLAYBACK && rendererState == RENDERER_RUNNING) { - UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); + audioPolicyManager_.UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); } else if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || rendererState == RENDERER_RELEASED || rendererState == RENDERER_PAUSED)) { - UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); + audioPolicyManager_.UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); } if (rendererState == RENDERER_RELEASED && !streamCollector_.ExistStreamForPipe(PIPE_TYPE_MULTICHANNEL)) { -- Gitee From 0c01053d1c971dfa5126fb40ae7eb253a81c1a03 Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 21:32:22 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- .../audio_policy/server/src/service/audio_policy_service.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 f2c50b4d2e..eef4bb0751 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -4911,10 +4911,10 @@ int32_t AudioPolicyService::UpdateTracker(AudioMode &mode, AudioStreamChangeInfo } if (mode == AUDIO_MODE_PLAYBACK && rendererState == RENDERER_RUNNING) { - audioPolicyManager_.UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); + audioDeviceManager_.UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); } else if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || rendererState == RENDERER_RELEASED || rendererState == RENDERER_PAUSED)) { - audioPolicyManager_.UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); + audioDeviceManager_.UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); } if (rendererState == RENDERER_RELEASED && !streamCollector_.ExistStreamForPipe(PIPE_TYPE_MULTICHANNEL)) { -- Gitee From 2bffd2f8571e8a9ebe32bd75b455ca7212de17e7 Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 21:34:55 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- interfaces/kits/c/audio_renderer/native_audiorenderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/c/audio_renderer/native_audiorenderer.h b/interfaces/kits/c/audio_renderer/native_audiorenderer.h index 7cae213b6e..e80a18f179 100644 --- a/interfaces/kits/c/audio_renderer/native_audiorenderer.h +++ b/interfaces/kits/c/audio_renderer/native_audiorenderer.h @@ -393,7 +393,7 @@ OH_AudioStream_Result OH_AudioRenderer_GetSilentModeAndMixWithOthers( * This function can only apply on audiorenderers whose streamUsage is * STREAM_USAGE_VOICE_COMMUNICATION/STREAM_USAGE_VIDEO_COMMUNICATION/STREAM_USAGE_VOICE_MESSAGE * Setting the device will only take effect if no other accessory such as headphones are in use - * + * * @since 13 * * @param renderer Renderer generated by OH_AudioStreamBuilder_GenerateRenderer() -- Gitee From 6d373b6869f05189f25854aade2ab7502549868b Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 22:06:59 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- .../server/src/service/audio_policy_service.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) 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 eef4bb0751..f5da24db6d 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -4910,18 +4910,13 @@ int32_t AudioPolicyService::UpdateTracker(AudioMode &mode, AudioStreamChangeInfo return ret; // only update tracker in new and prepared } - if (mode == AUDIO_MODE_PLAYBACK && rendererState == RENDERER_RUNNING) { - audioDeviceManager_.UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); - } else if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || - rendererState == RENDERER_RELEASED || rendererState == RENDERER_PAUSED)) { - audioDeviceManager_.UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); - } - if (rendererState == RENDERER_RELEASED && !streamCollector_.ExistStreamForPipe(PIPE_TYPE_MULTICHANNEL)) { DynamicUnloadModule(PIPE_TYPE_MULTICHANNEL); } - if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || rendererState == RENDERER_PAUSED)) { + if (mode == AUDIO_MODE_PLAYBACK && (rendererState == RENDERER_STOPPED || rendererState == RENDERER_PAUSED || + rendererState == RENDERER_RELEASED)) { + audioDeviceManager_.UpdateDefaultOutputDeviceWhenStopping(streamChangeInfo.audioRendererChangeInfo.sessionId); FetchDevice(true); } @@ -4970,6 +4965,8 @@ void AudioPolicyService::FetchOutputDeviceForTrack(AudioStreamChangeInfo &stream make_unique(streamChangeInfo.audioRendererChangeInfo)); streamCollector_.GetRendererStreamInfo(streamChangeInfo, *rendererChangeInfo[0]); + audioDeviceManager_.UpdateDefaultOutputDeviceWhenStarting(streamChangeInfo.audioRendererChangeInfo.sessionId); + FetchOutputDevice(rendererChangeInfo, reason); } -- Gitee From 3f5fc3d9c0ef739f23d17ddcc0c098187bd593f8 Mon Sep 17 00:00:00 2001 From: Wang Chongteng Date: Sat, 24 Aug 2024 22:10:35 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wang Chongteng --- .../audio_policy/server/src/service/audio_policy_service.cpp | 1 + 1 file changed, 1 insertion(+) 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 f5da24db6d..cf7e438af2 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -8491,6 +8491,7 @@ void AudioPolicyService::UpdateDefaultOutputDeviceWhenStopping(int32_t uid) for (const auto &sessionID : sessionIDSet) { audioDeviceManager_.UpdateDefaultOutputDeviceWhenStopping(sessionID); } + FetchDevice(true); } void AudioA2dpOffloadManager::OnA2dpPlayingStateChanged(const std::string &deviceAddress, int32_t playingState) -- Gitee