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 fdcea314e5b64ae7016ebb79d12bf168806c631d..1fa0ec5ca23dc7f0e2767dc63573e6e89f53b3e1 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 @@ -306,6 +306,10 @@ public: void SaveSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel); int32_t GetSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType); int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume); + + void SetVolumeLimit(AudioStreamType streamType); + void ResetVolumeLimit(); + void UpdateOtherStreamVolume(AudioStreamType streamType); private: friend class PolicyCallbackImpl; @@ -484,6 +488,7 @@ private: std::make_shared>(MAX_CACHE_AMOUNT); bool isDpReConnect_ = false; sptr deviceVolumeBehaviorListener_; + std::atomic volumeLimit_ = 1.0f; }; class PolicyCallbackImpl : public AudioServiceAdapterCallback { 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 2ea2e3bcf80c34e4d5c299a86670b72b516b1625..dd1eebe952b3ebb92ea3b37e9b366a80296390f3 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 @@ -179,6 +179,7 @@ private: int32_t HandleA2dpAbsVolume(AudioStreamType streamType, int32_t volumeLevel, DeviceType curDeviceType); int32_t HandleNearlinkDeviceAbsVolume(AudioStreamType streamType, int32_t volumeLevel, DeviceType curDeviceType); + void CheckReduceOtherActiveVolume(AudioStreamType streamType); 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 8be01d59d314be1f5d5a362d3d469df19b2b4dfb..55518015f879f02278a20395b321291c59543201 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 @@ -257,6 +257,9 @@ public: virtual float CalculateVolumeDbNonlinear(AudioStreamType streamType, DeviceType deviceType, int32_t volumeLevel) = 0; + virtual void SetVolumeLimit(AudioStreamType streamType) = 0; + virtual void ResetVolumeLimit() = 0; + virtual void UpdateOtherStreamVolume(AudioStreamType streamType) = 0; }; } // namespace AudioStandard } // namespace OHOS 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 2c3a33005e1a1e32a83e795a68b27d6feb297370..a01152f304e08929138f92a28f7df90bb42ade11 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 @@ -751,6 +751,7 @@ int32_t AudioAdapterManager::SetVolumeDb(AudioStreamType streamType) volumeDb = 1.0f; } + volumeDb = std::min(volumeDb, volumeLimit_.load()); CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_, ERR_OPERATION_FAILED, "SetSystemVolumeLevel audio adapter null"); @@ -3403,6 +3404,49 @@ int32_t AudioAdapterManager::SetSystemVolumeToEffect(AudioStreamType streamType, CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_, ERROR, "audioServiceAdapter is null"); return audioServiceAdapter_->SetSystemVolumeToEffect(streamType, volume); } + +void AudioAdapterManager::SetVolumeLimit(AudioStreamType streamType) +{ + int32_t volumeLevel = volumeDataMaintainer_.GetStreamVolume(streamType) * (GetStreamMute(streamType) ? 0 : 1); + + float volumeDb = 1.0f; + if (useNonlinearAlgo_) { + if (Util::IsDualToneStreamType(streamType) && + currentActiveDevice_.deviceType_ != DEVICE_TYPE_REMOTE_CAST && !VolumeUtils::IsPCVolumeEnable()) { + volumeDb = CalculateVolumeDbNonlinear(streamType, DEVICE_TYPE_SPEAKER, volumeLevel); + } else { + volumeDb = CalculateVolumeDbNonlinear(streamType, currentActiveDevice_.deviceType_, volumeLevel); + } + } else { + volumeDb = CalculateVolumeDb(volumeLevel); + } + // Set voice call assistant stream to full volume + if (streamType == STREAM_VOICE_CALL_ASSISTANT) { + volumeDb = 1.0f; + } + + volumeLimit_ = volumeDb; + AUDIO_INFO_LOG("volume limit set to %{public}f by stream %{public}d)", volumeDb, streamType); +} + +void AudioAdapterManager::ResetVolumeLimit() +{ + AUDIO_INFO_LOG("reset volume limit"); + volumeLimit_ = 1.0f; +} + +void AudioAdapterManager::UpdateOtherStreamVolume(AudioStreamType streamType) +{ + auto iter = defaultVolumeTypeList_.begin(); + while (iter != defaultVolumeTypeList_.end()) { + if (*iter == streamType) { + continue; + } + SetVolumeDb(*iter); + iter++; + } +} + // LCOV_EXCL_STOP } // namespace AudioStandard } // namespace OHOS 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 71cd9961b62637f3c4164e549610eb66611cd49e..c55317009c5c08eeeb3aca52d83718b95ae5f7e0 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 @@ -236,6 +236,13 @@ int32_t AudioVolumeManager::SetVolumeForSwitchDevice(AudioDeviceDescriptor devic const std::string &newSinkName, bool enableSetVoiceCallVolume) { Trace trace("AudioVolumeManager::SetVolumeForSwitchDevice:" + std::to_string(deviceDescriptor.deviceType_)); + + AudioScene lastScene = audioSceneManager_.GetLastAudioScene(); + if (audioSceneManager_.IsInPhoneCallScene()) { + audioPolicyManager_.SetVolumeLimit(STREAM_VOICE_CALL); + } else if (lastScene == AUDIO_SCENE_PHONE_CALL) { + audioPolicyManager_.ResetVolumeLimit(); + } // Load volume from KvStore and set volume for each stream type audioPolicyManager_.SetVolumeForSwitchDevice(deviceDescriptor); @@ -463,6 +470,8 @@ int32_t AudioVolumeManager::HandleNearlinkDeviceAbsVolume(AudioStreamType stream int32_t AudioVolumeManager::SetSystemVolumeLevel(AudioStreamType streamType, int32_t volumeLevel, int32_t zoneId) { + CheckReduceOtherActiveVolume(streamType); + if (zoneId > 0) { return audioPolicyManager_.SetZoneVolumeLevel(zoneId, VolumeUtils::GetVolumeTypeFromStreamType(streamType), volumeLevel); @@ -558,6 +567,15 @@ int32_t AudioVolumeManager::SelectDealSafeVolume(AudioStreamType streamType, int return sVolumeLevel; } +void AudioVolumeManager::CheckReduceOtherActiveVolume(AudioStreamType streamType) +{ + if (audioSceneManager_.IsInPhoneCallScene() && streamType == STREAM_VOICE_CALL) { + audioPolicyManager_.SetVolumeLimit(streamType); + audioPolicyManager_.UpdateOtherStreamVolume(streamType); + AUDIO_WARNING_LOG("streamType:%{public}d begin reduce other stream volume", streamType); + } +} + int32_t AudioVolumeManager::SetA2dpDeviceVolume(const std::string &macAddress, const int32_t volumeLevel, bool internalCall) { diff --git a/services/audio_policy/server/infra/config/file/audio_interrupt_policy_config.xml b/services/audio_policy/server/infra/config/file/audio_interrupt_policy_config.xml index c440d3510c81a9de6ef08241b2903c6ca2fe1b6d..8ff4edc1cc198a3aaa3c881ba09a1c8aeb5d5aca 100644 --- a/services/audio_policy/server/infra/config/file/audio_interrupt_policy_config.xml +++ b/services/audio_policy/server/infra/config/file/audio_interrupt_policy_config.xml @@ -34,13 +34,13 @@ - - - - - - - + + + + + + + @@ -738,21 +738,21 @@ - - - - - - + + + + + + - + - + 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..86e39536aaa90f0059003b707d2dc5b1007cfd48 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 @@ -1394,5 +1394,51 @@ HWTEST_F(AudioVolumeManagerUnitTest, AudioVolumeManager_067, TestSize.Level1) ret = audioVolumeManager->SetNearlinkDeviceVolumeEx(streamType, volumeLevel); EXPECT_EQ(ret, SUCCESS); } + +/** +* @tc.name : Test AudioVolumeManager. +* @tc.number: AudioVolumeManager_VolumeLimit_001 +* @tc.desc : Test volume limit interface. +*/ +HWTEST_F(AudioVolumeManagerUnitTest, AudioVolumeManager_VolumeLimit_001, TestSize.Level1) +{ + auto audioVolumeManager = std::make_shared(); + ASSERT_TRUE(audioVolumeManager != nullptr); + + int32_t zoneId = 0; + int32_t volumeLevel = 2; + AudioStreamType streamType = STREAM_VOICE_CALL; + + auto &manager = static_cast(audioVolumeManager->audioPolicyManager_); + float oldLimit = manager.volumeLimit_.load(); + audioVolumeManager->audioSceneManager_.audioScene_ = AUDIO_SCENE_PHONE_CALL; + audioVolumeManager->SetSystemVolumeLevel(streamType, volumeLevel, zoneId); + audioVolumeManager->audioSceneManager_.audioScene_ = AUDIO_SCENE_DEFAULT; + float newLimit = manager.volumeLimit_.load(); + + EXPECT_NE(newLimit, oldLimit); +} + +/** +* @tc.name : Test AudioVolumeManager. +* @tc.number: AudioVolumeManager_VolumeLimit_002 +* @tc.desc : Test reset volume limit interface. +*/ +HWTEST_F(AudioVolumeManagerUnitTest, AudioVolumeManager_VolumeLimit_002, TestSize.Level1) +{ + auto audioVolumeManager = std::make_shared(); + ASSERT_TRUE(audioVolumeManager != nullptr); + + AudioDeviceDescriptor audioDeviceDescriptor; + audioVolumeManager->audioSceneManager_.SetAudioScenePre(AUDIO_SCENE_PHONE_CALL); + int32_t ret = audioVolumeManager->SetVolumeForSwitchDevice(audioDeviceDescriptor, PORT_NONE, false); + EXPECT_EQ(ret, SUCCESS); + audioVolumeManager->audioSceneManager_.SetAudioScenePre(AUDIO_SCENE_DEFAULT); + ret = audioVolumeManager->SetVolumeForSwitchDevice(audioDeviceDescriptor, PORT_NONE, false); + EXPECT_EQ(ret, SUCCESS); + auto &manager = static_cast(audioVolumeManager->audioPolicyManager_); + float newLimit = manager.volumeLimit_.load(); + EXPECT_EQ(newLimit, 1.0f); +} } // namespace AudioStandard } // namespace OHOS