diff --git a/frameworks/js/napi/audiomanager/napi_audio_session_manager.cpp b/frameworks/js/napi/audiomanager/napi_audio_session_manager.cpp index 48cdcd983bfb5afeb0cc69d0a7e5983449fe807c..ecd97854a750b348e83438d0b1c6e59b8a6bd1ea 100644 --- a/frameworks/js/napi/audiomanager/napi_audio_session_manager.cpp +++ b/frameworks/js/napi/audiomanager/napi_audio_session_manager.cpp @@ -95,6 +95,10 @@ napi_value NapiAudioSessionMgr::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("setAudioSessionScene", SetAudioSessionScene), DECLARE_NAPI_FUNCTION("getDefaultOutputDevice", GetDefaultOutputDevice), DECLARE_NAPI_FUNCTION("setDefaultOutputDevice", SetDefaultOutputDevice), + DECLARE_NAPI_FUNCTION("getAvailableDevices", GetAvailableDevices), + DECLARE_NAPI_FUNCTION("selectMediaInputDevice", SelectMediaInputDevice), + DECLARE_NAPI_FUNCTION("getSelectedMediaInputDevice", GetSelectedMediaInputDevice), + DECLARE_NAPI_FUNCTION("clearSelectedMediaInputDevice", ClearSelectedMediaInputDevice), }; status = napi_define_class(env, AUDIO_SESSION_MGR_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr, @@ -658,6 +662,141 @@ napi_value NapiAudioSessionMgr::Off(napi_env env, napi_callback_info info) return undefinedResult; } +napi_value NapiAudioSessionMgr::SelectMediaInputDevice(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + if (context == nullptr) { + AUDIO_ERR_LOG("ActivateAudioSession failed : no memory"); + NapiAudioError::ThrowError(env, "ActivateAudioSession failed : no memory", NAPI_ERR_NO_MEMORY); + return NapiParamUtils::GetUndefinedValue(env); + } + + auto inputParser = [env, context](size_t argc, napi_value *argv) { + NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments", + NAPI_ERR_INVALID_PARAM); + NapiParamUtils::GetAudioDeviceDescriptor(env, context->deviceDescriptor, + context->bArgTransFlag, argv[PARAM0]); + }; + context->GetCbInfo(env, info, inputParser); + + auto executor = [context]() { + CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiSessionMgr = objectGuard.GetPtr(); + CHECK_AND_RETURN_LOG(CheckAudioSessionStatus(napiSessionMgr, context), + "context object state is error."); + if (!context->bArgTransFlag) { + context->SignError(NAPI_ERR_INVALID_PARAM); + } + context->intValue = napiSessionMgr->audioSessionMngr_->SelectInputDevice(context->deviceDescriptor); + NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SelectInputDevice failed", + NAPI_ERR_SYSTEM); + }; + auto complete = [env](napi_value &output) { + output = NapiParamUtils::GetUndefinedValue(env); + }; + return NapiAsyncWork::Enqueue(env, context, "SelectInputDevice", executor, complete); +} + +napi_value NapiAudioSessionMgr::GetAvailableDevices(napi_env env, napi_callback_info info) +{ + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value argv[ARGS_ONE] = {}; + auto *napiSessionMgr = 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 invalid"); + + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, argv[PARAM0], &valueType); + CHECK_AND_RETURN_RET_LOG(status == napi_ok && valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceUsage must be number"), + "valueType invalid"); + + int32_t intValue = 0; + status = napi_get_value_int32(env, argv[PARAM0], &intValue); + CHECK_AND_RETURN_RET_LOG(status == napi_ok && NapiAudioEnum::IsLegalDeviceUsage(intValue), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM, + "parameter verification failed: The param of deviceUsage must be enum DeviceUsage"), "invalid deviceusage"); + + CHECK_AND_RETURN_RET_LOG(napiSessionMgr != nullptr, result, "napiSessionMgr is nullptr"); + CHECK_AND_RETURN_RET_LOG(napiSessionMgr->audioSessionMngr_ != nullptr, result, + "audioSessionMngr_ is nullptr"); + AudioDeviceUsage usage = static_cast(intValue); + + std::vector> availableDescs = + napiSessionMgr->audioSessionMngr_->GetAvailableDevices(usage); + + std::vector> availableSptrDescs; + for (const auto &availableDesc : availableDescs) { + std::shared_ptr dec = std::make_shared(*availableDesc); + CHECK_AND_BREAK_LOG(dec != nullptr, "dec mallac failed,no memery."); + if (availableDesc->deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP_IN) { + dec->deviceType_ = DEVICE_TYPE_BLUETOOTH_SCO; + } + availableSptrDescs.push_back(dec); + } + NapiParamUtils::SetDeviceDescriptors(env, availableSptrDescs, result); + return result; +} + +napi_value NapiAudioSessionMgr::GetSelectedMediaInputDevice(napi_env env, napi_callback_info info) +{ + napi_value result = nullptr; + size_t argc = PARAM0; + auto *napiSessionMgr = GetParamWithSync(env, info, argc, nullptr); + CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "argcCount invalid"), "argcCount invalid"); + + CHECK_AND_RETURN_RET_LOG(napiSessionMgr != nullptr, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "can not get session"), "napiSessionMgr is nullptr"); + CHECK_AND_RETURN_RET_LOG(napiSessionMgr->audioSessionMngr_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "can not get session"), "audioSessionMngr_ is nullptr"); + + std::shared_ptr descriptor = napiSessionMgr->audioSessionMngr_->GetSelectedInputDevice(); + if (descriptor == nullptr) { + AUDIO_ERR_LOG("GetSelectedMediaInputDevice Failed"); + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE, "get selected input device error"); + return result; + } + NapiParamUtils::SetDeviceDescriptor(env, descriptor, result); + return result; +} + +napi_value NapiAudioSessionMgr::ClearSelectedMediaInputDevice(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + if (context == nullptr) { + AUDIO_ERR_LOG("ClearSelectedMediaInputDevice failed : no memory"); + NapiAudioError::ThrowError(env, "ClearSelectedMediaInputDevice failed : no memory", + NAPI_ERR_NO_MEMORY); + return NapiParamUtils::GetUndefinedValue(env); + } + context->GetCbInfo(env, info); + + auto executor = [context]() { + CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error."); + auto obj = reinterpret_cast(context->native); + ObjectRefMap objectGuard(obj); + auto *napiSessionMgr = objectGuard.GetPtr(); + if (napiSessionMgr == nullptr || napiSessionMgr->audioSessionMngr_ == nullptr) { + context->SignError(NAPI_ERR_SYSTEM, "System error. Internal variable exception."); + AUDIO_ERR_LOG("The napiSessionMgr or audioSessionMngr is nullptr"); + return; + } + context->intValue = napiSessionMgr->audioSessionMngr_->ClearSelectedInputDevice(); + if (context->intValue != SUCCESS) { + context->SignError(NAPI_ERR_SYSTEM, "System error. Set app volume fail."); + } + }; + + auto complete = [env, context](napi_value &output) { + output = NapiParamUtils::GetUndefinedValue(env); + }; + return NapiAsyncWork::Enqueue(env, context, "ClearSelectedMediaInputDevice", executor, complete); +} + napi_value NapiAudioSessionMgr::SetAudioSessionScene(napi_env env, napi_callback_info info) { napi_value result = nullptr; diff --git a/frameworks/js/napi/audiomanager/napi_audio_session_manager.h b/frameworks/js/napi/audiomanager/napi_audio_session_manager.h index 18f3fc3ccc59088d6599570a64795bfc18ca6a02..22090dd27a2d7ca3dd073fcfcc94461febb791d6 100644 --- a/frameworks/js/napi/audiomanager/napi_audio_session_manager.h +++ b/frameworks/js/napi/audiomanager/napi_audio_session_manager.h @@ -48,6 +48,8 @@ private: NapiAudioSessionMgr *objectInfo; AudioSessionStrategy audioSessionStrategy; int32_t deviceType; + std::shared_ptr deviceDescriptor; + bool bArgTransFlag = false; }; static napi_value Construct(napi_env env, napi_callback_info info); @@ -86,6 +88,10 @@ private: napi_env env, napi_value jsThis, napi_value *args, size_t len); static std::shared_ptr GetAudioSessionDeviceCallback( napi_value argv, NapiAudioSessionMgr *napiSessionMgr); + static napi_value GetAvailableDevices(napi_env env, napi_callback_info info); + static napi_value SelectMediaInputDevice(napi_env env, napi_callback_info info); + static napi_value GetSelectedMediaInputDevice(napi_env env, napi_callback_info info); + static napi_value ClearSelectedMediaInputDevice(napi_env env, napi_callback_info info); napi_env env_; AudioSessionManager *audioSessionMngr_; diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index e7ed0c67730d907be41eef9c354c8eca5d86f9dd..6a6132a2911fbcd6ee751413922a9851b79720dc 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -116,6 +116,8 @@ public: int32_t SelectInputDevice(sptr audioCapturerFilter, std::vector> audioDeviceDescriptors); + int32_t SelectInputDevice(std::shared_ptr &audioDeviceDescriptor); + int32_t ExcludeOutputDevices(AudioDeviceUsage audioDevUsage, std::vector> &audioDeviceDescriptors); @@ -414,6 +416,10 @@ public: std::vector> GetAvailableDevices(AudioDeviceUsage usage); + std::shared_ptr GetSelectedInputDevice(); + + int32_t ClearSelectedInputDevice(); + int32_t SetAvailableDeviceChangeCallback(const int32_t clientId, const AudioDeviceUsage usage, const std::shared_ptr& callback); diff --git a/interfaces/inner_api/native/audiomanager/include/audio_session_manager.h b/interfaces/inner_api/native/audiomanager/include/audio_session_manager.h index f16f5c72f14d8676c7fcb87e46c70857011f43a9..ee19f972a44db62f84c60546877336641d203677 100644 --- a/interfaces/inner_api/native/audiomanager/include/audio_session_manager.h +++ b/interfaces/inner_api/native/audiomanager/include/audio_session_manager.h @@ -16,6 +16,7 @@ #ifndef ST_AUDIO_SESSION_MANAGER_H #define ST_AUDIO_SESSION_MANAGER_H +#include "audio_device_descriptor.h" #include "audio_system_manager.h" #include "audio_session_device_info.h" @@ -274,6 +275,42 @@ public: */ void OnAudioSessionStateChanged(const AudioSessionStateChangedEvent &stateChangedEvent); + /** + * @brief Obtains all the available audio devices with a specific device usage. + * + * @param deviceUsage. Audio device usage. + * @return Returns AudioDeviceDescriptor vector + * @since 21 + */ + std::vector> GetAvailableDevices(AudioDeviceUsage usage); + + /** + * @brief Select an audio device. + * + * @param audioDeviceDescriptor. Audio device descriptor. + * @return Returns {@link SUCCESS} if callback registration is successful; returns an error code + * defined in {@link audio_errors.h} otherwise. + * @since 21 + */ + int32_t SelectInputDevice(std::shared_ptr audioDeviceDescriptor); + + /** + * @brief Get selected audio device. + * + * @return Returns AudioDeviceDescriptor + * @since 21 + */ + std::shared_ptr GetSelectedInputDevice(); + + /** + * @brief Clear selected audio device. + * + * @return Returns {@link SUCCESS} if callback registration is successful; returns an error code + * defined in {@link audio_errors.h} otherwise. + * @since 21 + */ + int32_t ClearSelectedInputDevice(); + private: std::mutex setDefaultOutputDeviceMutex_; bool setDefaultOutputDevice_ = false; diff --git a/services/audio_policy/BUILD.gn b/services/audio_policy/BUILD.gn index cba57a80c58d5c6f4b201f02a21f336e3ce79102..0527f33b043764789f262fc4c901cb554e526bf8 100644 --- a/services/audio_policy/BUILD.gn +++ b/services/audio_policy/BUILD.gn @@ -215,6 +215,7 @@ audio_ohos_library("audio_policy_service") { "server/domain/pipe/src/audio_global_config_manager.cpp", "server/service/service_main/src/audio_policy_service.cpp", "server/domain/device/src/audio_state_manager.cpp", + "server/domain/device/src/audio_usr_select_manager.cpp", "server/domain/pipe/src/audio_concurrency_service.cpp", "server/service/service_main/src/device_init_callback.cpp", "server/src/audio_client_tracker_callback_service.cpp", diff --git a/services/audio_policy/client/service/src/audio_policy_manager_device.cpp b/services/audio_policy/client/service/src/audio_policy_manager_device.cpp index 09dcfb30f0621e10b5e557288ffa778dadc0c573..93059dc0b2a339e6a0daffbca753ca4de4dd13de 100644 --- a/services/audio_policy/client/service/src/audio_policy_manager_device.cpp +++ b/services/audio_policy/client/service/src/audio_policy_manager_device.cpp @@ -68,6 +68,15 @@ int32_t AudioPolicyManager::SelectInputDevice(sptr audioCap return gsp->SelectInputDevice(audioCapturerFilter, audioDeviceDescriptors); } +int32_t AudioPolicyManager::SelectInputDevice(std::shared_ptr &audioDeviceDescriptor) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, -1, "audio policy manager proxy is NULL."); + CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor != nullptr, -1, + "SelectInputDevice get null device."); + return gsp->SelectInputDevice(audioDeviceDescriptor); +} + int32_t AudioPolicyManager::ExcludeOutputDevices(AudioDeviceUsage audioDevUsage, std::vector> &audioDeviceDescriptors) { @@ -433,6 +442,24 @@ std::vector> AudioPolicyManager::GetAvail return descs; } +std::shared_ptr AudioPolicyManager::GetSelectedInputDevice() +{ + std::shared_ptr descriptor = + std::make_shared(AudioDeviceDescriptor::DEVICE_INFO); + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, descriptor, "audio policy manager proxy is NULL."); + + gsp->GetSelectedInputDevice(descriptor); + return descriptor; +} + +int32_t AudioPolicyManager::ClearSelectedInputDevice() +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR, "audio policy manager proxy is NULL."); + return gsp->ClearSelectedInputDevice(); +} + int32_t AudioPolicyManager::SetAvailableDeviceChangeCallback(const int32_t clientId, const AudioDeviceUsage usage, const std::shared_ptr& callback) { diff --git a/services/audio_policy/idl/IAudioPolicy.idl b/services/audio_policy/idl/IAudioPolicy.idl index 62b3c23018eb9ba89cac21d24f5bc75efa4539c4..02143cb5dd2aac532738561175246bd5f745b7d2 100644 --- a/services/audio_policy/idl/IAudioPolicy.idl +++ b/services/audio_policy/idl/IAudioPolicy.idl @@ -109,6 +109,7 @@ interface IAudioPolicy { void SelectOutputDevice([in] sptr audioRendererFilter, [in] List> audioDeviceDescriptors); void GetSelectedDeviceInfo([in] int uid, [in] int pid, [in] int streamType, [out] String retStr); void SelectInputDevice([in] sptr audioCapturerFilter, [in] List> audioDeviceDescriptors); + void SelectInputDevice([in] sharedptr audioDeviceDescriptor); void GetPreferredOutputStreamType([in] AudioRendererInfo rendererInfo, [out] int streamType); void GetPreferredInputStreamType([in] AudioCapturerInfo capturerInfo, [out] int streamType); void CreateRendererClient([in] sharedptr streamDesc, [out] unsigned int flag, [inout] unsigned int sessionId, [out] String networkId); @@ -148,6 +149,8 @@ interface IAudioPolicy { void SetA2dpDeviceVolume([in] String macAddress, [in] int volume, [in] boolean updateUi); void SetNearlinkDeviceVolume([in] String macAddress, [in] int volumeType, [in] int volume, [in] boolean updateUi); void GetAvailableDevices([in] int usage, [out] List> retDeviceList); + void GetSelectedInputDevice([out] sharedptr audioDeviceDescriptor); + void ClearSelectedInputDevice(); void SetAvailableDeviceChangeCallback([in] int clientId, [in] int usage, [in] IRemoteObject object); void UnsetAvailableDeviceChangeCallback([in] int clientId, [in] int usage); void IsSpatializationEnabled([out] boolean ret); diff --git a/services/audio_policy/server/domain/device/include/audio_usr_select_manager.h b/services/audio_policy/server/domain/device/include/audio_usr_select_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..115bbdf1f2c31eaa7def3290b0663bca57d4fac2 --- /dev/null +++ b/services/audio_policy/server/domain/device/include/audio_usr_select_manager.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ST_AUDIO_USR_SELECT_MANAGER_H +#define ST_AUDIO_USR_SELECT_MANAGER_H + +#include "audio_system_manager.h" + +#include "ipc_skeleton.h" + +#include +#include +#include + +namespace OHOS { +namespace AudioStandard { +typedef std::shared_ptr AudioDevicePtr; +typedef std::deque AudioDeviceList; + +class AudioUsrSelectManager { +public: + static AudioUsrSelectManager& GetAudioUsrSelectManager() + { + static AudioUsrSelectManager audioUsrSelectManager; + return audioUsrSelectManager; + } + + // Set media render device selected by the user + void SelectInputDeviceByUid(const std::shared_ptr &deviceDescriptor, int32_t uid); + std::shared_ptr GetSelectedInputDeviceByUid(int32_t uid); + void ClearSelectedInputDeviceByUid(int32_t uid); + +private: + AudioUsrSelectManager() {}; + ~AudioUsrSelectManager() {}; + + std::unordered_map audioUsrSelectMap_; + std::mutex mutex_; +}; + +} // namespace AudioStandard +} // namespace OHOS +#endif // ST_AUDIO_USR_SELECT_MANAGER_H diff --git a/services/audio_policy/server/domain/device/src/audio_usr_select_manager.cpp b/services/audio_policy/server/domain/device/src/audio_usr_select_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14478e44de1dbc504e6d59864b1514e23574abeb --- /dev/null +++ b/services/audio_policy/server/domain/device/src/audio_usr_select_manager.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LOG_TAG +#define LOG_TAG "AudioUsrSelectManager" +#endif + +#include "audio_usr_select_manager.h" +#include "audio_policy_log.h" +#include "audio_utils.h" + +namespace OHOS { +namespace AudioStandard { + +void AudioUsrSelectManager::SelectInputDeviceByUid(const std::shared_ptr &deviceDescriptor, + int32_t uid) +{ + std::lock_guard lock(mutex_); + audioUsrSelectMap_[uid].push_front(deviceDescriptor); +} + +std::shared_ptr AudioUsrSelectManager::GetSelectedInputDeviceByUid(int32_t uid) +{ + std::lock_guard lock(mutex_); + AudioDeviceList descriptors = audioUsrSelectMap_[uid]; + std::shared_ptr descriptor; + if (descriptors.size() > 0) { + descriptor = descriptors.front(); + } else { + descriptor = std::make_shared(AudioDeviceDescriptor::DEVICE_INFO); + } + return descriptor; +} + +void AudioUsrSelectManager::ClearSelectedInputDeviceByUid(int32_t uid) +{ + std::lock_guard lock(mutex_); + audioUsrSelectMap_[uid].clear(); +} +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/include/audio_core_service.h b/services/audio_policy/server/service/service_main/include/audio_core_service.h index dd623410ae7fcf7945c1669b96ddf39a4615f859..7a02e226b5fe44ae75247d590246272dd590f769 100644 --- a/services/audio_policy/server/service/service_main/include/audio_core_service.h +++ b/services/audio_policy/server/service/service_main/include/audio_core_service.h @@ -26,6 +26,7 @@ #include "audio_stream_change_info.h" #include "audio_active_device.h" #include "audio_scene_manager.h" +#include "audio_usr_select_manager.h" #include "audio_volume_manager.h" #include "audio_capturer_session.h" #include "audio_device_manager.h" @@ -131,6 +132,10 @@ public: std::vector> selectedDesc); int32_t SelectInputDevice(sptr audioCapturerFilter, std::vector> selectedDesc); + int32_t SelectInputDeviceByUid(const std::shared_ptr &audioDeviceDescriptor, + int32_t uid); + std::shared_ptr GetSelectedInputDeviceByUid(int32_t uid); + int32_t ClearSelectedInputDeviceByUid(int32_t uid); void NotifyRemoteRenderState(std::string networkId, std::string condition, std::string value); int32_t OnCapturerSessionAdded(uint64_t sessionID, SessionInfo sessionInfo, AudioStreamInfo streamInfo); void CloseWakeUpAudioCapturer(); @@ -244,6 +249,9 @@ private: void NotifyDistributedOutputChange(const AudioDeviceDescriptor &deviceDesc); int32_t SelectInputDevice(sptr audioCapturerFilter, std::vector> selectedDesc); + int32_t SelectInputDeviceByUid(const std::shared_ptr &selectedDesc, int32_t uid); + std::shared_ptr GetSelectedInputDeviceByUid(int32_t uid); + int32_t ClearSelectedInputDeviceByUid(int32_t uid); void NotifyRemoteRenderState(std::string networkId, std::string condition, std::string value); int32_t OnCapturerSessionAdded(uint64_t sessionID, SessionInfo sessionInfo, AudioStreamInfo streamInfo); void CloseWakeUpAudioCapturer(); @@ -522,6 +530,7 @@ private: AudioPolicyConfigManager& policyConfigMananger_; AudioAffinityManager &audioAffinityManager_; SleAudioDeviceManager &sleAudioDeviceManager_; + AudioUsrSelectManager &audioUsrSelectManager_; std::shared_ptr audioPipeSelector_; std::shared_ptr audioSessionService_ = nullptr; diff --git a/services/audio_policy/server/service/service_main/include/audio_policy_server.h b/services/audio_policy/server/service/service_main/include/audio_policy_server.h index 73b8147036197aaa4fa4c917394a89fd88f88cd9..f62d08969086fd503cad16d5d7359634b8a16d27 100644 --- a/services/audio_policy/server/service/service_main/include/audio_policy_server.h +++ b/services/audio_policy/server/service/service_main/include/audio_policy_server.h @@ -163,6 +163,12 @@ public: int32_t SelectInputDevice(const sptr &audioCapturerFilter, const std::vector> &audioDeviceDescriptors) override; + int32_t SelectInputDevice(const std::shared_ptr &audioDeviceDescriptor) override; + + int32_t GetSelectedInputDevice(std::shared_ptr &AudioDeviceDescriptor) override; + + int32_t ClearSelectedInputDevice() override; + int32_t ExcludeOutputDevices(int32_t audioDevUsage, const std::vector> &audioDeviceDescriptors) override; diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp index 060909bc5371b3fc479fb9ca95df7d99a1f34a87..50022d7cdb42b1de3f302dd2b0fd87252d8951fb 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp @@ -78,6 +78,7 @@ AudioCoreService::AudioCoreService() policyConfigMananger_(AudioPolicyConfigManager::GetInstance()), audioAffinityManager_(AudioAffinityManager::GetAudioAffinityManager()), sleAudioDeviceManager_(SleAudioDeviceManager::GetInstance()), + audioUsrSelectManager_(AudioUsrSelectManager::GetAudioUsrSelectManager()), audioPipeSelector_(AudioPipeSelector::GetPipeSelector()), audioSessionService_(AudioSessionService::GetAudioSessionService()), pipeManager_(AudioPipeManager::GetPipeManager()) @@ -1073,6 +1074,28 @@ int32_t AudioCoreService::SelectInputDevice(sptr audioCaptu return audioRecoveryDevice_.SelectInputDevice(audioCapturerFilter, selectedDesc); } +int32_t AudioCoreService::SelectInputDeviceByUid(const std::shared_ptr &selectedDesc, + int32_t uid) +{ + int32_t result = SUCCESS; + audioUsrSelectManager_.SelectInputDeviceByUid(selectedDesc, uid); + AudioScene scene = audioSceneManager_.GetAudioScene(true); + CHECK_AND_RETURN_RET(scene != AUDIO_SCENE_PHONE_CALL && scene != AUDIO_SCENE_PHONE_CHAT, result); + result = FetchInputDeviceAndRoute("SelectInputDeviceByUid"); + return result; +} + +std::shared_ptr AudioCoreService::GetSelectedInputDeviceByUid(int32_t uid) +{ + return audioUsrSelectManager_.GetSelectedInputDeviceByUid(uid); +} + +int32_t AudioCoreService::ClearSelectedInputDeviceByUid(int32_t uid) +{ + audioUsrSelectManager_.ClearSelectedInputDeviceByUid(uid); + return SUCCESS; +} + void AudioCoreService::NotifyRemoteRenderState(std::string networkId, std::string condition, std::string value) { AUDIO_INFO_LOG("device<%{public}s> condition:%{public}s value:%{public}s", diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp index c26c4486f3e42d15816f41d10be95d76289fa84b..fb5ccd1b0e2abc833d0933d5aefd497ff5ce4b3c 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp @@ -401,6 +401,28 @@ int32_t AudioCoreService::EventEntry::SelectInputDevice(sptrSelectInputDevice(audioCapturerFilter, selectedDesc); } +int32_t AudioCoreService::EventEntry::SelectInputDeviceByUid(const std::shared_ptr &descriptor, + int32_t uid) +{ + Trace trace("KeyAction AudioCoreService::SelectInputDeviceByUid"); + std::lock_guard lock(eventMutex_); + return coreService_->SelectInputDeviceByUid(descriptor, uid); +} + +std::shared_ptr AudioCoreService::EventEntry::GetSelectedInputDeviceByUid(int32_t uid) +{ + Trace trace("KeyAction AudioCoreService::GetSelectedInputDeviceByUid"); + std::lock_guard lock(eventMutex_); + return coreService_->GetSelectedInputDeviceByUid(uid); +} + +int32_t AudioCoreService::EventEntry::ClearSelectedInputDeviceByUid(int32_t uid) +{ + Trace trace("KeyAction AudioCoreService::ClearSelectedInputDeviceByUid"); + std::lock_guard lock(eventMutex_); + return coreService_->ClearSelectedInputDeviceByUid(uid); +} + int32_t AudioCoreService::EventEntry::GetCurrentRendererChangeInfos(vector> &audioRendererChangeInfos, bool hasBTPermission, bool hasSystemPermission) { diff --git a/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp b/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp index f466e82bbd03110050db30b1fa288b53439b33bf..463ea6e1417840ac4a80335b86cd9d8baca1e9ba 100644 --- a/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp @@ -1978,6 +1978,12 @@ int32_t AudioPolicyServer::SelectInputDevice(const sptr &au return ret; } +int32_t AudioPolicyServer::SelectInputDevice(const std::shared_ptr &audioDeviceDescriptor) +{ + auto callerUid = IPCSkeleton::GetCallingUid(); + return eventEntry_->SelectInputDeviceByUid(audioDeviceDescriptor, callerUid); +} + int32_t AudioPolicyServer::ExcludeOutputDevices(int32_t audioDevUsageIn, const vector> &audioDeviceDescriptors) { @@ -3315,6 +3321,7 @@ void AudioPolicyServer::RegisteredTrackerClientDied(pid_t pid, pid_t uid) audioAffinityManager_.DelSelectRendererDevice(uid); std::lock_guard lock(clientDiedListenerStateMutex_); eventEntry_->RegisteredTrackerClientDied(uid, pid); + eventEntry_->ClearSelectedInputDeviceByUid(uid); auto filter = [&pid](int val) { return pid == val; @@ -3774,6 +3781,20 @@ int32_t AudioPolicyServer::SetNearlinkDeviceVolume(const std::string &macAddress return SUCCESS; } +int32_t AudioPolicyServer::GetSelectedInputDevice(std::shared_ptr &audioDeviceDescriptor) +{ + auto callerUid = IPCSkeleton::GetCallingUid(); + audioDeviceDescriptor = eventEntry_->GetSelectedInputDeviceByUid(callerUid); + return SUCCESS; +} + +int32_t AudioPolicyServer::ClearSelectedInputDevice() +{ + auto callerUid = IPCSkeleton::GetCallingUid(); + eventEntry_->ClearSelectedInputDeviceByUid(callerUid); + return SUCCESS; +} + int32_t AudioPolicyServer::GetAvailableDevices(int32_t usageIn, std::vector> &descs) { diff --git a/services/audio_policy/test/BUILD.gn b/services/audio_policy/test/BUILD.gn index 4c5c7f08d45657fc808ec9c4176527222357e589..6f24e6b78f50fabfdae24f5d6a53635d7d6ab2b1 100644 --- a/services/audio_policy/test/BUILD.gn +++ b/services/audio_policy/test/BUILD.gn @@ -85,6 +85,7 @@ group("audio_policy_unittest_packages") { ":audio_setting_provider_unit_test", ":audio_tone_parser_unit_test", ":audio_usb_manager_unit_test", + ":audio_usr_select_manager_unit_test", ":audio_volume_manager_unit_test", ":audio_zone_service_unit_test", ":audio_zone_unit_test", @@ -4743,6 +4744,52 @@ ohos_unittest("audio_usb_manager_unit_test") { ] } +ohos_unittest("audio_usr_select_manager_unit_test") { + module_out_path = module_output_path + + include_dirs = [ + "./unittest/audio_usr_select_manager_unit_test/include", + ] + + use_exceptions = true + + cflags = [ + "-Wall", + "-Werror", + "-Wno-macro-redefined", + "-fno-access-control", + ] + + external_deps = [ + "bluetooth:btframework", + "c_utils:utils", + "data_share:datashare_common", + "data_share:datashare_consumer", + "googletest:gmock", + "hilog:libhilog", + "init:libbegetutil", + "kv_store:distributeddata_inner", + "os_account:os_account_innerkits", + "power_manager:power_setting", + "power_manager:powermgr_client", + ] + + sources = [ "./unittest/audio_usr_select_manager_unit_test/src/audio_usr_select_manager_unit_test.cpp" ] + + deps = [ + "../../../frameworks/native/audioeffect:audio_effect", + "../../../frameworks/native/audioschedule:audio_schedule", + "../../../frameworks/native/audioutils:audio_utils", + "../../../services/audio_policy:audio_policy_client", + "../../../services/audio_policy:audio_policy_service", + "../../../services/audio_service:audio_client", + "../../../services/audio_service:audio_common", + "../../../services/audio_service:audio_process_service", + "../../../services/audio_service:audio_service", + "../../audio_policy:audio_policy_service_static", + ] +} + ohos_unittest("audio_session_unit_test") { module_out_path = module_output_path diff --git a/services/audio_policy/test/unittest/audio_usr_select_manager_unit_test/include/audio_usr_select_manager_unit_test.h b/services/audio_policy/test/unittest/audio_usr_select_manager_unit_test/include/audio_usr_select_manager_unit_test.h new file mode 100644 index 0000000000000000000000000000000000000000..642b4551c042f87d3842494ab85299314d29457e --- /dev/null +++ b/services/audio_policy/test/unittest/audio_usr_select_manager_unit_test/include/audio_usr_select_manager_unit_test.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_USR_SELECT_MANAGER_UNIT_TEST_H +#define AUDIO_USR_SELECT_MANAGER_UNIT_TEST_H + +#include "gtest/gtest.h" +#include "audio_usr_select_manager.h" + +namespace OHOS { +namespace AudioStandard { + +class AudioUsrSelectManagerUnitTest : public testing::Test { +public: + // SetUpTestCase: Called before all test cases + static void SetUpTestCase(void); + // TearDownTestCase: Called after all test case + static void TearDownTestCase(void); + // SetUp: Called before each test cases + void SetUp(void); + // TearDown: Called after each test cases + void TearDown(void); +}; +} // namespace AudioStandard +} // namespace OHOS +#endif //AUDIO_USR_SELECT_MANAGER_UNIT_TEST_H \ No newline at end of file diff --git a/services/audio_policy/test/unittest/audio_usr_select_manager_unit_test/src/audio_usr_select_manager_unit_test.cpp b/services/audio_policy/test/unittest/audio_usr_select_manager_unit_test/src/audio_usr_select_manager_unit_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3709bd21f27d0f8e2a1a77c4515cecb2589faaad --- /dev/null +++ b/services/audio_policy/test/unittest/audio_usr_select_manager_unit_test/src/audio_usr_select_manager_unit_test.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_usr_select_manager_unit_test.h" +#include "audio_errors.h" +#include "audio_info.h" +#include "audio_policy_log.h" + +#include +#include +#include + +using namespace testing::ext; + +namespace OHOS { +namespace AudioStandard { + +void AudioUsrSelectManagerUnitTest::SetUpTestCase(void) {} +void AudioUsrSelectManagerUnitTest::TearDownTestCase(void) {} +void AudioUsrSelectManagerUnitTest::SetUp(void) {} +void AudioUsrSelectManagerUnitTest::TearDown(void) {} + +/** +* @tc.name : Test AudioUsrSelectManager. +* @tc.number: AudioUsrSelectManagerUnitTest_001 +* @tc.desc : Test SelectInputDeviceByUid interface. +*/ +HWTEST_F(AudioUsrSelectManagerUnitTest, AudioUsrSelectManagerUnitTest_001, TestSize.Level0) +{ + AudioUsrSelectManager &audioUsrSelectManager = AudioUsrSelectManager::GetAudioUsrSelectManager(); + std::shared_ptr desc = std::make_shared(); + int32_t uid = 123; + audioUsrSelectManager.SelectInputDeviceByUid(desc, uid); + EXPECT_EQ(audioUsrSelectManager.audioUsrSelectMap_.size(), 1); + EXPECT_EQ(audioUsrSelectManager.audioUsrSelectMap_[uid].size(), 1); +} + +/** +* @tc.name : Test AudioStateManager. +* @tc.number: AudioUsrSelectManagerUnitTest_002 +* @tc.desc : Test GetSelectedInputDeviceByUid interface. +*/ +HWTEST_F(AudioUsrSelectManagerUnitTest, AudioUsrSelectManagerUnitTest_002, TestSize.Level1) +{ + AudioUsrSelectManager &audioUsrSelectManager = AudioUsrSelectManager::GetAudioUsrSelectManager(); + std::shared_ptr desc = std::make_shared(); + desc->deviceId_ = 123; + int32_t uid = 123; + audioUsrSelectManager.SelectInputDeviceByUid(desc, uid); + + std::shared_ptr audioDeviceDescriptor = + audioUsrSelectManager.GetSelectedInputDeviceByUid(uid); + EXPECT_EQ(audioDeviceDescriptor->deviceId_, 123); +} + +/** +* @tc.name : Test AudioStateManager. +* @tc.number: AudioUsrSelectManagerUnitTest_003 +* @tc.desc : Test ClearSelectedInputDeviceByUid interface. +*/ +HWTEST_F(AudioUsrSelectManagerUnitTest, AudioUsrSelectManagerUnitTest_003, TestSize.Level1) +{ + AudioUsrSelectManager &audioUsrSelectManager = AudioUsrSelectManager::GetAudioUsrSelectManager(); + std::shared_ptr desc = std::make_shared(); + int32_t uid = 123; + audioUsrSelectManager.SelectInputDeviceByUid(desc, uid); + + audioUsrSelectManager.ClearSelectedInputDeviceByUid(uid); + EXPECT_EQ(audioUsrSelectManager.audioUsrSelectMap_.size(), 1); + EXPECT_EQ(audioUsrSelectManager.audioUsrSelectMap_[uid].size(), 1); +} +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_service/client/src/audio_session_manager.cpp b/services/audio_service/client/src/audio_session_manager.cpp index 3b242ad329bb5f5dabbdfbec9020153c9f096ca8..85546683e13afce6b62185bcc69ad74932068fe9 100644 --- a/services/audio_service/client/src/audio_session_manager.cpp +++ b/services/audio_service/client/src/audio_session_manager.cpp @@ -110,6 +110,26 @@ int32_t AudioSessionManager::SetAudioSessionScene(const AudioSessionScene audioS return result; } +std::vector> AudioSessionManager::GetAvailableDevices(AudioDeviceUsage usage) +{ + return AudioPolicyManager::GetInstance().GetAvailableDevices(usage); +} + +int32_t AudioSessionManager::SelectInputDevice(std::shared_ptr audioDeviceDescriptor) +{ + return AudioPolicyManager::GetInstance().SelectInputDevice(audioDeviceDescriptor); +} + +std::shared_ptr AudioSessionManager::GetSelectedInputDevice() +{ + return AudioPolicyManager::GetInstance().GetSelectedInputDevice(); +} + +int32_t AudioSessionManager::ClearSelectedInputDevice() +{ + return AudioPolicyManager::GetInstance().ClearSelectedInputDevice(); +} + int32_t AudioSessionManager::SetAudioSessionStateChangeCallback( const std::shared_ptr &stateChangedCallback) {