diff --git a/frameworks/innerkitsimpl/audioadapter/BUILD.gn b/frameworks/innerkitsimpl/audioadapter/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..ce6acae28819890101e83ea179adeb2d269041d0 --- /dev/null +++ b/frameworks/innerkitsimpl/audioadapter/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_shared_library("pulse_audio_service_adapter") { + install_enable = true + sources = [ "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audioadapter/src/pulse_audio_service_adapter_impl.cpp" ] + cflags = [ "-fPIC" ] + cflags += [ "-Wall" ] + cflags_cc = cflags + + include_dirs = [ + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audioadapter/include", + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/common/include", + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/pulseaudio/include", + "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audioadapter/include", + "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audiocommon/include", + "//third_party/libxml2/include", + "//third_party/pulseaudio/src", + "//third_party/pulseaudio/confgure/src", + "//third_party/pulseaudio/include", + "//utils/native/base/include", + ] + + public_configs = [ ":audio_external_library_config" ] + + deps = [ + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/pulseaudio/src/pulse:pulse", + "//third_party/libxml2:xml2", + "//utils/native/base:utils", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + part_name = "multimedia_audio_standard" + subsystem_name = "multimedia" +} + +config("audio_external_library_config") { + include_dirs = [ "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/common/include" ] +} diff --git a/frameworks/innerkitsimpl/audioadapter/include/pulse_audio_service_adapter_impl.h b/frameworks/innerkitsimpl/audioadapter/include/pulse_audio_service_adapter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5d98492c4daccdcfa765827832773ac5bcc7e9f9 --- /dev/null +++ b/frameworks/innerkitsimpl/audioadapter/include/pulse_audio_service_adapter_impl.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_H +#define ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_H + +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#endif +#include "audio_service_adapter.h" + +namespace OHOS { +namespace AudioStandard { +class PulseAudioServiceAdapterImpl : public AudioServiceAdapter { +public: + PulseAudioServiceAdapterImpl(AudioServiceAdapterCallback *cb); + ~PulseAudioServiceAdapterImpl(); + + bool Connect() override; + int32_t OpenAudioPort(char *audioPortName, std::string moduleArgs) override; + int32_t CloseAudioPort(int32_t audioHandleIndex) override; + int32_t SetDefaultSink(std::string name) override; + int32_t SetDefaultSource(std::string name) override; + int32_t SetVolume(AudioStreamType streamType, float volume) override; + int32_t SetMute(AudioStreamType streamType, bool mute) override; + bool IsMute(AudioStreamType streamType) override; + bool IsStreamActive(AudioStreamType streamType) override; + void Disconnect() override; + + // Static Member functions + static void PaContextStateCb(pa_context *c, void *userdata); + static void PaModuleLoadCb(pa_context *c, uint32_t idx, void *userdata); + static void PaGetSinkInputInfoVolumeCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); + static void PaSubscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata); + static void PaGetSinkInputInfoMuteCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); + static void PaGetSinkInputInfoMuteStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); + static void PaGetSinkInputInfoCorkStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); +private: + + struct UserData { + PulseAudioServiceAdapterImpl *thiz; + AudioStreamType streamType; + float volume; + bool mute; + bool isCorked; + uint32_t idx; + }; + + bool ConnectToPulseAudio(); + std::string GetNameByStreamType(AudioStreamType streamType); + AudioStreamType GetIdByStreamType(std::string streamType); + + static constexpr uint32_t PA_CONNECT_RETRY_SLEEP_IN_MICRO_SECONDS = 500000; + pa_context *mContext = NULL; + pa_threaded_mainloop *mMainLoop = NULL; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_H diff --git a/services/src/audio_policy/server/service/src/manager/pulseaudio_policy_manager.cpp b/frameworks/innerkitsimpl/audioadapter/src/pulse_audio_service_adapter_impl.cpp similarity index 36% rename from services/src/audio_policy/server/service/src/manager/pulseaudio_policy_manager.cpp rename to frameworks/innerkitsimpl/audioadapter/src/pulse_audio_service_adapter_impl.cpp index 15eeaacc5b227a7cb080679d86285019ba3861bc..0ba7feac0b7f9bea3861d94a01343c759cffa7ba 100644 --- a/services/src/audio_policy/server/service/src/manager/pulseaudio_policy_manager.cpp +++ b/frameworks/innerkitsimpl/audioadapter/src/pulse_audio_service_adapter_impl.cpp @@ -13,24 +13,42 @@ * limitations under the License. */ +#ifndef ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_IMPL_H +#define ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_IMPL_H + #include +#include "pulse_audio_service_adapter_impl.h" #include "audio_errors.h" #include "media_log.h" -#include "pulseaudio_policy_manager.h" namespace OHOS { namespace AudioStandard { -bool PulseAudioPolicyManager::Init() +static AudioServiceAdapterCallback *mAudioServiceAdapterCallback; + +AudioServiceAdapter::~AudioServiceAdapter() = default; +PulseAudioServiceAdapterImpl::~PulseAudioServiceAdapterImpl() = default; + +std::unique_ptr AudioServiceAdapter::CreateAudioAdapter(AudioServiceAdapterCallback *cb) +{ + return std::make_unique(cb); +} + +PulseAudioServiceAdapterImpl::PulseAudioServiceAdapterImpl(AudioServiceAdapterCallback *cb) +{ + mAudioServiceAdapterCallback = cb; +} + +bool PulseAudioServiceAdapterImpl::Connect() { mMainLoop = pa_threaded_mainloop_new(); if (!mMainLoop) { - MEDIA_ERR_LOG("[PolicyManager] MainLoop creation failed"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] MainLoop creation failed"); return false; } if (pa_threaded_mainloop_start(mMainLoop) < 0) { - MEDIA_ERR_LOG("[PolicyManager] Failed to start mainloop"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to start mainloop"); pa_threaded_mainloop_free (mMainLoop); return false; } @@ -53,7 +71,7 @@ bool PulseAudioPolicyManager::Init() continue; } - MEDIA_DEBUG_LOG("[PolicyManager] pa context not ready... wait"); + MEDIA_DEBUG_LOG("[PulseAudioServiceAdapterImpl] pa context not ready... wait"); // Wait for the context to be ready pa_threaded_mainloop_wait(mMainLoop); @@ -61,102 +79,144 @@ bool PulseAudioPolicyManager::Init() pa_threaded_mainloop_unlock(mMainLoop); - bool isFirstBoot = false; - InitAudioPolicyKvStore(isFirstBoot); - InitVolumeMap(isFirstBoot); - InitRingerMode(isFirstBoot); return true; } -void PulseAudioPolicyManager::Deinit(void) +bool PulseAudioServiceAdapterImpl::ConnectToPulseAudio() { + std::unique_ptr userData = std::make_unique(); + userData->thiz = this; + if (mContext != NULL) { pa_context_disconnect (mContext); + pa_context_set_state_callback(mContext, NULL, NULL); + pa_context_set_subscribe_callback(mContext, NULL, NULL); + pa_context_unref(mContext); + } - /* Make sure we don't get any further callbacks */ - pa_context_set_state_callback (mContext, NULL, NULL); - pa_context_set_subscribe_callback (mContext, NULL, NULL); + pa_proplist *proplist = pa_proplist_new(); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "PulseAudio Service"); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.ohos.pulseaudio.service"); + mContext = pa_context_new_with_proplist(pa_threaded_mainloop_get_api(mMainLoop), NULL, proplist); + pa_proplist_free(proplist); - pa_context_unref (mContext); + if (mContext == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] creating pa context failed"); + return false; } - if (mMainLoop != NULL) { - pa_threaded_mainloop_stop (mMainLoop); - pa_threaded_mainloop_free (mMainLoop); + pa_context_set_state_callback(mContext, PulseAudioServiceAdapterImpl::PaContextStateCb, this); + if (pa_context_connect(mContext, NULL, PA_CONTEXT_NOFAIL, NULL) < 0) { + if (pa_context_errno(mContext) == PA_ERR_INVALID) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa context connect failed: %{public}s", + pa_strerror(pa_context_errno(mContext))); + goto Fail; + } } - return; + return true; + +Fail: + /* Make sure we don't get any further callbacks */ + pa_context_set_state_callback(mContext, NULL, NULL); + pa_context_set_subscribe_callback(mContext, NULL, NULL); + pa_context_unref(mContext); + return false; } -int32_t PulseAudioPolicyManager::SetStreamVolume(AudioStreamType streamType, float volume) +int32_t PulseAudioServiceAdapterImpl::OpenAudioPort(char *audioPortName, std::string moduleArgs) { std::unique_ptr userData = std::make_unique(); userData->thiz = this; - userData->volume = volume; - userData->streamType = streamType; - - if (mContext == NULL) { - MEDIA_ERR_LOG("[PolicyManager] mContext is nullptr"); - return ERROR; - } pa_threaded_mainloop_lock(mMainLoop); + pa_operation *operation = pa_context_load_module(mContext, audioPortName, moduleArgs.c_str(), PaModuleLoadCb, + reinterpret_cast(userData.get())); + if (operation == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_load_module returned nullptr"); + pa_threaded_mainloop_unlock(mMainLoop); + return ERR_INVALID_HANDLE; + } - // Incase if KvStore didnot connect during bootup - if (mAudioPolicyKvStore == nullptr) { - bool isFirstBoot = false; - InitAudioPolicyKvStore(isFirstBoot); + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) { + pa_threaded_mainloop_wait(mMainLoop); } - mVolumeMap[streamType] = volume; - WriteVolumeToKvStore(streamType, volume); + pa_operation_unref(operation); + pa_threaded_mainloop_unlock(mMainLoop); + + return userData->idx; +} - pa_operation *operation = pa_context_get_sink_input_info_list(mContext, - PulseAudioPolicyManager::GetSinkInputInfoVolumeCb, reinterpret_cast(userData.get())); +int32_t PulseAudioServiceAdapterImpl::CloseAudioPort(int32_t audioHandleIndex) +{ + pa_threaded_mainloop_lock(mMainLoop); + + pa_operation *operation = pa_context_unload_module(mContext, audioHandleIndex, NULL, NULL); if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_get_sink_input_info_list returned nullptr"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_unload_module returned nullptr!"); pa_threaded_mainloop_unlock(mMainLoop); return ERROR; } - userData.release(); - pa_threaded_mainloop_accept(mMainLoop); + pa_operation_unref(operation); + pa_threaded_mainloop_unlock(mMainLoop); + return SUCCESS; +} +int32_t PulseAudioServiceAdapterImpl::SetDefaultSink(std::string name) +{ + pa_threaded_mainloop_lock(mMainLoop); + pa_operation *operation = pa_context_set_default_sink(mContext, name.c_str(), NULL, NULL); + if (operation == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_set_default_sink failed!"); + pa_threaded_mainloop_unlock(mMainLoop); + return ERR_OPERATION_FAILED; + } pa_operation_unref(operation); pa_threaded_mainloop_unlock(mMainLoop); + return SUCCESS; } -float PulseAudioPolicyManager::GetStreamVolume(AudioStreamType streamType) + +int32_t PulseAudioServiceAdapterImpl::SetDefaultSource(std::string name) { - return mVolumeMap[streamType]; + pa_threaded_mainloop_lock(mMainLoop); + pa_operation *operation = pa_context_set_default_source(mContext, name.c_str(), NULL, NULL); + if (operation == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_set_default_source failed!"); + pa_threaded_mainloop_unlock(mMainLoop); + return ERR_OPERATION_FAILED; + } + pa_operation_unref(operation); + pa_threaded_mainloop_unlock(mMainLoop); + + return SUCCESS; } -int32_t PulseAudioPolicyManager::SetStreamMute(AudioStreamType streamType, bool mute) +int32_t PulseAudioServiceAdapterImpl::SetVolume(AudioStreamType streamType, float volume) { std::unique_ptr userData = std::make_unique(); userData->thiz = this; - userData->mute = mute; + userData->volume = volume; userData->streamType = streamType; if (mContext == NULL) { - MEDIA_ERR_LOG("[PolicyManager] mContext is nullptr"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] SetVolume mContext is nullptr"); return ERROR; } - pa_threaded_mainloop_lock(mMainLoop); - - pa_operation* operation = pa_context_get_sink_input_info_list(mContext, - PulseAudioPolicyManager::GetSinkInputInfoMuteCb, reinterpret_cast(userData.get())); + pa_operation *operation = pa_context_get_sink_input_info_list(mContext, + PulseAudioServiceAdapterImpl::PaGetSinkInputInfoVolumeCb, reinterpret_cast(userData.get())); if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_get_sink_input_info_list returned nullptr"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_get_sink_input_info_list nullptr"); pa_threaded_mainloop_unlock(mMainLoop); return ERROR; } + userData.release(); - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) { - pa_threaded_mainloop_wait(mMainLoop); - } + pa_threaded_mainloop_accept(mMainLoop); pa_operation_unref(operation); pa_threaded_mainloop_unlock(mMainLoop); @@ -164,26 +224,25 @@ int32_t PulseAudioPolicyManager::SetStreamMute(AudioStreamType streamType, bool return SUCCESS; } -bool PulseAudioPolicyManager::GetStreamMute(AudioStreamType streamType) +int32_t PulseAudioServiceAdapterImpl::SetMute(AudioStreamType streamType, bool mute) { std::unique_ptr userData = std::make_unique(); userData->thiz = this; + userData->mute = mute; userData->streamType = streamType; - userData->mute = false; if (mContext == NULL) { - MEDIA_ERR_LOG("[PolicyManager] mContext is nullptr"); - return false; + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] SetMute mContext is nullptr"); + return ERROR; } - pa_threaded_mainloop_lock(mMainLoop); pa_operation *operation = pa_context_get_sink_input_info_list(mContext, - PulseAudioPolicyManager::GetSinkInputInfoMuteStatusCb, reinterpret_cast(userData.get())); + PulseAudioServiceAdapterImpl::PaGetSinkInputInfoMuteCb, reinterpret_cast(userData.get())); if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_get_sink_input_info_list returned nullptr"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_get_sink_input_info_list returned nullptr"); pa_threaded_mainloop_unlock(mMainLoop); - return false; + return ERROR; } while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) { @@ -193,27 +252,27 @@ bool PulseAudioPolicyManager::GetStreamMute(AudioStreamType streamType) pa_operation_unref(operation); pa_threaded_mainloop_unlock(mMainLoop); - return (userData->mute) ? true : false; + return SUCCESS; } -bool PulseAudioPolicyManager::IsStreamActive(AudioStreamType streamType) +bool PulseAudioServiceAdapterImpl::IsMute(AudioStreamType streamType) { std::unique_ptr userData = std::make_unique(); userData->thiz = this; userData->streamType = streamType; - userData->isCorked = true; + userData->mute = false; if (mContext == NULL) { - MEDIA_ERR_LOG("[PolicyManager] mContext is nullptr"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] IsMute mContext is nullptr"); return false; } pa_threaded_mainloop_lock(mMainLoop); pa_operation *operation = pa_context_get_sink_input_info_list(mContext, - PulseAudioPolicyManager::GetSinkInputInfoCorkStatusCb, reinterpret_cast(userData.get())); + PulseAudioServiceAdapterImpl::PaGetSinkInputInfoMuteStatusCb, reinterpret_cast(userData.get())); if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_get_sink_input_info_list returned nullptr"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_get_sink_input_info_list returned nullptr"); pa_threaded_mainloop_unlock(mMainLoop); return false; } @@ -225,101 +284,29 @@ bool PulseAudioPolicyManager::IsStreamActive(AudioStreamType streamType) pa_operation_unref(operation); pa_threaded_mainloop_unlock(mMainLoop); - MEDIA_INFO_LOG("[PolicyManager] cork for stream %s : %d", - GetStreamNameByStreamType(streamType).c_str(), userData->isCorked); - - return (userData->isCorked) ? false : true; -} - - -int32_t PulseAudioPolicyManager::SetDeviceActive(AudioIOHandle ioHandle, DeviceType deviceType, - std::string name, bool active) -{ - pa_threaded_mainloop_lock(mMainLoop); - - switch (deviceType) { - case SPEAKER: - case BLUETOOTH_A2DP: { - pa_operation* operation = pa_context_set_default_sink(mContext, name.c_str(), NULL, NULL); - if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] set default sink failed!"); - pa_threaded_mainloop_unlock(mMainLoop); - return ERR_OPERATION_FAILED; - } - pa_operation_unref(operation); - break; - } - case MIC: - case BLUETOOTH_SCO: { - pa_operation* operation = pa_context_set_default_source(mContext, name.c_str(), NULL, NULL); - if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] set default source failed!"); - pa_threaded_mainloop_unlock(mMainLoop); - return ERR_OPERATION_FAILED; - } - - pa_operation_unref(operation); - break; - } - default: - break; - } - - pa_threaded_mainloop_unlock(mMainLoop); - return SUCCESS; -} - -int32_t PulseAudioPolicyManager::SetRingerMode(AudioRingerMode ringerMode) -{ - mRingerMode = ringerMode; - - // Incase if KvStore didnot connect during bootup - if (mAudioPolicyKvStore == nullptr) { - bool isFirstBoot = false; - InitAudioPolicyKvStore(isFirstBoot); - } - - WriteRingerModeToKvStore(ringerMode); - return SUCCESS; + return (userData->mute) ? true : false; } -AudioRingerMode PulseAudioPolicyManager::GetRingerMode() +bool PulseAudioServiceAdapterImpl::IsStreamActive(AudioStreamType streamType) { - return mRingerMode; -} + std::unique_ptr userData = std::make_unique(); + userData->thiz = this; + userData->streamType = streamType; + userData->isCorked = true; -AudioIOHandle PulseAudioPolicyManager::OpenAudioPort(std::shared_ptr audioPortInfo) -{ - std::string moduleArgs = GetModuleArgs(audioPortInfo); - MEDIA_INFO_LOG("[PolicyManager] load-module %{public}s %{public}s", audioPortInfo->name, moduleArgs.c_str()); - - if (!strcmp(audioPortInfo->name, PIPE_SOURCE) || !strcmp(audioPortInfo->name, PIPE_SINK)) { - if (audioPortInfo->fileName != nullptr) { - if (access(audioPortInfo->fileName, F_OK) == 0) { - int32_t ret = std::remove(audioPortInfo->fileName); - if (ret) { - MEDIA_ERR_LOG("[PolicyManager] Error Removing file: %{public}s Failed! ret val: %{public}d", - audioPortInfo->fileName, ret); - } - } else { - MEDIA_DEBUG_LOG("[PolicyManager] File: %{public}s does not exist!", audioPortInfo->fileName); - } - } else { - MEDIA_ERR_LOG("[PolicyManager] Error audioPortInfo->fileName is null!"); - } + if (mContext == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] IsStreamActive mContext is nullptr"); + return false; } pa_threaded_mainloop_lock(mMainLoop); - std::unique_ptr userData = std::make_unique(); - userData->thiz = this; - - pa_operation* operation = pa_context_load_module(mContext, audioPortInfo->name, moduleArgs.c_str(), ModuleLoadCb, - reinterpret_cast(userData.get())); + pa_operation *operation = pa_context_get_sink_input_info_list(mContext, + PulseAudioServiceAdapterImpl::PaGetSinkInputInfoCorkStatusCb, reinterpret_cast(userData.get())); if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_load_module returned nullptr"); + MEDIA_ERR_LOG("[IsStreamActive] pa_context_get_sink_input_info_list returned nullptr"); pa_threaded_mainloop_unlock(mMainLoop); - return PA_INVALID_INDEX; + return false; } while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) { @@ -329,118 +316,31 @@ AudioIOHandle PulseAudioPolicyManager::OpenAudioPort(std::shared_ptridx; - return ioHandle; -} - -int32_t PulseAudioPolicyManager::CloseAudioPort(AudioIOHandle ioHandle) -{ - pa_threaded_mainloop_lock(mMainLoop); - - pa_operation* operation = pa_context_unload_module(mContext, ioHandle, NULL, NULL); - if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_unload_module returned nullptr!"); - pa_threaded_mainloop_unlock(mMainLoop); - return ERROR; - } + MEDIA_INFO_LOG("[IsStreamActive] cork for stream %s : %d", + GetNameByStreamType(streamType).c_str(), userData->isCorked); - pa_operation_unref(operation); - pa_threaded_mainloop_unlock(mMainLoop); - return SUCCESS; + return (userData->isCorked) ? false : true; } -// Private Members -bool PulseAudioPolicyManager::ConnectToPulseAudio(void) +void PulseAudioServiceAdapterImpl::Disconnect() { if (mContext != NULL) { - pa_context_disconnect (mContext); - pa_context_set_state_callback (mContext, NULL, NULL); - pa_context_set_subscribe_callback (mContext, NULL, NULL); - - pa_context_unref (mContext); - } - - pa_proplist *proplist = pa_proplist_new(); - pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "PulseAudio Service"); - pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.ohos.pulseaudio.service"); - mContext = pa_context_new_with_proplist(pa_threaded_mainloop_get_api(mMainLoop), NULL, proplist); - pa_proplist_free(proplist); - - if (mContext == NULL) { - MEDIA_ERR_LOG("[PolicyManager] creating pa context failed"); - return false; - } - - pa_context_set_state_callback(mContext, PulseAudioPolicyManager::ContextStateCb, this); - - if (pa_context_connect(mContext, NULL, PA_CONTEXT_NOFAIL, NULL) < 0) { - if (pa_context_errno(mContext) == PA_ERR_INVALID) { - MEDIA_ERR_LOG("[PolicyManager] pa context connect failed: %{public}s", - pa_strerror(pa_context_errno(mContext))); - goto Fail; - } + pa_context_disconnect(mContext); + /* Make sure we don't get any further callbacks */ + pa_context_set_state_callback(mContext, NULL, NULL); + pa_context_set_subscribe_callback(mContext, NULL, NULL); + pa_context_unref(mContext); } - return true; - -Fail: - /* Make sure we don't get any further callbacks */ - pa_context_set_state_callback (mContext, NULL, NULL); - pa_context_set_subscribe_callback (mContext, NULL, NULL); - pa_context_unref (mContext); - return false; -} - -std::string PulseAudioPolicyManager::GetModuleArgs(std::shared_ptr audioPortInfo) -{ - std::string args; - - if (!strcmp(audioPortInfo->name, HDI_SINK)) { - if (audioPortInfo->rate != nullptr) { - args = "rate="; - args.append(audioPortInfo->rate); - } - - if (audioPortInfo->channels != nullptr) { - args.append(" channels="); - args.append(audioPortInfo->channels); - } - - if (audioPortInfo->buffer_size != nullptr) { - args.append(" buffer_size="); - args.append(audioPortInfo->buffer_size); - } - } else if (!strcmp(audioPortInfo->name, HDI_SOURCE)) { - if (audioPortInfo->rate != nullptr) { - args = "rate="; - args.append(audioPortInfo->rate); - } - - if (audioPortInfo->channels != nullptr) { - args.append(" channels="); - args.append(audioPortInfo->channels); - } - - if (audioPortInfo->buffer_size != nullptr) { - args.append(" buffer_size="); - args.append(audioPortInfo->buffer_size); - } - } else if (!strcmp(audioPortInfo->name, PIPE_SINK)) { - if (audioPortInfo->fileName != nullptr) { - args = "file="; - args.append(audioPortInfo->fileName); - } - } else if (!strcmp(audioPortInfo->name, PIPE_SOURCE)) { - if (audioPortInfo->fileName != nullptr) { - args = "file="; - args.append(audioPortInfo->fileName); - } + if (mMainLoop != NULL) { + pa_threaded_mainloop_stop(mMainLoop); + pa_threaded_mainloop_free(mMainLoop); } - return args; + return; } -std::string PulseAudioPolicyManager::GetStreamNameByStreamType(AudioStreamType streamType) +std::string PulseAudioServiceAdapterImpl::GetNameByStreamType(AudioStreamType streamType) { switch (streamType) { case STREAM_MUSIC: @@ -460,7 +360,7 @@ std::string PulseAudioPolicyManager::GetStreamNameByStreamType(AudioStreamType s } } -AudioStreamType PulseAudioPolicyManager::GetStreamIDByType(std::string streamType) +AudioStreamType PulseAudioServiceAdapterImpl::GetIdByStreamType(std::string streamType) { AudioStreamType stream = STREAM_MUSIC; @@ -478,218 +378,85 @@ AudioStreamType PulseAudioPolicyManager::GetStreamIDByType(std::string streamTyp return stream; } -bool PulseAudioPolicyManager::InitAudioPolicyKvStore(bool& isFirstBoot) +void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoMuteStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, + void *userdata) { - DistributedKvDataManager manager; - Options options; - - options.createIfMissing = false; - options.encrypt = false; - options.autoSync = true; - options.kvStoreType = KvStoreType::SINGLE_VERSION; - - AppId appId; - appId.appId = "policymanager"; - StoreId storeId; - storeId.storeId = "audiopolicy"; - - // open and initialize kvstore instance. - if (mAudioPolicyKvStore == nullptr) { - manager.GetSingleKvStore( - options, appId, storeId, [&](Status status, std::unique_ptr singleKvStore) { - if (status == Status::STORE_NOT_FOUND) { - MEDIA_ERR_LOG("[PolicyManager] InitAudioPolicyKvStore: STORE_NOT_FOUND!"); - return; - } else { - mAudioPolicyKvStore = std::move(singleKvStore); - } - }); - } - - if (mAudioPolicyKvStore == nullptr) { - MEDIA_INFO_LOG("[PolicyManager] First Boot: Create AudioPolicyKvStore"); - options.createIfMissing = true; - // [create and] open and initialize kvstore instance. - manager.GetSingleKvStore( - options, appId, storeId, [&](Status status, std::unique_ptr singleKvStore) { - if (status != Status::SUCCESS) { - MEDIA_ERR_LOG("[PolicyManager] Create AudioPolicyKvStore Failed!"); - return; - } - - mAudioPolicyKvStore = std::move(singleKvStore); - isFirstBoot = true; - }); - } - - if (mAudioPolicyKvStore == nullptr) { - MEDIA_ERR_LOG("[PolicyManager] InitAudioPolicyKvStore: Failed!"); - return false; - } - - return true; -} + UserData *userData = reinterpret_cast(userdata); + PulseAudioServiceAdapterImpl *thiz = userData->thiz; -void PulseAudioPolicyManager::InitVolumeMap(bool isFirstBoot) -{ - if (isFirstBoot == true) { - WriteVolumeToKvStore(STREAM_MUSIC, MAX_VOLUME); - WriteVolumeToKvStore(STREAM_RING, MAX_VOLUME); - MEDIA_INFO_LOG("[PolicyManager] Wrote default stream volumes to KvStore"); - } else { - LoadVolumeMap(); + if (eol < 0) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to get sink input information: %s", + pa_strerror(pa_context_errno(c))); + return; } - return; -} -void PulseAudioPolicyManager::InitRingerMode(bool isFirstBoot) -{ - if (mAudioPolicyKvStore == nullptr) { - MEDIA_ERR_LOG("[PolicyManager] mAudioPolicyKvStore is null!"); + if (eol) { + pa_threaded_mainloop_signal(thiz->mMainLoop, 0); return; } - if (isFirstBoot == true) { - mRingerMode = RINGER_MODE_NORMAL; - WriteRingerModeToKvStore(RINGER_MODE_NORMAL); - MEDIA_INFO_LOG("[PolicyManager] Wrote default ringer mode to KvStore"); - } else { - LoadRingerMode(); + if (i->proplist == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid Proplist for sink input (%{public}d).", i->index); + return; } -} -bool PulseAudioPolicyManager::LoadVolumeFromKvStore(AudioStreamType streamType) -{ - Key key; - Value value; - - switch (streamType) { - case STREAM_MUSIC: - key = "music"; - break; - case STREAM_RING: - key = "ring"; - break; - default: - return false; + const char *streamtype = pa_proplist_gets(i->proplist, "stream.type"); + if (streamtype == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid StreamType."); + return; } - Status status = mAudioPolicyKvStore->Get(key, value); - if (status == Status::SUCCESS) { - float volume = TransferByteArrayToType(value.Data()); - mVolumeMap[streamType] = volume; - MEDIA_DEBUG_LOG("[PolicyManager] volume from kvStore %{public}f for streamType:%{public}d", - volume, streamType); - return true; + std::string streamType(streamtype); + if (!streamType.compare(thiz->GetNameByStreamType(userData->streamType))) { + userData->mute = i->mute; + MEDIA_INFO_LOG("[PulseAudioServiceAdapterImpl] Mute : %{public}d for stream : %{public}s", + userData->mute, i->name); } - return false; + return; } -bool PulseAudioPolicyManager::LoadVolumeMap(void) +void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoMuteCb(pa_context *c, const pa_sink_input_info *i, + int eol, void *userdata) { - if (mAudioPolicyKvStore == nullptr) { - MEDIA_ERR_LOG("[PolicyManager] LoadVolumeMap: mAudioPolicyKvStore is null!"); - return false; - } - - if (!LoadVolumeFromKvStore(STREAM_MUSIC)) - MEDIA_ERR_LOG("[PolicyManager] LoadVolumeMap: Couldnot load volume for Music from kvStore!"); - - if (!LoadVolumeFromKvStore(STREAM_RING)) - MEDIA_ERR_LOG("[PolicyManager] LoadVolumeMap: Couldnot load volume for Ring from kvStore!"); - - return true; -} + UserData *userData = reinterpret_cast(userdata); + PulseAudioServiceAdapterImpl *thiz = userData->thiz; -bool PulseAudioPolicyManager::LoadRingerMode(void) -{ - if (mAudioPolicyKvStore == nullptr) { - MEDIA_ERR_LOG("[PolicyManager] LoadRingerMap: mAudioPolicyKvStore is null!"); - return false; + if (eol < 0) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to get sink input information: %s", + pa_strerror(pa_context_errno(c))); + return; } - // get ringer mode value from kvstore. - Key key = "ringermode"; - Value value; - Status status = mAudioPolicyKvStore->Get(key, value); - if (status == Status::SUCCESS) { - mRingerMode = static_cast(TransferByteArrayToType(value.Data())); - MEDIA_DEBUG_LOG("[PolicyManager] Ringer Mode from kvStore %{public}d", mRingerMode); + if (eol) { + pa_threaded_mainloop_signal(thiz->mMainLoop, 0); + return; } - return true; -} - -void PulseAudioPolicyManager::WriteVolumeToKvStore(AudioStreamType streamType, float volume) -{ - if (mAudioPolicyKvStore == nullptr) + if (i->proplist == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid Proplist for sink input (%{public}d).", i->index); return; - - Key key = GetStreamNameByStreamType(streamType); - Value value = Value(TransferTypeToByteArray(volume)); - - Status status = mAudioPolicyKvStore->Put(key, value); - if (status == Status::SUCCESS) { - MEDIA_INFO_LOG("[PolicyManager] volume %{public}f for %{public}s updated in kvStore", volume, - GetStreamNameByStreamType(streamType).c_str()); - } else { - MEDIA_ERR_LOG("[PolicyManager] volume %{public}f for %{public}s failed to update in kvStore!", volume, - GetStreamNameByStreamType(streamType).c_str()); } - return; -} - -void PulseAudioPolicyManager::WriteRingerModeToKvStore(AudioRingerMode ringerMode) -{ - if (mAudioPolicyKvStore == nullptr) + const char *streamtype = pa_proplist_gets(i->proplist, "stream.type"); + if (streamtype == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid StreamType."); return; - - Key key = "ringermode"; - Value value = Value(TransferTypeToByteArray(ringerMode)); - - Status status = mAudioPolicyKvStore->Put(key, value); - if (status == Status::SUCCESS) { - MEDIA_INFO_LOG("[PolicyManager] Wrote RingerMode:%d to kvStore", ringerMode); - } else { - MEDIA_ERR_LOG("[PolicyManager] Writing RingerMode:%d to kvStore failed!", ringerMode); } - return; -} - -void PulseAudioPolicyManager::HandleSinkInputEvent(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, - void *userdata) -{ - std::unique_ptr userData = std::make_unique(); - userData->thiz = this; - - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - pa_threaded_mainloop_lock(mMainLoop); - pa_operation* operation = pa_context_get_sink_input_info(c, idx, - PulseAudioPolicyManager::GetSinkInputInfoVolumeCb, reinterpret_cast(userData.get())); - if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] pa_context_get_sink_input_info_list returned nullptr"); - pa_threaded_mainloop_unlock(mMainLoop); - return; - } - userData.release(); - - pa_threaded_mainloop_accept(mMainLoop); - - pa_operation_unref(operation); - pa_threaded_mainloop_unlock(mMainLoop); + std::string streamType(streamtype); + if (!streamType.compare(thiz->GetNameByStreamType(userData->streamType))) { + pa_operation_unref(pa_context_set_sink_input_mute(c, i->index, (userData->mute) ? 1 : 0, NULL, NULL)); + MEDIA_INFO_LOG("[PulseAudioServiceAdapterImpl] Applied Mute : %{public}d for stream : %{public}s", + userData->mute, i->name); } return; } -void PulseAudioPolicyManager::ContextStateCb(pa_context *c, void *userdata) +void PulseAudioServiceAdapterImpl::PaContextStateCb(pa_context *c, void *userdata) { - PulseAudioPolicyManager* thiz = reinterpret_cast(userdata); - - MEDIA_DEBUG_LOG("[PolicyManager] ContextStateCb %d", pa_context_get_state(c)); + PulseAudioServiceAdapterImpl *thiz = reinterpret_cast(userdata); switch (pa_context_get_state(c)) { case PA_CONTEXT_UNCONNECTED: @@ -699,9 +466,9 @@ void PulseAudioPolicyManager::ContextStateCb(pa_context *c, void *userdata) break; case PA_CONTEXT_READY: { - pa_context_set_subscribe_callback(c, PulseAudioPolicyManager::SubscribeCb, thiz); + pa_context_set_subscribe_callback(c, PulseAudioServiceAdapterImpl::PaSubscribeCb, thiz); - pa_operation* operation = pa_context_subscribe(c, (pa_subscription_mask_t) + pa_operation *operation = pa_context_subscribe(c, (pa_subscription_mask_t) (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SINK_INPUT | PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT | PA_SUBSCRIPTION_MASK_CARD), NULL, NULL); @@ -724,37 +491,11 @@ void PulseAudioPolicyManager::ContextStateCb(pa_context *c, void *userdata) } } -void PulseAudioPolicyManager::SubscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) -{ - PulseAudioPolicyManager* thiz = reinterpret_cast(userdata); - - switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { - case PA_SUBSCRIPTION_EVENT_SINK: - break; - - case PA_SUBSCRIPTION_EVENT_SOURCE: - break; - - case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - thiz->HandleSinkInputEvent(c, t, idx, userdata); - break; - - case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: - break; - - default: - break; - } - - return; -} - -void PulseAudioPolicyManager::ModuleLoadCb(pa_context *c, uint32_t idx, void *userdata) +void PulseAudioServiceAdapterImpl::PaModuleLoadCb(pa_context *c, uint32_t idx, void *userdata) { UserData *userData = reinterpret_cast(userdata); - if (idx == PA_INVALID_INDEX) { - MEDIA_ERR_LOG("[PolicyManager] Failure: %s", pa_strerror(pa_context_errno(c))); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Failure: %s", pa_strerror(pa_context_errno(c))); userData->idx = PA_INVALID_INDEX; } else { userData->idx = idx; @@ -764,16 +505,17 @@ void PulseAudioPolicyManager::ModuleLoadCb(pa_context *c, uint32_t idx, void *us return; } -void PulseAudioPolicyManager::GetSinkInputInfoVolumeCb(pa_context *c, const pa_sink_input_info *i, int eol, +void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoVolumeCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) { - UserData* userData = reinterpret_cast(userdata); - PulseAudioPolicyManager* thiz = userData->thiz; + UserData *userData = reinterpret_cast(userdata); + PulseAudioServiceAdapterImpl *thiz = userData->thiz; - MEDIA_ERR_LOG("[PolicyManager] GetSinkInputInfoVolumeCb"); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] GetSinkInputInfoVolumeCb"); if (eol < 0) { delete userData; - MEDIA_ERR_LOG("[PolicyManager] Failed to get sink input information: %s", pa_strerror(pa_context_errno(c))); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to get sink input information: %s", + pa_strerror(pa_context_errno(c))); return; } @@ -784,28 +526,22 @@ void PulseAudioPolicyManager::GetSinkInputInfoVolumeCb(pa_context *c, const pa_s } if (i->proplist == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid Proplist for sink input (%{public}d).", i->index); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid Proplist for sink input (%{public}d).", i->index); return; } const char *streamtype = pa_proplist_gets(i->proplist, "stream.type"); const char *streamVolume = pa_proplist_gets(i->proplist, "stream.volumeFactor"); if ((streamtype == NULL) || (streamVolume == NULL)) { - MEDIA_ERR_LOG("[PolicyManager] Invalid StreamType."); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid StreamType."); return; } std::string streamType(streamtype); float volumeFactor = std::atof(streamVolume); - - AudioStreamType streamID = thiz->GetStreamIDByType(streamType); - float vol = thiz->mVolumeMap[streamID] * volumeFactor; - - if (thiz->mRingerMode != RINGER_MODE_NORMAL) { - if (!streamType.compare("ring")) { - vol = MIN_VOLUME; - } - } + AudioStreamType streamID = thiz->GetIdByStreamType(streamType); + float volumeCb = mAudioServiceAdapterCallback->OnGetVolumeCb(streamtype); + float vol = volumeCb * volumeFactor; pa_cvolume cv = i->volume; int32_t volume = pa_sw_volume_from_linear(vol); @@ -817,146 +553,90 @@ void PulseAudioPolicyManager::GetSinkInputInfoVolumeCb(pa_context *c, const pa_s pa_operation_unref(pa_context_set_sink_input_mute(c, i->index, 0, NULL, NULL)); } } - - MEDIA_INFO_LOG("[PolicyManager] Applied volume : %{public}f for stream : %{public}s, volumeInt%{public}d", + MEDIA_INFO_LOG("[PulseAudioServiceAdapterImpl]volume : %{public}f for stream : %{public}s, volumeInt%{public}d", vol, i->name, volume); return; } -void PulseAudioPolicyManager::GetSinkInputInfoCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) +void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoCorkStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, + void *userdata) { - UserData* userData = reinterpret_cast(userdata); + UserData *userData = reinterpret_cast(userdata); + PulseAudioServiceAdapterImpl *thiz = userData->thiz; if (eol < 0) { - MEDIA_ERR_LOG("[PolicyManager] Failed to get sink input information: %{public}s", + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to get sink input information: %s", pa_strerror(pa_context_errno(c))); return; } - pa_operation* operation = pa_context_move_sink_input_by_index(c, i->index, userData->idx, NULL, NULL); - if (operation == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Moving Sink Input %{public}d to Sink %{public}d Failed", - i->index, userData->idx); - } - MEDIA_ERR_LOG("[PolicyManager] Moving Sink Input %{public}d to Sink %{public}d", i->index, userData->idx); - - if (eol) { - MEDIA_DEBUG_LOG("[PolicyManager] All inputs moved"); - pa_threaded_mainloop_signal(userData->thiz->mMainLoop, 0); - return; - } - - return; -} - -void PulseAudioPolicyManager::GetSinkInputInfoMuteCb(pa_context *c, const pa_sink_input_info *i, - int eol, void *userdata) -{ - UserData* userData = reinterpret_cast(userdata); - PulseAudioPolicyManager* thiz = userData->thiz; - - if (eol < 0) { - MEDIA_ERR_LOG("[PolicyManager] Failed to get sink input information: %s", pa_strerror(pa_context_errno(c))); - return; - } - - if (eol) { - pa_threaded_mainloop_signal(thiz->mMainLoop, 0); - return; - } - - if (i->proplist == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid Proplist for sink input (%{public}d).", i->index); - return; - } - - const char *streamtype = pa_proplist_gets(i->proplist, "stream.type"); - if (streamtype == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid StreamType."); - return; - } - - std::string streamType(streamtype); - if (!streamType.compare(thiz->GetStreamNameByStreamType(userData->streamType))) { - pa_operation_unref(pa_context_set_sink_input_mute(c, i->index, (userData->mute) ? 1 : 0, NULL, NULL)); - - MEDIA_INFO_LOG("[PolicyManager] Applied Mute : %{public}d for stream : %{public}s", userData->mute, i->name); - } - - return; -} - -void PulseAudioPolicyManager::GetSinkInputInfoMuteStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, - void *userdata) -{ - UserData* userData = reinterpret_cast(userdata); - PulseAudioPolicyManager* thiz = userData->thiz; - - if (eol < 0) { - MEDIA_ERR_LOG("[PolicyManager] Failed to get sink input information: %s", pa_strerror(pa_context_errno(c))); - return; - } - if (eol) { pa_threaded_mainloop_signal(thiz->mMainLoop, 0); return; } if (i->proplist == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid Proplist for sink input (%{public}d).", i->index); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid Proplist for sink input (%{public}d).", i->index); return; } const char *streamtype = pa_proplist_gets(i->proplist, "stream.type"); if (streamtype == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid StreamType."); + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid StreamType."); return; } std::string streamType(streamtype); - if (!streamType.compare(thiz->GetStreamNameByStreamType(userData->streamType))) { - userData->mute = i->mute; - MEDIA_INFO_LOG("[PolicyManager] Mute : %{public}d for stream : %{public}s", userData->mute, i->name); + if (!streamType.compare(thiz->GetNameByStreamType(userData->streamType))) { + userData->isCorked = i->corked; + MEDIA_INFO_LOG("[PulseAudioServiceAdapterImpl] corked : %{public}d for stream : %{public}s", + userData->isCorked, i->name); } return; } -void PulseAudioPolicyManager::GetSinkInputInfoCorkStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, - void *userdata) +void PulseAudioServiceAdapterImpl::PaSubscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, + void *userdata) { - UserData* userData = reinterpret_cast(userdata); - PulseAudioPolicyManager* thiz = userData->thiz; - - if (eol < 0) { - MEDIA_ERR_LOG("[PolicyManager] Failed to get sink input information: %s", pa_strerror(pa_context_errno(c))); - return; - } + std::unique_ptr userData = std::make_unique(); + PulseAudioServiceAdapterImpl *thiz = reinterpret_cast(userdata); + userData->thiz = thiz; + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SINK: + break; - if (eol) { - pa_threaded_mainloop_signal(thiz->mMainLoop, 0); - return; - } + case PA_SUBSCRIPTION_EVENT_SOURCE: + break; - if (i->proplist == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid Proplist for sink input (%{public}d).", i->index); - return; - } + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + pa_threaded_mainloop_lock(thiz->mMainLoop); + pa_operation *operation = pa_context_get_sink_input_info(c, idx, + PulseAudioServiceAdapterImpl::PaGetSinkInputInfoVolumeCb, reinterpret_cast(userData.get())); + if (operation == NULL) { + MEDIA_ERR_LOG("[PulseAudioServiceAdapterImpl] pa_context_get_sink_input_info_list nullptr"); + pa_threaded_mainloop_unlock(thiz->mMainLoop); + return; + } + userData.release(); + pa_threaded_mainloop_accept(thiz->mMainLoop); + pa_operation_unref(operation); + pa_threaded_mainloop_unlock(thiz->mMainLoop); + } + break; - const char *streamtype = pa_proplist_gets(i->proplist, "stream.type"); - if (streamtype == NULL) { - MEDIA_ERR_LOG("[PolicyManager] Invalid StreamType."); - return; - } + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + break; - std::string streamType(streamtype); - if (!streamType.compare(thiz->GetStreamNameByStreamType(userData->streamType))) { - userData->isCorked = i->corked; - MEDIA_INFO_LOG("[PolicyManager] corked : %{public}d for stream : %{public}s", userData->isCorked, i->name); + default: + break; } return; } } // namespace AudioStandard } // namespace OHOS + +#endif // ST_PULSEAUDIO_AUDIO_SERVICE_ADAPTER_IMPL_H diff --git a/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source.h b/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source.h index 993b3319c5b0ad1dd2b3925597536ea588bbbdb0..e6b7fb89272412bb53a4a4cfedb6f15e006be52f 100644 --- a/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source.h +++ b/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source.h @@ -59,6 +59,7 @@ public: static AudioCapturerSource* GetInstance(void); bool capturerInited_; + static bool micMuteState_; private: const int32_t HALF_FACTOR = 2; diff --git a/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source_intf.h b/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source_intf.h index a7e89c3617bdfcf56f1cca7bbd42e81b66844342..e419eb5988d17cdddc1dc61ca1dfe5f069943bb0 100644 --- a/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source_intf.h +++ b/frameworks/innerkitsimpl/audiocapturer/include/audio_capturer_source_intf.h @@ -34,6 +34,8 @@ int32_t AudioCapturerSourceStart(void); int32_t AudioCapturerSourceStop(void); int32_t AudioCapturerSourceFrame(char *, uint64_t, uint64_t *); int32_t AudioCapturerSourceSetVolume(float, float); +bool AudioCapturerSourceIsMuteRequired(void); +int32_t AudioCapturerSourceSetMute(bool); int32_t AudioCapturerSourceGetVolume(float *left, float *right); #ifdef __cplusplus } diff --git a/frameworks/innerkitsimpl/audiocapturer/src/audio_capturer_source.cpp b/frameworks/innerkitsimpl/audiocapturer/src/audio_capturer_source.cpp index fce1495c5e510b3ab88c18c2ab2a0dc02b40022e..2bd2ef049bb2ae9ace1be6ee5eb2721d69150b85 100644 --- a/frameworks/innerkitsimpl/audiocapturer/src/audio_capturer_source.cpp +++ b/frameworks/innerkitsimpl/audiocapturer/src/audio_capturer_source.cpp @@ -26,6 +26,8 @@ namespace AudioStandard { const char *g_audioOutTestFilePath = "/data/local/tmp/audio_capture.pcm"; #endif // CAPTURE_DUMP +bool AudioCapturerSource::micMuteState_ = false; + AudioCapturerSource::AudioCapturerSource() : capturerInited_(false), started_(false), paused_(false), leftVolume_(MAX_VOLUME_LEVEL), rightVolume_(MAX_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr), audioCapture_(nullptr), @@ -262,7 +264,6 @@ int32_t AudioCapturerSource::Start(void) return ERR_NOT_STARTED; } started_ = true; - audioCapture_->volume.SetVolume(reinterpret_cast(audioCapture_), MAX_VOLUME_LEVEL); } return SUCCESS; @@ -315,6 +316,7 @@ int32_t AudioCapturerSource::SetMute(bool isMute) return ERR_OPERATION_FAILED; } + micMuteState_ = isMute; return SUCCESS; } @@ -493,6 +495,25 @@ int32_t AudioCapturerSourceGetVolume(float *left, float *right) return ret; } +bool AudioCapturerSourceIsMuteRequired(void) +{ + return AudioCapturerSource::micMuteState_; +} + +int32_t AudioCapturerSourceSetMute(bool isMute) +{ + int32_t ret; + + if (!g_audioCaptureSourceInstance->capturerInited_) { + MEDIA_ERR_LOG("audioCapturer Not Inited! Init the capturer first\n"); + return ERR_DEVICE_INIT; + } + + ret = g_audioCaptureSourceInstance->SetMute(isMute); + + return ret; +} + #ifdef __cplusplus } #endif diff --git a/frameworks/innerkitsimpl/pulseaudio/src/modules/hdi/hdi_source.c b/frameworks/innerkitsimpl/pulseaudio/src/modules/hdi/hdi_source.c index 410b084e1956ab9958db6b749f2c89bfe7b68a35..30b3eeef3c198c599cac2a31497383774c7df410 100644 --- a/frameworks/innerkitsimpl/pulseaudio/src/modules/hdi/hdi_source.c +++ b/frameworks/innerkitsimpl/pulseaudio/src/modules/hdi/hdi_source.c @@ -64,8 +64,6 @@ struct userdata { pa_usec_t block_usec; pa_usec_t timestamp; AudioSourceAttr attrs; - // A flag to signal us to prevent silent record during bootup - bool IsReady; bool IsCapturerInit; }; @@ -102,7 +100,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off case PA_SOURCE_MESSAGE_GET_LATENCY: { pa_usec_t now; now = pa_rtclock_now(); - *((int64_t*) data) = (int64_t)now - (int64_t)u->timestamp; + *((int64_t*)data) = (int64_t)now - (int64_t)u->timestamp; return 0; } default: { @@ -114,66 +112,41 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off /* Called from the IO thread. */ static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_state, - pa_suspend_cause_t new_suspend_cause) { + pa_suspend_cause_t new_suspend_cause) { struct userdata *u = NULL; pa_assert(s); pa_assert_se(u = s->userdata); - if (s->thread_info.state == PA_SOURCE_SUSPENDED || s->thread_info.state == PA_SOURCE_INIT) { - if (PA_SOURCE_IS_OPENED(new_state)) - u->timestamp = pa_rtclock_now(); - } - - return 0; -} - -static pa_hook_result_t source_output_fixate_hook_cb(pa_core *c, pa_source_output_new_data *data, - struct userdata *u) { - int ret; - MEDIA_DEBUG_LOG("HDI Source: Detected source output"); - pa_assert(data); - pa_assert(u); - - if (!strcmp(u->source->name, data->source->name)) { - // Signal Ready when a Source Output is connected - if (!u->IsReady) - u->IsReady = true; - - ret = pa_capturer_init(u); - if (ret != 0) { - MEDIA_DEBUG_LOG("HDI Source: Cannot initialize Capturer! ret=%d", ret); - return PA_HOOK_OK; - } + if ((s->thread_info.state == PA_SOURCE_SUSPENDED || s->thread_info.state == PA_SOURCE_INIT) && + PA_SOURCE_IS_OPENED(new_state)) { u->timestamp = pa_rtclock_now(); - pa_source_suspend(u->source, false, PA_SUSPEND_IDLE); - } - - return PA_HOOK_OK; -} - -static pa_hook_result_t source_output_move_finish_hook_cb(pa_core *c, pa_source_output *output, struct userdata *u) { - int ret; - - MEDIA_DEBUG_LOG("HDI Source: Detected source move finish"); - pa_assert(output); - pa_assert(u); - - if (!strcmp(output->source->name, u->source->name)) { - // Signal Ready when a source output is connected - if (!u->IsReady) - u->IsReady = true; - - ret = pa_capturer_init(u); - if (ret != 0) { - pa_log_error("HDI Source: Cannot initialize capturer! ret=%d", ret); - return PA_HOOK_OK; + if (new_state == PA_SOURCE_RUNNING && !u->IsCapturerInit) { + if (pa_capturer_init(u)) { + MEDIA_ERR_LOG("HDI capturer reinitialization failed"); + return -PA_ERR_IO; + } + u->IsCapturerInit = true; + MEDIA_DEBUG_LOG("Successfully reinitialized HDI renderer"); + } + } else if (s->thread_info.state == PA_SOURCE_IDLE) { + if (new_state == PA_SOURCE_SUSPENDED) { + if (u->IsCapturerInit) { + pa_capturer_exit(); + u->IsCapturerInit = false; + MEDIA_DEBUG_LOG("Deinitialized HDI capturer"); + } + } else if (new_state == PA_SOURCE_RUNNING && !u->IsCapturerInit) { + MEDIA_DEBUG_LOG("Idle to Running reinitializing HDI capturing device"); + if (pa_capturer_init(u)) { + MEDIA_ERR_LOG("Idle to Running HDI capturer reinitialization failed"); + return -PA_ERR_IO; + } + u->IsCapturerInit = true; + MEDIA_DEBUG_LOG("Idle to RunningsSuccessfully reinitialized HDI renderer"); } - - u->timestamp = pa_rtclock_now(); - pa_source_suspend(u->source, false, PA_SUSPEND_IDLE); } - return PA_HOOK_OK; + return 0; } static int get_capturer_frame_from_hdi(pa_memchunk *chunk, struct userdata *u) { @@ -194,7 +167,7 @@ static int get_capturer_frame_from_hdi(pa_memchunk *chunk, struct userdata *u) { pa_memblock_release(chunk->memblock); MEDIA_DEBUG_LOG("HDI Source: request bytes: %{public}" PRIu64 ", replyBytes: %{public}" PRIu64, requestBytes, replyBytes); - if(replyBytes > requestBytes) { + if (replyBytes > requestBytes) { MEDIA_ERR_LOG("HDI Source: Error replyBytes > requestBytes. Requested data Length: " "%{public}" PRIu64 ", Read: %{public}" PRIu64 " bytes", requestBytes, replyBytes); pa_memblock_unref(chunk->memblock); @@ -229,11 +202,10 @@ static void thread_func(void *userdata) { u->timestamp = pa_rtclock_now(); MEDIA_DEBUG_LOG("HDI Source: u->timestamp : %{public}" PRIu64, u->timestamp); - while(true) { + while (true) { int ret = 0; - if (PA_SOURCE_IS_OPENED(u->source->thread_info.state) && - (u->source->thread_info.state != PA_SOURCE_SUSPENDED) && u->IsReady && u->IsCapturerInit) { + if (PA_SOURCE_IS_RUNNING(u->source->thread_info.state) && u->IsCapturerInit) { pa_memchunk chunk; pa_usec_t now; @@ -252,12 +224,6 @@ static void thread_func(void *userdata) { pa_rtpoll_set_timer_absolute(u->rtpoll, u->timestamp + u->block_usec); } else { - if (u->IsCapturerInit) { - u->IsCapturerInit = false; - pa_capturer_exit(); - MEDIA_INFO_LOG("HDI Source: Capturer exit done"); - } - pa_rtpoll_set_timer_disabled(u->rtpoll); MEDIA_INFO_LOG("HDI Source: pa_rtpoll_set_timer_disabled done "); } @@ -266,7 +232,7 @@ static void thread_func(void *userdata) { if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) { /* If this was no regular exit from the loop we have to continue * processing messages until we received PA_MESSAGE_SHUTDOWN */ - MEDIA_INFO_LOG("HDI Source: pa_rtpoll_run ret:%{public}d failed", ret ); + MEDIA_INFO_LOG("HDI Source: pa_rtpoll_run ret:%{public}d failed", ret); pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); @@ -286,19 +252,26 @@ static int pa_capturer_init(struct userdata *u) { ret = AudioCapturerSourceInit(&u->attrs); if (ret != 0) { - MEDIA_INFO_LOG("Audio capturer init failed!"); + MEDIA_ERR_LOG("Audio capturer init failed!"); return ret; } - ret = AudioCapturerSourceStart(); + ret = AudioCapturerSourceSetVolume(DEFAULT_LEFT_VOLUME, DEFAULT_RIGHT_VOLUME); if (ret != 0) { - MEDIA_INFO_LOG("Audio capturer start failed!"); + MEDIA_ERR_LOG("audio capturer set volume failed!"); goto fail; } - ret = AudioCapturerSourceSetVolume(DEFAULT_LEFT_VOLUME, DEFAULT_RIGHT_VOLUME); + bool muteState = AudioCapturerSourceIsMuteRequired(); + ret = AudioCapturerSourceSetMute(muteState); if (ret != 0) { - MEDIA_INFO_LOG("audio capturer set volume failed!"); + MEDIA_ERR_LOG("audio capturer set muteState: %d failed!", muteState); + goto fail; + } + + ret = AudioCapturerSourceStart(); + if (ret != 0) { + MEDIA_ERR_LOG("Audio capturer start failed!"); goto fail; } @@ -310,14 +283,13 @@ fail: return ret; } -static void pa_capturer_exit() { +static void pa_capturer_exit(void) { AudioCapturerSourceStop(); AudioCapturerSourceDeInit(); } - static int pa_set_source_properties(pa_module *m, pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map, - struct userdata *u) { + struct userdata *u) { pa_source_new_data data; pa_source_new_data_init(&data); @@ -387,9 +359,6 @@ pa_source *pa_hdi_source_new(pa_module *m, pa_modargs *ma, const char*driver) { u->module = m; u->rtpoll = pa_rtpoll_new(); - // Set IsReady to false at start. will be made true when a Source Output is connected - u->IsReady = false; - if (pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll) < 0) { MEDIA_INFO_LOG("pa_thread_mq_init() failed."); goto fail; @@ -411,11 +380,6 @@ pa_source *pa_hdi_source_new(pa_module *m, pa_modargs *ma, const char*driver) { goto fail; } - pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_NORMAL, - (pa_hook_cb_t) source_output_fixate_hook_cb, u); - pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH], PA_HOOK_NORMAL, - (pa_hook_cb_t) source_output_move_finish_hook_cb, u); - thread_name = pa_sprintf_malloc("hdi-source-record"); if (!(u->thread = pa_thread_new(thread_name, thread_func, u))) { MEDIA_INFO_LOG("Failed to create hdi-source-record thread!"); diff --git a/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/include/audio_policy_test.h b/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/include/audio_policy_test.h index 472f942660496fcd4c8f7474354f7281ee2638dc..c93f2b0e9a689e25a964c303b797a1ff0442788a 100644 --- a/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/include/audio_policy_test.h +++ b/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/include/audio_policy_test.h @@ -1,58 +1,59 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -namespace OHOS { -namespace AudioStandard { -namespace V1_0 { -using namespace std; -using namespace testing; - -struct PolicyParam { - float volume; - AudioStreamType streamType; - AudioRingerMode ringerMode; - AudioStandard::DeviceType deviceType; - AudioStandard::AudioDeviceDescriptor::DeviceFlag deviceFlag; - AudioStandard::AudioDeviceDescriptor::DeviceRole deviceRole; - bool active; - bool mute; - string key; - string value; -}; - -class AudioPolicyTest : public TestWithParam { -public: - AudioPolicyTest() {} - - virtual ~AudioPolicyTest() {} - - // SetUpTestCase: Called before all test cases - static void SetUpTestCase(void); - // TearDownTestCase: Called after all test case - static void TearDownTestCase(void); - // SetUp: Called before each test cases - void SetUp(void) override; - // TearDown: Called after each test cases - void TearDown(void) override; -}; -} -} -} +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace OHOS { +namespace AudioStandard { +namespace V1_0 { +using namespace std; +using namespace testing; + +struct PolicyParam { + float volume; + AudioStreamType streamType; + AudioRingerMode ringerMode; + ActiveDeviceType actDeviceType; + AudioDeviceDescriptor::DeviceType deviceType; + AudioDeviceDescriptor::DeviceFlag deviceFlag; + AudioDeviceDescriptor::DeviceRole deviceRole; + bool active; + bool mute; + string key; + string value; +}; + +class AudioPolicyTest : public TestWithParam { +public: + AudioPolicyTest() {} + + virtual ~AudioPolicyTest() {} + + // SetUpTestCase: Called before all test cases + static void SetUpTestCase(void); + // TearDownTestCase: Called after all test case + static void TearDownTestCase(void); + // SetUp: Called before each test cases + void SetUp(void) override; + // TearDown: Called after each test cases + void TearDown(void) override; +}; +} +} +} diff --git a/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/src/audio_policy_test.cpp b/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/src/audio_policy_test.cpp index f2d5fb8efa3b6e300b7e54f098234e61974dc36e..dbd4821312c9ad46ae9fb77f4c2ae422074cd2c4 100644 --- a/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/src/audio_policy_test.cpp +++ b/frameworks/innerkitsimpl/test/moduletest/audiopolicy/1.0/src/audio_policy_test.cpp @@ -1,493 +1,467 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "audio_policy_test.h" -#include "audio_system_manager.h" - -using namespace std; -using namespace OHOS::AudioStandard; -using namespace testing::ext; - -namespace OHOS { -namespace AudioStandard { -namespace V1_0 { -void AudioPolicyTest::SetUpTestCase(void) -{ - ASSERT_NE(nullptr, AudioSystemManager::GetInstance()); -} - -void AudioPolicyTest::TearDownTestCase(void) {} - -void AudioPolicyTest::SetUp(void) {} - -void AudioPolicyTest::TearDown(void) {} - -namespace { -const PolicyParam VOLUME_PARAMS[] = { - { - .volume = 0.5, - .streamType = STREAM_MUSIC - }, - { - .volume = 0.5, - .streamType = STREAM_RING - } -}; - -const PolicyParam MUTE_PARAMS[] = { - { - .streamType = STREAM_MUSIC, - .mute = true - }, - { - .streamType = STREAM_MUSIC, - .mute = false - } -}; - -const PolicyParam STREAM_PARAMS[] = { - { - .streamType = STREAM_MUSIC, - .active = true - }, - { - .streamType = STREAM_RING, - .active = false - } -}; - -const PolicyParam DEVICE_PARAMS[] = { - { - .deviceType = SPEAKER, - .active = true - }, - { - .deviceType = MIC, - .active = true - }, - { - .deviceType = BLUETOOTH_A2DP, - .active = true - }, - { - .deviceType = BLUETOOTH_A2DP, - .active = false - }, - { - .deviceType = BLUETOOTH_SCO, - .active = true - }, - { - .deviceType = BLUETOOTH_SCO, - .active = false - }, - { - .deviceType = MIC, - .active = true - }, - { - .deviceType = BLUETOOTH_SCO, - .active = true - }, - { - .deviceType = SPEAKER, - .active = true - }, - { - .deviceType = BLUETOOTH_A2DP, - .active = true - }, -}; - -const PolicyParam RINGER_MODE_PARAMS[] = { - { - .ringerMode = RINGER_MODE_NORMAL - }, - { - .ringerMode = RINGER_MODE_SILENT - }, - { - .ringerMode = RINGER_MODE_VIBRATE - }, -}; - -const PolicyParam MIC_MUTE_PARAMS[] = { - { - .mute = true - }, - { - .mute = false - } -}; - -const PolicyParam VOLUME_RANGE_PARAMS[] = { - { - .streamType = STREAM_MUSIC - }, - { - .streamType = STREAM_RING - } -}; - -const PolicyParam AUDIO_PARAMS[] = { - { - .key = "sampling_rate", - .value = "8000" - }, - { - .key = "sampling_rate", - .value = "44100" - }, - { - .key = "sampling_rate", - .value = "96000" - } -}; - -const PolicyParam DEVICES_PARAMS[] = { - { - .deviceType = MIC, - .deviceFlag = AudioDeviceDescriptor::DeviceFlag::INPUT_DEVICES_FLAG, - .deviceRole = AudioDeviceDescriptor::DeviceRole::INPUT_DEVICE - }, - { - .deviceType = SPEAKER, - .deviceFlag = AudioDeviceDescriptor::DeviceFlag::OUTPUT_DEVICES_FLAG, - .deviceRole = AudioDeviceDescriptor::DeviceRole::OUTPUT_DEVICE - } -}; -} // namespace - -/* - * Set Volume - * - */ -class AudioPolicySetVolumeTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicySetVolumeTest, SetVolume, TestSize.Level1) -{ - PolicyParam params = GetParam(); - - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - float volume = params.volume; - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetVolume(volumeType, volume)); -} - -INSTANTIATE_TEST_CASE_P( - SetVolume, - AudioPolicySetVolumeTest, - ValuesIn(VOLUME_PARAMS)); - -/* - * Get Volume - * - */ - -class AudioPolicyGetVolumeTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyGetVolumeTest, GetVolume, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - float volume = params.volume; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetVolume(volumeType, volume)); - EXPECT_EQ(volume, AudioSystemManager::GetInstance()->GetVolume(volumeType)); -} - -INSTANTIATE_TEST_CASE_P( - GetVolume, - AudioPolicyGetVolumeTest, - ValuesIn(VOLUME_PARAMS)); - -/* - * Set Mute - * - */ -class AudioPolicySetMuteTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicySetMuteTest, SetMute, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - bool mute = params.mute; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMute(volumeType, mute)); -} - - -INSTANTIATE_TEST_CASE_P( - SetMute, - AudioPolicySetMuteTest, - ValuesIn(MUTE_PARAMS)); - -/* - * Is Mute - * - */ -class AudioPolicyGetMuteTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyGetMuteTest, IsStreamMute, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - bool mute = params.mute; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMute(volumeType, mute)); - EXPECT_EQ(mute, AudioSystemManager::GetInstance()->IsStreamMute(volumeType)); -} - -INSTANTIATE_TEST_CASE_P( - IsStreamMute, - AudioPolicyGetMuteTest, - ValuesIn(MUTE_PARAMS)); - -/* - * Is Stream Active - * - */ -class AudioPolicyIsStreamActiveTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyIsStreamActiveTest, IsStreamActive, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - - // review this code - EXPECT_EQ(params.active, AudioSystemManager::GetInstance()->IsStreamActive(volumeType)); -} - -INSTANTIATE_TEST_CASE_P( - IsStreamActive, - AudioPolicyIsStreamActiveTest, - ValuesIn(STREAM_PARAMS)); - -/* - * Set Device Active - * - */ -class AudioPolicySetDeviceActiveTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicySetDeviceActiveTest, SetDeviceActive, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioDeviceDescriptor::DeviceType deviceType = static_cast(params.deviceType); - bool active = params.active; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetDeviceActive(deviceType, active)); -} - -INSTANTIATE_TEST_CASE_P( - SetDeviceActive, - AudioPolicySetDeviceActiveTest, - ValuesIn(DEVICE_PARAMS)); - -/* - * Is Device Active - * - */ - -class AudioPolicyIsDeviceActiveTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyIsDeviceActiveTest, IsDeviceActive, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioDeviceDescriptor::DeviceType deviceType = static_cast(params.deviceType); - bool active = params.active; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetDeviceActive(deviceType, active)); - EXPECT_EQ(active, AudioSystemManager::GetInstance()->IsDeviceActive(deviceType)); -} - - -INSTANTIATE_TEST_CASE_P( - IsDeviceActive, - AudioPolicyIsDeviceActiveTest, - ValuesIn(DEVICE_PARAMS)); - -/* - * Set Ringer Mode - * - */ -class AudioPolicySetRingerModeTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicySetRingerModeTest, SetRingerMode, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioRingerMode ringerMode = params.ringerMode; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetRingerMode(ringerMode)); -} - - -INSTANTIATE_TEST_CASE_P( - SetRingerMode, - AudioPolicySetRingerModeTest, - ValuesIn(RINGER_MODE_PARAMS)); - -/* - * Get Ringer Mode - * - */ - -class AudioPolicyGetRingerModeTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyGetRingerModeTest, GetRingerMode, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioRingerMode ringerMode = params.ringerMode; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetRingerMode(ringerMode)); - EXPECT_EQ(ringerMode, AudioSystemManager::GetInstance()->GetRingerMode()); -} - -INSTANTIATE_TEST_CASE_P( - GetRingerMode, - AudioPolicyGetRingerModeTest, - ValuesIn(RINGER_MODE_PARAMS)); - - -/* - * Set microphone mute - * - */ -class AudioPolicySetMicrophoneMuteTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicySetMicrophoneMuteTest, SetMicrophoneMute, TestSize.Level1) -{ - PolicyParam params = GetParam(); - bool mute = params.mute; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMicrophoneMute(mute)); -} - -INSTANTIATE_TEST_CASE_P( - SetMicrophoneMute, - AudioPolicySetMicrophoneMuteTest, - ValuesIn(MIC_MUTE_PARAMS)); - -/* - * Is Microphone Mute - * - */ -class AudioPolicyGetMicrophoneMuteTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyGetMicrophoneMuteTest, IsMicrophoneMute, TestSize.Level1) -{ - PolicyParam params = GetParam(); - bool mute = params.mute; - - EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMicrophoneMute(mute)); - EXPECT_EQ(mute, AudioSystemManager::GetInstance()->IsMicrophoneMute()); -} - -INSTANTIATE_TEST_CASE_P( - IsMicrophoneMute, - AudioPolicyGetMicrophoneMuteTest, - ValuesIn(MIC_MUTE_PARAMS)); - -/* - * Check volume range - * - */ -class AudioPolicyVolumeRangeTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyVolumeRangeTest, GetMaxVolume, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - EXPECT_EQ(1.0, AudioSystemManager::GetInstance()->GetMaxVolume(volumeType)); -} - -HWTEST_P(AudioPolicyVolumeRangeTest, GetMinVolume, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::AudioVolumeType volumeType - = static_cast(params.streamType); - EXPECT_EQ(0, AudioSystemManager::GetInstance()->GetMinVolume(volumeType)); -} - -INSTANTIATE_TEST_CASE_P( - GetMaxVolume, - AudioPolicyVolumeRangeTest, - ValuesIn(VOLUME_RANGE_PARAMS)); - -INSTANTIATE_TEST_CASE_P( - GetMinVolume, - AudioPolicyVolumeRangeTest, - ValuesIn(VOLUME_RANGE_PARAMS)); - -/* - * Check volume range - * - */ -class AudioPolicyAudioParameterTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyAudioParameterTest, SetAudioParameter, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::GetInstance()->SetAudioParameter(params.key, params.value); - EXPECT_EQ(params.value, AudioSystemManager::GetInstance()->GetAudioParameter(params.key)); -} - -INSTANTIATE_TEST_CASE_P( - SetAudioParameter, - AudioPolicyAudioParameterTest, - ValuesIn(AUDIO_PARAMS)); - -HWTEST_P(AudioPolicyAudioParameterTest, GetAudioParameter, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioSystemManager::GetInstance()->SetAudioParameter(params.key, params.value); - EXPECT_EQ(params.value, AudioSystemManager::GetInstance()->GetAudioParameter(params.key)); -} - -INSTANTIATE_TEST_CASE_P( - GetAudioParameter, - AudioPolicyAudioParameterTest, - ValuesIn(AUDIO_PARAMS)); - -/* - * Check volume range - * - */ -class AudioPolicyGetDevicesTest : public AudioPolicyTest {}; - -HWTEST_P(AudioPolicyGetDevicesTest, GetDevices, TestSize.Level1) -{ - PolicyParam params = GetParam(); - AudioDeviceDescriptor::DeviceFlag deviceFlag = static_cast(params.deviceFlag); - AudioDeviceDescriptor::DeviceType deviceType = static_cast(params.deviceType); - AudioDeviceDescriptor::DeviceRole deviceRole = static_cast(params.deviceRole); - vector> audioDeviceDescriptors - = AudioSystemManager::GetInstance()->GetDevices(deviceFlag); - sptr audioDeviceDescriptor = audioDeviceDescriptors[0]; - EXPECT_EQ(deviceType, audioDeviceDescriptor->deviceType_); - EXPECT_EQ(deviceRole, audioDeviceDescriptor->deviceRole_); -} - -INSTANTIATE_TEST_CASE_P( - GetDevices, - AudioPolicyGetDevicesTest, - ValuesIn(DEVICES_PARAMS)); -} -} -} +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_policy_test.h" +#include "audio_system_manager.h" + +using namespace std; +using namespace OHOS::AudioStandard; +using namespace testing::ext; + +namespace OHOS { +namespace AudioStandard { +namespace V1_0 { +void AudioPolicyTest::SetUpTestCase(void) +{ + ASSERT_NE(nullptr, AudioSystemManager::GetInstance()); +} + +void AudioPolicyTest::TearDownTestCase(void) {} + +void AudioPolicyTest::SetUp(void) {} + +void AudioPolicyTest::TearDown(void) {} + +namespace { +const PolicyParam VOLUME_PARAMS[] = { + { + .volume = 8, + .streamType = STREAM_MUSIC + }, + { + .volume = 8, + .streamType = STREAM_RING + } +}; + +const PolicyParam MUTE_PARAMS[] = { + { + .streamType = STREAM_MUSIC, + .mute = true + }, + { + .streamType = STREAM_MUSIC, + .mute = false + } +}; + +const PolicyParam STREAM_PARAMS[] = { + { + .streamType = STREAM_MUSIC, + .active = true + }, + { + .streamType = STREAM_RING, + .active = false + } +}; + +const PolicyParam ACTIVE_DEVICE_PARAMS[] = { + { + .actDeviceType = SPEAKER, + .active = true + }, + { + .actDeviceType = BLUETOOTH_SCO, + .active = true + }, + { + .actDeviceType = BLUETOOTH_SCO, + .active = false + }, + { + .actDeviceType = SPEAKER, + .active = true + }, + { + .actDeviceType = BLUETOOTH_SCO, + .active = true + }, +}; + +const PolicyParam RINGER_MODE_PARAMS[] = { + { + .ringerMode = RINGER_MODE_NORMAL + }, + { + .ringerMode = RINGER_MODE_SILENT + }, + { + .ringerMode = RINGER_MODE_VIBRATE + }, +}; + +const PolicyParam MIC_MUTE_PARAMS[] = { + { + .mute = true + }, + { + .mute = false + } +}; + +const PolicyParam VOLUME_RANGE_PARAMS[] = { + { + .streamType = STREAM_MUSIC + }, + { + .streamType = STREAM_RING + } +}; + +const PolicyParam AUDIO_PARAMS[] = { + { + .key = "sampling_rate", + .value = "8000" + }, + { + .key = "sampling_rate", + .value = "44100" + }, + { + .key = "sampling_rate", + .value = "96000" + } +}; + +const PolicyParam DEVICES_PARAMS[] = { + { + .deviceType = AudioDeviceDescriptor::MIC, + .deviceFlag = AudioDeviceDescriptor::DeviceFlag::INPUT_DEVICES_FLAG, + .deviceRole = AudioDeviceDescriptor::DeviceRole::INPUT_DEVICE + }, + { + .deviceType = AudioDeviceDescriptor::SPEAKER, + .deviceFlag = AudioDeviceDescriptor::DeviceFlag::OUTPUT_DEVICES_FLAG, + .deviceRole = AudioDeviceDescriptor::DeviceRole::OUTPUT_DEVICE + } +}; +} // namespace + +/* + * Set Volume + * + */ +class AudioPolicySetVolumeTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicySetVolumeTest, SetVolume, TestSize.Level1) +{ + PolicyParam params = GetParam(); + + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + float volume = params.volume; + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetVolume(volumeType, volume)); +} + +INSTANTIATE_TEST_CASE_P( + SetVolume, + AudioPolicySetVolumeTest, + ValuesIn(VOLUME_PARAMS)); + +/* + * Get Volume + * + */ +class AudioPolicyGetVolumeTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyGetVolumeTest, GetVolume, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + float volume = params.volume; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetVolume(volumeType, volume)); + EXPECT_EQ(volume, AudioSystemManager::GetInstance()->GetVolume(volumeType)); +} + +INSTANTIATE_TEST_CASE_P( + GetVolume, + AudioPolicyGetVolumeTest, + ValuesIn(VOLUME_PARAMS)); + +/* + * Set Mute + * + */ +class AudioPolicySetMuteTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicySetMuteTest, SetMute, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + bool mute = params.mute; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMute(volumeType, mute)); +} + +INSTANTIATE_TEST_CASE_P( + SetMute, + AudioPolicySetMuteTest, + ValuesIn(MUTE_PARAMS)); + +/* + * Is Mute + * + */ +class AudioPolicyGetMuteTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyGetMuteTest, IsStreamMute, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + bool mute = params.mute; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMute(volumeType, mute)); + EXPECT_EQ(mute, AudioSystemManager::GetInstance()->IsStreamMute(volumeType)); +} + +INSTANTIATE_TEST_CASE_P( + IsStreamMute, + AudioPolicyGetMuteTest, + ValuesIn(MUTE_PARAMS)); + +/* + * Is Stream Active + * + */ +class AudioPolicyIsStreamActiveTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyIsStreamActiveTest, IsStreamActive, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + + // review this code + EXPECT_EQ(params.active, AudioSystemManager::GetInstance()->IsStreamActive(volumeType)); +} + +INSTANTIATE_TEST_CASE_P( + IsStreamActive, + AudioPolicyIsStreamActiveTest, + ValuesIn(STREAM_PARAMS)); + +/* + * Set Device Active + * + */ +class AudioPolicySetDeviceActiveTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicySetDeviceActiveTest, SetDeviceActive, TestSize.Level1) +{ + PolicyParam params = GetParam(); + ActiveDeviceType deviceType = params.actDeviceType; + bool active = params.active; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetDeviceActive(deviceType, active)); +} + +INSTANTIATE_TEST_CASE_P( + SetDeviceActive, + AudioPolicySetDeviceActiveTest, + ValuesIn(ACTIVE_DEVICE_PARAMS)); + +/* + * Is Device Active + * + */ +class AudioPolicyIsDeviceActiveTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyIsDeviceActiveTest, IsDeviceActive, TestSize.Level1) +{ + PolicyParam params = GetParam(); + ActiveDeviceType deviceType = params.actDeviceType; + bool active = params.active; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetDeviceActive(deviceType, active)); + EXPECT_EQ(active, AudioSystemManager::GetInstance()->IsDeviceActive(deviceType)); +} + +INSTANTIATE_TEST_CASE_P( + IsDeviceActive, + AudioPolicyIsDeviceActiveTest, + ValuesIn(ACTIVE_DEVICE_PARAMS)); + +/* + * Set Ringer Mode + * + */ +class AudioPolicySetRingerModeTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicySetRingerModeTest, SetRingerMode, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioRingerMode ringerMode = params.ringerMode; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetRingerMode(ringerMode)); +} + + +INSTANTIATE_TEST_CASE_P( + SetRingerMode, + AudioPolicySetRingerModeTest, + ValuesIn(RINGER_MODE_PARAMS)); + +/* + * Get Ringer Mode + * + */ +class AudioPolicyGetRingerModeTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyGetRingerModeTest, GetRingerMode, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioRingerMode ringerMode = params.ringerMode; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetRingerMode(ringerMode)); + EXPECT_EQ(ringerMode, AudioSystemManager::GetInstance()->GetRingerMode()); +} + +INSTANTIATE_TEST_CASE_P( + GetRingerMode, + AudioPolicyGetRingerModeTest, + ValuesIn(RINGER_MODE_PARAMS)); + +/* + * Set microphone mute + * + */ +class AudioPolicySetMicrophoneMuteTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicySetMicrophoneMuteTest, SetMicrophoneMute, TestSize.Level1) +{ + PolicyParam params = GetParam(); + bool mute = params.mute; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMicrophoneMute(mute)); +} + +INSTANTIATE_TEST_CASE_P( + SetMicrophoneMute, + AudioPolicySetMicrophoneMuteTest, + ValuesIn(MIC_MUTE_PARAMS)); + +/* + * Is Microphone Mute + * + */ +class AudioPolicyGetMicrophoneMuteTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyGetMicrophoneMuteTest, IsMicrophoneMute, TestSize.Level1) +{ + PolicyParam params = GetParam(); + bool mute = params.mute; + + EXPECT_EQ(MEDIA_OK, AudioSystemManager::GetInstance()->SetMicrophoneMute(mute)); + EXPECT_EQ(mute, AudioSystemManager::GetInstance()->IsMicrophoneMute()); +} + +INSTANTIATE_TEST_CASE_P( + IsMicrophoneMute, + AudioPolicyGetMicrophoneMuteTest, + ValuesIn(MIC_MUTE_PARAMS)); + +/* + * Check volume range + * + */ +class AudioPolicyVolumeRangeTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyVolumeRangeTest, GetMaxVolume, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + EXPECT_EQ(1.0, AudioSystemManager::GetInstance()->GetMaxVolume(volumeType)); +} + +HWTEST_P(AudioPolicyVolumeRangeTest, GetMinVolume, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::AudioVolumeType volumeType + = static_cast(params.streamType); + EXPECT_EQ(0, AudioSystemManager::GetInstance()->GetMinVolume(volumeType)); +} + +INSTANTIATE_TEST_CASE_P( + GetMaxVolume, + AudioPolicyVolumeRangeTest, + ValuesIn(VOLUME_RANGE_PARAMS)); + +INSTANTIATE_TEST_CASE_P( + GetMinVolume, + AudioPolicyVolumeRangeTest, + ValuesIn(VOLUME_RANGE_PARAMS)); + +/* + * Check volume range + * + */ +class AudioPolicyAudioParameterTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyAudioParameterTest, SetAudioParameter, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::GetInstance()->SetAudioParameter(params.key, params.value); + EXPECT_EQ(params.value, AudioSystemManager::GetInstance()->GetAudioParameter(params.key)); +} + +INSTANTIATE_TEST_CASE_P( + SetAudioParameter, + AudioPolicyAudioParameterTest, + ValuesIn(AUDIO_PARAMS)); + +HWTEST_P(AudioPolicyAudioParameterTest, GetAudioParameter, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioSystemManager::GetInstance()->SetAudioParameter(params.key, params.value); + EXPECT_EQ(params.value, AudioSystemManager::GetInstance()->GetAudioParameter(params.key)); +} + +INSTANTIATE_TEST_CASE_P( + GetAudioParameter, + AudioPolicyAudioParameterTest, + ValuesIn(AUDIO_PARAMS)); + +/* + * Check volume range + * + */ +class AudioPolicyGetDevicesTest : public AudioPolicyTest {}; + +HWTEST_P(AudioPolicyGetDevicesTest, GetDevices, TestSize.Level1) +{ + PolicyParam params = GetParam(); + AudioDeviceDescriptor::DeviceFlag deviceFlag = params.deviceFlag; + AudioDeviceDescriptor::DeviceType deviceType = params.deviceType; + AudioDeviceDescriptor::DeviceRole deviceRole = params.deviceRole; + vector> audioDeviceDescriptors + = AudioSystemManager::GetInstance()->GetDevices(deviceFlag); + sptr audioDeviceDescriptor = audioDeviceDescriptors[0]; + EXPECT_EQ(deviceType, audioDeviceDescriptor->deviceType_); + EXPECT_EQ(deviceRole, audioDeviceDescriptor->deviceRole_); +} + +INSTANTIATE_TEST_CASE_P( + GetDevices, + AudioPolicyGetDevicesTest, + ValuesIn(DEVICES_PARAMS)); +} +} +} diff --git a/frameworks/kitsimpl/audio_manager/src/audio_device_descriptor_napi.cpp b/frameworks/kitsimpl/audio_manager/src/audio_device_descriptor_napi.cpp index 2ee0823282dc87fe2e62b4803361507d52210e30..02d7d6e7a46abf0163c30c1e825908555c03fb58 100644 --- a/frameworks/kitsimpl/audio_manager/src/audio_device_descriptor_napi.cpp +++ b/frameworks/kitsimpl/audio_manager/src/audio_device_descriptor_napi.cpp @@ -50,55 +50,6 @@ void AudioDeviceDescriptorNapi::Destructor(napi_env env, void *nativeObject, voi } } -static AudioDeviceDescriptorNapi::DeviceType GetJSDeviceType(AudioDeviceDescriptor::DeviceType deviceType) -{ - AudioDeviceDescriptorNapi::DeviceType result; - - switch (deviceType) { - case AudioDeviceDescriptor::SPEAKER: - result = AudioDeviceDescriptorNapi::SPEAKER; - break; - case AudioDeviceDescriptor::WIRED_HEADSET: - result = AudioDeviceDescriptorNapi::WIRED_HEADSET; - break; - case AudioDeviceDescriptor::BLUETOOTH_SCO: - result = AudioDeviceDescriptorNapi::BLUETOOTH_SCO; - break; - case AudioDeviceDescriptor::BLUETOOTH_A2DP: - result = AudioDeviceDescriptorNapi::BLUETOOTH_A2DP; - break; - case AudioDeviceDescriptor::MIC: - result = AudioDeviceDescriptorNapi::MIC; - break; - default: - result = AudioDeviceDescriptorNapi::INVALID; - HiLog::Error(LABEL, "Unknown device type!"); - break; - } - - return result; -} - -static AudioDeviceDescriptorNapi::DeviceRole GetJSDeviceRole(AudioDeviceDescriptor::DeviceRole deviceRole) -{ - AudioDeviceDescriptorNapi::DeviceRole result; - - switch (deviceRole) { - case AudioDeviceDescriptor::INPUT_DEVICE: - result = AudioDeviceDescriptorNapi::INPUT_DEVICE; - break; - case AudioDeviceDescriptor::OUTPUT_DEVICE: - result = AudioDeviceDescriptorNapi::OUTPUT_DEVICE; - break; - default: - result = AudioDeviceDescriptorNapi::INPUT_DEVICE; - HiLog::Error(LABEL, "Unknown device role!"); - break; - } - - return result; -} - napi_value AudioDeviceDescriptorNapi::Init(napi_env env, napi_value exports) { napi_status status; @@ -193,7 +144,7 @@ napi_value AudioDeviceDescriptorNapi::GetDeviceRole(napi_env env, napi_callback_ status = napi_unwrap(env, thisVar, (void **)&deviceDescriptor); if (status == napi_ok) { deviceRole = deviceDescriptor->audioDescriptor_->deviceRole_; - status = napi_create_int32(env, GetJSDeviceRole(deviceRole), &jsResult); + status = napi_create_int32(env, deviceRole, &jsResult); if (status == napi_ok) { return jsResult; } @@ -216,7 +167,7 @@ napi_value AudioDeviceDescriptorNapi::GetDeviceType(napi_env env, napi_callback_ status = napi_unwrap(env, thisVar, (void **)&deviceDescriptor); if (status == napi_ok) { deviceType = deviceDescriptor->audioDescriptor_->deviceType_; - status = napi_create_int32(env, GetJSDeviceType(deviceType), &jsResult); + status = napi_create_int32(env, deviceType, &jsResult); if (status == napi_ok) { return jsResult; } diff --git a/frameworks/kitsimpl/audio_manager/src/audio_manager_napi.cpp b/frameworks/kitsimpl/audio_manager/src/audio_manager_napi.cpp index 1170dd5a61479452085abc22fff06be7bd8f26b3..e67cc4fff746e599880a8475ffc10c1868d4ceaa 100644 --- a/frameworks/kitsimpl/audio_manager/src/audio_manager_napi.cpp +++ b/frameworks/kitsimpl/audio_manager/src/audio_manager_napi.cpp @@ -28,6 +28,7 @@ napi_ref AudioManagerNapi::audioVolumeTypeRef_ = nullptr; napi_ref AudioManagerNapi::deviceFlagRef_ = nullptr; napi_ref AudioManagerNapi::deviceRoleRef_ = nullptr; napi_ref AudioManagerNapi::deviceTypeRef_ = nullptr; +napi_ref AudioManagerNapi::activeDeviceTypeRef_ = nullptr; napi_ref AudioManagerNapi::audioRingModeRef_ = nullptr; #define GET_PARAMS(env, info, num) \ @@ -106,60 +107,6 @@ static AudioSystemManager::AudioVolumeType GetNativeAudioVolumeType(int32_t volu return result; } -static AudioDeviceDescriptor::DeviceType GetNativeDeviceType(int32_t deviceType) -{ - AudioDeviceDescriptor::DeviceType result = AudioDeviceDescriptor::DEVICE_TYPE_NONE; - - switch (deviceType) { - case AudioDeviceDescriptorNapi::SPEAKER: - result = AudioDeviceDescriptor::SPEAKER; - break; - case AudioDeviceDescriptorNapi::WIRED_HEADSET: - result = AudioDeviceDescriptor::WIRED_HEADSET; - break; - case AudioDeviceDescriptorNapi::BLUETOOTH_SCO: - result = AudioDeviceDescriptor::BLUETOOTH_SCO; - break; - case AudioDeviceDescriptorNapi::BLUETOOTH_A2DP: - result = AudioDeviceDescriptor::BLUETOOTH_A2DP; - break; - case AudioDeviceDescriptorNapi::MIC: - result = AudioDeviceDescriptor::MIC; - break; - case AudioDeviceDescriptorNapi::INVALID: - default: - result = AudioDeviceDescriptor::DEVICE_TYPE_NONE; - HiLog::Error(LABEL, "Unknown device type!"); - break; - } - - return result; -} - -static AudioDeviceDescriptor::DeviceFlag GetNativeDeviceFlag(int32_t deviceFlag) -{ - AudioDeviceDescriptor::DeviceFlag result = AudioDeviceDescriptor::ALL_DEVICES_FLAG; - - switch (deviceFlag) { - case AudioManagerNapi::OUTPUT_DEVICES_FLAG: - result = AudioDeviceDescriptor::OUTPUT_DEVICES_FLAG; - break; - case AudioManagerNapi::INPUT_DEVICES_FLAG: - result = AudioDeviceDescriptor::INPUT_DEVICES_FLAG; - break; - case AudioManagerNapi::ALL_DEVICES_FLAG: - result = AudioDeviceDescriptor::ALL_DEVICES_FLAG; - break; - default: - result = AudioDeviceDescriptor::ALL_DEVICES_FLAG; - HiLog::Error(LABEL, "Unknown device flag!, %{public}d", deviceFlag); - break; - } - - return result; -} - - static AudioRingerMode GetNativeAudioRingerMode(int32_t ringMode) { AudioRingerMode result = RINGER_MODE_NORMAL; @@ -269,15 +216,15 @@ napi_value AudioManagerNapi::CreateDeviceFlagObject(napi_env env) status = napi_create_object(env, &result); if (status == napi_ok) { - for (int i = AudioManagerNapi::OUTPUT_DEVICES_FLAG; i <= AudioManagerNapi::ALL_DEVICES_FLAG; i++) { + for (int i = AudioDeviceDescriptor::DEVICE_FLAG_NONE + 1; i < AudioDeviceDescriptor::DEVICE_FLAG_MAX; i++) { switch (i) { - case AudioManagerNapi::OUTPUT_DEVICES_FLAG: + case AudioDeviceDescriptor::OUTPUT_DEVICES_FLAG: propName = "OUTPUT_DEVICES_FLAG"; break; - case AudioManagerNapi::INPUT_DEVICES_FLAG: + case AudioDeviceDescriptor::INPUT_DEVICES_FLAG: propName = "INPUT_DEVICES_FLAG"; break; - case AudioManagerNapi::ALL_DEVICES_FLAG: + case AudioDeviceDescriptor::ALL_DEVICES_FLAG: propName = "ALL_DEVICES_FLAG"; break; default: @@ -313,12 +260,12 @@ napi_value AudioManagerNapi::CreateDeviceRoleObject(napi_env env) status = napi_create_object(env, &result); if (status == napi_ok) { - for (int i = AudioDeviceDescriptorNapi::INPUT_DEVICE; i <= AudioDeviceDescriptorNapi::OUTPUT_DEVICE; i++) { + for (int i = AudioDeviceDescriptor::DEVICE_ROLE_NONE + 1; i < AudioDeviceDescriptor::DEVICE_ROLE_MAX; i++) { switch (i) { - case AudioDeviceDescriptorNapi::INPUT_DEVICE: + case AudioDeviceDescriptor::INPUT_DEVICE: propName = "INPUT_DEVICE"; break; - case AudioDeviceDescriptorNapi::OUTPUT_DEVICE: + case AudioDeviceDescriptor::OUTPUT_DEVICE: propName = "OUTPUT_DEVICE"; break; default: @@ -354,24 +301,27 @@ napi_value AudioManagerNapi::CreateDeviceTypeObject(napi_env env) status = napi_create_object(env, &result); if (status == napi_ok) { - for (int i = AudioDeviceDescriptorNapi::INVALID; i <= AudioDeviceDescriptorNapi::MIC; i++) { + for (int i = AudioDeviceDescriptor::DEVICE_TYPE_NONE + 1; i < AudioDeviceDescriptor::DEVICE_TYPE_MAX; i++) { switch (i) { - case AudioDeviceDescriptorNapi::INVALID: + case AudioDeviceDescriptor::INVALID: propName = "INVALID"; break; - case AudioDeviceDescriptorNapi::SPEAKER: + case AudioDeviceDescriptor::EARPIECE: + propName = "EARPIECE"; + break; + case AudioDeviceDescriptor::SPEAKER: propName = "SPEAKER"; break; - case AudioDeviceDescriptorNapi::WIRED_HEADSET: + case AudioDeviceDescriptor::WIRED_HEADSET: propName = "WIRED_HEADSET"; break; - case AudioDeviceDescriptorNapi::BLUETOOTH_SCO: + case AudioDeviceDescriptor::BLUETOOTH_SCO: propName = "BLUETOOTH_SCO"; break; - case AudioDeviceDescriptorNapi::BLUETOOTH_A2DP: + case AudioDeviceDescriptor::BLUETOOTH_A2DP: propName = "BLUETOOTH_A2DP"; break; - case AudioDeviceDescriptorNapi::MIC: + case AudioDeviceDescriptor::MIC: propName = "MIC"; break; default: @@ -398,6 +348,47 @@ napi_value AudioManagerNapi::CreateDeviceTypeObject(napi_env env) return result; } +napi_value AudioManagerNapi::CreateActiveDeviceTypeObject(napi_env env) +{ + napi_value result = nullptr; + napi_status status; + int32_t refCount = 1; + string propName; + + status = napi_create_object(env, &result); + if (status == napi_ok) { + for (int i = ACTIVE_DEVICE_TYPE_NONE + 1; i < ACTIVE_DEVICE_TYPE_MAX; i++) { + switch (i) { + case SPEAKER: + propName = "SPEAKER"; + break; + case BLUETOOTH_SCO: + propName = "BLUETOOTH_SCO"; + break; + default: + HiLog::Error(LABEL, "No prop with this value!"); + continue; + } + status = AddNamedProperty(env, result, propName, i); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to add named prop!"); + break; + } + propName.clear(); + } + if (status == napi_ok) { + status = napi_create_reference(env, result, refCount, &activeDeviceTypeRef_); + if (status == napi_ok) { + return result; + } + } + } + HiLog::Error(LABEL, "CreateActiveDeviceTypeObject is Failed!"); + napi_get_undefined(env, &result); + + return result; +} + napi_value AudioManagerNapi::CreateAudioRingModeObject(napi_env env) { napi_value result = nullptr; @@ -474,6 +465,7 @@ napi_value AudioManagerNapi::Init(napi_env env, napi_value exports) DECLARE_NAPI_PROPERTY("DeviceFlag", CreateDeviceFlagObject(env)), DECLARE_NAPI_PROPERTY("DeviceRole", CreateDeviceRoleObject(env)), DECLARE_NAPI_PROPERTY("DeviceType", CreateDeviceTypeObject(env)), + DECLARE_NAPI_PROPERTY("ActiveDeviceType", CreateActiveDeviceTypeObject(env)), DECLARE_NAPI_PROPERTY("AudioRingMode", CreateAudioRingModeObject(env)) }; @@ -1133,7 +1125,7 @@ napi_value AudioManagerNapi::SetDeviceActive(napi_env env, napi_callback_info in [](napi_env env, void *data) { auto context = static_cast(data); context->status = context->objectInfo->audioMngr_->SetDeviceActive( - GetNativeDeviceType(context->deviceType), context->isActive); + static_cast(context->deviceType), context->isActive); }, SetFunctionAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); if (status != napi_ok) { @@ -1192,7 +1184,7 @@ napi_value AudioManagerNapi::IsDeviceActive(napi_env env, napi_callback_info inf [](napi_env env, void *data) { auto context = static_cast(data); context->isActive = - context->objectInfo->audioMngr_->IsDeviceActive(GetNativeDeviceType(context->deviceType)); + context->objectInfo->audioMngr_->IsDeviceActive(static_cast(context->deviceType)); context->isTrue = context->isActive; context->status = 0; }, @@ -1646,8 +1638,8 @@ napi_value AudioManagerNapi::GetDevices(napi_env env, napi_callback_info info) env, nullptr, resource, [](napi_env env, void *data) { auto context = static_cast(data); - context->deviceDescriptors = - context->objectInfo->audioMngr_->GetDevices(GetNativeDeviceFlag(context->deviceFlag)); + context->deviceDescriptors = context->objectInfo->audioMngr_->GetDevices( + static_cast(context->deviceFlag)); context->status = 0; }, GetDevicesAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); diff --git a/interfaces/innerkits/native/audioadapter/include/audio_service_adapter.h b/interfaces/innerkits/native/audioadapter/include/audio_service_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..e1ae1b1dee018b0703e0a8c8d9c01e2520d86aa8 --- /dev/null +++ b/interfaces/innerkits/native/audioadapter/include/audio_service_adapter.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ST_AUDIO_SERVICE_ADAPTER_H +#define ST_AUDIO_SERVICE_ADAPTER_H + +#include +#include +#include + +#include "audio_info.h" + +namespace OHOS { +namespace AudioStandard { +class AudioServiceAdapterCallback { +public: + /** + * @brief computes the volume to be set in audioserver + * + * @param streamType streamType for which volume will be computed + * @return Returns volume level in float + */ + virtual float OnGetVolumeCb(std::string streamType) = 0; +}; + +class AudioServiceAdapter { +public: + /** + * @brief creater audioserviceadapter instance + * + * @param cb callback reference for AudioServiceAdapterCallback class + * @return Returns instance of class that extends AudioServiceAdapter + */ + static std::unique_ptr CreateAudioAdapter(AudioServiceAdapterCallback *cb); + + /** + * @brief Connect to underlining audio server + * + * @return Returns true if connection is success, else return false + * @since 1.0 + * @version 1.0 + */ + virtual bool Connect() = 0; + + /** + * @brief Opens the audio port while loading the audio modules source and sink. + * + * @param audioPortName name of the audio modules to be loaded + * @param moduleArgs audio module info like rate, channel etc + * @return Returns module index if module loaded sucessfully; returns an error code + * defined in {@link audio_errors.h} otherwise. + */ + virtual int32_t OpenAudioPort(char *audioPortName, std::string moduleArgs) = 0; + + /** + * @brief closes/unloads the audio modules loaded. + * + * @param audioHandleIndex the index of the loaded audio module + * @return Returns {@link SUCCESS} if module/port is closed successfully; returns an error code + * defined in {@link audio_errors.h} otherwise. + */ + virtual int32_t CloseAudioPort(int32_t audioHandleIndex) = 0; + + /** + * @brief sets default audio sink. + * + * @param name name of default audio sink to be set + * @return Returns {@link SUCCESS} if default audio sink is set successfully; returns an error code + * defined in {@link audio_errors.h} otherwise. + */ + virtual int32_t SetDefaultSink(std::string name) = 0; + + /** + * @brief sets default audio source. + * + * @param name name of default audio source to be set + * @return Returns {@link SUCCESS} if default audio source is set successfully; returns an error code + * defined in {@link audio_errors.h} otherwise. + */ + virtual int32_t SetDefaultSource(std::string name) = 0; + + /** + * @brief sets audio volume + * + * @param streamType the streamType for which volume will be set, streamType defined in{@link audio_info.h} + * @param volume the volume level to be set + * @return Returns {@link SUCCESS} if volume is set successfully; returns an error code + * defined in {@link audio_errors.h} otherwise. + */ + virtual int32_t SetVolume(AudioStreamType streamType, float volume) = 0; + + /** + * @brief set mute for give streamType + * + * @param streamType the streamType for which mute will be set, streamType defined in{@link audio_info.h} + * @param mute boolean value, true: Set mute; false: Set unmute + * @return Returns {@link SUCCESS} if mute/unmute is set successfully; returns an error code + * defined in {@link audio_errors.h} otherwise. + */ + virtual int32_t SetMute(AudioStreamType streamType, bool mute) = 0; + + /** + * @brief returns if given streamType is set to mute + * + * @param streamType the streamType for which mute status will be fetched, streamType defined in{@link audio_info.h} + * @return Returns true: Is streamType is set as mute; else returns false + */ + virtual bool IsMute(AudioStreamType streamType) = 0; + + /** + * @brief returns if given streamType is active(currently the streamType audio is played) + * + * @param streamType the streamType for which status will be fetched streamType defined in{@link audio_info.h} + * @return Returns true: If streamType is active; else returns false + */ + virtual bool IsStreamActive(AudioStreamType streamType); + + /** + * @brief Disconnects the connected audio server + * + * @return void + */ + virtual void Disconnect() = 0; + + virtual ~AudioServiceAdapter(); +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // ST_AUDIO_SERVICE_ADAPTER_H diff --git a/interfaces/innerkits/native/audiocommon/include/audio_info.h b/interfaces/innerkits/native/audiocommon/include/audio_info.h index bf35bc9eadc0f33907fab6f9d6fc70b8e7ed0144..3a9a6583e313b44c0289270658d168651a53e87d 100644 --- a/interfaces/innerkits/native/audiocommon/include/audio_info.h +++ b/interfaces/innerkits/native/audiocommon/include/audio_info.h @@ -24,48 +24,11 @@ namespace OHOS { namespace AudioStandard { -// Audio Device Types -enum DeviceType { - /** - * Indicates device type none. - */ - DEVICE_TYPE_NONE = -1, - /** - * Indicates a speaker built in a device. - */ - SPEAKER = 0, - /** - * Indicates a headset, which is the combination of a pair of headphones and a microphone. - */ - WIRED_HEADSET = 1, - /** - * Indicates a Bluetooth device used for telephony. - */ - BLUETOOTH_SCO = 2, - /** - * Indicates a Bluetooth device supporting the Advanced Audio Distribution Profile (A2DP). - */ - BLUETOOTH_A2DP = 3, - /** - * Indicates a microphone built in a device. - */ - MIC = 4 -}; - -// Audio Role -enum DeviceRole { - /** - * Device role none. - */ - DEVICE_ROLE_NONE = -1, - /** - * Input device role. - */ - INPUT_DEVICE = 0, - /** - * Output device role. - */ - OUTPUT_DEVICE = 1 +enum ActiveDeviceType { + ACTIVE_DEVICE_TYPE_NONE = -1, + SPEAKER = 2, + BLUETOOTH_SCO = 7, + ACTIVE_DEVICE_TYPE_MAX }; enum AudioStreamType { @@ -238,6 +201,7 @@ const std::vector AUDIO_SUPPORTED_SAMPLING_RATES { SAMPLE_RATE_64000, SAMPLE_RATE_96000 }; + typedef uint32_t AudioIOHandle; } // namespace AudioStandard } // namespace OHOS diff --git a/interfaces/innerkits/native/audiomanager/include/audio_system_manager.h b/interfaces/innerkits/native/audiomanager/include/audio_system_manager.h index 0a57e8956ebb65163e668732e26ab6bde2d0becd..ac16359ef0c9dda57952709dcd6d7ce76eb8969e 100644 --- a/interfaces/innerkits/native/audiomanager/include/audio_system_manager.h +++ b/interfaces/innerkits/native/audiomanager/include/audio_system_manager.h @@ -28,18 +28,26 @@ class AudioDeviceDescriptor : public Parcelable { friend class AudioSystemManager; public: enum DeviceFlag { + /** + * Device flag none. + */ + DEVICE_FLAG_NONE = -1, /** * Indicates all output audio devices. */ - OUTPUT_DEVICES_FLAG = 0, + OUTPUT_DEVICES_FLAG = 1, /** * Indicates all input audio devices. */ - INPUT_DEVICES_FLAG = 1, + INPUT_DEVICES_FLAG = 2, /** * Indicates all audio devices. */ - ALL_DEVICES_FLAG = 2 + ALL_DEVICES_FLAG = 3, + /** + * Device flag max count. + */ + DEVICE_FLAG_MAX }; enum DeviceRole { @@ -50,11 +58,15 @@ enum DeviceRole { /** * Input device role. */ - INPUT_DEVICE = 0, + INPUT_DEVICE = 1, /** * Output device role. */ - OUTPUT_DEVICE = 1 + OUTPUT_DEVICE = 2, + /** + * Device role max count. + */ + DEVICE_ROLE_MAX }; enum DeviceType { @@ -62,26 +74,38 @@ enum DeviceType { * Indicates device type none. */ DEVICE_TYPE_NONE = -1, + /** + * Indicates invalid device + */ + INVALID = 0, + /** + * Indicates earpiece + */ + EARPIECE = 1, /** * Indicates a speaker built in a device. */ - SPEAKER = 0, + SPEAKER = 2, /** * Indicates a headset, which is the combination of a pair of headphones and a microphone. */ - WIRED_HEADSET = 1, + WIRED_HEADSET = 3, /** * Indicates a Bluetooth device used for telephony. */ - BLUETOOTH_SCO = 2, + BLUETOOTH_SCO = 7, /** * Indicates a Bluetooth device supporting the Advanced Audio Distribution Profile (A2DP). */ - BLUETOOTH_A2DP = 3, + BLUETOOTH_A2DP = 8, /** * Indicates a microphone built in a device. */ - MIC = 4 + MIC = 15, + /** + * Indicates device type max count. + */ + DEVICE_TYPE_MAX }; DeviceType getType(); @@ -157,8 +181,8 @@ enum AudioVolumeType { std::vector> GetDevices(AudioDeviceDescriptor::DeviceFlag deviceFlag) const; const std::string GetAudioParameter(const std::string key) const; void SetAudioParameter(const std::string key, const std::string value) const; - int32_t SetDeviceActive(AudioDeviceDescriptor::DeviceType deviceType, bool flag) const; - bool IsDeviceActive(AudioDeviceDescriptor::DeviceType deviceType) const; + int32_t SetDeviceActive(ActiveDeviceType deviceType, bool flag) const; + bool IsDeviceActive(ActiveDeviceType deviceType) const; bool IsStreamActive(AudioSystemManager::AudioVolumeType volumeType) const; bool SetRingerMode(AudioRingerMode ringMode) const; AudioRingerMode GetRingerMode() const; diff --git a/interfaces/innerkits/native/audiopolicy/include/audio_policy_manager.h b/interfaces/innerkits/native/audiopolicy/include/audio_policy_manager.h index cf677eefea328ae51309c0136118ed8aa4aabd9b..3386122b3412ca5b93d0264af4a141486750cc4a 100644 --- a/interfaces/innerkits/native/audiopolicy/include/audio_policy_manager.h +++ b/interfaces/innerkits/native/audiopolicy/include/audio_policy_manager.h @@ -18,9 +18,12 @@ #include #include "audio_info.h" +#include "audio_system_manager.h" namespace OHOS { namespace AudioStandard { +using InternalDeviceType = AudioDeviceDescriptor::DeviceType; + class AudioPolicyManager { public: static AudioPolicyManager& GetInstance() @@ -39,9 +42,9 @@ public: bool IsStreamActive(AudioStreamType streamType); - int32_t SetDeviceActive(DeviceType deviceType, bool active); + int32_t SetDeviceActive(InternalDeviceType deviceType, bool active); - bool IsDeviceActive(DeviceType deviceType); + bool IsDeviceActive(InternalDeviceType deviceType); int32_t SetRingerMode(AudioRingerMode ringMode); diff --git a/interfaces/innerkits/native/audiostream/include/audio_stream.h b/interfaces/innerkits/native/audiostream/include/audio_stream.h index 8becc4732cf8f5b8387cd8d3ffd2ec27edebccbe..e8d5503b1ad90f99cd05043cb765397b93698e7b 100644 --- a/interfaces/innerkits/native/audiostream/include/audio_stream.h +++ b/interfaces/innerkits/native/audiostream/include/audio_stream.h @@ -89,6 +89,7 @@ private: State state_; std::atomic isReadInProgress_; std::atomic isWriteInProgress_; + uint64_t resetTimestamp_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/interfaces/kits/js/audio_manager/@ohos.multimedia.audio.d.ts b/interfaces/kits/js/audio_manager/@ohos.multimedia.audio.d.ts index 4ed98a3abce1ef683d98030a36282c82925229e4..683c676801635a2078236fed32402efcf2152d4b 100644 --- a/interfaces/kits/js/audio_manager/@ohos.multimedia.audio.d.ts +++ b/interfaces/kits/js/audio_manager/@ohos.multimedia.audio.d.ts @@ -90,26 +90,45 @@ declare namespace audio { * Invalid device */ INVALID = 0, + /** + * earpiece + */ + EARPIECE = 1, /** * Speaker */ - SPEAKER = 1, + SPEAKER = 2, /** * Wired headset */ - WIRED_HEADSET = 2, + WIRED_HEADSET = 3, /** * Bluetooth device using the synchronous connection oriented link (SCO) */ - BLUETOOTH_SCO = 3, + BLUETOOTH_SCO = 7, /** * Bluetooth device using advanced audio distribution profile (A2DP) */ - BLUETOOTH_A2DP = 4, + BLUETOOTH_A2DP = 8, /** * Microphone */ - MIC = 5, + MIC = 15, + } + /** + * Enumerates Active device types. + * @devices + * @sysCap SystemCapability.Multimedia.Audio + */ + enum ActiveDeviceType { + /** + * Speaker + */ + SPEAKER = 2, + /** + * Bluetooth device using the synchronous connection oriented link (SCO) + */ + BLUETOOTH_SCO = 7, } /** * Enumerates Audio Ringer modes @@ -310,25 +329,25 @@ declare namespace audio { * @devices * @sysCap SystemCapability.Multimedia.Audio */ - setDeviceActive(deviceType: DeviceType, active: boolean, callback: AsyncCallback): void; + setDeviceActive(deviceType: ActiveDeviceType, active: boolean, callback: AsyncCallback): void; /** * Activates the device. This method uses a promise to return the execution result. * @sysCap SystemCapability.Multimedia.Audio * @devices */ - setDeviceActive(deviceType: DeviceType, active: boolean): Promise; + setDeviceActive(deviceType: ActiveDeviceType, active: boolean): Promise; /** * Checks whether the device is active. This method uses an asynchronous callback to return the execution result. * @sysCap SystemCapability.Multimedia.Audio * @devices */ - isDeviceActive(deviceType: DeviceType, callback: AsyncCallback): void; + isDeviceActive(deviceType: ActiveDeviceType, callback: AsyncCallback): void; /** * Checks whether the device is active. This method uses a promise to return the execution result. * @sysCap SystemCapability.Multimedia.Audio * @devices */ - isDeviceActive(deviceType: DeviceType): Promise; + isDeviceActive(deviceType: ActiveDeviceType): Promise; } /** diff --git a/interfaces/kits/js/audio_manager/include/audio_device_descriptor_napi.h b/interfaces/kits/js/audio_manager/include/audio_device_descriptor_napi.h index 9b9bcbb86467ff6db7f4b0407bcd0e61c81ff590..7192dfffa665c5d37339a09acb2942ac5ae5ab20 100644 --- a/interfaces/kits/js/audio_manager/include/audio_device_descriptor_napi.h +++ b/interfaces/kits/js/audio_manager/include/audio_device_descriptor_napi.h @@ -31,20 +31,6 @@ public: AudioDeviceDescriptorNapi(); ~AudioDeviceDescriptorNapi(); - enum DeviceType { - INVALID = 0, - SPEAKER = 1, - WIRED_HEADSET = 2, - BLUETOOTH_SCO = 3, - BLUETOOTH_A2DP = 4, - MIC = 5 - }; - - enum DeviceRole { - INPUT_DEVICE = 1, - OUTPUT_DEVICE = 2 - }; - static napi_value Init(napi_env env, napi_value exports); static napi_value CreateAudioDeviceDescriptorWrapper(napi_env env, sptr deviceDescriptor); diff --git a/interfaces/kits/js/audio_manager/include/audio_manager_napi.h b/interfaces/kits/js/audio_manager/include/audio_manager_napi.h index 416e59bbe246870afb3e5e75ede58f8a8c313324..4a0f34303ffb871f69cb1b4329af3c37d13d8088 100644 --- a/interfaces/kits/js/audio_manager/include/audio_manager_napi.h +++ b/interfaces/kits/js/audio_manager/include/audio_manager_napi.h @@ -36,12 +36,6 @@ public: MEDIA = 3 }; - enum DeviceFlag { - OUTPUT_DEVICES_FLAG = 1, - INPUT_DEVICES_FLAG = 2, - ALL_DEVICES_FLAG = 3 - }; - enum AudioRingMode { RINGER_MODE_SILENT = 0, RINGER_MODE_VIBRATE, @@ -77,6 +71,7 @@ private: static napi_value CreateDeviceFlagObject(napi_env env); static napi_value CreateDeviceRoleObject(napi_env env); static napi_value CreateDeviceTypeObject(napi_env env); + static napi_value CreateActiveDeviceTypeObject(napi_env env); static napi_value CreateAudioRingModeObject(napi_env env); static napi_ref sConstructor_; @@ -84,6 +79,7 @@ private: static napi_ref deviceFlagRef_; static napi_ref deviceRoleRef_; static napi_ref deviceTypeRef_; + static napi_ref activeDeviceTypeRef_; static napi_ref audioRingModeRef_; AudioSystemManager *audioMngr_; diff --git a/ohos.build b/ohos.build index 8c3cc5b08b677d815882e89d184afd3c2f4b4b5b..771f3372d2b90ee6dedf059d5ab61c4e09a17b8b 100644 --- a/ohos.build +++ b/ohos.build @@ -19,7 +19,8 @@ "//foundation/multimedia/audio_standard/sa_profile:audio_policy_service_sa_profile", "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audiopolicy:audio_policy_test", "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audiocapturer:audio_capturer_source", - "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audiorenderer:audio_renderer_sink" + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audiorenderer:audio_renderer_sink", + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audioadapter:pulse_audio_service_adapter" ], "inner_kits": [ { diff --git a/services/BUILD.gn b/services/BUILD.gn index eb798a89cf892474ea280e713c92b66e49487cec..914d49b395c5f537700c736c1763b438c6e4191b 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -97,7 +97,9 @@ config("audio_policy_public_config") { "//foundation/multimedia/audio_standard/services/include/client", "//foundation/distributedschedule/safwk/services/safwk/include", "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/common/include", + "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audioadapter/include", "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audiocommon/include", + "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audiopolicy/include", "//foundation/multimedia/audio_standard/interfaces/innerkits/native/audiomanager/include", "//foundation/multimedia/audio_standard/services/src/audio_policy/server/service/include/common", "//foundation/multimedia/audio_standard/services/src/audio_policy/server/service/include/interface", @@ -139,7 +141,7 @@ ohos_shared_library("audio_policy_service") { "//foundation/multimedia/audio_standard/services/src/audio_policy/server/audio_policy_server.cpp", "//foundation/multimedia/audio_standard/services/src/audio_policy/server/service/src/audio_policy_service.cpp", "//foundation/multimedia/audio_standard/services/src/audio_policy/server/service/src/config/xml_parser.cpp", - "//foundation/multimedia/audio_standard/services/src/audio_policy/server/service/src/manager/pulseaudio_policy_manager.cpp", + "//foundation/multimedia/audio_standard/services/src/audio_policy/server/service/src/manager/audio_adapter_manager.cpp", ] public_configs = [ ":audio_policy_public_config" ] @@ -147,7 +149,7 @@ ohos_shared_library("audio_policy_service") { deps = [ "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/pulseaudio/src/pulse:pulse", + "//foundation/multimedia/audio_standard/frameworks/innerkitsimpl/audioadapter:pulse_audio_service_adapter", "//third_party/libxml2:xml2", "//utils/native/base:utils", ] @@ -163,7 +165,11 @@ ohos_shared_library("audio_policy_service") { } ohos_prebuilt_etc("audio_policy_config") { - source = "$AUDIO_POLICY_SERVER_DIR/etc/audio_policy_config.xml" + if (device_name == "rk3566" || device_name == "rk3568") { + source = "$AUDIO_POLICY_SERVER_DIR/etc/rk3568/audio_policy_config.xml" + } else { + source = "$AUDIO_POLICY_SERVER_DIR/etc/audio_policy_config.xml" + } subsystem_name = "multimedia" module_install_dir = "etc/audio" diff --git a/services/etc/pulseaudio.cfg b/services/etc/pulseaudio.cfg index 8ba6d3e933b2d37b95bdc401fb66452a6b62b9bc..37bcc11a231ad343634e28bd87aadc4ec0538d04 100644 --- a/services/etc/pulseaudio.cfg +++ b/services/etc/pulseaudio.cfg @@ -2,6 +2,7 @@ "jobs" : [{ "name" : "post-fs-data", "cmds" : [ + "rm /data/data/.pulse_dir/pid", "mkdir /data/data/.pulse_dir", "chmod 777 /data/data/.pulse_dir", "chown system shell /data/data/.pulse_dir", diff --git a/services/include/audio_policy/client/audio_policy_base.h b/services/include/audio_policy/client/audio_policy_base.h index 1fd80b4ed080c330bdf030a7884b2c158c7b15cd..8d5cad2286f046defd52e3bef93afbb59c6f58a8 100644 --- a/services/include/audio_policy/client/audio_policy_base.h +++ b/services/include/audio_policy/client/audio_policy_base.h @@ -17,6 +17,7 @@ #define I_AUDIO_POLICY_BASE_H #include "audio_policy_types.h" +#include "audio_policy_manager.h" #include "ipc_types.h" #include "iremote_broker.h" #include "iremote_proxy.h" @@ -37,9 +38,9 @@ public: virtual bool IsStreamActive(AudioStreamType streamType) = 0; - virtual int32_t SetDeviceActive(DeviceType deviceType, bool active) = 0; + virtual int32_t SetDeviceActive(InternalDeviceType deviceType, bool active) = 0; - virtual bool IsDeviceActive(DeviceType deviceType) = 0; + virtual bool IsDeviceActive(InternalDeviceType deviceType) = 0; virtual int32_t SetRingerMode(AudioRingerMode ringMode) = 0; diff --git a/services/include/audio_policy/client/audio_policy_proxy.h b/services/include/audio_policy/client/audio_policy_proxy.h index 913ee455ae4ea7d08ef4f1875691a62676fe6dae..38226388fd9208a0e33d5504f958d4b47c0861f6 100644 --- a/services/include/audio_policy/client/audio_policy_proxy.h +++ b/services/include/audio_policy/client/audio_policy_proxy.h @@ -36,9 +36,9 @@ public: bool IsStreamActive(AudioStreamType streamType) override; - int32_t SetDeviceActive(DeviceType deviceType, bool active) override; + int32_t SetDeviceActive(InternalDeviceType deviceType, bool active) override; - bool IsDeviceActive(DeviceType deviceType) override; + bool IsDeviceActive(InternalDeviceType deviceType) override; int32_t SetRingerMode(AudioRingerMode ringMode) override; diff --git a/services/include/audio_policy/server/audio_policy_server.h b/services/include/audio_policy/server/audio_policy_server.h index 290e35aa3d775f85d337b72486c52f8bf594fecd..695f1f30a43ab98668f9bbb6adb6e115de744128 100644 --- a/services/include/audio_policy/server/audio_policy_server.h +++ b/services/include/audio_policy/server/audio_policy_server.h @@ -49,9 +49,9 @@ public: bool IsStreamActive(AudioStreamType streamType) override; - int32_t SetDeviceActive(DeviceType deviceType, bool active) override; + int32_t SetDeviceActive(InternalDeviceType deviceType, bool active) override; - bool IsDeviceActive(DeviceType deviceType) override; + bool IsDeviceActive(InternalDeviceType deviceType) override; int32_t SetRingerMode(AudioRingerMode ringMode) override; diff --git a/services/src/audio_policy/client/audio_policy_manager.cpp b/services/src/audio_policy/client/audio_policy_manager.cpp index aafbd0b7bf2bb99d5bd3572607b71130bfae4359..bc5820f369e735b535c805c519bab0fed1dea8e0 100644 --- a/services/src/audio_policy/client/audio_policy_manager.cpp +++ b/services/src/audio_policy/client/audio_policy_manager.cpp @@ -78,12 +78,12 @@ bool AudioPolicyManager::IsStreamActive(AudioStreamType streamType) return g_sProxy->IsStreamActive(streamType); } -int32_t AudioPolicyManager::SetDeviceActive(DeviceType deviceType, bool active) +int32_t AudioPolicyManager::SetDeviceActive(InternalDeviceType deviceType, bool active) { return g_sProxy->SetDeviceActive(deviceType, active); } -bool AudioPolicyManager::IsDeviceActive(DeviceType deviceType) +bool AudioPolicyManager::IsDeviceActive(InternalDeviceType deviceType) { return g_sProxy->IsDeviceActive(deviceType); } diff --git a/services/src/audio_policy/client/audio_policy_proxy.cpp b/services/src/audio_policy/client/audio_policy_proxy.cpp index b5b59b099bde71735934f294371e48b4246e8a87..95c1f7483fbb587cce16af8f3a485f7bd94ec463 100644 --- a/services/src/audio_policy/client/audio_policy_proxy.cpp +++ b/services/src/audio_policy/client/audio_policy_proxy.cpp @@ -130,7 +130,7 @@ bool AudioPolicyProxy::IsStreamActive(AudioStreamType streamType) return reply.ReadBool(); } -int32_t AudioPolicyProxy::SetDeviceActive(DeviceType deviceType, bool active) +int32_t AudioPolicyProxy::SetDeviceActive(InternalDeviceType deviceType, bool active) { MessageParcel data; MessageParcel reply; @@ -146,7 +146,7 @@ int32_t AudioPolicyProxy::SetDeviceActive(DeviceType deviceType, bool active) return reply.ReadInt32(); } -bool AudioPolicyProxy::IsDeviceActive(DeviceType deviceType) +bool AudioPolicyProxy::IsDeviceActive(InternalDeviceType deviceType) { MessageParcel data; MessageParcel reply; diff --git a/services/src/audio_policy/server/audio_policy_manager_stub.cpp b/services/src/audio_policy/server/audio_policy_manager_stub.cpp index 2594769d58e91454ddba657bda5413e6c8830a7f..0cad74985c6aa6ad6760f8ebf3f17ec9ab721d6e 100644 --- a/services/src/audio_policy/server/audio_policy_manager_stub.cpp +++ b/services/src/audio_policy/server/audio_policy_manager_stub.cpp @@ -79,7 +79,7 @@ void AudioPolicyManagerStub::IsStreamActiveInternal(MessageParcel &data, Message void AudioPolicyManagerStub::SetDeviceActiveInternal(MessageParcel &data, MessageParcel &reply) { - DeviceType deviceType = static_cast(data.ReadInt32()); + InternalDeviceType deviceType = static_cast(data.ReadInt32()); bool active = data.ReadBool(); int32_t result = SetDeviceActive(deviceType, active); if (result == SUCCESS) @@ -90,7 +90,7 @@ void AudioPolicyManagerStub::SetDeviceActiveInternal(MessageParcel &data, Messag void AudioPolicyManagerStub::IsDeviceActiveInternal(MessageParcel &data, MessageParcel &reply) { - DeviceType deviceType = static_cast(data.ReadInt32()); + InternalDeviceType deviceType = static_cast(data.ReadInt32()); bool result = IsDeviceActive(deviceType); reply.WriteBool(result); } diff --git a/services/src/audio_policy/server/audio_policy_server.cpp b/services/src/audio_policy/server/audio_policy_server.cpp index 0cfcdb581608cf028608909eed5ae63aa33f9f16..eafd87a2236fff93bc14151ffc7e6260f22f0b4f 100644 --- a/services/src/audio_policy/server/audio_policy_server.cpp +++ b/services/src/audio_policy/server/audio_policy_server.cpp @@ -77,12 +77,12 @@ bool AudioPolicyServer::IsStreamActive(AudioStreamType streamType) return mPolicyService.IsStreamActive(streamType); } -int32_t AudioPolicyServer::SetDeviceActive(DeviceType deviceType, bool active) +int32_t AudioPolicyServer::SetDeviceActive(InternalDeviceType deviceType, bool active) { return mPolicyService.SetDeviceActive(deviceType, active); } -bool AudioPolicyServer::IsDeviceActive(DeviceType deviceType) +bool AudioPolicyServer::IsDeviceActive(InternalDeviceType deviceType) { return mPolicyService.IsDeviceActive(deviceType); } diff --git a/services/src/audio_policy/server/etc/rk3568/audio_policy_config.xml b/services/src/audio_policy/server/etc/rk3568/audio_policy_config.xml new file mode 100644 index 0000000000000000000000000000000000000000..24e14e2686b52d69d043317632b0521410820097 --- /dev/null +++ b/services/src/audio_policy/server/etc/rk3568/audio_policy_config.xml @@ -0,0 +1,35 @@ + + + + + + + + Speaker + Built-In Mic + + + + + + + + + Speaker + Built-In Mic + + + + + + + + + + + + + + + + diff --git a/services/src/audio_policy/server/service/include/audio_policy_service.h b/services/src/audio_policy/server/service/include/audio_policy_service.h index f5f99f1f4bf199e12c9cee06817979df1fce68b4..3ffb3b1911e3f6003c788e011eb72526c336f88e 100644 --- a/services/src/audio_policy/server/service/include/audio_policy_service.h +++ b/services/src/audio_policy/server/service/include/audio_policy_service.h @@ -55,9 +55,9 @@ public: bool IsStreamActive(AudioStreamType streamType) const; - int32_t SetDeviceActive(DeviceType deviceType, bool active); + int32_t SetDeviceActive(InternalDeviceType deviceType, bool active); - bool IsDeviceActive(DeviceType deviceType) const; + bool IsDeviceActive(InternalDeviceType deviceType) const; int32_t SetRingerMode(AudioRingerMode ringMode); @@ -68,9 +68,9 @@ public: void OnAudioPortPinAvailable(std::shared_ptr portInfo); - void OnDefaultOutputPortPin(DeviceType device); + void OnDefaultOutputPortPin(InternalDeviceType device); - void OnDefaultInputPortPin(DeviceType device); + void OnDefaultInputPortPin(InternalDeviceType device); private: @@ -82,15 +82,14 @@ private: virtual ~AudioPolicyService() {} - AudioIOHandle GetAudioIOHandle(DeviceType deviceType); - std::list& GetActiveDevicesList(DeviceType deviceType) + AudioIOHandle GetAudioIOHandle(InternalDeviceType deviceType); + std::list& GetActiveDevicesList(InternalDeviceType deviceType) { switch (deviceType) { - case SPEAKER: - case BLUETOOTH_A2DP: + case InternalDeviceType::SPEAKER: + case InternalDeviceType::BLUETOOTH_SCO: return mActiveOutputDevices; - case MIC: - case BLUETOOTH_SCO: + case InternalDeviceType::MIC: return mActiveInputDevices; default: return mActiveOutputDevices; // Default case return Output device @@ -100,9 +99,9 @@ private: IAudioPolicyInterface& mAudioPolicyManager; Parser& mConfigParser; std::unordered_map mIOHandles; - std::list mActiveOutputDevices; - std::list mActiveInputDevices; - std::string GetPortName(DeviceType deviceType); + std::list mActiveOutputDevices; + std::list mActiveInputDevices; + std::string GetPortName(InternalDeviceType deviceType); }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/src/audio_policy/server/service/include/config/xml_parser.h b/services/src/audio_policy/server/service/include/config/xml_parser.h index b9a117f4c64ed53067564ae087511f472b7efceb..5ac727d5ebbee46091bf19555926f58eb1506710 100644 --- a/services/src/audio_policy/server/service/include/config/xml_parser.h +++ b/services/src/audio_policy/server/service/include/config/xml_parser.h @@ -57,7 +57,7 @@ private: void ParseDefaultInputDevice(xmlNode* node); void ParseAudioPorts(xmlNode* node); void ParseAudioPortPins(xmlNode* node); - DeviceType GetDeviceType(xmlChar* device); + InternalDeviceType GetDeviceType(xmlChar *device); IPortObserver& mPortObserver; xmlDoc* mDoc; diff --git a/services/src/audio_policy/server/service/include/interface/iaudio_policy_interface.h b/services/src/audio_policy/server/service/include/interface/iaudio_policy_interface.h index b026d2e097838aab2bfaba6c594a71d04ff2957a..51f36771d4d23fad446ca1dfa674cae5ac54f0ff 100644 --- a/services/src/audio_policy/server/service/include/interface/iaudio_policy_interface.h +++ b/services/src/audio_policy/server/service/include/interface/iaudio_policy_interface.h @@ -18,6 +18,7 @@ #include "audio_config.h" #include "audio_info.h" +#include "audio_policy_manager.h" #include "audio_policy_types.h" #include @@ -45,7 +46,8 @@ public: virtual int32_t CloseAudioPort(AudioIOHandle ioHandle) = 0; - virtual int32_t SetDeviceActive(AudioIOHandle ioHandle, DeviceType deviceType, std::string name, bool active) = 0; + virtual int32_t SetDeviceActive(AudioIOHandle ioHandle, InternalDeviceType deviceType, + std::string name, bool active) = 0; virtual int32_t SetRingerMode(AudioRingerMode ringerMode) = 0; diff --git a/services/src/audio_policy/server/service/include/interface/iport_observer.h b/services/src/audio_policy/server/service/include/interface/iport_observer.h index af7ef9ab68cde912018ae414d648cf94d5b9aeb9..8e53159172ca006fa0ae6c495b88ca6f0bf8d869 100644 --- a/services/src/audio_policy/server/service/include/interface/iport_observer.h +++ b/services/src/audio_policy/server/service/include/interface/iport_observer.h @@ -25,8 +25,8 @@ class IPortObserver { public: virtual void OnAudioPortAvailable(std::shared_ptr portInfo) = 0; virtual void OnAudioPortPinAvailable(std::shared_ptr portInfo) = 0; - virtual void OnDefaultOutputPortPin(DeviceType device) = 0; - virtual void OnDefaultInputPortPin(DeviceType device) = 0; + virtual void OnDefaultOutputPortPin(InternalDeviceType device) = 0; + virtual void OnDefaultInputPortPin(InternalDeviceType device) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/src/audio_policy/server/service/include/manager/pulseaudio_policy_manager.h b/services/src/audio_policy/server/service/include/manager/audio_adapter_manager.h similarity index 63% rename from services/src/audio_policy/server/service/include/manager/pulseaudio_policy_manager.h rename to services/src/audio_policy/server/service/include/manager/audio_adapter_manager.h index 9286ce7e586cf2e7e7e3c9980e49a7d195870835..97cb41663c1e7a39a874e545c7c2a3bed6a6451f 100644 --- a/services/src/audio_policy/server/service/include/manager/pulseaudio_policy_manager.h +++ b/services/src/audio_policy/server/service/include/manager/audio_adapter_manager.h @@ -13,20 +13,13 @@ * limitations under the License. */ -#ifndef ST_PULSEAUDIO_POLICY_MANAGER_H -#define ST_PULSEAUDIO_POLICY_MANAGER_H - -#ifdef __cplusplus -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#endif +#ifndef ST_AUDIO_ADAPTER_MANAGER_H +#define ST_AUDIO_ADAPTER_MANAGER_H #include #include +#include "audio_service_adapter.h" #include "distributed_kv_data_manager.h" #include "iaudio_policy_interface.h" #include "types.h" @@ -35,7 +28,7 @@ namespace OHOS { namespace AudioStandard { using namespace OHOS::DistributedKv; -class PulseAudioPolicyManager : public IAudioPolicyInterface { +class AudioAdapterManager : public IAudioPolicyInterface { public: static constexpr char HDI_SINK[] = "libmodule-hdi-sink.z.so"; static constexpr char HDI_SOURCE[] = "libmodule-hdi-source.z.so"; @@ -43,7 +36,6 @@ public: static constexpr char PIPE_SOURCE[] = "libmodule-pipe-source.z.so"; static constexpr float MAX_VOLUME = 1.0f; static constexpr float MIN_VOLUME = 0.0f; - static constexpr uint32_t PA_CONNECT_RETRY_SLEEP_IN_MICRO_SECONDS = 500000; bool Init(); void Deinit(void); @@ -52,8 +44,8 @@ public: static IAudioPolicyInterface& GetInstance() { - static PulseAudioPolicyManager policyManager; - return policyManager; + static AudioAdapterManager audioAdapterManager; + return audioAdapterManager; } int32_t SetStreamVolume(AudioStreamType streamType, float volume); @@ -70,31 +62,15 @@ public: int32_t CloseAudioPort(AudioIOHandle ioHandle); - int32_t SetDeviceActive(AudioIOHandle ioHandle, DeviceType deviceType, std::string name, bool active); + int32_t SetDeviceActive(AudioIOHandle ioHandle, InternalDeviceType deviceType, std::string name, bool active); int32_t SetRingerMode(AudioRingerMode ringerMode); AudioRingerMode GetRingerMode(void); - // Static Member functions - static void ContextStateCb(pa_context *c, void *userdata); - - static void SubscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata); - - static void ModuleLoadCb(pa_context *c, uint32_t idx, void *userdata); - - static void GetSinkInputInfoVolumeCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); - - static void GetSinkInputInfoCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); - - static void GetSinkInputInfoMuteCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); - - static void GetSinkInputInfoMuteStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); - - static void GetSinkInputInfoCorkStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); private: struct UserData { - PulseAudioPolicyManager* thiz; + AudioAdapterManager *thiz; AudioStreamType streamType; float volume; bool mute; @@ -102,20 +78,17 @@ private: uint32_t idx; }; - PulseAudioPolicyManager() - : mContext(nullptr), - mMainLoop(nullptr), - mRingerMode(RINGER_MODE_NORMAL), + AudioAdapterManager() + : mRingerMode(RINGER_MODE_NORMAL), mAudioPolicyKvStore(nullptr) { mVolumeMap[STREAM_MUSIC] = MAX_VOLUME; mVolumeMap[STREAM_RING] = MAX_VOLUME; } - virtual ~PulseAudioPolicyManager() {} + virtual ~AudioAdapterManager() {} bool ConnectToPulseAudio(void); - void HandleSinkInputEvent(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata); std::string GetModuleArgs(std::shared_ptr audioPortInfo); std::string GetStreamNameByStreamType(AudioStreamType streamType); AudioStreamType GetStreamIDByType(std::string streamType); @@ -128,12 +101,12 @@ private: bool LoadRingerMode(void); void WriteRingerModeToKvStore(AudioRingerMode ringerMode); - pa_context* mContext; - pa_threaded_mainloop* mMainLoop; + std::unique_ptr mAudioServiceAdapter; std::unordered_map mVolumeMap; AudioRingerMode mRingerMode; std::unique_ptr mAudioPolicyKvStore; + friend class PolicyCallbackImpl; }; } // namespace AudioStandard } // namespace OHOS -#endif // ST_PULSEAUDIO_POLICY_MANAGER_H +#endif // ST_PULSEAUDIO_ADAPTER_MANAGER_H diff --git a/services/src/audio_policy/server/service/include/manager/audio_policy_manager_factory.h b/services/src/audio_policy/server/service/include/manager/audio_policy_manager_factory.h index f9867aaa106cd43ed53974a276f54d825ab38ba7..7c99399984a6e9f5faf82b4ff53c433efcd4ce14 100644 --- a/services/src/audio_policy/server/service/include/manager/audio_policy_manager_factory.h +++ b/services/src/audio_policy/server/service/include/manager/audio_policy_manager_factory.h @@ -17,7 +17,7 @@ #define ST_AUDIO_POLICY_MANAGER_FACTORY_H #include -#include "pulseaudio_policy_manager.h" +#include "audio_adapter_manager.h" namespace OHOS { namespace AudioStandard { @@ -25,7 +25,7 @@ class AudioPolicyManagerFactory { public: static IAudioPolicyInterface& GetAudioPolicyManager(void) { - return PulseAudioPolicyManager::GetInstance(); + return AudioAdapterManager::GetInstance(); } }; } // namespace AudioStandard diff --git a/services/src/audio_policy/server/service/src/audio_policy_service.cpp b/services/src/audio_policy/server/service/src/audio_policy_service.cpp index dc78bb0d3001814e5b538a4725b156bf6bdfd404..a704fb3eeaedbf790110ff4279b961eb2f9a4129 100644 --- a/services/src/audio_policy/server/service/src/audio_policy_service.cpp +++ b/services/src/audio_policy/server/service/src/audio_policy_service.cpp @@ -67,22 +67,19 @@ bool AudioPolicyService::IsStreamActive(AudioStreamType streamType) const return mAudioPolicyManager.IsStreamActive(streamType); } -std::string AudioPolicyService::GetPortName(DeviceType deviceType) +std::string AudioPolicyService::GetPortName(InternalDeviceType deviceType) { std::string portName = PORT_NONE; switch (deviceType) { - case BLUETOOTH_A2DP: + case InternalDeviceType::BLUETOOTH_SCO: portName = BLUEZ_SINK; break; - case SPEAKER: + case InternalDeviceType::SPEAKER: portName = HDI_SINK; break; - case MIC: + case InternalDeviceType::MIC: portName = HDI_SOURCE; break; - case BLUETOOTH_SCO: - portName = BLUEZ_SOURCE; - break; default: portName = PORT_NONE; break; @@ -90,16 +87,16 @@ std::string AudioPolicyService::GetPortName(DeviceType deviceType) return portName; } -int32_t AudioPolicyService::SetDeviceActive(DeviceType deviceType, bool active) +int32_t AudioPolicyService::SetDeviceActive(InternalDeviceType deviceType, bool active) { MEDIA_DEBUG_LOG("[Policy Service] deviceType %{public}d, activate?: %{public}d", deviceType, active); - if (deviceType == DEVICE_TYPE_NONE) + if (deviceType == InternalDeviceType::DEVICE_TYPE_NONE) return ERR_DEVICE_NOT_SUPPORTED; bool updateActiveDevices = true; AudioIOHandle ioHandle = GetAudioIOHandle(deviceType); - list &activeDevices = GetActiveDevicesList(deviceType); + list &activeDevices = GetActiveDevicesList(deviceType); if (!active) { if (activeDevices.size() <= 1) { @@ -107,7 +104,7 @@ int32_t AudioPolicyService::SetDeviceActive(DeviceType deviceType, bool active) return ERROR; } - list::const_iterator iter = activeDevices.begin(); + list::const_iterator iter = activeDevices.begin(); while (iter != activeDevices.end()) { if (*iter == deviceType) { iter = activeDevices.erase(iter); @@ -134,7 +131,7 @@ int32_t AudioPolicyService::SetDeviceActive(DeviceType deviceType, bool active) } if (updateActiveDevices) { - list::const_iterator iter = activeDevices.begin(); + list::const_iterator iter = activeDevices.begin(); while (iter != activeDevices.end()) { if (*iter == deviceType) { iter = activeDevices.erase(iter); @@ -148,14 +145,14 @@ int32_t AudioPolicyService::SetDeviceActive(DeviceType deviceType, bool active) return SUCCESS; } -bool AudioPolicyService::IsDeviceActive(DeviceType deviceType) const +bool AudioPolicyService::IsDeviceActive(InternalDeviceType deviceType) const { bool result = false; switch (deviceType) { - case SPEAKER: - case BLUETOOTH_A2DP: - for (list::const_iterator iter = mActiveOutputDevices.begin(); + case InternalDeviceType::SPEAKER: + case InternalDeviceType::BLUETOOTH_SCO: + for (list::const_iterator iter = mActiveOutputDevices.begin(); iter != mActiveOutputDevices.end(); ++iter) { if (*iter == deviceType) { result = true; @@ -163,16 +160,6 @@ bool AudioPolicyService::IsDeviceActive(DeviceType deviceType) const } } break; - case MIC: - case BLUETOOTH_SCO: - for (list::const_iterator iter = mActiveInputDevices.begin(); - iter != mActiveInputDevices.end(); ++iter) { - if (*iter == deviceType) { - result = true; - break; - } - } - break; default: break; } @@ -204,7 +191,7 @@ void AudioPolicyService::OnAudioPortPinAvailable(shared_ptr po return; } -void AudioPolicyService::OnDefaultOutputPortPin(DeviceType deviceType) +void AudioPolicyService::OnDefaultOutputPortPin(InternalDeviceType deviceType) { AudioIOHandle ioHandle = GetAudioIOHandle(deviceType); mAudioPolicyManager.SetDeviceActive(ioHandle, deviceType, HDI_SINK, true); @@ -213,7 +200,7 @@ void AudioPolicyService::OnDefaultOutputPortPin(DeviceType deviceType) return; } -void AudioPolicyService::OnDefaultInputPortPin(DeviceType deviceType) +void AudioPolicyService::OnDefaultInputPortPin(InternalDeviceType deviceType) { MEDIA_DEBUG_LOG("OnDefaultInputPortPin DeviceType: %{public}d", deviceType); AudioIOHandle ioHandle = GetAudioIOHandle(deviceType); @@ -223,23 +210,19 @@ void AudioPolicyService::OnDefaultInputPortPin(DeviceType deviceType) } // private methods -AudioIOHandle AudioPolicyService::GetAudioIOHandle(DeviceType deviceType) +AudioIOHandle AudioPolicyService::GetAudioIOHandle(InternalDeviceType deviceType) { AudioIOHandle ioHandle; switch (deviceType) { - case SPEAKER: - case WIRED_HEADSET: + case InternalDeviceType::SPEAKER: ioHandle = mIOHandles[HDI_SINK]; break; - case BLUETOOTH_A2DP: + case InternalDeviceType::BLUETOOTH_SCO: ioHandle = mIOHandles[BLUEZ_SINK]; break; - case MIC: + case InternalDeviceType::MIC: ioHandle = mIOHandles[HDI_SOURCE]; break; - case BLUETOOTH_SCO: - ioHandle = mIOHandles[BLUEZ_SOURCE]; - break; default: ioHandle = mIOHandles[HDI_SINK]; break; diff --git a/services/src/audio_policy/server/service/src/config/xml_parser.cpp b/services/src/audio_policy/server/service/src/config/xml_parser.cpp index 5bb9e7d3e4690d1eda4050fc9077f2ca7c9ad23a..a76bcf85ed56b8180b58ac9cadffa7ccba98f842 100644 --- a/services/src/audio_policy/server/service/src/config/xml_parser.cpp +++ b/services/src/audio_policy/server/service/src/config/xml_parser.cpp @@ -227,13 +227,14 @@ void XMLParser::ParseAudioPortPins(xmlNode* node) return; } -DeviceType XMLParser::GetDeviceType(xmlChar* device) +InternalDeviceType XMLParser::GetDeviceType(xmlChar *device) { if (!xmlStrcmp(device, reinterpret_cast("Speaker"))) - return SPEAKER; + return InternalDeviceType::SPEAKER; if (!xmlStrcmp(device, reinterpret_cast("Built-In Mic"))) - return MIC; - return DEVICE_TYPE_NONE; + return InternalDeviceType::MIC; + + return InternalDeviceType::DEVICE_TYPE_NONE; } } // namespace AudioStandard } // namespace OHOS diff --git a/services/src/audio_policy/server/service/src/manager/audio_adapter_manager.cpp b/services/src/audio_policy/server/service/src/manager/audio_adapter_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..960db0ca6b8a50708354ef451e34edf4f05d5f64 --- /dev/null +++ b/services/src/audio_policy/server/service/src/manager/audio_adapter_manager.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "audio_errors.h" +#include "media_log.h" +#include "audio_adapter_manager.h" + +namespace OHOS { +namespace AudioStandard { +class PolicyCallbackImpl : public AudioServiceAdapterCallback { +public: + explicit PolicyCallbackImpl(AudioAdapterManager *audioAdapterManager) + { + audioAdapterManager_ = audioAdapterManager; + } + + float OnGetVolumeCb(std::string streamType) + { + if (audioAdapterManager_->mRingerMode != RINGER_MODE_NORMAL) { + if (!streamType.compare("ring")) { + return AudioAdapterManager::MIN_VOLUME; + } + } + AudioStreamType streamID = audioAdapterManager_->GetStreamIDByType(streamType); + return audioAdapterManager_->mVolumeMap[streamID]; + } +private: + AudioAdapterManager *audioAdapterManager_; +}; + +bool AudioAdapterManager::Init() +{ + PolicyCallbackImpl *policyCallbackImpl = new PolicyCallbackImpl(this); + mAudioServiceAdapter = AudioServiceAdapter::CreateAudioAdapter(policyCallbackImpl); + bool result = mAudioServiceAdapter->Connect(); + if (!result) { + MEDIA_ERR_LOG("[AudioAdapterManager] Error in connecting audio adapter"); + return false; + } + bool isFirstBoot = false; + InitAudioPolicyKvStore(isFirstBoot); + InitVolumeMap(isFirstBoot); + InitRingerMode(isFirstBoot); + + return true; +} + +void AudioAdapterManager::Deinit(void) +{ + return mAudioServiceAdapter->Disconnect(); +} + +int32_t AudioAdapterManager::SetStreamVolume(AudioStreamType streamType, float volume) +{ + // Incase if KvStore didnot connect during bootup + if (mAudioPolicyKvStore == nullptr) { + bool isFirstBoot = false; + InitAudioPolicyKvStore(isFirstBoot); + } + mVolumeMap[streamType] = volume; + WriteVolumeToKvStore(streamType, volume); + + return mAudioServiceAdapter->SetVolume(streamType, volume); +} + +float AudioAdapterManager::GetStreamVolume(AudioStreamType streamType) +{ + return mVolumeMap[streamType]; +} + +int32_t AudioAdapterManager::SetStreamMute(AudioStreamType streamType, bool mute) +{ + bool result = mAudioServiceAdapter->SetMute(streamType, mute); + return result; +} + +bool AudioAdapterManager::GetStreamMute(AudioStreamType streamType) +{ + bool result = mAudioServiceAdapter->IsMute(streamType); + return result; +} + +bool AudioAdapterManager::IsStreamActive(AudioStreamType streamType) +{ + bool result = mAudioServiceAdapter->IsStreamActive(streamType); + return result; +} +int32_t AudioAdapterManager::SetDeviceActive(AudioIOHandle ioHandle, InternalDeviceType deviceType, + std::string name, bool active) +{ + switch (deviceType) { + case InternalDeviceType::SPEAKER: + case InternalDeviceType::BLUETOOTH_SCO: { + return mAudioServiceAdapter->SetDefaultSink(name); + } + case InternalDeviceType::MIC: { + return mAudioServiceAdapter->SetDefaultSource(name); + } + default: + break; + } + return SUCCESS; +} + +int32_t AudioAdapterManager::SetRingerMode(AudioRingerMode ringerMode) +{ + mRingerMode = ringerMode; + + // Incase if KvStore didnot connect during bootup + if (mAudioPolicyKvStore == nullptr) { + bool isFirstBoot = false; + InitAudioPolicyKvStore(isFirstBoot); + } + + WriteRingerModeToKvStore(ringerMode); + return SUCCESS; +} + +AudioRingerMode AudioAdapterManager::GetRingerMode() +{ + return mRingerMode; +} + +AudioIOHandle AudioAdapterManager::OpenAudioPort(std::shared_ptr audioPortInfo) +{ + std::string moduleArgs = GetModuleArgs(audioPortInfo); + MEDIA_INFO_LOG("[AudioAdapterManager] load-module %{public}s %{public}s", audioPortInfo->name, moduleArgs.c_str()); + if (!strcmp(audioPortInfo->name, PIPE_SOURCE) || !strcmp(audioPortInfo->name, PIPE_SINK)) { + if (audioPortInfo->fileName != nullptr && access(audioPortInfo->fileName, F_OK) == 0) { + int32_t ret = std::remove(audioPortInfo->fileName); + if (ret) { + MEDIA_ERR_LOG("[AudioAdapterManager] Error Removing file: %{public}s Failed! ret val: %{public}d", + audioPortInfo->fileName, ret); + } + } else { + MEDIA_ERR_LOG("[AudioAdapterManager] Error audioPortInfo->fileName is null! or file not exists"); + } + } + AudioIOHandle ioHandle = mAudioServiceAdapter->OpenAudioPort(audioPortInfo->name, moduleArgs.c_str()); + return ioHandle; +} + +int32_t AudioAdapterManager::CloseAudioPort(AudioIOHandle ioHandle) +{ + return mAudioServiceAdapter->CloseAudioPort(ioHandle); +} + +// Private Members +std::string AudioAdapterManager::GetModuleArgs(std::shared_ptr audioPortInfo) +{ + std::string args; + + if (!strcmp(audioPortInfo->name, HDI_SINK)) { + if (audioPortInfo->rate != nullptr) { + args = "rate="; + args.append(audioPortInfo->rate); + } + + if (audioPortInfo->channels != nullptr) { + args.append(" channels="); + args.append(audioPortInfo->channels); + } + + if (audioPortInfo->buffer_size != nullptr) { + args.append(" buffer_size="); + args.append(audioPortInfo->buffer_size); + } + } else if (!strcmp(audioPortInfo->name, HDI_SOURCE)) { + if (audioPortInfo->rate != nullptr) { + args = "rate="; + args.append(audioPortInfo->rate); + } + + if (audioPortInfo->channels != nullptr) { + args.append(" channels="); + args.append(audioPortInfo->channels); + } + + if (audioPortInfo->buffer_size != nullptr) { + args.append(" buffer_size="); + args.append(audioPortInfo->buffer_size); + } + } else if (!strcmp(audioPortInfo->name, PIPE_SINK)) { + if (audioPortInfo->fileName != nullptr) { + args = "file="; + args.append(audioPortInfo->fileName); + } + } else if (!strcmp(audioPortInfo->name, PIPE_SOURCE)) { + if (audioPortInfo->fileName != nullptr) { + args = "file="; + args.append(audioPortInfo->fileName); + } + } + + return args; +} + +std::string AudioAdapterManager::GetStreamNameByStreamType(AudioStreamType streamType) +{ + switch (streamType) { + case STREAM_MUSIC: + return "music"; + case STREAM_RING: + return "ring"; + case STREAM_SYSTEM: + return "system"; + case STREAM_NOTIFICATION: + return "notification"; + case STREAM_ALARM: + return "alarm"; + case STREAM_DTMF: + return "dtmf"; + default: + return ""; + } +} + +AudioStreamType AudioAdapterManager::GetStreamIDByType(std::string streamType) +{ + AudioStreamType stream = STREAM_MUSIC; + + if (!streamType.compare(std::string("music"))) + stream = STREAM_MUSIC; + else if (!streamType.compare(std::string("ring"))) + stream = STREAM_RING; + else if (!streamType.compare(std::string("system"))) + stream = STREAM_SYSTEM; + else if (!streamType.compare(std::string("notification"))) + stream = STREAM_NOTIFICATION; + else if (!streamType.compare(std::string("alarm"))) + stream = STREAM_ALARM; + + return stream; +} + +bool AudioAdapterManager::InitAudioPolicyKvStore(bool& isFirstBoot) +{ + DistributedKvDataManager manager; + Options options; + + options.createIfMissing = false; + options.encrypt = false; + options.autoSync = true; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + + AppId appId; + appId.appId = "policymanager"; + StoreId storeId; + storeId.storeId = "audiopolicy"; + + // open and initialize kvstore instance. + if (mAudioPolicyKvStore == nullptr) { + manager.GetSingleKvStore( + options, appId, storeId, [&](Status status, std::unique_ptr singleKvStore) { + if (status == Status::STORE_NOT_FOUND) { + MEDIA_ERR_LOG("[AudioAdapterManager] InitAudioPolicyKvStore: STORE_NOT_FOUND!"); + return; + } else { + mAudioPolicyKvStore = std::move(singleKvStore); + } + }); + } + + if (mAudioPolicyKvStore == nullptr) { + MEDIA_INFO_LOG("[AudioAdapterManager] First Boot: Create AudioPolicyKvStore"); + options.createIfMissing = true; + // [create and] open and initialize kvstore instance. + manager.GetSingleKvStore( + options, appId, storeId, [&](Status status, std::unique_ptr singleKvStore) { + if (status != Status::SUCCESS) { + MEDIA_ERR_LOG("[AudioAdapterManager] Create AudioPolicyKvStore Failed!"); + return; + } + + mAudioPolicyKvStore = std::move(singleKvStore); + isFirstBoot = true; + }); + } + + if (mAudioPolicyKvStore == nullptr) { + MEDIA_ERR_LOG("[AudioAdapterManager] InitAudioPolicyKvStore: Failed!"); + return false; + } + + return true; +} + +void AudioAdapterManager::InitVolumeMap(bool isFirstBoot) +{ + if (isFirstBoot == true) { + WriteVolumeToKvStore(STREAM_MUSIC, MAX_VOLUME); + WriteVolumeToKvStore(STREAM_RING, MAX_VOLUME); + MEDIA_INFO_LOG("[AudioAdapterManager] Wrote default stream volumes to KvStore"); + } else { + LoadVolumeMap(); + } + return; +} + +void AudioAdapterManager::InitRingerMode(bool isFirstBoot) +{ + if (mAudioPolicyKvStore == nullptr) { + MEDIA_ERR_LOG("[AudioAdapterManager] mAudioPolicyKvStore is null!"); + return; + } + + if (isFirstBoot == true) { + mRingerMode = RINGER_MODE_NORMAL; + WriteRingerModeToKvStore(RINGER_MODE_NORMAL); + MEDIA_INFO_LOG("[AudioAdapterManager] Wrote default ringer mode to KvStore"); + } else { + LoadRingerMode(); + } +} + +bool AudioAdapterManager::LoadVolumeFromKvStore(AudioStreamType streamType) +{ + Key key; + Value value; + + switch (streamType) { + case STREAM_MUSIC: + key = "music"; + break; + case STREAM_RING: + key = "ring"; + break; + default: + return false; + } + + Status status = mAudioPolicyKvStore->Get(key, value); + if (status == Status::SUCCESS) { + float volume = TransferByteArrayToType(value.Data()); + mVolumeMap[streamType] = volume; + MEDIA_DEBUG_LOG("[AudioAdapterManager] volume from kvStore %{public}f for streamType:%{public}d", + volume, streamType); + return true; + } + + return false; +} + +bool AudioAdapterManager::LoadVolumeMap(void) +{ + if (mAudioPolicyKvStore == nullptr) { + MEDIA_ERR_LOG("[AudioAdapterManager] LoadVolumeMap: mAudioPolicyKvStore is null!"); + return false; + } + + if (!LoadVolumeFromKvStore(STREAM_MUSIC)) + MEDIA_ERR_LOG("[AudioAdapterManager] LoadVolumeMap: Couldnot load volume for Music from kvStore!"); + + if (!LoadVolumeFromKvStore(STREAM_RING)) + MEDIA_ERR_LOG("[AudioAdapterManager] LoadVolumeMap: Couldnot load volume for Ring from kvStore!"); + + return true; +} + +bool AudioAdapterManager::LoadRingerMode(void) +{ + if (mAudioPolicyKvStore == nullptr) { + MEDIA_ERR_LOG("[AudioAdapterManager] LoadRingerMap: mAudioPolicyKvStore is null!"); + return false; + } + + // get ringer mode value from kvstore. + Key key = "ringermode"; + Value value; + Status status = mAudioPolicyKvStore->Get(key, value); + if (status == Status::SUCCESS) { + mRingerMode = static_cast(TransferByteArrayToType(value.Data())); + MEDIA_DEBUG_LOG("[AudioAdapterManager] Ringer Mode from kvStore %{public}d", mRingerMode); + } + + return true; +} + +void AudioAdapterManager::WriteVolumeToKvStore(AudioStreamType streamType, float volume) +{ + if (mAudioPolicyKvStore == nullptr) + return; + + Key key = GetStreamNameByStreamType(streamType); + Value value = Value(TransferTypeToByteArray(volume)); + + Status status = mAudioPolicyKvStore->Put(key, value); + if (status == Status::SUCCESS) { + MEDIA_INFO_LOG("[AudioAdapterManager] volume %{public}f for %{public}s updated in kvStore", volume, + GetStreamNameByStreamType(streamType).c_str()); + } else { + MEDIA_ERR_LOG("[AudioAdapterManager] volume %{public}f for %{public}s failed to update in kvStore!", volume, + GetStreamNameByStreamType(streamType).c_str()); + } + + return; +} + +void AudioAdapterManager::WriteRingerModeToKvStore(AudioRingerMode ringerMode) +{ + if (mAudioPolicyKvStore == nullptr) + return; + + Key key = "ringermode"; + Value value = Value(TransferTypeToByteArray(ringerMode)); + + Status status = mAudioPolicyKvStore->Put(key, value); + if (status == Status::SUCCESS) { + MEDIA_INFO_LOG("[AudioAdapterManager] Wrote RingerMode:%d to kvStore", ringerMode); + } else { + MEDIA_ERR_LOG("[AudioAdapterManager] Writing RingerMode:%d to kvStore failed!", ringerMode); + } + + return; +} +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/src/client/audio_stream.cpp b/services/src/client/audio_stream.cpp index a94f092c3bbd0a03e57ee903281db5798feb21ee..f1154566a8d29c80e9b77e35f27a4ed31ccdbe23 100644 --- a/services/src/client/audio_stream.cpp +++ b/services/src/client/audio_stream.cpp @@ -30,7 +30,8 @@ AudioStream::AudioStream(AudioStreamType eStreamType, AudioMode eMode) : eStream eMode_(eMode), state_(NEW), isReadInProgress_(false), - isWriteInProgress_(false) + isWriteInProgress_(false), + resetTimestamp_(0) { MEDIA_DEBUG_LOG("AudioStream ctor"); } @@ -52,9 +53,9 @@ bool AudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase ba uint64_t paTimeStamp = 0; if (GetCurrentTimeStamp(paTimeStamp) == SUCCESS) { MEDIA_DEBUG_LOG("AudioStream: GetAudioTime in microseconds: %{public}" PRIu64, paTimeStamp); - timestamp.time.tv_sec = static_cast(paTimeStamp / TIME_CONVERSION_US_S); + timestamp.time.tv_sec = static_cast((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S); timestamp.time.tv_nsec - = static_cast((paTimeStamp - (timestamp.time.tv_sec * TIME_CONVERSION_US_S)) + = static_cast(((paTimeStamp - resetTimestamp_) - (timestamp.time.tv_sec * TIME_CONVERSION_US_S)) * TIME_CONVERSION_NS_US); return true; } @@ -211,6 +212,11 @@ bool AudioStream::StartAudioStream() MEDIA_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_); return false; } + + if (state_ == STOPPED && GetCurrentTimeStamp(resetTimestamp_)) { + MEDIA_ERR_LOG("Failed to get timestamp after stop needed for resetting"); + } + int32_t ret = StartStream(); if (ret != SUCCESS) { MEDIA_ERR_LOG("StartStream Start failed:%{public}d", ret); diff --git a/services/src/client/audio_system_manager.cpp b/services/src/client/audio_system_manager.cpp index d63d8fe1da51d7888c56bf1dc4768fcd88d43bf8..bc76591f3725a5d2d11c07bb8d441d0e3d2266e0 100644 --- a/services/src/client/audio_system_manager.cpp +++ b/services/src/client/audio_system_manager.cpp @@ -76,12 +76,10 @@ AudioRingerMode AudioSystemManager::GetRingerMode() const return (AudioPolicyManager::GetInstance().GetRingerMode()); } -int32_t AudioSystemManager::SetDeviceActive(AudioDeviceDescriptor::DeviceType deviceType, bool flag) const +int32_t AudioSystemManager::SetDeviceActive(ActiveDeviceType deviceType, bool flag) const { switch (deviceType) { case SPEAKER: - case BLUETOOTH_A2DP: - case MIC: case BLUETOOTH_SCO: break; default: @@ -90,16 +88,13 @@ int32_t AudioSystemManager::SetDeviceActive(AudioDeviceDescriptor::DeviceType de } /* Call Audio Policy SetDeviceActive */ - DeviceType devType = (DeviceType)deviceType; - return (AudioPolicyManager::GetInstance().SetDeviceActive(devType, flag)); + return (AudioPolicyManager::GetInstance().SetDeviceActive(static_cast(deviceType), flag)); } -bool AudioSystemManager::IsDeviceActive(AudioDeviceDescriptor::DeviceType deviceType) const +bool AudioSystemManager::IsDeviceActive(ActiveDeviceType deviceType) const { switch (deviceType) { case SPEAKER: - case BLUETOOTH_A2DP: - case MIC: case BLUETOOTH_SCO: break; default: @@ -108,8 +103,7 @@ bool AudioSystemManager::IsDeviceActive(AudioDeviceDescriptor::DeviceType device } /* Call Audio Policy IsDeviceActive */ - DeviceType devType = (DeviceType)deviceType; - return (AudioPolicyManager::GetInstance().IsDeviceActive(devType)); + return (AudioPolicyManager::GetInstance().IsDeviceActive(static_cast(deviceType))); } bool AudioSystemManager::IsStreamActive(AudioSystemManager::AudioVolumeType volumeType) const diff --git a/services/src/server/audio_server.cpp b/services/src/server/audio_server.cpp index f7ebe972538a7abb3a51b557a1b8fc63daebd76d..ff7d99527b74d5f36cbe407716b283435432a459 100644 --- a/services/src/server/audio_server.cpp +++ b/services/src/server/audio_server.cpp @@ -114,10 +114,11 @@ int32_t AudioServer::SetMicrophoneMute(bool isMute) AudioCapturerSource* audioCapturerSourceInstance = AudioCapturerSource::GetInstance(); if (audioCapturerSourceInstance->capturerInited_ == false) { - MEDIA_ERR_LOG("Capturer is not initialized. Start the recording first !"); - return ERR_INVALID_OPERATION; + MEDIA_INFO_LOG("Capturer is not initialized. Set the flag mute state flag"); + AudioCapturerSource::micMuteState_ = isMute; + return 0; } - + return audioCapturerSourceInstance->SetMute(isMute); } @@ -127,11 +128,14 @@ bool AudioServer::IsMicrophoneMute() bool isMute = false; if (audioCapturerSourceInstance->capturerInited_ == false) { - MEDIA_ERR_LOG("Capturer is not initialized. Start the recording first !"); - } else if (audioCapturerSourceInstance->GetMute(isMute)) { + MEDIA_INFO_LOG("Capturer is not initialized. Get the mic mute state flag value!"); + return AudioCapturerSource::micMuteState_; + } + + if (audioCapturerSourceInstance->GetMute(isMute)) { MEDIA_ERR_LOG("GetMute status in capturer returned Error !"); } - + return isMute; } diff --git a/services/test/audio_capturer_test.cpp b/services/test/audio_capturer_test.cpp index e78c3f435a00525809d2d463388de896ba6c63c0..cc6c2d27c1db65d11eb6ef2a7af8049e94c3af56 100644 --- a/services/test/audio_capturer_test.cpp +++ b/services/test/audio_capturer_test.cpp @@ -25,8 +25,8 @@ using namespace OHOS::AudioStandard; namespace AudioTestConstants { constexpr int32_t SECOND_ARG_IDX = 2; constexpr int32_t THIRD_ARG_IDX = 3; - constexpr int32_t PAUSE_BUFFER_POSITION = 512; - constexpr int32_t PAUSE_READ_TIME_SECONDS = 2; + constexpr int32_t PAUSE_BUFFER_POSITION = 128; + constexpr int32_t PAUSE_READ_TIME_SECONDS = 10; constexpr int32_t SUCCESS = 0; } @@ -96,20 +96,14 @@ public: return false; } - uint32_t frameCount; - if (audioCapturer->GetFrameCount(frameCount) < 0) { - MEDIA_ERR_LOG(" GetMinimumFrameCount failed"); - return false; - } - - uint8_t* buffer = (uint8_t *) malloc(bufferLen); + uint8_t* buffer = (uint8_t *)malloc(bufferLen); if (buffer == nullptr) { MEDIA_ERR_LOG("AudioCapturerTest: Failed to allocate buffer"); return false; } size_t size = 1; - size_t numBuffersToCapture = 1024; + size_t numBuffersToCapture = 256; while (numBuffersToCapture) { size_t bytesRead = 0; while (bytesRead < bufferLen) { @@ -124,18 +118,23 @@ public: if (bytesRead < 0) { MEDIA_ERR_LOG("Bytes read failed. error code %{public}zu", bytesRead); break; - } else if (bytesRead > 0) { - fwrite(buffer, size, bytesRead, pFile); - numBuffersToCapture--; - if ((numBuffersToCapture == AudioTestConstants::PAUSE_BUFFER_POSITION) - && (audioCapturer->Stop())) { - MEDIA_INFO_LOG("Audio capture stopped for 2 seconds"); - sleep(AudioTestConstants::PAUSE_READ_TIME_SECONDS); - if (!audioCapturer->Start()) { - MEDIA_ERR_LOG("resume stream failed"); - audioCapturer->Release(); - break; - } + } else if (bytesRead == 0) { + continue; + } + + if (fwrite(buffer, size, bytesRead, pFile) != bytesRead) { + MEDIA_ERR_LOG("error occured in fwrite"); + } + numBuffersToCapture--; + if ((numBuffersToCapture == AudioTestConstants::PAUSE_BUFFER_POSITION) + && (audioCapturer->Stop())) { + MEDIA_INFO_LOG("Audio capture stopped for %{public}d seconds", + AudioTestConstants::PAUSE_READ_TIME_SECONDS); + sleep(AudioTestConstants::PAUSE_READ_TIME_SECONDS); + if (!audioCapturer->Start()) { + MEDIA_ERR_LOG("resume stream failed"); + audioCapturer->Release(); + break; } } } diff --git a/services/test/audio_policy_test.cpp b/services/test/audio_policy_test.cpp index c06bf32a36083b334b14b7cf3961c64925b34781..3805af2e8d28ba3b1c4d9147780c64c8c8385f7d 100644 --- a/services/test/audio_policy_test.cpp +++ b/services/test/audio_policy_test.cpp @@ -41,7 +41,7 @@ static void PrintUsage(void) cout << "\taudio_policy_test - Audio Policy Test " << endl << endl; cout << "SYNOPSIS" << endl << endl; cout << "\t#include " << endl << endl; - cout << "\t./audio_playback_test [OPTIONS]..." << endl << endl; + cout << "\t./audio_policy_test [OPTIONS]..." << endl << endl; cout << "DESCRIPTION" << endl << endl; cout << "\tControls audio volume, audio routing, audio mute" << endl << endl; cout << "-V\n\tSets Volume for streams, -S to setStream" << endl << endl; @@ -52,12 +52,13 @@ static void PrintUsage(void) cout << "\t3\tRING" << endl << endl; cout << "-D\n\tSets Device Active" << endl << endl; cout << "\tSupported Devices are" << endl << endl; - cout << "\t0\tSPEAKER" << endl << endl; - cout << "\t3\tBLUETOOTH_A2DP" << endl << endl; - cout << "\t4\tMIC" << endl << endl; + cout << "\t2\tSPEAKER" << endl << endl; + cout << "\t7\tBLUETOOTH_SCO" << endl << endl; cout << "-d\n\tGets Device Active" << endl << endl; cout << "-M\n\tSets Mute for streams, -S to setStream" << endl << endl; cout << "-m\n\tGets Mute for streams, -S to setStream" << endl << endl; + cout << "-U\n\t Mutes the Microphone" << endl << endl; + cout << "-u\n\t Checks if the Microphone is muted " << endl << endl; cout << "-R\n\tSets RingerMode" << endl << endl; cout << "-r\n\tGets RingerMode status" << endl << endl; cout << "-s\n\tGet Stream Status" << endl << endl; @@ -93,6 +94,19 @@ static void HandleMute(const AudioSystemManager *audioSystemMgr, int streamType, } } +static void HandleMicMute(const AudioSystemManager *audioSystemMgr, char option) +{ + if (option == 'u') { + bool muteStatus = audioSystemMgr->IsMicrophoneMute(); + cout << "Is Mic Mute : " << muteStatus << endl; + } else { + int mute = strtol(optarg, nullptr, AudioPolicyTest::OPT_ARG_BASE); + cout << "Set Mic Mute : " << mute << endl; + int32_t result = audioSystemMgr->SetMicrophoneMute((mute) ? true : false); + cout << "Set Mic Mute Result: " << result << endl; + } +} + static void SetStreamType(int &streamType) { streamType = strtol(optarg, nullptr, AudioPolicyTest::OPT_ARG_BASE); @@ -118,7 +132,7 @@ static void SetDeviceActive(const AudioSystemManager *audioSystemMgr, int argc, } cout << "Active : " << active << endl << endl; - int32_t result = audioSystemMgr->SetDeviceActive(AudioDeviceDescriptor::DeviceType(device), + int32_t result = audioSystemMgr->SetDeviceActive(ActiveDeviceType(device), (active) ? true : false); cout << "Set DeviceActive Result: " << result << endl; } @@ -126,7 +140,7 @@ static void SetDeviceActive(const AudioSystemManager *audioSystemMgr, int argc, static void IsDeviceActive(const AudioSystemManager *audioSystemMgr) { int device = strtol(optarg, nullptr, AudioPolicyTest::OPT_ARG_BASE); - bool devActiveStatus = audioSystemMgr->IsDeviceActive(AudioDeviceDescriptor::DeviceType(device)); + bool devActiveStatus = audioSystemMgr->IsDeviceActive(ActiveDeviceType(device)); cout << "GetDevice Active : " << devActiveStatus << endl; } @@ -170,7 +184,7 @@ int main(int argc, char* argv[]) int streamType = static_cast(AudioSystemManager::AudioVolumeType::STREAM_MUSIC); AudioSystemManager *audioSystemMgr = AudioSystemManager::GetInstance(); - while ((opt = getopt(argc, argv, ":V:S:D:M:R:d:s:vmr")) != -1) { + while ((opt = getopt(argc, argv, ":V:U:S:D:M:R:d:s:vmru")) != -1) { switch (opt) { case 'V': case 'v': @@ -180,6 +194,10 @@ int main(int argc, char* argv[]) case 'm': HandleMute(audioSystemMgr, streamType, opt); break; + case 'U': + case 'u': + HandleMicMute(audioSystemMgr, opt); + break; case 'S': SetStreamType(streamType); break;