diff --git a/frameworks/cj/include/multimedia_audio_volume_manager_callback.h b/frameworks/cj/include/multimedia_audio_volume_manager_callback.h index 38a8bddf65010ae951f64997258f02512df556fc..7cd7576c605776eb042326cd2d23eaebe355b855 100644 --- a/frameworks/cj/include/multimedia_audio_volume_manager_callback.h +++ b/frameworks/cj/include/multimedia_audio_volume_manager_callback.h @@ -29,6 +29,7 @@ public: void RegisterFunc(std::function cjCallback); void OnVolumeKeyEvent(VolumeEvent volumeEvent) override; + void OnVolumeDegreeEvent(VolumeEvent volumeEvent) override {} private: std::function func_ {}; diff --git a/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.cpp b/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.cpp index 46c2584235cc1641e1cd2971be89c9bc56499fdc..b11655c0b0fa21024f66d06552b0938026be13a1 100644 --- a/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.cpp +++ b/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.cpp @@ -54,6 +54,22 @@ bool NapiAudioVolumeKeyEvent::GetVolumeTsfnFlag() return regVolumeTsfn_; } +void NapiAudioVolumeKeyEvent::CreateVolumeDegreeTsfn(napi_env env) +{ + regVolumeDegreeTsfn_ = true; + napi_value cbName; + std::string callbackName = "volumeDegreeChange"; + napi_create_string_utf8(env, callbackName.c_str(), callbackName.length(), &cbName); + napi_add_env_cleanup_hook(env, Cleanup, this); + napi_create_threadsafe_function(env, nullptr, nullptr, cbName, 0, 1, this, + nullptr, nullptr, SafeJsCallbackVolumeEventWork, &amVolEntTsfn_); +} + +bool NapiAudioVolumeKeyEvent::GetVolumeDegreeTsfnFlag() +{ + return regVolumeDegreeTsfn_; +} + napi_threadsafe_function NapiAudioVolumeKeyEvent::GetTsfn() { std::lock_guard lock(mutex_); @@ -80,6 +96,26 @@ void NapiAudioVolumeKeyEvent::OnVolumeKeyEvent(VolumeEvent volumeEvent) return OnJsCallbackVolumeEvent(cb); } +void NapiAudioVolumeKeyEvent::OnVolumeDegreeEvent(VolumeEvent volumeEvent) +{ + std::lock_guard lock(mutex_); + AUDIO_PRERELEASE_LOGI("OnVolumeDegreeEvent is called volumeType=%{public}d, volumeDegree=%{public}d," + "isUpdateUi=%{public}d", volumeEvent.volumeType, volumeEvent.volumeDegree, volumeEvent.updateUi); + CHECK_AND_RETURN_LOG(audioVolumeKeyEventJsCallback_ != nullptr, + "NapiAudioVolumeDegreeEvent:No JS callback registered return"); + std::unique_ptr cb = std::make_unique(); + CHECK_AND_RETURN_LOG(cb != nullptr, "No memory"); + cb->callback = audioVolumeKeyEventJsCallback_; + cb->callbackName = VOLUME_DEGREE_CHANGE_EVENT_CALLBACK_NAME; + cb->volumeEvent.volumeType = volumeEvent.volumeType; + cb->volumeEvent.volumeDegree = volumeEvent.volumeDegree; + cb->volumeEvent.updateUi = volumeEvent.updateUi; + cb->volumeEvent.volumeGroupId = volumeEvent.volumeGroupId; + cb->volumeEvent.networkId = volumeEvent.networkId; + + return OnJsCallbackVolumeEvent(cb); +} + void NapiAudioVolumeKeyEvent::SaveCallbackReference(const std::string &callbackName, napi_value args) { std::lock_guard lock(mutex_); @@ -90,7 +126,8 @@ void NapiAudioVolumeKeyEvent::SaveCallbackReference(const std::string &callbackN "NapiAudioVolumeKeyEvent: creating reference for callback fail"); callback_ = callback; std::shared_ptr cb = std::make_shared(env_, callback); - if (callbackName == VOLUME_KEY_EVENT_CALLBACK_NAME) { + if (callbackName == VOLUME_KEY_EVENT_CALLBACK_NAME || + callbackName == VOLUME_DEGREE_CHANGE_EVENT_CALLBACK_NAME) { audioVolumeKeyEventJsCallback_ = cb; } else { AUDIO_ERR_LOG("NapiAudioVolumeKeyEvent: Unknown callback type: %{public}s", callbackName.c_str()); diff --git a/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.h b/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.h index c3c74a8e7096fcd60337358667874de78552c014..eecf99904234e25e90011854c5c59c0a3c7a27a3 100644 --- a/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.h +++ b/frameworks/js/napi/audiomanager/callback/napi_audio_volume_key_event.h @@ -26,16 +26,20 @@ namespace OHOS { namespace AudioStandard { const std::string VOLUME_KEY_EVENT_CALLBACK_NAME = "volumeChange"; +const std::string VOLUME_DEGREE_CHANGE_EVENT_CALLBACK_NAME = "volumeDegreeChange"; class NapiAudioVolumeKeyEvent : public VolumeKeyEventCallback { public: explicit NapiAudioVolumeKeyEvent(napi_env env); virtual ~NapiAudioVolumeKeyEvent(); void OnVolumeKeyEvent(VolumeEvent volumeEvent) override; + void OnVolumeDegreeEvent(VolumeEvent volumeEvent) override; void SaveCallbackReference(const std::string &callbackName, napi_value args); bool ContainSameJsCallback(napi_value args); void CreateVolumeTsfn(napi_env env); bool GetVolumeTsfnFlag(); + void CreateVolumeDegreeTsfn(napi_env env); + bool GetVolumeDegreeTsfnFlag(); napi_threadsafe_function GetTsfn(); private: @@ -56,6 +60,7 @@ private: napi_ref callback_ = nullptr; static napi_ref sConstructor_; bool regVolumeTsfn_ = false; + bool regVolumeDegreeTsfn_ = false; napi_threadsafe_function amVolEntTsfn_ = nullptr; }; } // namespace AudioStandard diff --git a/frameworks/js/napi/audiomanager/napi_audio_volume_manager.cpp b/frameworks/js/napi/audiomanager/napi_audio_volume_manager.cpp index 06a251f32a3dda035134b4a8968c702e7e309a66..e02284702836f35b89d94ce2e7a153bb3f8e8a89 100644 --- a/frameworks/js/napi/audiomanager/napi_audio_volume_manager.cpp +++ b/frameworks/js/napi/audiomanager/napi_audio_volume_manager.cpp @@ -178,6 +178,9 @@ napi_value NapiAudioVolumeManager::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("on", On), DECLARE_NAPI_FUNCTION("off", Off), DECLARE_NAPI_FUNCTION("forceVolumeKeyControlType", ForceVolumeKeyControlType), + DECLARE_NAPI_FUNCTION("getSystemVolumePercentage", GetSystemVolumePercentage), + DECLARE_NAPI_FUNCTION("setSystemVolumePercentage", SetSystemVolumePercentage), + DECLARE_NAPI_FUNCTION("getMinSystemVolumePercentage", GetMinSystemVolumePercentage), }; status = napi_define_class(env, AUDIO_VOLUME_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr, @@ -1220,20 +1223,17 @@ napi_value NapiAudioVolumeManager::RegisterCallback(napi_env env, napi_value jsT cb->CreateVolumeTsfn(env); } } else if (!cbName.compare(APP_VOLUME_CHANGE_CALLBACK_NAME)) { - undefinedResult = RegisterSelfAppVolumeChangeCallback(env, args, cbName, - napiVolumeManager); + undefinedResult = RegisterSelfAppVolumeChangeCallback(env, args, cbName, napiVolumeManager); } else if (!cbName.compare(APP_VOLUME_CHANGE_CALLBACK_NAME_FOR_UID)) { - undefinedResult = RegisterAppVolumeChangeForUidCallback(env, args, cbName, - napiVolumeManager); + undefinedResult = RegisterAppVolumeChangeForUidCallback(env, args, cbName, napiVolumeManager); } else if (!cbName.compare(ACTIVE_VOLUME_TYPE_CHANGE_CALLBACK_NAME)) { - undefinedResult = RegisterActiveVolumeTypeChangeCallback(env, args, cbName, - napiVolumeManager); + undefinedResult = RegisterActiveVolumeTypeChangeCallback(env, args, cbName, napiVolumeManager); } else if (!cbName.compare(AUDIO_STREAM_VOLUME_CHANGE_CALLBACK_NAME)) { - undefinedResult = RegisterStreamVolumeChangeCallback(env, args, cbName, - napiVolumeManager); + undefinedResult = RegisterStreamVolumeChangeCallback(env, args, cbName, napiVolumeManager); } else if (!cbName.compare(AUDIO_SYSTEM_VOLUME_CHANGE_CALLBACK_NAME)) { - undefinedResult = RegisterSystemVolumeChangeCallback(env, args, cbName, - napiVolumeManager); + undefinedResult = RegisterSystemVolumeChangeCallback(env, args, cbName, napiVolumeManager); + } else if (!cbName.compare(VOLUME_DEGREE_CHANGE_EVENT_CALLBACK_NAME)) { + undefinedResult = RegisterVolumeDegreeChangeCallback(env, args, cbName, napiVolumeManager); } else { AUDIO_ERR_LOG("No such callback supported"); NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM, @@ -1420,6 +1420,37 @@ napi_value NapiAudioVolumeManager::RegisterSystemVolumeChangeCallback(napi_env e return result; } +napi_value NapiAudioVolumeManager::RegisterVolumeDegreeChangeCallback(napi_env env, napi_value *args, + const std::string &cbName, NapiAudioVolumeManager *napiAudioVolumeManager) +{ + CHECK_AND_RETURN_RET_LOG(napiAudioVolumeManager && napiAudioVolumeManager->audioSystemMngr_, + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "audio volume manager is nullptr."); + napi_value result = nullptr; + napi_get_undefined(env, &result); + if (napiAudioVolumeManager->volumeDegreeCallbackNapi_ == nullptr) { + napiAudioVolumeManager->volumeDegreeCallbackNapi_ = std::make_shared< + NapiAudioVolumeKeyEvent>(env); + int32_t ret = napiAudioVolumeManager->audioSystemMngr_->RegisterVolumeDegreeCallback( + napiAudioVolumeManager->cachedClientId_, napiAudioVolumeManager->volumeDegreeCallbackNapi_); + napiAudioVolumeManager->volumeDegreeCallbackNapiList_.push_back( + std::static_pointer_cast( + napiAudioVolumeManager->volumeDegreeCallbackNapi_)); + if (ret) { + AUDIO_ERR_LOG("Failed"); + } + } + + std::shared_ptr cb = + std::static_pointer_cast(napiAudioVolumeManager->volumeDegreeCallbackNapi_); + CHECK_AND_RETURN_RET_LOG(cb && args, + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "callback is nullptr"); + cb->SaveCallbackReference(cbName, args[PARAM1]); + if (!cb->GetVolumeDegreeTsfnFlag()) { + cb->CreateVolumeDegreeTsfn(env); + } + return result; +} + napi_value NapiAudioVolumeManager::On(napi_env env, napi_callback_info info) { napi_value undefinedResult = nullptr; @@ -1539,6 +1570,8 @@ void NapiAudioVolumeManager::UnregisterCallbackFir(napi_env env, napi_value *arg UnregisterStreamVolumeChangeCallback(env, args, argc, napiVolumeManager); } else if (!cbName.compare(AUDIO_SYSTEM_VOLUME_CHANGE_CALLBACK_NAME)) { UnregisterSystemVolumeChangeCallback(env, args, argc, napiVolumeManager); + } else if (!cbName.compare(VOLUME_DEGREE_CHANGE_EVENT_CALLBACK_NAME)) { + UnregisterVolumeDegreeChangeCallback(env, args, argc, napiVolumeManager); } else { AUDIO_ERR_LOG("No such callback supported"); NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM, @@ -1692,6 +1725,44 @@ void NapiAudioVolumeManager::UnregisterSystemVolumeChangeCallback(napi_env env, } } +void NapiAudioVolumeManager::UnregisterVolumeDegreeChangeCallback(napi_env env, napi_value *args, + size_t argc, NapiAudioVolumeManager *napiAudioVolumeManager) +{ + napi_value callback = nullptr; + CHECK_AND_RETURN_LOG(args && napiAudioVolumeManager && napiAudioVolumeManager->audioSystemMngr_, + "callback is nullptr"); + if (argc == ARGS_TWO) { + callback = args[PARAM1]; + } + if (callback != nullptr) { + std::shared_ptr cb = GetVolumeDegreeNapiCallback( + callback, napiAudioVolumeManager); + if (cb == nullptr) { + AUDIO_ERR_LOG("nullptr"); + return; + } + int32_t ret = napiAudioVolumeManager->audioSystemMngr_->UnregisterVolumeDegreeCallback( + napiAudioVolumeManager->cachedClientId_, cb); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("failed"); + return; + } + napiAudioVolumeManager->volumeDegreeCallbackNapiList_.remove(cb); + napiAudioVolumeManager->volumeDegreeCallbackNapi_.reset(); + napiAudioVolumeManager->volumeDegreeCallbackNapi_ = nullptr; + } else { + int32_t ret = napiAudioVolumeManager->audioSystemMngr_->UnregisterVolumeDegreeCallback( + napiAudioVolumeManager->cachedClientId_, nullptr); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("failed"); + return; + } + napiAudioVolumeManager->volumeDegreeCallbackNapiList_.clear(); + napiAudioVolumeManager->volumeDegreeCallbackNapi_.reset(); + napiAudioVolumeManager->volumeDegreeCallbackNapi_ = nullptr; + } +} + std::shared_ptr NapiAudioVolumeManager::GetVolumeEventNapiCallback(napi_value argv, NapiAudioVolumeManager *napiVolumeManager) { @@ -1704,6 +1775,22 @@ std::shared_ptr NapiAudioVolumeManager::GetVolumeEventN return cb; } +std::shared_ptr NapiAudioVolumeManager::GetVolumeDegreeNapiCallback(napi_value argv, + NapiAudioVolumeManager *napiVolumeManager) +{ + CHECK_AND_RETURN_RET_LOG(napiVolumeManager, nullptr, "audio volume manager is nullptr"); + std::shared_ptr cb = nullptr; + for (auto &iter : napiVolumeManager->volumeDegreeCallbackNapiList_) { + if (iter == nullptr) { + continue; + } + if (iter->ContainSameJsCallback(argv)) { + cb = iter; + } + } + return cb; +} + std::shared_ptr NapiAudioVolumeManager::GetStreamVolumeChangeNapiCallback( napi_value argv, NapiAudioVolumeManager *napiVolumeManager) { @@ -1776,5 +1863,124 @@ napi_value NapiAudioVolumeManager::ForceVolumeKeyControlType(napi_env env, napi_ }; return NapiAsyncWork::Enqueue(env, context, "ForceVolumeKeyControlType", executor, complete); } + +napi_value NapiAudioVolumeManager::GetSystemVolumePercentage(napi_env env, napi_callback_info info) +{ + CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED, "No system permission"), + "No system permission"); + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value args[ARGS_ONE] = {}; + auto *napiAudioVolumeManager = GetParamWithSync(env, info, argc, args); + CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "mandatory parameters are left unspecified"), "invalid arguments"); + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, args[PARAM0], &valueType); + CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "incorrect parameter types: The type of audioVolumeType must be number"), + "invalid valueType"); + + int32_t volType; + NapiParamUtils::GetValueInt32(env, volType, args[PARAM0]); + CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentVolType(volType), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM, + "parameter verification failed: The param of volType must be enum AudioVolumeType"), + "get volType failed"); + + NapiDfxUtils::SendVolumeApiInvokeEvent(static_cast(getuid()), + "GetSystemVolumePercentage", volType); + + if (napiAudioVolumeManager == nullptr || napiAudioVolumeManager->audioSystemMngr_ == nullptr) { + AUDIO_ERR_LOG("napiAudioVolumeManager or audioSystemMngr is nullptr!"); + return nullptr; + } + int32_t systemVolume = napiAudioVolumeManager->audioSystemMngr_->GetVolumeDegree( + NapiAudioEnum::GetNativeAudioVolumeType(volType)); + NapiParamUtils::SetValueInt32(env, systemVolume, result); + return result; +} + +napi_value NapiAudioVolumeManager::SetSystemVolumePercentage(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + if (context == nullptr) { + AUDIO_ERR_LOG("failed : no memory"); + NapiAudioError::ThrowError(env, "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_THREE, "invalid arguments", + NAPI_ERR_INVALID_PARAM); + context->status = NapiParamUtils::GetValueInt32(env, context->volumeType, argv[PARAM0]); + NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volumeType failed", + NAPI_ERR_INVALID_PARAM); + if (!NapiAudioEnum::IsLegalInputArgumentVolType(context->volumeType)) { + context->SignError(context->errCode == NAPI_ERR_INVALID_PARAM? + NAPI_ERR_INVALID_PARAM : NAPI_ERR_UNSUPPORTED); + } + context->status = NapiParamUtils::GetValueInt32(env, context->volDegree, argv[PARAM1]); + NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get volDegree failed", + NAPI_ERR_INVALID_PARAM); + }; + 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 *napiAudioVolumeManager = objectGuard.GetPtr(); + CHECK_AND_RETURN_LOG(CheckAudioVolumeManagerStatus(napiAudioVolumeManager, context), + "audio volume manager state is error."); + context->intValue = napiAudioVolumeManager->audioSystemMngr_->SetVolumeDegree( + NapiAudioEnum::GetNativeAudioVolumeType(context->volumeType), context->volDegree); + NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "failed", NAPI_ERR_SYSTEM); + }; + + auto complete = [env](napi_value &output) { + output = NapiParamUtils::GetUndefinedValue(env); + }; + return NapiAsyncWork::Enqueue(env, context, "SetSystemVolumePercentage", executor, complete); +} + +napi_value NapiAudioVolumeManager::GetMinSystemVolumePercentage(napi_env env, napi_callback_info info) +{ + CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED, "No system permission"), + "No system permission"); + napi_value result = nullptr; + size_t argc = ARGS_ONE; + napi_value args[ARGS_ONE] = {}; + auto *napiAudioVolumeManager = GetParamWithSync(env, info, argc, args); + CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "mandatory parameters are left unspecified"), "invalid arguments"); + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, args[PARAM0], &valueType); + CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, + NAPI_ERR_INVALID_PARAM, "incorrect parameter types: The type of audioVolumeType must be number"), + "invalid valueType"); + + int32_t volType; + NapiParamUtils::GetValueInt32(env, volType, args[PARAM0]); + CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentVolType(volType), + NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM, + "parameter verification failed: The param of volType must be enum AudioVolumeType"), + "get volType failed"); + + NapiDfxUtils::SendVolumeApiInvokeEvent(static_cast(getuid()), + "getMinSystemVolumePercentage", volType); + + if (napiAudioVolumeManager == nullptr || napiAudioVolumeManager->audioSystemMngr_ == nullptr) { + AUDIO_ERR_LOG("napiAudioVolumeManager or audioSystemMngr is nullptr!"); + return nullptr; + } + int32_t minSystemVolume = napiAudioVolumeManager->audioSystemMngr_->GetMinVolumeDegree( + NapiAudioEnum::GetNativeAudioVolumeType(volType)); + NapiParamUtils::SetValueInt32(env, minSystemVolume, result); + return result; +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/js/napi/audiomanager/napi_audio_volume_manager.h b/frameworks/js/napi/audiomanager/napi_audio_volume_manager.h index 0dd7a5f6a543c3761c09c55f50f44e1e703b45e6..d8bc5b72e666a9393ccbe7d65d4678e9f3532002 100644 --- a/frameworks/js/napi/audiomanager/napi_audio_volume_manager.h +++ b/frameworks/js/napi/audiomanager/napi_audio_volume_manager.h @@ -48,6 +48,7 @@ private: bool isMute; bool isTrue; int32_t volLevel; + int32_t volDegree; int32_t appUid; bool isOwned; std::string networkId; @@ -104,6 +105,8 @@ private: size_t argc, const std::string &cbName, NapiAudioVolumeManager *napiAudioVolumeManager); static std::shared_ptr GetVolumeEventNapiCallback(napi_value argv, NapiAudioVolumeManager *napiVolumeManager); + static std::shared_ptr GetVolumeDegreeNapiCallback(napi_value argv, + NapiAudioVolumeManager *napiVolumeManager); static std::shared_ptr GetStreamVolumeChangeNapiCallback(napi_value argv, NapiAudioVolumeManager *napiVolumeManager); static std::shared_ptr GetSystemVolumeChangeNapiCallback(napi_value argv, @@ -120,20 +123,30 @@ private: const std::string &cbName, NapiAudioVolumeManager *napiAudioVolumeManager); static void UnregisterSystemVolumeChangeCallback(napi_env env, napi_value *args, size_t argc, NapiAudioVolumeManager *napiAudioVolumeManager); + static napi_value RegisterVolumeDegreeChangeCallback(napi_env env, napi_value *args, + const std::string &cbName, NapiAudioVolumeManager *napiAudioVolumeManager); + static void UnregisterVolumeDegreeChangeCallback(napi_env env, napi_value *args, + size_t argc, NapiAudioVolumeManager *napiAudioVolumeManager); static napi_value Construct(napi_env env, napi_callback_info info); static void Destructor(napi_env env, void *nativeObject, void *finalizeHint); static napi_value ForceVolumeKeyControlType(napi_env env, napi_callback_info info); + static napi_value GetSystemVolumePercentage(napi_env env, napi_callback_info info); + static napi_value SetSystemVolumePercentage(napi_env env, napi_callback_info info); + static napi_value GetMinSystemVolumePercentage(napi_env env, napi_callback_info info); + AudioSystemManager *audioSystemMngr_; int32_t cachedClientId_ = -1; std::shared_ptr volumeKeyEventCallbackNapi_ = nullptr; + std::shared_ptr volumeDegreeCallbackNapi_ = nullptr; std::shared_ptr streamVolumeChangeCallbackNapi_ = nullptr; std::shared_ptr systemVolumeChangeCallbackNapi_ = nullptr; std::shared_ptr selfAppVolumeChangeCallbackNapi_ = nullptr; std::shared_ptr appVolumeChangeCallbackForUidNapi_ = nullptr; std::shared_ptr activeVolumeTypeChangeCallbackNapi_ = nullptr; std::list> volumeKeyEventCallbackNapiList_; + std::list> volumeDegreeCallbackNapiList_; std::list> streamVolumeChangeCallbackNapiList_; std::list> systemVolumeChangeCallbackNapiList_; diff --git a/frameworks/js/napi/common/napi_param_utils.cpp b/frameworks/js/napi/common/napi_param_utils.cpp index c672b1b6915e547733505a569566e6f736d36e4d..92302790164f5c8aa03357989f905859c18fca94 100644 --- a/frameworks/js/napi/common/napi_param_utils.cpp +++ b/frameworks/js/napi/common/napi_param_utils.cpp @@ -795,6 +795,7 @@ napi_status NapiParamUtils::SetValueVolumeEvent(const napi_env& env, const Volum SetValueString(env, "networkId", volumeEvent.networkId, result); SetValueInt32(env, "volumeMode", NapiAudioEnum::GetJsAudioVolumeMode(static_cast(volumeEvent.volumeMode)), result); + SetValueInt32(env, "volumeDegree", static_cast(volumeEvent.volumeDegree), result); return napi_ok; } diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index 04e63588365b51bfaddf96ef8a2d169a45ea32c3..333de0fba4e497a40d03c4744d243bb038622018 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -709,6 +709,14 @@ public: const std::shared_ptr &selectedAudioDevice); int32_t ForceVolumeKeyControlType(AudioVolumeType volumeType, int32_t duration); + int32_t SetVolumeDegreeCallback(const int32_t clientPid, + const std::shared_ptr &callback, API_VERSION api_v = API_9); + int32_t UnsetVolumeDegreeCallback(const std::shared_ptr &callback); + int32_t SetSystemVolumeDegree(AudioVolumeType volumeType, int32_t volumeDegree, + int32_t volumeFlag, int32_t uid); + int32_t GetSystemVolumeDegree(AudioVolumeType volumeType, int32_t uid); + int32_t GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType = DEVICE_TYPE_NONE); + private: AudioPolicyManager() {} ~AudioPolicyManager() {} diff --git a/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp b/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp index df0eecedc006442102751d6ac11f101ccc659a93..32c23afbdd9cee9778df19af20fc5387325b6e04 100644 --- a/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp +++ b/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp @@ -2253,5 +2253,74 @@ HWTEST(AudioManagerUnitTest, NotifyProcessBackgroundState_001, TestSize.Level1) ret = AudioSystemManager::GetInstance()->NotifyProcessBackgroundState(uid, pid); EXPECT_NE(SUCCESS, ret); } + +/** + * @tc.name : Test SetVolumeDegree API + * @tc.number: SetVolumeDegree_001 + * @tc.desc : SetVolumeDegree + * @tc.require: + */ +HWTEST(AudioManagerUnitTest, SetVolumeDegree_001, TestSize.Level0) +{ + auto manager = AudioSystemManager::GetInstance(); + + int32_t degree = 44; + AudioStreamType streamType = STREAM_MUSIC; + int32_t ret = manager->SetVolumeDegree(streamType, degree); + EXPECT_EQ(SUCCESS, ret); + + AudioStreamType streamType2 = STREAM_ULTRASONIC; + ret = manager->SetVolumeDegree(streamType2, degree); + EXPECT_EQ(SUCCESS, ret); + + AudioStreamType streamType3 = STREAM_APP; + ret = manager->SetVolumeDegree(streamType3, degree); + EXPECT_EQ(ERR_NOT_SUPPORTED, ret); +} + +/** + * @tc.name : Test GetVolumeDegree API + * @tc.number: GetVolumeDegree_001 + * @tc.desc : GetVolumeDegree + * @tc.require: + */ +HWTEST(AudioManagerUnitTest, GetVolumeDegree_001, TestSize.Level0) +{ + auto manager = AudioSystemManager::GetInstance(); + int32_t degree = 44; + AudioStreamType streamType = STREAM_ALARM; + int32_t ret = manager->SetVolumeDegree(streamType, degree); + EXPECT_EQ(SUCCESS, ret); + + ret = manager->GetVolumeDegree(streamType); + EXPECT_EQ(ret, degree); + + AudioStreamType streamType3 = STREAM_APP; + ret = manager->GetVolumeDegree(streamType3); + EXPECT_EQ(ERR_NOT_SUPPORTED, ret); +} + +/** + * @tc.name : Test GetMinVolumeDegree API + * @tc.number: GetMinVolumeDegree_001 + * @tc.desc : GetMinVolumeDegree + * @tc.require: + */ +HWTEST(AudioManagerUnitTest, GetMinVolumeDegree_001, TestSize.Level0) +{ + auto manager = AudioSystemManager::GetInstance(); + + AudioVolumeType streamType = STREAM_ALL; + int32_t ret = manager->GetMinVolumeDegree(streamType); + EXPECT_EQ(SUCCESS, ret); + + AudioVolumeType streamType2 = STREAM_ULTRASONIC; + ret = manager->GetMinVolumeDegree(streamType2); + EXPECT_EQ(SUCCESS, ret); + + AudioVolumeType streamType3 = STREAM_MUSIC; + ret = manager->GetMinVolumeDegree(streamType3); + EXPECT_EQ(SUCCESS, ret); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiopolicy/test/unittest/volume_change_test/include/audio_volume_change_unit_test.h b/frameworks/native/audiopolicy/test/unittest/volume_change_test/include/audio_volume_change_unit_test.h index 73ebc8ac5be7399b9062a1b23d658e6a578e435d..5d56143bf5a4210656299e666a11c5c22714dcb8 100644 --- a/frameworks/native/audiopolicy/test/unittest/volume_change_test/include/audio_volume_change_unit_test.h +++ b/frameworks/native/audiopolicy/test/unittest/volume_change_test/include/audio_volume_change_unit_test.h @@ -35,6 +35,7 @@ public: ~ApplicationCallback() = default; void OnVolumeKeyEvent(VolumeEvent volumeEvent) override; + void OnVolumeDegreeEvent(VolumeEvent volumeEvent) override; private: std::string testCaseName_; }; diff --git a/frameworks/native/audiopolicy/test/unittest/volume_change_test/src/audio_volume_change_unit_test.cpp b/frameworks/native/audiopolicy/test/unittest/volume_change_test/src/audio_volume_change_unit_test.cpp index df4e2b187f8a647532cb5688b176cf6668cdf067..b269b7c9d7eefd324825054d42348ac17b18f233 100644 --- a/frameworks/native/audiopolicy/test/unittest/volume_change_test/src/audio_volume_change_unit_test.cpp +++ b/frameworks/native/audiopolicy/test/unittest/volume_change_test/src/audio_volume_change_unit_test.cpp @@ -35,6 +35,7 @@ namespace { int32_t g_streamType(0); int32_t g_volumeLevel(0); + int32_t g_volumeDegree(-1); bool g_isUpdateUi(false); int32_t g_volumeGroupId(0); std::string g_networkId(LOCAL_NETWORK_ID); @@ -59,6 +60,19 @@ void ApplicationCallback::OnVolumeKeyEvent(VolumeEvent volumeEvent) g_condVar.notify_all(); } +void ApplicationCallback::OnVolumeDegreeEvent(VolumeEvent volumeEvent) +{ + g_isCallbackReceived = true; + g_streamType = volumeEvent.volumeType; + g_volumeLevel = volumeEvent.volume; + g_volumeDegree = volumeEvent.volumeDegree; + g_callbackName = testCaseName_; + g_isUpdateUi = volumeEvent.updateUi; + g_volumeGroupId = volumeEvent.volumeGroupId; + g_networkId = volumeEvent.networkId; + g_condVar.notify_all(); +} + void AudioVolumeChangeUnitTest::WaitForCallback() { std::unique_lock lock(g_mutex); @@ -191,5 +205,42 @@ HWTEST_F(AudioVolumeChangeUnitTest, volumeChange_test_003, TestSize.Level1) } g_audioManagerInstance->UnregisterVolumeKeyEventCallback(getpid()); } + +/* + * Feature: AudioVolumeChangeUnitTest + * Function: Set volume degree for AudioStreamType::STREAM_VOICE_CALL + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: + */ +HWTEST_F(AudioVolumeChangeUnitTest, volumeDegreeChange_test_001, TestSize.Level1) +{ + ASSERT_NE(g_audioManagerInstance, nullptr); + int32_t result; + int32_t callBackSetResult; + std::string testCaseName("volumeDegreeChange_test_001"); + g_isCallbackReceived = false; + AudioStreamType streamType = AudioStreamType::STREAM_MUSIC; + AudioVolumeType volumeType = static_cast(streamType); + int32_t volume = 0; + g_callbackName = testCaseName; + bool isUpdateUi = false; + auto appCallback = make_shared(testCaseName); + + callBackSetResult = g_audioManagerInstance->RegisterVolumeDegreeCallback(getpid(), appCallback); + result = g_audioManagerInstance->SetVolume(volumeType, volume); + EXPECT_EQ(result, SUCCESS); + EXPECT_EQ(callBackSetResult, SUCCESS); + if (result == SUCCESS) { + // Wait here for callback. If not callback for 2 mintues, will skip this step + AudioVolumeChangeUnitTest::WaitForCallback(); + EXPECT_EQ(streamType, g_streamType); + EXPECT_EQ(volume, g_volumeDegree); + EXPECT_EQ(isUpdateUi, g_isUpdateUi); + EXPECT_STREQ(g_callbackName.c_str(), testCaseName.c_str()); + } + g_audioManagerInstance->UnregisterVolumeDegreeCallback(getpid()); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audioutils/src/audio_utils.cpp b/frameworks/native/audioutils/src/audio_utils.cpp index 67a46f0562612d66f66e09c8e754b4dfef070626..9c122a23fea1477cdbe8afb4e58acf9641120a6d 100644 --- a/frameworks/native/audioutils/src/audio_utils.cpp +++ b/frameworks/native/audioutils/src/audio_utils.cpp @@ -89,6 +89,10 @@ const int32_t DATA_INDEX_4 = 4; const int32_t DATA_INDEX_5 = 5; const int32_t STEREO_CHANNEL_COUNT = 2; const int BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401; +const int32_t MAX_VOLUME_DEGREE = 100; +const int32_t MIN_VOLUME_DEGREE = 0; +const int32_t MIN_VOLUME_LEVEL = 0; +const int32_t DEFAULT_MAX_VOLUME_LEVEL = 15; const char* DUMP_PULSE_DIR = "/data/data/.pulse_dir/"; const char* DUMP_SERVICE_DIR = "/data/local/tmp/"; @@ -1966,6 +1970,70 @@ std::set& VolumeUtils::GetStreamUsageSetForVolumeType(AudioVolumeTy } } +int32_t VolumeUtils::VolumeDegreeToLevel(int32_t degree, int32_t maxLevel) +{ + if (degree < MIN_VOLUME_DEGREE || degree > MAX_VOLUME_DEGREE || + maxLevel - 1 <= 0) { + return MIN_VOLUME_LEVEL; + } + + if (degree == MIN_VOLUME_DEGREE) { + return MIN_VOLUME_LEVEL; + } + + if (degree == MAX_VOLUME_DEGREE) { + return maxLevel; + } + + int32_t quotient = (MAX_VOLUME_DEGREE - MIN_VOLUME_DEGREE - 1) / (maxLevel - 1); + int32_t level = degree / quotient; + int32_t remainder = degree % quotient; + level += remainder > 0 ? 1 : 0; + + if (level == maxLevel) { + level--; + } + return level; +} + +int32_t VolumeUtils::VolumeLevelToDegree(int32_t level, int32_t maxLevel) +{ + if (level < MIN_VOLUME_LEVEL || level > maxLevel || + maxLevel - 1 <= 0) { + return MIN_VOLUME_DEGREE; + } + + if (level == MIN_VOLUME_LEVEL) { + return MIN_VOLUME_DEGREE; + } + + if (level == maxLevel) { + return MAX_VOLUME_DEGREE; + } + + int32_t ceiling = GetVolumeLevelMaxDegree(level, maxLevel); + int32_t offset = 0; + if (maxLevel == DEFAULT_MAX_VOLUME_LEVEL) { + const int32_t DEF_STEPS = 3; + offset = level / DEF_STEPS; + int32_t remainder = level % DEF_STEPS; + offset += remainder > 0 ? 1 : 0; + } + + int32_t degree = ceiling - offset; + return degree; +} + +int32_t VolumeUtils::GetVolumeLevelMaxDegree(int32_t level, int32_t maxLevel) +{ + if (maxLevel - 1 <= 0) { + return MIN_VOLUME_DEGREE; + } + int32_t quotient = (MAX_VOLUME_DEGREE - MIN_VOLUME_DEGREE - 1) / (maxLevel - 1); + int32_t ceiling = level * quotient; + return ceiling; +} + std::string GetEncryptStr(const std::string &src) { if (src.empty()) { diff --git a/interfaces/inner_api/native/audiocommon/include/audio_common_utils.h b/interfaces/inner_api/native/audiocommon/include/audio_common_utils.h index a970f9255d8adfa9fa3d6a54f59d57119da192a0..0000c224eb27b7229174aadc5c0dfd794a6c7254 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_common_utils.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_common_utils.h @@ -32,6 +32,9 @@ public: AudioVolumeType volumeType); static std::vector GetSupportedAudioVolumeTypes(); static std::vector GetStreamUsagesByVolumeType(AudioVolumeType audioVolumeType); + static int32_t VolumeDegreeToLevel(int32_t degree, int32_t maxLevel); + static int32_t VolumeLevelToDegree(int32_t level, int32_t maxLevel);\ + static int32_t GetVolumeLevelMaxDegree(int32_t level, int32_t maxLevel); private: static std::set& GetStreamUsageSetForVolumeType(AudioVolumeType volumeType); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index b7e7777a3bc7f25ef9d8b2fa07f7d001c3604fd9..095a900fd588a3f07e5ad1940c89655cb4ebacc2 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -348,6 +348,7 @@ enum CallbackChange : int32_t { CALLBACK_AUDIO_SESSION_STATE, CALLBACK_AUDIO_SESSION_DEVICE, CALLBACK_AUDIO_SESSION_INPUT_DEVICE, + CALLBACK_SET_VOLUME_DEGREE_CHANGE, CALLBACK_MAX, }; @@ -405,6 +406,7 @@ constexpr CallbackChange CALLBACK_ENUMS[] = { CALLBACK_AUDIO_SESSION_STATE, CALLBACK_AUDIO_SESSION_DEVICE, CALLBACK_AUDIO_SESSION_INPUT_DEVICE, + CALLBACK_SET_VOLUME_DEGREE_CHANGE, }; static_assert((sizeof(CALLBACK_ENUMS) / sizeof(CallbackChange)) == static_cast(CALLBACK_MAX), @@ -413,6 +415,7 @@ static_assert((sizeof(CALLBACK_ENUMS) / sizeof(CallbackChange)) == static_cast(volumeType)) && parcel.WriteInt32(volume) + && parcel.WriteInt32(volumeDegree) && parcel.WriteBool(updateUi) && parcel.WriteInt32(volumeGroupId) && parcel.WriteString(networkId) @@ -437,6 +441,7 @@ struct VolumeEvent : public Parcelable { { volumeType = static_cast(parcel.ReadInt32()); volume = parcel.ReadInt32(); + volumeDegree = parcel.ReadInt32(); updateUi = parcel.ReadBool(); volumeGroupId = parcel.ReadInt32(); networkId = parcel.ReadString(); @@ -1439,6 +1444,7 @@ struct Volume { bool isMute = false; float volumeFloat = 1.0f; uint32_t volumeInt = 0; + uint32_t volumeDegree = 0; }; enum AppIsBackState { diff --git a/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h b/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h index 05333fe6af1b0ae1b336c4371afb6155f9c42e19..5174bfebf18acf76ca5e0687eeb2c439a500f8e8 100644 --- a/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h +++ b/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h @@ -191,6 +191,13 @@ public: * @since 8 */ virtual void OnVolumeKeyEvent(VolumeEvent volumeEvent) = 0; + /** + * @brief VolumeKeyEventCallback will be executed when volume degree is updated + * + * @param volumeEvent the volume event info. + * @since 11 + */ + virtual void OnVolumeDegreeEvent(VolumeEvent volumeEvent) {} }; class StreamVolumeChangeCallback { diff --git a/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h b/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h index 021ddb5fb7d4cf84e9ced67c0992d44883d84905..1dffd95db4d4c8a783e40df90c4c9e3d169c4140 100644 --- a/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h +++ b/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h @@ -732,6 +732,26 @@ public: int32_t UnregisterVolumeKeyEventCallback(const int32_t clientPid, const std::shared_ptr &callback = nullptr); + /** + * @brief registers the volume degree callback listener + * + * @return Returns {@link SUCCESS} if callback registration is successful; returns an error code + * defined in {@link audio_errors.h} otherwise. + * @since 8 + */ + int32_t RegisterVolumeDegreeCallback(const int32_t clientPid, + const std::shared_ptr &callback, API_VERSION api_v = API_11); + + /** + * @brief Unregisters the volumeKeyEvent callback listener + * + * @return Returns {@link SUCCESS} if callback unregistration is successful; returns an error code + * defined in {@link audio_errors.h} otherwise. + * @since 8 + */ + int32_t UnregisterVolumeDegreeCallback(const int32_t clientPid, + const std::shared_ptr &callback = nullptr); + /** * @brief registers the systemVolumeChange callback listener * @@ -1496,6 +1516,34 @@ public: */ void CleanUpResource(); + /** + * @brief set stream volume degree. + * + * @param volumeType Audio stream type. + * @param degree volume degree. It must be an integer with the range [0, 100]. + * @return Returns {@link SUCCESS} if the operation is successfully. + * @since 21 + */ + int32_t SetVolumeDegree(AudioVolumeType volumeType, int32_t degree, int32_t uid = 0); + + /** + * @brief get stream volume degree. + * + * @param volumeType Audio stream type. + * @return Returns the volume degree for the specified Audio stream type. + * @since 21 + */ + int32_t GetVolumeDegree(AudioVolumeType volumeType, int32_t uid = 0); + + /** + * @brief get stream min volume degree. + * + * @param volumeType Audio stream type. + * @return Returns the minimum volume degree for the specified Audio stream type. + * @since 21 + */ + int32_t GetMinVolumeDegree(AudioVolumeType volumeType); + class WorkgroupPrioRecorder { public: WorkgroupPrioRecorder(int32_t grpId); diff --git a/services/audio_policy/client/service/src/audio_policy_manager.cpp b/services/audio_policy/client/service/src/audio_policy_manager.cpp index 6d2fa2280ba6bf39b002a52e30acb9b779085e89..dc6c9a19ae2f6509ed70b7cfce7efbe91f8468af 100644 --- a/services/audio_policy/client/service/src/audio_policy_manager.cpp +++ b/services/audio_policy/client/service/src/audio_policy_manager.cpp @@ -3297,6 +3297,80 @@ int32_t AudioPolicyManager::CheckAudioPolicyClientRegisted() return result; } +int32_t AudioPolicyManager::SetVolumeDegreeCallback(const int32_t clientPid, + const std::shared_ptr &callback, API_VERSION api_v) +{ + AUDIO_INFO_LOG("client: %{public}d", clientPid); + if (api_v == API_11 && !PermissionUtil::VerifySystemPermission()) { + AUDIO_ERR_LOG("No system permission"); + return ERR_PERMISSION_DENIED; + } + CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "volume back is nullptr"); + + if (!isAudioPolicyClientRegisted_) { + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR, "audio policy manager proxy is NULL."); + int32_t ret = RegisterPolicyCallbackClientFunc(gsp); + if (ret != SUCCESS) { + return ret; + } + } + + std::lock_guard lockCbMap(callbackChangeInfos_[CALLBACK_SET_VOLUME_DEGREE_CHANGE].mutex); + if (audioPolicyClientStubCB_ != nullptr) { + audioPolicyClientStubCB_->AddVolumeDegreeCallback(callback); + size_t callbackSize = audioPolicyClientStubCB_->GetVolumeDegreeCallbackSize(); + if (callbackSize == 1) { + callbackChangeInfos_[CALLBACK_SET_VOLUME_DEGREE_CHANGE].isEnable = true; + SetClientCallbacksEnable(CALLBACK_SET_VOLUME_DEGREE_CHANGE, true); + } + } + return SUCCESS; +} + +int32_t AudioPolicyManager::UnsetVolumeDegreeCallback( + const std::shared_ptr &callback) +{ + AUDIO_DEBUG_LOG("Start to unregister"); + std::lock_guard lockCbMap(callbackChangeInfos_[CALLBACK_SET_VOLUME_DEGREE_CHANGE].mutex); + if (audioPolicyClientStubCB_ != nullptr) { + audioPolicyClientStubCB_->RemoveVolumeDegreeCallback(callback); + if (audioPolicyClientStubCB_->GetVolumeDegreeCallbackSize() == 0) { + callbackChangeInfos_[CALLBACK_SET_VOLUME_DEGREE_CHANGE].isEnable = false; + SetClientCallbacksEnable(CALLBACK_SET_VOLUME_DEGREE_CHANGE, false, false); + } + } + return SUCCESS; +} + +int32_t AudioPolicyManager::SetSystemVolumeDegree(AudioVolumeType volumeType, int32_t volumeDegree, + int32_t volumeFlag, int32_t uid) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR, "audio policy manager proxy is NULL."); + return gsp->SetSystemVolumeDegree(volumeType, volumeDegree, volumeFlag, uid); +} + +int32_t AudioPolicyManager::GetSystemVolumeDegree(AudioVolumeType volumeType, int32_t uid) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR, "audio policy manager proxy is NULL."); + + int32_t volumeDegree = -1; + gsp->GetSystemVolumeDegree(volumeType, uid, volumeDegree); + return volumeDegree; +} + +int32_t AudioPolicyManager::GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR, "audio policy manager proxy is NULL."); + + int32_t volumeDegree = -1; + gsp->GetMinVolumeDegree(volumeType, deviceType, volumeDegree); + return volumeDegree; +} + AudioPolicyManager& AudioPolicyManager::GetInstance() { static AudioPolicyManager policyManager; diff --git a/services/audio_policy/client/stub/include/audio_policy_client_stub_impl.h b/services/audio_policy/client/stub/include/audio_policy_client_stub_impl.h index 445f73af26e3ad250c84776e70fe51fa47b66deb..c3f7ec8d1dddc3301a708af525bfa13bf2c57415 100644 --- a/services/audio_policy/client/stub/include/audio_policy_client_stub_impl.h +++ b/services/audio_policy/client/stub/include/audio_policy_client_stub_impl.h @@ -35,6 +35,9 @@ public: int32_t AddVolumeKeyEventCallback(const std::shared_ptr &cb); int32_t RemoveVolumeKeyEventCallback(const std::shared_ptr &cb); size_t GetVolumeKeyEventCallbackSize() const; + int32_t AddVolumeDegreeCallback(const std::shared_ptr &cb); + int32_t RemoveVolumeDegreeCallback(const std::shared_ptr &cb); + size_t GetVolumeDegreeCallbackSize() const; int32_t AddSystemVolumeChangeCallback(const std::shared_ptr &cb); int32_t RemoveSystemVolumeChangeCallback(const std::shared_ptr &cb); size_t GetSystemVolumeChangeCallbackSize() const; @@ -150,6 +153,7 @@ public: int32_t OnRecreateCapturerStreamEvent(uint32_t sessionId, int32_t streamFlag, const AudioStreamDeviceChangeReasonExt &reason) override; int32_t OnVolumeKeyEvent(const VolumeEvent &volumeEvent) override; + int32_t OnVolumeDegreeEvent(const VolumeEvent &volumeEvent) override; int32_t OnAudioFocusInfoChange(const std::vector> &focusInfoList) override; int32_t OnAudioFocusRequested(const AudioInterrupt &requestFocus) override; int32_t OnAudioFocusAbandoned(const AudioInterrupt &abandonFocus) override; @@ -191,6 +195,7 @@ private: const std::vector>& desc); std::vector> volumeKeyEventCallbackList_; + std::vector> volumeDegreeCallbackList_; std::vector, std::weak_ptr>> streamVolumeChangeCallbackList_; std::vector> systemVolumeChangeCallbackList_; @@ -237,6 +242,7 @@ private: mutable std::mutex pOutputDeviceChangeMutex_; mutable std::mutex pInputDeviceChangeMutex_; mutable std::mutex volumeKeyEventMutex_; + mutable std::mutex volumeDegreeEventMutex_; mutable std::mutex deviceChangeMutex_; mutable std::mutex ringerModeMutex_; mutable std::mutex activeVolumeTypeChangeMutex_; diff --git a/services/audio_policy/client/stub/src/audio_policy_client_stub_impl.cpp b/services/audio_policy/client/stub/src/audio_policy_client_stub_impl.cpp index c4618700abba11bd13634a43ca77a08c70ea9b6d..983c592c831b249765c1ac0619a602098d824b9b 100644 --- a/services/audio_policy/client/stub/src/audio_policy_client_stub_impl.cpp +++ b/services/audio_policy/client/stub/src/audio_policy_client_stub_impl.cpp @@ -74,6 +74,48 @@ int32_t AudioPolicyClientStubImpl::OnVolumeKeyEvent(const VolumeEvent &volumeEve return SUCCESS; } +int32_t AudioPolicyClientStubImpl::AddVolumeDegreeCallback(const std::shared_ptr &cb) +{ + std::lock_guard lockCbMap(volumeDegreeEventMutex_); + volumeDegreeCallbackList_.push_back(cb); + return SUCCESS; +} + +int32_t AudioPolicyClientStubImpl::RemoveVolumeDegreeCallback(const std::shared_ptr &cb) +{ + std::lock_guard lockCbMap(volumeDegreeEventMutex_); + if (cb == nullptr) { + volumeDegreeCallbackList_.clear(); + return SUCCESS; + } + auto it = find_if(volumeDegreeCallbackList_.begin(), volumeDegreeCallbackList_.end(), + [&cb](const std::weak_ptr& elem) { + return elem.lock() == cb; + }); + if (it != volumeDegreeCallbackList_.end()) { + volumeDegreeCallbackList_.erase(it); + } + return SUCCESS; +} + +size_t AudioPolicyClientStubImpl::GetVolumeDegreeCallbackSize() const +{ + std::lock_guard lockCbMap(volumeDegreeEventMutex_); + return volumeDegreeCallbackList_.size(); +} + +int32_t AudioPolicyClientStubImpl::OnVolumeDegreeEvent(const VolumeEvent &volumeEvent) +{ + std::lock_guard lockCbMap(volumeDegreeEventMutex_); + for (auto it = volumeDegreeCallbackList_.begin(); it != volumeDegreeCallbackList_.end(); ++it) { + std::shared_ptr volumeKeyEventCallback = (*it).lock(); + if (volumeKeyEventCallback != nullptr) { + volumeKeyEventCallback->OnVolumeDegreeEvent(volumeEvent); + } + } + return SUCCESS; +} + int32_t AudioPolicyClientStubImpl::AddSystemVolumeChangeCallback(const std::shared_ptr &cb) { std::lock_guard lockCbMap(systemVolumeChangeMutex_); diff --git a/services/audio_policy/idl/IAudioPolicy.idl b/services/audio_policy/idl/IAudioPolicy.idl index 9715a1c3e186c90d126651d1f58de42756c49c88..0b90a56640e319a04f63f14ef0ac708579772f6d 100644 --- a/services/audio_policy/idl/IAudioPolicy.idl +++ b/services/audio_policy/idl/IAudioPolicy.idl @@ -295,6 +295,9 @@ interface IAudioPolicy { void SetAppConcurrencyMode([in] int appUid, [in] int mode); void SetAppSilentOnDisplay([in] int displayId); void IsIntelligentNoiseReductionEnabledForCurrentDevice([in] int sourceType, [out] boolean ret); + void SetSystemVolumeDegree([in] int volumeType, [in] int volumeDegree, [in] int volumeFlag, [in] int uid); + void GetSystemVolumeDegree([in] int volumeType, [in] int uid, [out] int volumeDegree); + void GetMinVolumeDegree([in] int volumeType, [in] int deviceType, [out] int volumeDegree); // WARNING: above functions correspond with AudioPolicyInterfaceCode void GetAudioZoneByName([in] String name, [out] int zoneId); diff --git a/services/audio_policy/idl/IAudioPolicyClient.idl b/services/audio_policy/idl/IAudioPolicyClient.idl index 51d879575bb8bb585aeae88efbc3ebf88adcd312..9659e90acd23e9fb88caea5fb978347c579a3beb 100644 --- a/services/audio_policy/idl/IAudioPolicyClient.idl +++ b/services/audio_policy/idl/IAudioPolicyClient.idl @@ -90,4 +90,6 @@ interface IAudioPolicyClient { void OnAudioSessionCurrentDeviceChanged([in] CurrentOutputDeviceChangedEvent deviceChangedEvent); [customMsgOption flags=MessageOption::TF_ASYNC_WAKEUP_LATER | MessageOption::TF_ASYNC] void OnAudioSessionCurrentInputDeviceChanged([in] CurrentInputDeviceChangedEvent deviceChangedEvent); + [customMsgOption flags=MessageOption::TF_ASYNC_WAKEUP_LATER | MessageOption::TF_ASYNC] + void OnVolumeDegreeEvent([in] VolumeEvent volumeEvent); } diff --git a/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h b/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h index 8645206c88f969faa31a594b73f9b1bbaf830d49..d94383ae50d5e212469bf2771c933f9c23c172cd 100644 --- a/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h +++ b/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h @@ -48,6 +48,7 @@ struct AppConfigVolume { }; const int32_t MAX_CACHE_AMOUNT = 10; +static constexpr int32_t MAX_VOLUME_DEGREE = 100; class AudioAdapterManager : public IAudioPolicyInterface { public: static constexpr std::string_view SPLIT_STREAM_SINK = "libmodule-split-stream-sink.z.so"; @@ -167,7 +168,7 @@ public: bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false); - float CalculateVolumeDb(int32_t volumeLevel); + float CalculateVolumeDb(int32_t volumeLevel, int32_t maxDegree = MAX_VOLUME_LEVEL); int32_t SetSystemSoundUri(const std::string &key, const std::string &uri); @@ -259,6 +260,9 @@ public: void HandleSaveVolume(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel, std::string networkId); + void HandleSaveVolumeDegree(DeviceType deviceType, AudioStreamType streamType, + int32_t volumeDegree, std::string networkId); + void HandleStreamMuteStatus(AudioStreamType streamType, bool mute, StreamUsage streamUsage = STREAM_USAGE_UNKNOWN, const DeviceType &deviceType = DEVICE_TYPE_NONE, std::string networkId = LOCAL_NETWORK_ID); @@ -306,11 +310,17 @@ public: void SaveSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel); int32_t GetSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType); int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume); + int32_t SetSystemVolumeDegree(AudioStreamType streamType, int32_t volumeDegree); + int32_t GetSystemVolumeDegree(AudioStreamType streamType); + int32_t GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType = DEVICE_TYPE_NONE); private: + float CalculateVolumeDbNonlinearExt(AudioStreamType streamType, DeviceType deviceType, int32_t volumeDegree); + int32_t SetVolumeDb(AudioStreamType streamType, int32_t volumeDegree); friend class PolicyCallbackImpl; static constexpr int32_t MAX_VOLUME_LEVEL = 15; static constexpr int32_t MIN_VOLUME_LEVEL = 0; + static constexpr int32_t MIN_VALID_VOLUME_DEGREE = 1; static constexpr int32_t DEFAULT_VOLUME_LEVEL = 7; static constexpr int32_t DP_DEFAULT_VOLUME_LEVEL = 25; static constexpr int32_t APP_MAX_VOLUME_LEVEL = 100; diff --git a/services/audio_policy/server/domain/volume/include/audio_adapter_manager_handler.h b/services/audio_policy/server/domain/volume/include/audio_adapter_manager_handler.h index 8fd66887f2bc8fe82bdb261a6212dc27f84374e3..467174db6ab6a2c416c11bb24366c406007ebd53 100644 --- a/services/audio_policy/server/domain/volume/include/audio_adapter_manager_handler.h +++ b/services/audio_policy/server/domain/volume/include/audio_adapter_manager_handler.h @@ -40,6 +40,7 @@ public: VOLUME_DATABASE_SAVE, STREAM_MUTE_STATUS_UPDATE, RINGER_MODE_UPDATE, + VOLUME_DEGREE_DATABASE_SAVE, }; struct VolumeDataEvent { @@ -52,6 +53,7 @@ public: AudioStreamType streamType_; int32_t volumeLevel_; std::string networkId_; + int32_t volumeDegree_; }; struct StreamMuteStatusEvent { @@ -78,6 +80,8 @@ public: bool SendKvDataUpdate(const bool &isFirstBoot); bool SendSaveVolume(const DeviceType &deviceType, const AudioStreamType &streamType, const int32_t &volumeLevel, std::string networkId = "LocalDevice"); + bool SendSaveVolumeDegree(DeviceType deviceType, AudioStreamType streamType, int32_t volumeDegree, + std::string networkId = "LocalDevice"); bool SendStreamMuteStatusUpdate(const AudioStreamType &streamType, const bool &mute, const StreamUsage &streamUsage, const DeviceType &deviceType = DEVICE_TYPE_NONE, std::string networkId = LOCAL_NETWORK_ID); @@ -90,6 +94,7 @@ private: /* Handle Event*/ void HandleUpdateKvDataEvent(const AppExecFwk::InnerEvent::Pointer &event); void HandleVolumeDataBaseSave(const AppExecFwk::InnerEvent::Pointer &event); + void HandleVolumeDegreeDataBaseSave(const AppExecFwk::InnerEvent::Pointer &event); void HandleUpdateStreamMuteStatus(const AppExecFwk::InnerEvent::Pointer &event); void HandleUpdateRingerMode(const AppExecFwk::InnerEvent::Pointer &event); diff --git a/services/audio_policy/server/domain/volume/include/audio_volume_manager.h b/services/audio_policy/server/domain/volume/include/audio_volume_manager.h index 302cdc30a0319c70a98f81edccfe1f3ef1d2b076..559726f4f2c28bdf4c303bd106f424ad5ecdb4a1 100644 --- a/services/audio_policy/server/domain/volume/include/audio_volume_manager.h +++ b/services/audio_policy/server/domain/volume/include/audio_volume_manager.h @@ -87,7 +87,8 @@ public: int32_t GetSystemVolumeLevel(AudioStreamType streamType, int32_t zoneId = 0); int32_t GetAppVolumeLevel(int32_t appUid, int32_t &volumeLevel); int32_t GetSystemVolumeLevelNoMuteState(AudioStreamType streamType); - int32_t SetSystemVolumeLevel(AudioStreamType streamType, int32_t volumeLevel, int32_t zoneId = 0); + int32_t SetSystemVolumeLevel(AudioStreamType streamType, int32_t volumeLevel, int32_t zoneId = 0, + bool syncVolDegree = true); int32_t SetAppVolumeMuted(int32_t appUid, bool muted); int32_t IsAppVolumeMute(int32_t appUid, bool owned, bool &isMute); int32_t SetAppRingMuted(int32_t appUid, bool muted); @@ -139,6 +140,10 @@ public: bool IsNeedForceControlVolumeType(); AudioVolumeType GetForceControlVolumeType(); void SendLoudVolumeMode(LoudVolumeHoldType funcHoldType, bool state, bool repeatTrigNotif = false); + int32_t SetSystemVolumeDegree(AudioStreamType streamType, int32_t volumeDegree, + int32_t zoneId, bool syncVolLevel = true); + int32_t GetSystemVolumeDegree(AudioStreamType streamType); + int32_t GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType) const; private: AudioVolumeManager() : audioPolicyManager_(AudioPolicyManagerFactory::GetAudioPolicyManager()), @@ -179,6 +184,8 @@ private: int32_t HandleA2dpAbsVolume(AudioStreamType streamType, int32_t volumeLevel, DeviceType curDeviceType); int32_t HandleNearlinkDeviceAbsVolume(AudioStreamType streamType, int32_t volumeLevel, DeviceType curDeviceType); + int32_t SetSystemVolumeLevelInner(AudioStreamType streamType, int32_t volumeLevel, int32_t zoneId); + int32_t SetSystemVolumeDegreeInner(AudioStreamType streamType, int32_t volumeDegree, int32_t zoneId); private: std::shared_ptr policyVolumeMap_ = nullptr; volatile Volume *volumeVector_ = nullptr; diff --git a/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h b/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h index 0f50e6eae4907157d24a22da84d2e2010f2f528b..aefc926e1e49f8f2ad7897e89952d7c658eeb65d 100644 --- a/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h +++ b/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h @@ -136,7 +136,7 @@ public: virtual bool SetSinkMute(const std::string &sinkName, bool isMute, bool isSync = false) = 0; - virtual float CalculateVolumeDb(int32_t volumeLevel) = 0; + virtual float CalculateVolumeDb(int32_t volumeLevel, int32_t maxDegree = 0) = 0; virtual int32_t SetSystemSoundUri(const std::string &key, const std::string &uri) = 0; @@ -209,6 +209,9 @@ public: virtual void HandleSaveVolume(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel, std::string networkId) = 0; + virtual void HandleSaveVolumeDegree(DeviceType deviceType, AudioStreamType streamType, int32_t volumeDegree, + std::string networkId) = 0; + virtual void HandleStreamMuteStatus(AudioStreamType streamType, bool mute, StreamUsage streamUsage = STREAM_USAGE_UNKNOWN, const DeviceType &deviceType = DEVICE_TYPE_NONE, @@ -263,6 +266,9 @@ public: virtual float CalculateVolumeDbNonlinear(AudioStreamType streamType, DeviceType deviceType, int32_t volumeLevel) = 0; + virtual int32_t SetSystemVolumeDegree(AudioStreamType streamType, int32_t volumeDegree) = 0; + virtual int32_t GetSystemVolumeDegree(AudioStreamType streamType) = 0; + virtual int32_t GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/volume/include/volume_data_maintainer.h b/services/audio_policy/server/domain/volume/include/volume_data_maintainer.h index 875531bcb27d1f5dbffa75ea67b72cc7bc54f648..c2fa52dae8120c8a7534ef5b680b3555f7b8ef6d 100644 --- a/services/audio_policy/server/domain/volume/include/volume_data_maintainer.h +++ b/services/audio_policy/server/domain/volume/include/volume_data_maintainer.h @@ -136,6 +136,11 @@ public: void SaveSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel); int32_t GetSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType); + void SetVolumeDegree(AudioStreamType streamType, int32_t volumeDegree); + int32_t GetVolumeDegree(AudioStreamType streamType); + bool SaveVolumeDegree(DeviceType type, AudioStreamType streamType, int32_t volumeDegree, + std::string networkId = LOCAL_NETWORK_ID); + bool GetVolumeDegree(DeviceType deviceType, AudioStreamType streamType, std::string networkId = LOCAL_NETWORK_ID); private: static std::string GetVolumeKeyForDataShare(DeviceType deviceType, AudioStreamType streamType, std::string networkId = LOCAL_NETWORK_ID); @@ -165,6 +170,7 @@ private: // Stores the mute status of audio streams used by the app. std::unordered_map> appStreamMuteMap_; + std::unordered_map volumeDegreeMap_; // save system volume degree map bool isSettingsCloneHaveStarted_ = false; std::unordered_map> deviceTypeToSystemVolumeForEffectMap_; }; diff --git a/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp b/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp index 44e41f309267c8018f9a91f71b04848bb6f87ad9..42dfa57d9dd6e2f605a811be485dfea457854597 100644 --- a/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp +++ b/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp @@ -653,6 +653,12 @@ void AudioAdapterManager::HandleSaveVolume(DeviceType deviceType, AudioStreamTyp volumeDataMaintainer_.SaveVolume(deviceType, streamType, volumeLevel, networkId); } +void AudioAdapterManager::HandleSaveVolumeDegree(DeviceType deviceType, AudioStreamType streamType, + int32_t volumeDegree, std::string networkId) +{ + volumeDataMaintainer_.SaveVolumeDegree(deviceType, streamType, volumeDegree, networkId); +} + void AudioAdapterManager::HandleStreamMuteStatus(AudioStreamType streamType, bool mute, StreamUsage streamUsage, const DeviceType &deviceType, std::string networkId) { @@ -769,6 +775,33 @@ int32_t AudioAdapterManager::SetVolumeDb(AudioStreamType streamType) return SUCCESS; } +int32_t AudioAdapterManager::SetVolumeDb(AudioStreamType streamType, int32_t volumeDegree) +{ + float volumeDb = 1.0f; + if (useNonlinearAlgo_) { + if (Util::IsDualToneStreamType(streamType) && + currentActiveDevice_.deviceType_ != DEVICE_TYPE_REMOTE_CAST && !VolumeUtils::IsPCVolumeEnable()) { + volumeDb = CalculateVolumeDbNonlinearExt(streamType, DEVICE_TYPE_SPEAKER, volumeDegree); + } else { + volumeDb = CalculateVolumeDbNonlinearExt(streamType, currentActiveDevice_.deviceType_, volumeDegree); + } + } else { + volumeDb = CalculateVolumeDb(volumeDegree, MAX_VOLUME_DEGREE); + } + // Set voice call assistant stream to full volume + if (streamType == STREAM_VOICE_CALL_ASSISTANT) { + volumeDb = 1.0f; + } + + AUDIO_INFO_LOG("streamType:%{public}d volumeDb:%{public}f volumeDegree:%{public}d devicetype:%{public}d", + streamType, volumeDb, volumeDegree, currentActiveDevice_.deviceType_); + + // audio volume + SetAudioVolume(streamType, volumeDb); + + return SUCCESS; +} + void AudioAdapterManager::SetAppAudioVolume(int32_t appUid, float volumeDb) { std::lock_guard lock(audioVolumeMutex_); @@ -977,8 +1010,10 @@ int32_t AudioAdapterManager::SetInnerStreamMute(AudioStreamType streamType, bool int32_t volume = GetSystemVolumeLevel(streamType); VolumeEvent volumeEvent = VolumeEvent(streamType, volume, false); + volumeEvent.volumeDegree = GetSystemVolumeDegree(streamType); if (audioPolicyServerHandler_ != nullptr) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } return SetVolumeDb(streamType); @@ -2338,6 +2373,11 @@ void AudioAdapterManager::InitVolumeMap(bool isFirstBoot) auto ret = volumeDataMaintainer_.SaveVolume(deviceType, streamType, volumeLevel); resetFirstFlag = ret ? resetFirstFlag : true; } + + if (!volumeDataMaintainer_.GetVolumeDegree(deviceType, streamType)) { + int32_t defVolumeDegree = MIN_VOLUME_LEVEL; + volumeDataMaintainer_.SaveVolumeDegree(deviceType, streamType, defVolumeDegree); + } } } if (resetFirstFlag) { @@ -2506,9 +2546,12 @@ bool AudioAdapterManager::LoadVolumeMap(void) for (auto &streamType: defaultVolumeTypeList_) { if (Util::IsDualToneStreamType(streamType) && currentActiveDevice_.deviceType_ != DEVICE_TYPE_REMOTE_CAST) { result = volumeDataMaintainer_.GetVolume(DEVICE_TYPE_SPEAKER, streamType, currentActiveDevice_.networkId_); + volumeDataMaintainer_.GetVolumeDegree(DEVICE_TYPE_SPEAKER, streamType, currentActiveDevice_.networkId_); } else { result = volumeDataMaintainer_.GetVolume(currentActiveDevice_.deviceType_, streamType, currentActiveDevice_.networkId_); + volumeDataMaintainer_.GetVolumeDegree(currentActiveDevice_.deviceType_, streamType, + currentActiveDevice_.networkId_); } if (!result) { AUDIO_ERR_LOG("LoadVolumeMap: Could not load volume for streamType[%{public}d] from kvStore", streamType); @@ -2590,11 +2633,13 @@ void AudioAdapterManager::SetVolumeCallbackAfterClone() VolumeEvent volumeEvent; volumeEvent.volumeType = streamType; volumeEvent.volume = GetSystemVolumeLevel(streamType); + volumeEvent.volumeDegree = GetSystemVolumeDegree(streamType); volumeEvent.updateUi = false; volumeEvent.volumeGroupId = 0; volumeEvent.networkId = LOCAL_NETWORK_ID; if (audioPolicyServerHandler_ != nullptr) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } } } @@ -2893,9 +2938,13 @@ std::string AudioAdapterManager::GetMuteKeyForDeviceType(DeviceType deviceType, return type; } -float AudioAdapterManager::CalculateVolumeDb(int32_t volumeLevel) +float AudioAdapterManager::CalculateVolumeDb(int32_t volumeLevel, int32_t maxDegree) { - float value = static_cast(volumeLevel) / MAX_VOLUME_LEVEL; + if (maxDegree == 0) { + maxDegree = MAX_VOLUME_LEVEL; + } + + float value = static_cast(volumeLevel) / maxDegree; float roundValue = static_cast(value * CONST_FACTOR); return static_cast(roundValue) / CONST_FACTOR; @@ -3069,6 +3118,42 @@ float AudioAdapterManager::CalculateVolumeDbNonlinear(AudioStreamType streamType return exp(dbValue * 0.115129f); } +float AudioAdapterManager::CalculateVolumeDbNonlinearExt(AudioStreamType streamType, + DeviceType deviceType, int32_t volumeDegree) +{ + AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + int32_t volumeLevelMax = GetMaxVolumeLevel(volumeType); + int32_t volumeLevel = VolumeUtils::VolumeDegreeToLevel(volumeDegree, volumeLevelMax); + int32_t volumeLevelMin = GetMinVolumeLevel(volumeType); + int32_t preVolumeLevel = std::max(volumeLevel - 1, volumeLevelMin); + int32_t nextVolumeLevel = std::min(volumeLevel + 1, volumeLevelMax); + + float curDbFactor = CalculateVolumeDbNonlinear(streamType, deviceType, volumeLevel); + float preDbFactor = CalculateVolumeDbNonlinear(streamType, deviceType, preVolumeLevel); + float nextDbFactor = CalculateVolumeDbNonlinear(streamType, deviceType, nextVolumeLevel); + + int32_t curDegreeBase = VolumeUtils::VolumeLevelToDegree(volumeLevel, volumeLevelMax); + int32_t preDegreeCeiling = VolumeUtils::GetVolumeLevelMaxDegree(preVolumeLevel, volumeLevelMax); + float dbValue = 0.0f; + if (volumeDegree < curDegreeBase) { + int32_t preDegreeBase = VolumeUtils::VolumeLevelToDegree(preVolumeLevel, volumeLevelMax); + int32_t divide1 = std::max(curDegreeBase - preDegreeBase + preDegreeCeiling - preDegreeBase, 1); + int32_t divide2 = std::max(curDegreeBase - preDegreeBase, 1); + float baseDbFactor = preDbFactor + (curDbFactor - preDbFactor) * (preDegreeCeiling - preDegreeBase) / divide1; + dbValue = baseDbFactor + (curDbFactor - preDbFactor) * (volumeDegree - preDegreeCeiling) / divide2; + } else { + int32_t nextDegreeBase = VolumeUtils::VolumeLevelToDegree(nextVolumeLevel, volumeLevelMax); + int32_t curDegreeCeiling = VolumeUtils::GetVolumeLevelMaxDegree(volumeLevel, volumeLevelMax); + int32_t divide = std::max(nextDegreeBase - curDegreeBase + curDegreeCeiling - curDegreeBase, 1); + dbValue = curDbFactor + (nextDbFactor - curDbFactor) * (volumeDegree - curDegreeBase) / divide; + } + + AUDIO_DEBUG_LOG("volumeDegree=%{public}d, curDegreeBase=%{public}d, " + "volumeLevel=%{public}d, preDegreeCeiling=%{public}d, db=%{public}f", + volumeDegree, curDegreeBase, volumeLevel, preDegreeCeiling, dbValue); + return dbValue; +} + void AudioAdapterManager::InitVolumeMapIndex() { useNonlinearAlgo_ = 0; @@ -3407,5 +3492,62 @@ int32_t AudioAdapterManager::SetSystemVolumeToEffect(AudioStreamType streamType, return audioServiceAdapter_->SetSystemVolumeToEffect(streamType, volume); } // LCOV_EXCL_STOP + +int32_t AudioAdapterManager::SetSystemVolumeDegree(AudioStreamType streamType, int32_t volumeDegree) +{ + Trace trace("streamType:" + std::to_string(streamType) + ", volumeDegree:" + std::to_string(volumeDegree)); + AUDIO_INFO_LOG("streamType: %{public}d, deviceType: %{public}d, volumeDegree:%{public}d", + streamType, currentActiveDevice_.deviceType_, volumeDegree); + if (GetSystemVolumeDegree(streamType) == volumeDegree && + currentActiveDevice_.deviceType_ != DEVICE_TYPE_BLUETOOTH_SCO && + currentActiveDevice_.deviceType_ != DEVICE_TYPE_BLUETOOTH_A2DP && !VolumeUtils::IsPCVolumeEnable()) { + AUDIO_INFO_LOG("The volume is the same as before."); + return SUCCESS; + } + + if (volumeDegree == 0 && !VolumeUtils::IsPCVolumeEnable() && + (streamType == STREAM_VOICE_CALL || + streamType == STREAM_ALARM || streamType == STREAM_ACCESSIBILITY || + streamType == STREAM_VOICE_COMMUNICATION)) { + // these types can not set to mute, but don't return error + AUDIO_ERR_LOG("this type can not set mute"); + return SUCCESS; + } + + int32_t minRet = GetMinVolumeDegree(streamType); + CHECK_AND_RETURN_RET_LOG(volumeDegree >= minRet && volumeDegree <= MAX_VOLUME_DEGREE, ERR_OPERATION_FAILED, + "volume not in scope, mimRet:%{public}d", minRet); + + volumeDataMaintainer_.SetVolumeDegree(streamType, volumeDegree); + + if (handler_ != nullptr) { + if (Util::IsDualToneStreamType(streamType) && currentActiveDevice_.deviceType_ != DEVICE_TYPE_REMOTE_CAST) { + AUDIO_INFO_LOG("DualToneStreamType. Save volume for speaker."); + handler_->SendSaveVolumeDegree(DEVICE_TYPE_SPEAKER, streamType, volumeDegree, "LocalDevice"); + } else { + handler_->SendSaveVolumeDegree(currentActiveDevice_.deviceType_, streamType, volumeDegree, + currentActiveDevice_.networkId_); + } + } + + return SetVolumeDb(streamType, volumeDegree); +} + +int32_t AudioAdapterManager::GetSystemVolumeDegree(AudioStreamType streamType) +{ + if (GetStreamMuteInternal(streamType)) { + return MIN_VOLUME_LEVEL; + } + + return volumeDataMaintainer_.GetVolumeDegree(streamType); +} + +int32_t AudioAdapterManager::GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType) +{ + int32_t minLevel = GetMinVolumeLevel(volumeType, deviceType); + int32_t maxLevel = GetMaxVolumeLevel(volumeType, deviceType); + int32_t minDegree = VolumeUtils::VolumeLevelToDegree(minLevel, maxLevel); + return std::min(MIN_VALID_VOLUME_DEGREE, minDegree); +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/volume/src/audio_adapter_manager_handler.cpp b/services/audio_policy/server/domain/volume/src/audio_adapter_manager_handler.cpp index 7d538c407476b91b706ed462954fc645af109111..b0058114fb0d2d331627117fbcd7db5a915a484e 100644 --- a/services/audio_policy/server/domain/volume/src/audio_adapter_manager_handler.cpp +++ b/services/audio_policy/server/domain/volume/src/audio_adapter_manager_handler.cpp @@ -63,6 +63,19 @@ bool AudioAdapterManagerHandler::SendSaveVolume(const DeviceType &deviceType, return ret; } +bool AudioAdapterManagerHandler::SendSaveVolumeDegree(DeviceType deviceType, AudioStreamType streamType, + int32_t volumeDegree, std::string networkId) +{ + auto eventContextObj = std::make_shared(deviceType, streamType, 0, networkId); + CHECK_AND_RETURN_RET_LOG(eventContextObj != nullptr, false, "EventContextObj get nullptr"); + eventContextObj->volumeDegree_ = volumeDegree; + lock_guard runnerlock(runnerMutex_); + bool ret = SendEvent(AppExecFwk::InnerEvent::Get( + EventAdapterManagerServerCmd::VOLUME_DEGREE_DATABASE_SAVE, eventContextObj)); + CHECK_AND_RETURN_RET_LOG(ret, ret, "send event failed"); + return ret; +} + bool AudioAdapterManagerHandler::SendStreamMuteStatusUpdate(const AudioStreamType &streamType, const bool &mute, const StreamUsage &streamUsage, const DeviceType &deviceType, std::string networkId) { @@ -104,6 +117,14 @@ void AudioAdapterManagerHandler::HandleVolumeDataBaseSave(const AppExecFwk::Inne eventContextObj->streamType_, eventContextObj->volumeLevel_, eventContextObj->networkId_); } +void AudioAdapterManagerHandler::HandleVolumeDegreeDataBaseSave(const AppExecFwk::InnerEvent::Pointer &event) +{ + std::shared_ptr eventContextObj = event->GetSharedObject(); + CHECK_AND_RETURN_LOG(eventContextObj != nullptr, "EventContextObj get nullptr"); + AudioPolicyManagerFactory::GetAudioPolicyManager().HandleSaveVolumeDegree(eventContextObj->deviceType_, + eventContextObj->streamType_, eventContextObj->volumeDegree_, eventContextObj->networkId_); +} + void AudioAdapterManagerHandler::HandleUpdateStreamMuteStatus(const AppExecFwk::InnerEvent::Pointer &event) { std::shared_ptr eventContextObj = event->GetSharedObject(); @@ -144,6 +165,9 @@ void AudioAdapterManagerHandler::ProcessEvent(const AppExecFwk::InnerEvent::Poin case RINGER_MODE_UPDATE: HandleUpdateRingerMode(event); break; + case VOLUME_DEGREE_DATABASE_SAVE: + HandleVolumeDegreeDataBaseSave(event); + break; default: break; } diff --git a/services/audio_policy/server/domain/volume/src/audio_volume_manager.cpp b/services/audio_policy/server/domain/volume/src/audio_volume_manager.cpp index f530d60b6d59be780be1c67c00bbe34b16b83350..060a7c1628c8cb73f9ed1ad4a6dad32b1c89ac4b 100644 --- a/services/audio_policy/server/domain/volume/src/audio_volume_manager.cpp +++ b/services/audio_policy/server/domain/volume/src/audio_volume_manager.cpp @@ -154,8 +154,10 @@ bool AudioVolumeManager::SetSharedVolume(AudioVolumeType streamType, DeviceType volumeVector_[index].isMute = vol.isMute; volumeVector_[index].volumeFloat = vol.volumeFloat; volumeVector_[index].volumeInt = vol.volumeInt; - AUDIO_INFO_LOG("Success Set Shared Volume with StreamType:%{public}d, DeviceType:%{public}d, volume:%{public}d", - streamType, deviceType, vol.volumeInt); + volumeVector_[index].volumeDegree = vol.volumeDegree; + AUDIO_INFO_LOG("Success Set Shared Volume with StreamType:%{public}d, DeviceType:%{public}d, \ + volume:%{public}d, volumeDegree:%{public}d", + streamType, deviceType, vol.volumeInt, vol.volumeDegree); AudioServerProxy::GetInstance().NotifyStreamVolumeChangedProxy(streamType, vol.volumeFloat); return true; @@ -462,6 +464,24 @@ int32_t AudioVolumeManager::HandleNearlinkDeviceAbsVolume(AudioStreamType stream } int32_t AudioVolumeManager::SetSystemVolumeLevel(AudioStreamType streamType, int32_t volumeLevel, + int32_t zoneId, bool syncVolDegree) +{ + if (syncVolDegree) { + AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + int32_t currentVolumeLevel = GetSystemVolumeLevel(streamType, zoneId); + if (volumeLevel != currentVolumeLevel) { + int32_t volumeLevelMax = GetMaxVolumeLevel(volumeType); + int32_t volumeDegree = VolumeUtils::VolumeLevelToDegree(volumeLevel, volumeLevelMax); + SetSystemVolumeDegreeInner(streamType, volumeDegree, zoneId); + } else { + AUDIO_WARNING_LOG("volume level dont change, keep volume degree unchanged"); + } + } + + return SetSystemVolumeLevelInner(streamType, volumeLevel, zoneId); +} + +int32_t AudioVolumeManager::SetSystemVolumeLevelInner(AudioStreamType streamType, int32_t volumeLevel, int32_t zoneId) { if (zoneId > 0) { @@ -585,6 +605,10 @@ int32_t AudioVolumeManager::SetA2dpDeviceVolume(const std::string &macAddress, c audioA2dpDevice_.SetA2dpDeviceMute(macAddress, mute); audioPolicyManager_.SetAbsVolumeMute(mute); + AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(STREAM_MUSIC); + int32_t volumeLevelMax = GetMaxVolumeLevel(volumeType); + int32_t volumeDegree = VolumeUtils::VolumeLevelToDegree(volumeLevel, volumeLevelMax); + audioPolicyManager_.SetSystemVolumeDegree(volumeType, volumeDegree); AUDIO_INFO_LOG("success for macaddress:[%{public}s], volume value:[%{public}d]", GetEncryptAddr(macAddress).c_str(), sVolumeLevel); AUDIO_INFO_LOG("SetA2dpAbsVolume streamType: STREAM_MUSIC, volumeLevel: %{public}d", sVolumeLevel); @@ -640,6 +664,10 @@ int32_t AudioVolumeManager::SetNearlinkDeviceVolume(const std::string &macAddres } isBtFirstBoot_ = false; } + AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + int32_t volumeLevelMax = GetMaxVolumeLevel(volumeType); + int32_t volumeDegree = VolumeUtils::VolumeLevelToDegree(volumeLevel, volumeLevelMax); + audioPolicyManager_.SetSystemVolumeDegree(volumeType, volumeDegree); ret = SleAudioDeviceManager::GetInstance().SetNearlinkDeviceVolumeLevel(macAddress, streamType, sVolumeLevel); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "SetDeviceAbsVolume failed"); ret = SetNearlinkDeviceVolumeEx(streamType, sVolumeLevel); @@ -982,11 +1010,13 @@ void AudioVolumeManager::SetSafeVolumeCallback(AudioStreamType streamType) VolumeEvent volumeEvent; volumeEvent.volumeType = streamType; volumeEvent.volume = GetSystemVolumeLevel(streamType); + volumeEvent.volumeDegree = GetSystemVolumeDegree(streamType); volumeEvent.updateUi = true; volumeEvent.volumeGroupId = 0; volumeEvent.networkId = LOCAL_NETWORK_ID; if (audioPolicyServerHandler_ != nullptr && IsRingerModeMute()) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } } @@ -1499,5 +1529,48 @@ void ForceControlVolumeTypeMonitor::SetTimer(int32_t duration, duration_ = (duration > MAX_DURATION_TIME_S ? MAX_DURATION_TIME_S : duration); StartMonitor(duration_, cb); } + +int32_t AudioVolumeManager::SetSystemVolumeDegree(AudioStreamType streamType, int32_t volumeDegree, + int32_t zoneId, bool syncVolLevel) +{ + if (syncVolLevel) { + AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + int32_t volumeLevelMax = GetMaxVolumeLevel(volumeType); + int32_t volumeLevel = VolumeUtils::VolumeDegreeToLevel(volumeDegree, volumeLevelMax); + SetSystemVolumeLevelInner(streamType, volumeLevel, zoneId); + } + + return SetSystemVolumeDegreeInner(streamType, volumeDegree, zoneId); +} + +int32_t AudioVolumeManager::SetSystemVolumeDegreeInner(AudioStreamType streamType, int32_t volumeDegree, + int32_t zoneId) +{ + AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + int32_t maxLevel = GetMaxVolumeLevel(volumeType); + int32_t volumeLevel = VolumeUtils::VolumeDegreeToLevel(volumeDegree, maxLevel); + Volume vol{}; + vol.isMute = volumeDegree == 0; + vol.volumeInt = volumeLevel; + vol.volumeDegree = static_cast(volumeDegree); + vol.volumeFloat = audioPolicyManager_.CalculateVolumeDb(volumeDegree, MAX_VOLUME_DEGREE); + DeviceType curOutputDeviceType = audioActiveDevice_.GetCurrentOutputDeviceType(); + SetSharedVolume(streamType, curOutputDeviceType, vol); + + return audioPolicyManager_.SetSystemVolumeDegree(volumeType, volumeDegree); +} + +int32_t AudioVolumeManager::GetSystemVolumeDegree(AudioStreamType streamType) +{ + return audioPolicyManager_.GetSystemVolumeDegree(streamType); +} + +int32_t AudioVolumeManager::GetMinVolumeDegree(AudioVolumeType volumeType, DeviceType deviceType) const +{ + if (volumeType == STREAM_ALL) { + volumeType = STREAM_MUSIC; + } + return audioPolicyManager_.GetMinVolumeDegree(volumeType, deviceType); +} } } diff --git a/services/audio_policy/server/domain/volume/src/volume_data_maintainer.cpp b/services/audio_policy/server/domain/volume/src/volume_data_maintainer.cpp index cdf1ad2efc783b36ebace8f770131ad0e4f8baaf..0f70f1be0e00d1f71ab1747ba7a46867ed4c9aa1 100644 --- a/services/audio_policy/server/domain/volume/src/volume_data_maintainer.cpp +++ b/services/audio_policy/server/domain/volume/src/volume_data_maintainer.cpp @@ -117,6 +117,29 @@ bool VolumeDataMaintainer::SaveVolume(DeviceType type, AudioStreamType streamTyp return SaveVolumeInternal(type, streamForVolumeMap, volumeLevel, networkId); } +bool VolumeDataMaintainer::SaveVolumeDegree(DeviceType type, AudioStreamType streamTypeIn, + int32_t volumeDegree, std::string networkId) +{ + std::lock_guard lock(volumeForDbMutex_); + AudioStreamType streamType = VolumeUtils::GetVolumeTypeFromStreamType(streamTypeIn); + + std::string volumeKey = GetVolumeKeyForDataShare(type, streamType, networkId); + if (!volumeKey.compare("")) { + AUDIO_ERR_LOG("[device %{public}d, streamType %{public}d] is not supported for datashare", + type, streamType); + return false; + } + volumeKey += "_degree"; + + AudioSettingProvider& audioSettingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID); + ErrCode ret = audioSettingProvider.PutIntValue(volumeKey, volumeDegree, "system"); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("Save Volume To DataBase volumeMap failed"); + return false; + } + return true; +} + bool VolumeDataMaintainer::SaveVolumeInternal(DeviceType type, AudioStreamType streamType, int32_t volumeLevel, std::string networkId) { @@ -147,6 +170,38 @@ bool VolumeDataMaintainer::GetVolume(DeviceType deviceType, AudioStreamType stre return GetVolumeInternal(deviceType, streamForVolumeMap, networkId); } +bool VolumeDataMaintainer::GetVolumeDegree(DeviceType deviceType, AudioStreamType streamTypeIn, std::string networkId) +{ + std::lock_guard lock(volumeForDbMutex_); + AudioStreamType streamType = VolumeUtils::GetVolumeTypeFromStreamType(streamTypeIn); + // Voice call assistant stream is full volume by default + if (streamType == STREAM_VOICE_CALL_ASSISTANT) { + return true; + } + std::string volumeKey = GetVolumeKeyForDataShare(deviceType, streamType, networkId); + if (!volumeKey.compare("")) { + AUDIO_ERR_LOG("[device %{public}d, streamType %{public}d] is not supported for datashare", + deviceType, streamType); + return false; + } + volumeKey += "_degree"; + + AudioSettingProvider& audioSettingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID); + int32_t volumeValue = 0; + ErrCode ret = audioSettingProvider.GetIntValue(volumeKey, volumeValue, "system"); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("Get streamType %{public}d, deviceType %{public}d, Volume FromDataBase volumeMap failed.", + streamType, deviceType); + return false; + } else { + volumeDegreeMap_[streamType] = volumeValue; + AUDIO_PRERELEASE_LOGI("Get streamType %{public}d, deviceType %{public}d, "\ + "Volume FromDataBase volumeMap from datashare %{public}d.", streamType, deviceType, volumeValue); + } + + return true; +} + bool VolumeDataMaintainer::GetVolumeInternal(DeviceType deviceType, AudioStreamType streamType, std::string networkId) { // Voice call assistant stream is full volume by default @@ -1064,5 +1119,19 @@ int32_t VolumeDataMaintainer::GetSystemVolumeForEffect(DeviceType deviceType, Au return DEFAULT_SYSTEM_VOLUME_FOR_EFFECT; } +void VolumeDataMaintainer::SetVolumeDegree(AudioStreamType streamType, int32_t volumeDegree) +{ + std::lock_guard lock(volumeMutex_); + AudioStreamType streamForVolumeMap = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + volumeDegreeMap_[streamForVolumeMap] = volumeDegree; +} + +int32_t VolumeDataMaintainer::GetVolumeDegree(AudioStreamType streamType) +{ + std::lock_guard lock(volumeMutex_); + AudioStreamType streamForVolumeMap = VolumeUtils::GetVolumeTypeFromStreamType(streamType); + return volumeDegreeMap_[streamForVolumeMap]; +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/infra/async_action_handler/include/audio_policy_server_handler.h b/services/audio_policy/server/infra/async_action_handler/include/audio_policy_server_handler.h index b57f2d369a66a28d38ed9410c89b2e35766b4230..19d31bf4bad5ebbdfb51f29004c9b3e572cc78e9 100644 --- a/services/audio_policy/server/infra/async_action_handler/include/audio_policy_server_handler.h +++ b/services/audio_policy/server/infra/async_action_handler/include/audio_policy_server_handler.h @@ -82,6 +82,7 @@ public: SESSION_DEVICE_CHANGE, SESSION_INPUT_DEVICE_CHANGE, INTERRUPT_EVENT_FOR_AUDIO_SESSION, + VOLUME_DEGREE_EVENT, }; /* event data */ class EventContextObj { @@ -159,6 +160,7 @@ public: DeviceBlockStatus status); void HandleMicrophoneBlockedCallback(const AppExecFwk::InnerEvent::Pointer &event); bool SendVolumeKeyEventCallback(const VolumeEvent &volumeEvent); + bool SendVolumeDegreeEventCallback(const VolumeEvent &volumeEvent); bool SendAudioFocusInfoChangeCallback(int32_t callbackCategory, const AudioInterrupt &audioInterrupt, const std::list> &focusInfoList); bool SendRingerModeUpdatedCallback(const AudioRingerMode &ringMode); @@ -220,6 +222,7 @@ private: void HandleDeviceChangedCallback(const AppExecFwk::InnerEvent::Pointer &event); void HandleAvailableDeviceChange(const AppExecFwk::InnerEvent::Pointer &event); void HandleVolumeKeyEvent(const AppExecFwk::InnerEvent::Pointer &event); + void HandleVolumeDegreeEvent(const AppExecFwk::InnerEvent::Pointer &event); void HandleRequestCateGoryEvent(const AppExecFwk::InnerEvent::Pointer &event); void HandleAbandonCateGoryEvent(const AppExecFwk::InnerEvent::Pointer &event); void HandleFocusInfoChangeEvent(const AppExecFwk::InnerEvent::Pointer &event); diff --git a/services/audio_policy/server/infra/async_action_handler/src/audio_policy_server_handler.cpp b/services/audio_policy/server/infra/async_action_handler/src/audio_policy_server_handler.cpp index 58e59c4ec5555948a0aa32dcb745c94493c3e9fa..80e69f53c627ddd14a3532d6c873b411e5b8ffd7 100644 --- a/services/audio_policy/server/infra/async_action_handler/src/audio_policy_server_handler.cpp +++ b/services/audio_policy/server/infra/async_action_handler/src/audio_policy_server_handler.cpp @@ -212,6 +212,20 @@ bool AudioPolicyServerHandler::SendVolumeKeyEventCallback(const VolumeEvent &vol return ret; } +bool AudioPolicyServerHandler::SendVolumeDegreeEventCallback(const VolumeEvent &volumeEvent) +{ + std::shared_ptr eventContextObj = std::make_shared(); + CHECK_AND_RETURN_RET_LOG(eventContextObj != nullptr, false, "EventContextObj get nullptr"); + if (volumeEvent.volumeType == AudioStreamType::STREAM_VOICE_CALL_ASSISTANT) { + return false; + } + eventContextObj->volumeEvent = volumeEvent; + lock_guard runnerlock(runnerMutex_); + bool ret = SendEvent(AppExecFwk::InnerEvent::Get(EventAudioServerCmd::VOLUME_DEGREE_EVENT, eventContextObj)); + CHECK_AND_RETURN_RET_LOG(ret, ret, "SendVolumeKeyEventCallback event failed"); + return ret; +} + bool AudioPolicyServerHandler::SendAudioSessionDeactiveCallback( const std::pair &sessionDeactivePair) { @@ -812,6 +826,34 @@ void AudioPolicyServerHandler::HandleVolumeKeyEvent(const AppExecFwk::InnerEvent } } +void AudioPolicyServerHandler::HandleVolumeDegreeEvent(const AppExecFwk::InnerEvent::Pointer &event) +{ + std::shared_ptr eventContextObj = event->GetSharedObject(); + CHECK_AND_RETURN_LOG(eventContextObj != nullptr, "EventContextObj get nullptr"); + std::lock_guard lock(handleMapMutex_); + for (auto it = audioPolicyClientProxyAPSCbsMap_.begin(); it != audioPolicyClientProxyAPSCbsMap_.end(); ++it) { + std::shared_ptr volumeChangeCb = it->second; + if (volumeChangeCb == nullptr) { + AUDIO_ERR_LOG("nullptr for client : %{public}d", it->first); + continue; + } + if (VolumeUtils::GetVolumeTypeFromStreamType(eventContextObj->volumeEvent.volumeType) == STREAM_SYSTEM && + !volumeChangeCb->hasSystemPermission_) { + AUDIO_DEBUG_LOG("Non system applications do not send system callbacks"); + continue; + } + AUDIO_PRERELEASE_LOGI("clientPid : %{public}d, volumeType : %{public}d," \ + " volumeDegree : %{public}d, updateUi : %{public}d ", it->first, + static_cast(eventContextObj->volumeEvent.volumeType), eventContextObj->volumeEvent.volumeDegree, + static_cast(eventContextObj->volumeEvent.updateUi)); + if (clientCallbacksMap_.count(it->first) > 0 && + clientCallbacksMap_[it->first].count(CALLBACK_SET_VOLUME_DEGREE_CHANGE) > 0 && + clientCallbacksMap_[it->first][CALLBACK_SET_VOLUME_DEGREE_CHANGE]) { + volumeChangeCb->OnVolumeDegreeEvent(eventContextObj->volumeEvent); + } + } +} + void AudioPolicyServerHandler::HandleAudioSessionDeactiveCallback(const AppExecFwk::InnerEvent::Pointer &event) { std::shared_ptr eventContextObj = event->GetSharedObject(); @@ -1644,6 +1686,9 @@ void AudioPolicyServerHandler::HandleOtherServiceEvent(const uint32_t &eventId, case EventAudioServerCmd::SESSION_INPUT_DEVICE_CHANGE: HandleAudioSessionInputDeviceChangeEvent(event); break; + case EventAudioServerCmd::VOLUME_DEGREE_EVENT: + HandleVolumeDegreeEvent(event); + break; default: break; } diff --git a/services/audio_policy/server/infra/ipc_proxy/include/audio_policy_client_holder.h b/services/audio_policy/server/infra/ipc_proxy/include/audio_policy_client_holder.h index a0aadff18eec3fa80b7aa1eaa02503b54e7a0ea7..2cd598c5bd2699b55b42118fe5d69d0e7d523e7b 100644 --- a/services/audio_policy/server/infra/ipc_proxy/include/audio_policy_client_holder.h +++ b/services/audio_policy/server/infra/ipc_proxy/include/audio_policy_client_holder.h @@ -67,6 +67,7 @@ public: void OnAudioSessionStateChanged(const AudioSessionStateChangedEvent &stateChangedEvent); void OnAudioSessionCurrentDeviceChanged(const CurrentOutputDeviceChangedEvent &deviceChangedEvent); void OnAudioSessionCurrentInputDeviceChanged(const CurrentInputDeviceChangedEvent &deviceChangedEvent); + void OnVolumeDegreeEvent(const VolumeEvent &volumeEvent); public: bool hasBTPermission_ = true; diff --git a/services/audio_policy/server/infra/ipc_proxy/src/audio_policy_client_holder.cpp b/services/audio_policy/server/infra/ipc_proxy/src/audio_policy_client_holder.cpp index 615d8cbc3f3048df2214b7c7035a8a3a33c098ec..81e1ae3a7396ed69d74dc6138c5e4f0e5e909e8e 100644 --- a/services/audio_policy/server/infra/ipc_proxy/src/audio_policy_client_holder.cpp +++ b/services/audio_policy/server/infra/ipc_proxy/src/audio_policy_client_holder.cpp @@ -284,5 +284,12 @@ void AudioPolicyClientHolder::OnAudioSessionCurrentInputDeviceChanged( CHECK_AND_RETURN_LOG(audioPolicyClient_ != nullptr, "audioPolicyClient_ is nullptr."); audioPolicyClient_->OnAudioSessionCurrentInputDeviceChanged(deviceChangedEvent); } + +void AudioPolicyClientHolder::OnVolumeDegreeEvent(const VolumeEvent &volumeEvent) +{ + CHECK_AND_RETURN_LOG(audioPolicyClient_ != nullptr, "audioPolicyClient_ is nullptr."); + audioPolicyClient_->OnVolumeDegreeEvent(volumeEvent); +} + } // namespace AudioStandard } // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/server/infra/ipc_proxy/test/unittest/audio_policy_client_holder_unit_test/include/mock_audio_policy_client.h b/services/audio_policy/server/infra/ipc_proxy/test/unittest/audio_policy_client_holder_unit_test/include/mock_audio_policy_client.h index dc7963d178d6683b6c410aec208ea1011276ab6c..828ad9b76922e126a8d3d431c078079be9ada435 100644 --- a/services/audio_policy/server/infra/ipc_proxy/test/unittest/audio_policy_client_holder_unit_test/include/mock_audio_policy_client.h +++ b/services/audio_policy/server/infra/ipc_proxy/test/unittest/audio_policy_client_holder_unit_test/include/mock_audio_policy_client.h @@ -100,6 +100,8 @@ public: (const CurrentOutputDeviceChangedEvent& deviceChangedEvent), (override)); MOCK_METHOD(ErrCode, OnAudioSessionCurrentInputDeviceChanged, (const CurrentInputDeviceChangedEvent& deviceChangedEvent), (override)); + MOCK_METHOD(ErrCode, OnVolumeDegreeEvent, + (const VolumeEvent& volumeEvent), (override)); }; } // namespace AudioStandard 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 32313acdbb2b10d4a9adb1b47b93c79874f8bf37..554b7faf2acf160ee7aa5fa58b9212839d98a9ea 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 @@ -66,6 +66,13 @@ class AudioPolicyServerHandler; class AudioSessionService; class BluetoothEventSubscriber; +struct VolumeUpdateOption { + bool isUpdateUi = false; + bool mute = false; + int32_t zoneId = 0; + bool syncDegree = true; +}; + class AudioPolicyServer : public SystemAbility, public AudioPolicyStub, public AudioStreamRemovedCallback { @@ -701,6 +708,9 @@ public: int32_t CallRingtoneLibrary(); int32_t ReloadLoudVolumeMode(const int32_t streamInFocus, const int32_t setVolMode, bool &ret) override; bool CheckLoudVolumeMode(bool mute, int32_t volumeLevel, AudioStreamType streamType); + int32_t SetSystemVolumeDegree(int32_t streamType, int32_t volumeDegree, int32_t volumeFlag, int32_t uid) override; + int32_t GetSystemVolumeDegree(int32_t streamType, int32_t uid, int32_t &volumeDegree) override; + int32_t GetMinVolumeDegree(int32_t volumeType, int32_t deviceType, int32_t &volumeDegree) override; protected: void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; void RegisterParamCallback(); @@ -748,14 +758,13 @@ private: // for audio volume and mute status int32_t SetRingerModeInternal(AudioRingerMode inputRingerMode, bool hasUpdatedVolume = false); int32_t SetSystemVolumeLevelInternal(AudioStreamType streamType, int32_t volumeLevel, - bool isUpdateUi, int32_t zoneId = 0); + bool isUpdateUi, int32_t zoneId = 0, bool syncDegree = true); int32_t SetAppVolumeLevelInternal(int32_t appUid, int32_t volumeLevel, bool isUpdateUi); int32_t SetAppVolumeMutedInternal(int32_t appUid, bool muted, bool isUpdateUi); int32_t SetAppRingMutedInternal(int32_t appUid, bool muted); int32_t SetSystemVolumeLevelWithDeviceInternal(AudioStreamType streamType, int32_t volumeLevel, bool isUpdateUi, DeviceType deviceType); - int32_t SetSingleStreamVolume(AudioStreamType streamType, int32_t volumeLevel, bool isUpdateUi, - bool mute, int32_t zoneId = 0); + int32_t SetSingleStreamVolume(AudioStreamType streamType, int32_t volumeLevel, const VolumeUpdateOption &option); int32_t SetAppSingleStreamVolume(int32_t streamType, int32_t volumeLevel, bool isUpdateUi); int32_t SetSingleStreamVolumeWithDevice(AudioStreamType streamType, int32_t volumeLevel, bool isUpdateUi, DeviceType deviceType); @@ -836,6 +845,7 @@ private: void UpdateDefaultOutputDeviceWhenStopping(const uint32_t sessionID); void ChangeVolumeOnVoiceAssistant(AudioStreamType &streamInFocus); AudioStreamType GetCurrentStreamInFocus(); + int32_t GetSystemVolumeDegreeInternal(AudioStreamType streamType); AudioEffectService &audioEffectService_; AudioAffinityManager &audioAffinityManager_; 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 45bbb04a5fc95f0368da98c9ee36fbe025382731..5e4bbf536479d9cd974d8a75e2b798540b31ddfd 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 @@ -436,11 +436,13 @@ bool AudioPolicyServer::MaxOrMinVolumeOption(const int32_t &volLevel, const int3 VolumeEvent volumeEvent; volumeEvent.volumeType = (streamInFocus == STREAM_ALL) ? STREAM_MUSIC : streamInFocus; volumeEvent.volume = volLevel; + volumeEvent.volumeDegree = VolumeUtils::VolumeLevelToDegree(volLevel, volumeLevelMax); volumeEvent.updateUi = true; volumeEvent.volumeGroupId = 0; volumeEvent.networkId = LOCAL_NETWORK_ID; CHECK_AND_RETURN_RET_LOG(audioPolicyServerHandler_ != nullptr, false, "audioPolicyServerHandler_ is nullptr"); audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); return true; } @@ -1481,11 +1483,13 @@ void AudioPolicyServer::SendMuteKeyEventCbWithUpdateUiOrNot(AudioStreamType stre VolumeEvent volumeEvent; volumeEvent.volumeType = streamType; volumeEvent.volume = GetSystemVolumeLevelInternal(streamType, zoneId); + volumeEvent.volumeDegree = GetSystemVolumeDegreeInternal(streamType); volumeEvent.updateUi = isUpdateUi; volumeEvent.volumeGroupId = 0; volumeEvent.networkId = LOCAL_NETWORK_ID; if (audioPolicyServerHandler_ != nullptr) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } } @@ -1597,7 +1601,7 @@ int32_t AudioPolicyServer::IsAppVolumeMute(int32_t appUid, bool owned, bool &isM // LCOV_EXCL_STOP int32_t AudioPolicyServer::SetSystemVolumeLevelInternal(AudioStreamType streamType, int32_t volumeLevel, - bool isUpdateUi, int32_t zoneId) + bool isUpdateUi, int32_t zoneId, bool syncDegree) { AUDIO_INFO_LOG("streamType: %{public}d, volumeLevel: %{public}d, updateUi: %{public}d", streamType, volumeLevel, isUpdateUi); @@ -1613,11 +1617,12 @@ int32_t AudioPolicyServer::SetSystemVolumeLevelInternal(AudioStreamType streamTy CheckLoudVolumeMode(mute, volumeLevel, streamType); } #endif + VolumeUpdateOption option{isUpdateUi, mute, zoneId, syncDegree}; if (streamType == STREAM_ALL) { for (auto audioStreamType : GET_STREAM_ALL_VOLUME_TYPES) { AUDIO_INFO_LOG("SetVolume of STREAM_ALL, SteamType = %{public}d, mute = %{public}d, level = %{public}d", audioStreamType, mute, volumeLevel); - int32_t setResult = SetSingleStreamVolume(audioStreamType, volumeLevel, isUpdateUi, mute, zoneId); + int32_t setResult = SetSingleStreamVolume(audioStreamType, volumeLevel, option); if (setResult != SUCCESS && setResult != ERR_SET_VOL_FAILED_BY_SAFE_VOL && setResult != ERR_SET_VOL_FAILED_BY_VOLUME_CONTROL_DISABLED) { return setResult; @@ -1625,7 +1630,7 @@ int32_t AudioPolicyServer::SetSystemVolumeLevelInternal(AudioStreamType streamTy } return SUCCESS; } - return SetSingleStreamVolume(streamType, volumeLevel, isUpdateUi, mute, zoneId); + return SetSingleStreamVolume(streamType, volumeLevel, option); } int32_t AudioPolicyServer::SetSystemVolumeLevelWithDeviceInternal(AudioStreamType streamType, int32_t volumeLevel, @@ -1648,12 +1653,14 @@ void AudioPolicyServer::SendVolumeKeyEventCbWithUpdateUiOrNot(AudioStreamType st VolumeEvent volumeEvent; volumeEvent.volumeType = streamType; volumeEvent.volume = GetSystemVolumeLevelInternal(streamType, zoneId); + volumeEvent.volumeDegree = GetSystemVolumeDegreeInternal(streamType); volumeEvent.updateUi = isUpdateUi; volumeEvent.volumeGroupId = 0; volumeEvent.networkId = LOCAL_NETWORK_ID; bool ringerModeMute = audioVolumeManager_.IsRingerModeMute(); if (audioPolicyServerHandler_ != nullptr && ringerModeMute) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } } @@ -1719,9 +1726,13 @@ int32_t AudioPolicyServer::SetAppSingleStreamVolume(int32_t appUid, int32_t volu return ret; } -int32_t AudioPolicyServer::SetSingleStreamVolume(AudioStreamType streamType, int32_t volumeLevel, bool isUpdateUi, - bool mute, int32_t zoneId) +int32_t AudioPolicyServer::SetSingleStreamVolume(AudioStreamType streamType, int32_t volumeLevel, + const VolumeUpdateOption &option) { + bool isUpdateUi = option.isUpdateUi; + bool mute = option.mute; + int32_t zoneId = option.zoneId; + bool updateRingerMode = false; if ((streamType == AudioStreamType::STREAM_RING || streamType == AudioStreamType::STREAM_VOICE_RING) && VolumeUtils::GetVolumeTypeFromStreamType(streamType) == AudioStreamType::STREAM_RING) { @@ -1738,7 +1749,7 @@ int32_t AudioPolicyServer::SetSingleStreamVolume(AudioStreamType streamType, int } } - int32_t ret = audioVolumeManager_.SetSystemVolumeLevel(streamType, volumeLevel, zoneId); + int32_t ret = audioVolumeManager_.SetSystemVolumeLevel(streamType, volumeLevel, zoneId, option.syncDegree); if (ret == SUCCESS) { std::string currentTime = GetTime(); int32_t appUid = IPCSkeleton::GetCallingUid(); @@ -1769,7 +1780,8 @@ int32_t AudioPolicyServer::SetSingleStreamVolumeWithDevice(AudioStreamType strea ret = audioVolumeManager_.SaveSpecifiedDeviceVolume(streamType, volumeLevel, deviceType); } else { bool mute = GetStreamMuteInternal(streamType); - ret = SetSingleStreamVolume(streamType, volumeLevel, isUpdateUi, mute); + VolumeUpdateOption option{isUpdateUi, mute}; + ret = SetSingleStreamVolume(streamType, volumeLevel, option); } return ret; } @@ -3715,12 +3727,17 @@ int32_t AudioPolicyServer::SetA2dpDeviceVolume(const std::string &macAddress, in VolumeEvent volumeEvent; volumeEvent.volumeType = streamInFocus; volumeEvent.volume = volume; + + int32_t volumeLevelMax = -1; + GetMaxVolumeLevel(static_cast(streamInFocus), volumeLevelMax); + volumeEvent.volumeDegree = VolumeUtils::VolumeLevelToDegree(volume, volumeLevelMax); volumeEvent.updateUi = updateUi; volumeEvent.volumeGroupId = 0; volumeEvent.networkId = LOCAL_NETWORK_ID; if (ret == SUCCESS && audioPolicyServerHandler_ != nullptr && audioPolicyManager_.GetActiveDevice() == DEVICE_TYPE_BLUETOOTH_A2DP) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } return ret; } @@ -3742,10 +3759,14 @@ int32_t AudioPolicyServer::SetNearlinkDeviceVolume(const std::string &macAddress CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result, "Set volume failed"); VolumeEvent volumeEvent = VolumeEvent(streamType, volume, updateUi); + int32_t volumeLevelMax = -1; + GetMaxVolumeLevel(streamTypeIn, volumeLevelMax); + volumeEvent.volumeDegree = VolumeUtils::VolumeLevelToDegree(volume, volumeLevelMax); CHECK_AND_RETURN_RET_LOG(audioPolicyServerHandler_ != nullptr, ERROR, "audioPolicyServerHandler_ is nullptr"); if (audioActiveDevice_.GetCurrentOutputDeviceType() == DEVICE_TYPE_NEARLINK) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } } else { return SetSystemVolumeLevelWithDeviceInternal(streamType, volume, updateUi, DEVICE_TYPE_NEARLINK); @@ -4678,10 +4699,12 @@ void AudioPolicyServer::SendVolumeKeyEventToRssWhenAccountsChanged() VolumeEvent volumeEvent; volumeEvent.volumeType = STREAM_MUSIC; volumeEvent.volume = GetSystemVolumeLevelInternal(STREAM_MUSIC); + volumeEvent.volumeDegree = GetSystemVolumeDegreeInternal(STREAM_MUSIC); volumeEvent.updateUi = false; volumeEvent.notifyRssWhenAccountsChange = true; if (audioPolicyServerHandler_ != nullptr) { audioPolicyServerHandler_->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler_->SendVolumeDegreeEventCallback(volumeEvent); } } @@ -5368,5 +5391,65 @@ int32_t AudioPolicyServer::IsIntelligentNoiseReductionEnabledForCurrentDevice(in static_cast(sourceType)); return SUCCESS; } + +int32_t AudioPolicyServer::SetSystemVolumeDegree(int32_t streamTypeIn, int32_t volumeDegree, int32_t volumeFlag, + int32_t uid) +{ + AudioStreamType streamType = static_cast(streamTypeIn); + if (!PermissionUtil::VerifySystemPermission()) { + AUDIO_ERR_LOG("No system permission"); + return ERR_PERMISSION_DENIED; + } + + if (!IsVolumeTypeValid(streamType)) { + return ERR_NOT_SUPPORTED; + } + + std::lock_guard lock(systemVolumeMutex_); + int32_t callingUid = uid != 0 ? uid : IPCSkeleton::GetCallingUid(); + int32_t zoneId = AudioZoneService::GetInstance().FindAudioZoneByUid(callingUid); + + int32_t volumeLevelMax = -1; + GetMaxVolumeLevel(streamTypeIn, volumeLevelMax); + int32_t volumeLevel = VolumeUtils::VolumeDegreeToLevel(volumeDegree, volumeLevelMax); + int32_t ret = SetSystemVolumeLevelInternal(streamType, volumeLevel, + volumeFlag == VolumeFlag::FLAG_SHOW_SYSTEM_UI, uid, false); + if (ret != SUCCESS) { + return ret; + } + + if (streamType == STREAM_ALL) { + for (auto audioStreamType : GET_STREAM_ALL_VOLUME_TYPES) { + AUDIO_INFO_LOG("Set volume degree of STREAM_ALL, steamType:%{public}d, degree:%{public}d", + audioStreamType, volumeDegree); + int32_t setResult = audioVolumeManager_.SetSystemVolumeDegree(streamType, volumeDegree, zoneId, false); + if (setResult != SUCCESS ) { + return setResult; + } + } + return SUCCESS; + } + return audioVolumeManager_.SetSystemVolumeDegree(streamType, volumeDegree, zoneId, false); +} + +int32_t AudioPolicyServer::GetSystemVolumeDegree(int32_t streamType, int32_t uid, int32_t &volumeDegree) +{ + std::lock_guard lock(systemVolumeMutex_); + AudioStreamType newStreamType = static_cast(streamType); + volumeDegree = GetSystemVolumeDegreeInternal(newStreamType); + return SUCCESS; +} + +int32_t AudioPolicyServer::GetSystemVolumeDegreeInternal(AudioStreamType streamType) +{ + return audioVolumeManager_.GetSystemVolumeDegree(streamType); +} + +int32_t AudioPolicyServer::GetMinVolumeDegree(int32_t volumeType, int32_t deviceType, int32_t &volumeDegree) +{ + volumeDegree = audioVolumeManager_.GetMinVolumeDegree(static_cast(volumeType), + static_cast(deviceType)); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/test/unittest/audio_adapter_manager_unit_test/src/audio_adapter_manager_unit_test.cpp b/services/audio_policy/test/unittest/audio_adapter_manager_unit_test/src/audio_adapter_manager_unit_test.cpp index 0b4b6ee21b073851192f394dd093d8ff3a905f81..a1d774eb04dfd5eb48407af0ddedc978b9ef19b9 100644 --- a/services/audio_policy/test/unittest/audio_adapter_manager_unit_test/src/audio_adapter_manager_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_adapter_manager_unit_test/src/audio_adapter_manager_unit_test.cpp @@ -503,6 +503,31 @@ HWTEST_F(AudioAdapterManagerUnitTest, SetInnerStreamMute_002, TestSize.Level4) EXPECT_EQ(audioAdapterManager->GetStreamMute(streamType), mute); } +/** + * @tc.name: Test SetSystemVolumeDegree + * @tc.desc: SetSystemVolumeDegree_001 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AudioAdapterManagerUnitTest, SetSystemVolumeDegree_001, TestSize.Level4) +{ + auto audioAdapterManager = std::make_shared(); + ASSERT_NE(audioAdapterManager, nullptr); + AudioStreamType streamType = STREAM_MUSIC; + int32_t volumeDegree = 44; + auto ret = audioAdapterManager->SetSystemVolumeDegree(streamType, volumeDegree); + EXPECT_EQ(ret, SUCCESS); + + ret = audioAdapterManager->SetSystemVolumeDegree(streamType, volumeDegree); + EXPECT_EQ(ret, SUCCESS); + + ret = audioAdapterManager->GetSystemVolumeDegree(streamType); + EXPECT_EQ(ret, volumeDegree); + + ret = audioAdapterManager->GetMinVolumeDegree(streamType); + EXPECT_EQ(ret, 0); +} + /** * @tc.name: Test SetSleVoliceStatusFlag * @tc.desc: SetSleVoliceStatusFlag_001 diff --git a/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp b/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp index e098462fa685dfc93243ec30b34676c2ec21ddc4..5d2e77dabe32c06d42bc85ad9378ee4c3fb70721 100644 --- a/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp @@ -2938,13 +2938,14 @@ HWTEST(AudioPolicyUnitTest, AudioPolicyServer_136, TestSize.Level1) ASSERT_TRUE(server != nullptr); int32_t volumeLevel = 1; - auto ret = server->SetSingleStreamVolume(AudioStreamType::STREAM_VOICE_ASSISTANT, volumeLevel, true, false); + VolumeUpdateOption option{true, false}; + auto ret = server->SetSingleStreamVolume(AudioStreamType::STREAM_VOICE_ASSISTANT, volumeLevel, option); EXPECT_EQ(ret, SUCCESS); - ret = server->SetSingleStreamVolume(AudioStreamType::STREAM_RING, volumeLevel, true, false); + ret = server->SetSingleStreamVolume(AudioStreamType::STREAM_RING, volumeLevel, option); EXPECT_EQ(ret, SUCCESS); - ret = server->SetSingleStreamVolume(AudioStreamType::STREAM_VOICE_RING, volumeLevel, true, false); + ret = server->SetSingleStreamVolume(AudioStreamType::STREAM_VOICE_RING, volumeLevel, option); EXPECT_EQ(ret, SUCCESS); } diff --git a/services/audio_policy/test/unittest/audio_policy_manager_unit_test/src/audio_policy_manager_unit_test.cpp b/services/audio_policy/test/unittest/audio_policy_manager_unit_test/src/audio_policy_manager_unit_test.cpp index cffbf5f4b411e6bb1232b28b2c55ab11f989e3fd..b8447a02733c75ab9f4eb896d1ba3261f61480f5 100644 --- a/services/audio_policy/test/unittest/audio_policy_manager_unit_test/src/audio_policy_manager_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_policy_manager_unit_test/src/audio_policy_manager_unit_test.cpp @@ -728,6 +728,28 @@ HWTEST(AudioPolicyManager, CreateCapturerClient_002, TestSize.Level1) EXPECT_EQ(oldSessionId, originalSessionId); } +/** +* @tc.name : Test AudioPolicyManager. +* @tc.number: SetSystemVolumeDegree_001. +* @tc.desc : Test SetSystemVolumeDegree. +*/ +HWTEST(AudioPolicyManager, SetSystemVolumeDegree_001, TestSize.Level1) +{ + auto audioPolicyManager_ = std::make_shared(); + ASSERT_TRUE(audioPolicyManager_ != nullptr); + + AudioVolumeType volumeType = AudioVolumeType::STREAM_MUSIC; + int32_t volumeDegree = 4; + auto result = audioPolicyManager_->SetSystemVolumeDegree(volumeType, volumeDegree, 0, 0); + EXPECT_EQ(result, SUCCESS); + + result = audioPolicyManager_->GetSystemVolumeDegree(volumeType, 0); + EXPECT_EQ(result, volumeDegree); + + result = audioPolicyManager_->GetMinVolumeDegree(volumeType); + EXPECT_EQ(result, 0); +} + /** * @tc.name : Test AudioPolicyManager. * @tc.number: GetDirectPlaybackSupport_001. diff --git a/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_second_unit_test.cpp b/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_second_unit_test.cpp index c03d329d9f0a19f2746baf9a3517cc10da3d6e0f..0d2715557decc764eacc4e9024a50e80fdbc5896 100644 --- a/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_second_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_second_unit_test.cpp @@ -1186,5 +1186,136 @@ HWTEST_F(AudioPolicyServiceExtUnitTest, GetSinkPortName_004, TestSize.Level1) EXPECT_EQ(HEARING_AID_SPEAKER, retPortName); } +/** +* @tc.name : Test SetSystemVolumeDegree +* @tc.number: SetSystemVolumeDegree_001 +* @tc.desc : Test AudioPolicyService interfaces. +*/ +HWTEST_F(AudioPolicyServiceExtUnitTest, SetSystemVolumeDegree_001, TestSize.Level1) +{ + auto server = GetServerUtil::GetServerPtr(); + ASSERT_TRUE(server != nullptr); + int32_t streamType = static_cast(STREAM_MUSIC); + int32_t volumeDegree = 44; + int32_t ret = server->SetSystemVolumeDegree(streamType, volumeDegree, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + int32_t streamType2 = static_cast(STREAM_APP); + ret = server->SetSystemVolumeDegree(streamType2, volumeDegree, 0, 0); + EXPECT_EQ(ret, ERR_NOT_SUPPORTED); + + server->GetSystemVolumeDegree(streamType, 0, ret); + EXPECT_EQ(ret, volumeDegree); + + server->GetMinVolumeDegree(streamType, DEVICE_TYPE_NONE, ret); + EXPECT_EQ(ret, 0); + + auto &manager = static_cast(server->audioPolicyManager_); + manager.isVolumeUnadjustable_ = true; + ret = server->SetSystemVolumeDegree(streamType, volumeDegree, 0, 0); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + manager.isVolumeUnadjustable_ = false; +} + +/** +* @tc.name : Test SetSystemVolumeDegree +* @tc.number: SetSystemVolumeDegree_002 +* @tc.desc : Test AudioPolicyService differernt degree. +*/ +HWTEST_F(AudioPolicyServiceExtUnitTest, SetSystemVolumeDegree_002, TestSize.Level1) +{ + auto server = GetServerUtil::GetServerPtr(); + ASSERT_TRUE(server != nullptr); + int32_t streamType = static_cast(STREAM_MUSIC); + int32_t volumeDegree1 = -1; + int32_t volumeDegree2 = 0; + int32_t volumeDegree3 = 1; + int32_t volumeDegree4 = 99; + int32_t volumeDegree5 = 100; + int32_t volumeDegree6 = 101; + + int32_t volumelevel1 = 1; + int32_t volumelevel2 = 14; + + int32_t ret = server->SetSystemVolumeDegree(streamType, volumeDegree1, 0, 0); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + + ret = server->SetSystemVolumeDegree(streamType, volumeDegree6, 0, 0); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + + ret = server->SetSystemVolumeDegree(streamType, volumeDegree2, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + ret = server->SetSystemVolumeDegree(streamType, volumeDegree5, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + ret = server->SetSystemVolumeDegree(streamType, volumeDegree3, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + server->GetSystemVolumeLevel(streamType, 0, ret); + EXPECT_EQ(ret, volumelevel1); + + ret = server->SetSystemVolumeDegree(streamType, volumeDegree4, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + server->GetSystemVolumeLevel(streamType, 0, ret); + EXPECT_EQ(ret, volumelevel2); +} + +/** +* @tc.name : Test SetSystemVolumeDegree +* @tc.number: SetSystemVolumeDegree_003 +* @tc.desc : Test AudioPolicyService differernt degree by set level. +*/ +HWTEST_F(AudioPolicyServiceExtUnitTest, SetSystemVolumeDegree_003, TestSize.Level1) +{ + auto server = GetServerUtil::GetServerPtr(); + ASSERT_TRUE(server != nullptr); + int32_t streamType = static_cast(STREAM_MUSIC); + int32_t volumeLevel1 = 1; + int32_t volumeLevel2 = 15; + + int32_t volumeDegree1 = 6; + int32_t volumeDegree2 = 100; + int32_t ret = server->SetSystemVolumeLevel(streamType, volumeLevel1, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + server->GetSystemVolumeDegree(streamType, 0, ret); + EXPECT_EQ(ret, volumeDegree1); + + ret = server->SetSystemVolumeLevel(streamType, volumeLevel2, 0, 0); + EXPECT_EQ(ret, SUCCESS); + + server->GetSystemVolumeDegree(streamType, 0, ret); + EXPECT_EQ(ret, volumeDegree2); +} + +/** +* @tc.name : Test SetSystemVolumeDegree +* @tc.number: SetSystemVolumeDegree_003 +* @tc.desc : Test AudioPolicyService differernt degree by set level 2. +*/ +HWTEST_F(AudioPolicyServiceExtUnitTest, SetSystemVolumeDegree_004, TestSize.Level1) +{ + auto server = GetServerUtil::GetServerPtr(); + ASSERT_TRUE(server != nullptr); + int32_t streamType1 = static_cast(STREAM_MUSIC); + int32_t volumeDegree1 = 0; + int32_t volumeDegree2 = 100; + + int32_t success = 0; + for (int32_t i = volumeDegree1; i <= volumeDegree2; ++i) { + AUDIO_INFO_LOG("level1=%{public}d", i); + int32_t ret = server->SetSystemVolumeDegree(streamType1, i, 0, 0); + if (ret == SUCCESS) { + success++; + } else { + AUDIO_INFO_LOG("level1=%{public}d, failed", i); + } + } + + EXPECT_EQ(volumeDegree2 - volumeDegree1 + 1, success); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/test/unittest/audio_volume_manager_unit_test/src/audio_volume_manager_unit_test.cpp b/services/audio_policy/test/unittest/audio_volume_manager_unit_test/src/audio_volume_manager_unit_test.cpp index 580d66628267398c66217532d2fc6c513a7c725a..43e1ce8e7a9e8fe071a4c6f4e3b4ed8aa742838f 100644 --- a/services/audio_policy/test/unittest/audio_volume_manager_unit_test/src/audio_volume_manager_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_volume_manager_unit_test/src/audio_volume_manager_unit_test.cpp @@ -1335,6 +1335,33 @@ HWTEST_F(AudioVolumeManagerUnitTest, AudioVolumeManager_062, TestSize.Level1) EXPECT_EQ(ret, SUCCESS); } +/** +* @tc.name : Test AudioVolumeManager. +* @tc.number: AudioVolumeManagerDegree_001 +* @tc.desc : Test SetSystemVolumeDegree interface. +*/ +HWTEST_F(AudioVolumeManagerUnitTest, AudioVolumeManagerDegree_001, TestSize.Level1) +{ + AudioVolumeManager& audioVolumeManager(AudioVolumeManager::GetInstance()); + int32_t zoneId = 0; + int32_t ret = audioVolumeManager.SetAdjustVolumeForZone(zoneId); + EXPECT_EQ(ret, SUCCESS); + zoneId = 1; + ret = audioVolumeManager.SetAdjustVolumeForZone(zoneId); + EXPECT_NE(ret, SUCCESS); + + AudioStreamType streamType = STREAM_MUSIC; + int32_t volumeDegree = 44; + ret = audioVolumeManager.SetSystemVolumeDegree(streamType, volumeDegree, 0); + EXPECT_EQ(ret, SUCCESS); + + ret = audioVolumeManager.GetSystemVolumeDegree(streamType); + EXPECT_EQ(ret, volumeDegree); + + ret = audioVolumeManager.GetMinVolumeDegree(streamType, DEVICE_TYPE_NONE); + EXPECT_EQ(ret, 0); +} + /** * @tc.name : Test AudioVolumeManager. * @tc.number: AudioVolumeManager_063 diff --git a/services/audio_policy/test/unittest/volume_data_maintainer_unit_test/src/volume_data_maintainer_unit_test.cpp b/services/audio_policy/test/unittest/volume_data_maintainer_unit_test/src/volume_data_maintainer_unit_test.cpp index 7582a6b9d12d4cac7d39464e1b99c9d3d45a7911..7c8b280018217ba74ad5c898b54d97c39f436df8 100644 --- a/services/audio_policy/test/unittest/volume_data_maintainer_unit_test/src/volume_data_maintainer_unit_test.cpp +++ b/services/audio_policy/test/unittest/volume_data_maintainer_unit_test/src/volume_data_maintainer_unit_test.cpp @@ -73,6 +73,50 @@ HWTEST(VolumeDataMaintainerUnitTest, VolumeDataMaintainerUnitTest_003, TestSize. EXPECT_EQ(ret, false); } +/** +* @tc.name : Test VolumeDataMaintainer. +* @tc.number: VolumeDataMaintainerDegreeUnitTest_001. +* @tc.desc : Test VolumeDataMaintainer API. +*/ +HWTEST(VolumeDataMaintainerUnitTest, VolumeDataMaintainerDegreeUnitTest_001, TestSize.Level1) +{ + std::shared_ptr volumeDataMaintainerRet = std::make_shared(); + DeviceType typeRet = DEVICE_TYPE_NONE; + AudioStreamType streamTypeRet = STREAM_DEFAULT; + int32_t volumeLevelRet = 0; + auto ret = volumeDataMaintainerRet->SaveVolumeDegree(typeRet, streamTypeRet, volumeLevelRet); + EXPECT_EQ(ret, false); +} + +/** +* @tc.name : Test VolumeDataMaintainer. +* @tc.number: VolumeDataMaintainerDegreeUnitTest_002. +* @tc.desc : Test VolumeDataMaintainer API. +*/ +HWTEST(VolumeDataMaintainerUnitTest, VolumeDataMaintainerDegreeUnitTest_002, TestSize.Level1) +{ + std::shared_ptr volumeDataMaintainerRet = std::make_shared(); + DeviceType typeRet = DEVICE_TYPE_DP; + AudioStreamType streamTypeRet = STREAM_MUSIC; + int32_t volumeLevelRet = 0; + auto ret = volumeDataMaintainerRet->SaveVolumeDegree(typeRet, streamTypeRet, volumeLevelRet); + EXPECT_EQ(ret, false); +} + +/** +* @tc.name : Test VolumeDataMaintainer. +* @tc.number: VolumeDataMaintainerDegreeUnitTest_003. +* @tc.desc : Test VolumeDataMaintainer API. +*/ +HWTEST(VolumeDataMaintainerUnitTest, VolumeDataMaintainerDegreeUnitTest_003, TestSize.Level1) +{ + std::shared_ptr volumeDataMaintainerRet = std::make_shared(); + DeviceType deviceTypeRet = DEVICE_TYPE_NONE; + AudioStreamType streamTypeRet = STREAM_DEFAULT; + auto ret = volumeDataMaintainerRet->GetVolumeDegree(deviceTypeRet, streamTypeRet); + EXPECT_EQ(ret, false); +} + /** * @tc.name : Test VolumeDataMaintainer. * @tc.number: VolumeDataMaintainerUnitTest_004. diff --git a/services/audio_service/client/src/audio_system_manager.cpp b/services/audio_service/client/src/audio_system_manager.cpp index 2449102dd5d9a1323f7c8f585785ec9fa111f8bc..870e15e96bf1ed95ca1947fb3bd739d3e97270b4 100644 --- a/services/audio_service/client/src/audio_system_manager.cpp +++ b/services/audio_service/client/src/audio_system_manager.cpp @@ -1270,6 +1270,29 @@ int32_t AudioSystemManager::UnregisterVolumeKeyEventCallback(const int32_t clien return ret; } +int32_t AudioSystemManager::RegisterVolumeDegreeCallback(const int32_t clientPid, + const std::shared_ptr &callback, API_VERSION api_v) +{ + AUDIO_DEBUG_LOG("register"); + + CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, + "nullptr"); + volumeChangeClientPid_ = clientPid; + + return AudioPolicyManager::GetInstance().SetVolumeDegreeCallback(clientPid, callback, api_v); +} + +int32_t AudioSystemManager::UnregisterVolumeDegreeCallback(const int32_t clientPid, + const std::shared_ptr &callback) +{ + AUDIO_DEBUG_LOG("unregister"); + int32_t ret = AudioPolicyManager::GetInstance().UnsetVolumeDegreeCallback(callback); + if (!ret) { + AUDIO_DEBUG_LOG("success"); + } + return ret; +} + int32_t AudioSystemManager::RegisterSystemVolumeChangeCallback(const int32_t clientPid, const std::shared_ptr &callback) { @@ -2613,5 +2636,74 @@ void AudioSystemManager::CleanUpResource() { AudioPolicyManager::GetInstance().CleanUpResource(); } + +int32_t AudioSystemManager::SetVolumeDegree(AudioVolumeType volumeType, int32_t degree, int32_t uid) +{ + AUDIO_INFO_LOG("volumeType[%{public}d], volumeDegree[%{public}d]", volumeType, degree); + + /* Validate volume type and return INVALID_PARAMS error */ + switch (volumeType) { + case STREAM_VOICE_CALL: + case STREAM_VOICE_COMMUNICATION: + case STREAM_RING: + case STREAM_MUSIC: + case STREAM_ALARM: + case STREAM_SYSTEM: + case STREAM_ACCESSIBILITY: + case STREAM_VOICE_ASSISTANT: + break; + case STREAM_ULTRASONIC: + case STREAM_ALL:{ + bool ret = PermissionUtil::VerifySelfPermission(); + CHECK_AND_RETURN_RET_LOG(ret, ERR_PERMISSION_DENIED, "No system permission"); + break; + } + default: + AUDIO_ERR_LOG("volumeType[%{public}d] is not supported", volumeType); + return ERR_NOT_SUPPORTED; + } + + return AudioPolicyManager::GetInstance().SetSystemVolumeDegree(volumeType, degree, uid == 0, uid); +} + +int32_t AudioSystemManager::GetVolumeDegree(AudioVolumeType volumeType, int32_t uid) +{ + switch (volumeType) { + case STREAM_MUSIC: + case STREAM_RING: + case STREAM_NOTIFICATION: + case STREAM_VOICE_CALL: + case STREAM_VOICE_COMMUNICATION: + case STREAM_VOICE_ASSISTANT: + case STREAM_ALARM: + case STREAM_SYSTEM: + case STREAM_ACCESSIBILITY: + case STREAM_VOICE_RING: + break; + case STREAM_ULTRASONIC: + case STREAM_ALL:{ + bool ret = PermissionUtil::VerifySelfPermission(); + CHECK_AND_RETURN_RET_LOG(ret, ERR_PERMISSION_DENIED, "No system permission"); + break; + } + default: + AUDIO_ERR_LOG("volumeType[%{public}d] is not supported", volumeType); + return ERR_NOT_SUPPORTED; + } + + return AudioPolicyManager::GetInstance().GetSystemVolumeLevel(volumeType, uid); +} + +int32_t AudioSystemManager::GetMinVolumeDegree(AudioVolumeType volumeType) +{ + if (volumeType == STREAM_ALL || + volumeType == STREAM_ULTRASONIC) { + bool ret = PermissionUtil::VerifySelfPermission(); + CHECK_AND_RETURN_RET_LOG(ret, ERR_PERMISSION_DENIED, + "volumeType=%{public}d has no system permission", volumeType); + } + + return AudioPolicyManager::GetInstance().GetMinVolumeDegree(volumeType); +} } // namespace AudioStandard } // namespace OHOS diff --git a/test/fuzztest/audiopolicymanager_fuzzer/audio_policy_manager_fuzzer.cpp b/test/fuzztest/audiopolicymanager_fuzzer/audio_policy_manager_fuzzer.cpp index c0bcd220bf55c6da14c4de6ef58db902ab8a4f10..b9c2dfd421faea5332d7da061c3049a3b68416b4 100644 --- a/test/fuzztest/audiopolicymanager_fuzzer/audio_policy_manager_fuzzer.cpp +++ b/test/fuzztest/audiopolicymanager_fuzzer/audio_policy_manager_fuzzer.cpp @@ -265,6 +265,7 @@ void AudioPolicyManagerFourFuzzTest() int32_t clientPid = GetData(); int32_t uid = GetData(); std::shared_ptr volumeKeyEventCallback; + std::shared_ptr volumeDegreeEventCallback; API_VERSION api_v = GetData(); std::shared_ptr systemVolumeChangeCallback; std::shared_ptr audioRendererStateChangeCallback; @@ -300,6 +301,8 @@ void AudioPolicyManagerFourFuzzTest() AudioPolicyManager::GetInstance().GetPreferredInputStreamType(capturerInfo); AudioPolicyManager::GetInstance().CreateRendererClient(streamDesc, flag, sessionId, networkId); AudioPolicyManager::GetInstance().CreateCapturerClient(streamDesc, flag, sessionId); + AudioPolicyManager::GetInstance().SetVolumeDegreeCallback(clientPid, volumeDegreeEventCallback, api_v); + AudioPolicyManager::GetInstance().UnsetVolumeDegreeCallback(volumeDegreeEventCallback); } void AudioPolicyManagerFiveFuzzTest() @@ -487,6 +490,10 @@ void AudioPolicyManagerNiNeFuzzTest() vector> audioCapturerChangeInfos; StreamUsage streamUsage = GetData(); std::string address = "address"; + int32_t volumeDegree = GetData(); + AudioVolumeType volumeType = GetData(); + int32_t volumeFlag = GetData(); + uid_t uid = GetData(); AudioPolicyManager::GetInstance().SetMicrophoneMutePersistent(isMute, type); AudioPolicyManager::GetInstance().GetPersistentMicMuteState(); @@ -500,6 +507,9 @@ void AudioPolicyManagerNiNeFuzzTest() AudioPolicyManager::GetInstance().GetSpatializationState(streamUsage); AudioPolicyManager::GetInstance().IsSpatializationSupported(); AudioPolicyManager::GetInstance().IsSpatializationSupportedForDevice(address); + AudioPolicyManager::GetInstance().SetSystemVolumeDegree(volumeType, volumeDegree, volumeFlag, uid); + AudioPolicyManager::GetInstance().GetSystemVolumeDegree(volumeType, uid); + AudioPolicyManager::GetInstance().GetMinVolumeDegree(volumeType); } void AudioPolicyManagerDeviceOneFuzzTest() diff --git a/test/fuzztest/audiopolicyservenhance_fuzzer/audio_policy_serv_enhance_fuzzer.cpp b/test/fuzztest/audiopolicyservenhance_fuzzer/audio_policy_serv_enhance_fuzzer.cpp index a5dc526bd3311fd48cd6928e53c9364669673125..c7a99c2ebaca60b50a55a7e423717f3ce4c4ab4b 100644 --- a/test/fuzztest/audiopolicyservenhance_fuzzer/audio_policy_serv_enhance_fuzzer.cpp +++ b/test/fuzztest/audiopolicyservenhance_fuzzer/audio_policy_serv_enhance_fuzzer.cpp @@ -106,6 +106,7 @@ void AudioSendCallbackFuzzTest() VolumeEvent volumeEvent; audioPolicyServerHandler->SendVolumeKeyEventCallback(volumeEvent); + audioPolicyServerHandler->SendVolumeDegreeEventCallback(volumeEvent); std::pair sessionDeactivePair; audioPolicyServerHandler->SendAudioSessionDeactiveCallback(sessionDeactivePair); diff --git a/test/fuzztest/audiopolicyserver_fuzzer/audio_policy_server_fuzzer.cpp b/test/fuzztest/audiopolicyserver_fuzzer/audio_policy_server_fuzzer.cpp index 5deb9a9bc7e953746bd82a8747be68a489a61ff6..034e036fe370c3874beb19d8e1fa9cfdbcc44cbd 100644 --- a/test/fuzztest/audiopolicyserver_fuzzer/audio_policy_server_fuzzer.cpp +++ b/test/fuzztest/audiopolicyserver_fuzzer/audio_policy_server_fuzzer.cpp @@ -651,9 +651,10 @@ void AudioPolicyServerSetSingleStreamVolumeFuzztest() bool isUpdateUi = GetData(); bool mute = GetData(); int32_t zoneId = GetData(); - audioPolicyServer->SetSingleStreamVolume(AudioStreamType::STREAM_RING, volumeLevel, isUpdateUi, mute, zoneId); + VolumeUpdateOption option{isUpdateUi, mute, zoneId}; + audioPolicyServer->SetSingleStreamVolume(AudioStreamType::STREAM_RING, volumeLevel, option); audioPolicyServer->SetSingleStreamVolume(AudioStreamType::STREAM_VOICE_ASSISTANT, volumeLevel, - isUpdateUi, mute, zoneId); + option); } void AudioPolicyServerSetSingleStreamVolumeWithDeviceFuzztest()