diff --git a/frameworks/native/audioutils/include/audio_utils.h b/frameworks/native/audioutils/include/audio_utils.h index 7be9359022009c3c3baf2dea1d90c7c384d0fdf6..0f0dad53de16e1c72f67d6c481fcf974debc03ab 100644 --- a/frameworks/native/audioutils/include/audio_utils.h +++ b/frameworks/native/audioutils/include/audio_utils.h @@ -158,6 +158,13 @@ bool isEqual(T a, T b, double precision = 0.01) return std::abs(a - b) < precision; } +// return true if value is not in the array. +template +inline bool NotContain(const std::vector &array, const V &value) +{ + return std::find(array.begin(), array.end(), value) == array.end(); +} + template bool GetSysPara(const char *key, T &value); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h index d5ac975c33cdfcad1ace24bac81d4ca8cf6f3736..76c6aa52599bd6aa1716815a18c2cefb7c2aa239 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_stream_info.h @@ -18,6 +18,8 @@ #include #include +#include "audio_source_type.h" + namespace OHOS { namespace AudioStandard { @@ -505,6 +507,31 @@ const std::vector AUDIO_SUPPORTED_STREAM_USAGES { STREAM_USAGE_VOICE_RINGTONE, }; +const std::vector AUDIO_SUPPORTED_SOURCE_TYPES = { + SOURCE_TYPE_INVALID, + SOURCE_TYPE_MIC, + SOURCE_TYPE_VOICE_RECOGNITION, + SOURCE_TYPE_PLAYBACK_CAPTURE, + SOURCE_TYPE_WAKEUP, + SOURCE_TYPE_VOICE_CALL, + SOURCE_TYPE_VOICE_COMMUNICATION, + SOURCE_TYPE_ULTRASONIC, + SOURCE_TYPE_VIRTUAL_CAPTURE, + SOURCE_TYPE_VOICE_MESSAGE, + SOURCE_TYPE_REMOTE_CAST, + SOURCE_TYPE_VOICE_TRANSCRIPTION, +}; + +const std::vector AUDIO_FAST_STREAM_SUPPORTED_SOURCE_TYPES = { + SOURCE_TYPE_MIC, + SOURCE_TYPE_VOICE_RECOGNITION, + SOURCE_TYPE_VOICE_CALL, + SOURCE_TYPE_VOICE_COMMUNICATION, + SOURCE_TYPE_VIRTUAL_CAPTURE, + SOURCE_TYPE_VOICE_MESSAGE, + SOURCE_TYPE_VOICE_TRANSCRIPTION, +}; + // Supported audio parameters for fast audio stream const std::vector AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES { SAMPLE_RATE_48000, diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index c89929e4ea2fe598a8630c4f29fe9f1cf7ac5cf2..f657b4f3aeb9714df4b6ba24f89818201b35fd5a 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -169,6 +169,10 @@ private: void ResetRecordConfig(AudioProcessConfig &config); AudioProcessConfig ResetProcessConfig(const AudioProcessConfig &config); + bool CheckStreamInfoFormat(const AudioProcessConfig &config); + bool CheckRendererFormat(const AudioProcessConfig &config); + bool CheckRecorderFormat(const AudioProcessConfig &config); + bool CheckConfigFormat(const AudioProcessConfig &config); int32_t GetHapBuildApiVersion(int32_t callerUid); void AudioServerDied(pid_t pid); diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index f03ae2437811fa24d138c9f7e64c3e6ceafb6abb..4e5ca361040197f5117340f26b75fa7756e352c3 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -1289,10 +1289,89 @@ AudioProcessConfig AudioServer::ResetProcessConfig(const AudioProcessConfig &con return resetConfig; } +bool AudioServer::CheckStreamInfoFormat(const AudioProcessConfig &config) +{ + if (NotContain(AUDIO_SUPPORTED_SAMPLING_RATES, config.streamInfo.samplingRate)) { + AUDIO_ERR_LOG("Check format failed invalid samplingRate:%{public}d", config.streamInfo.samplingRate); + return false; + } + + if (NotContain(AUDIO_SUPPORTED_FORMATS, config.streamInfo.format)) { + AUDIO_ERR_LOG("Check format failed invalid format:%{public}d", config.streamInfo.format); + return false; + } + + if (NotContain(AUDIO_SUPPORTED_ENCODING_TYPES, config.streamInfo.encoding)) { + AUDIO_ERR_LOG("Check format failed invalid encoding:%{public}d", config.streamInfo.encoding); + return false; + } + + // both renderer and capturer check RENDERER_SUPPORTED_CHANNELLAYOUTS, should we rename it? + if (NotContain(RENDERER_SUPPORTED_CHANNELLAYOUTS, config.streamInfo.channelLayout)) { + AUDIO_ERR_LOG("Check format failed invalid channelLayout:%{public}" PRId64".", config.streamInfo.channelLayout); + return false; + } + + if (config.audioMode == AUDIO_MODE_PLAYBACK && NotContain(RENDERER_SUPPORTED_CHANNELS, + config.streamInfo.channels)) { + AUDIO_ERR_LOG("Check format failed invalid renderer channels:%{public}d", config.streamInfo.channels); + return false; + } + + if (config.audioMode == AUDIO_MODE_RECORD && NotContain(CAPTURER_SUPPORTED_CHANNELS, config.streamInfo.channels)) { + AUDIO_ERR_LOG("Check format failed invalid capturer channels:%{public}d", config.streamInfo.channels); + return false; + } + + return true; +} + +bool AudioServer::CheckRendererFormat(const AudioProcessConfig &config) +{ + if (NotContain(AUDIO_SUPPORTED_STREAM_USAGES, config.rendererInfo.streamUsage)) { + AUDIO_ERR_LOG("Check format failed invalid streamUsage:%{public}d", config.rendererInfo.streamUsage); + return false; + } + return true; +} + +bool AudioServer::CheckRecorderFormat(const AudioProcessConfig &config) +{ + if (NotContain(AUDIO_SUPPORTED_SOURCE_TYPES, config.capturerInfo.sourceType)) { + AUDIO_ERR_LOG("Check format failed invalid sourceType:%{public}d", config.capturerInfo.sourceType); + return false; + } + if (config.capturerInfo.capturerFlags != AUDIO_FLAG_NORMAL && NotContain(AUDIO_FAST_STREAM_SUPPORTED_SOURCE_TYPES, + config.capturerInfo.sourceType)) { + AUDIO_ERR_LOG("Check format failed invalid fast sourceType:%{public}d", config.capturerInfo.sourceType); + return false; + } + return true; +} + +bool AudioServer::CheckConfigFormat(const AudioProcessConfig &config) +{ + if (!CheckStreamInfoFormat(config)) { + return false; + } + if (config.audioMode == AUDIO_MODE_PLAYBACK) { + return CheckRendererFormat(config); + } + + if (config.audioMode == AUDIO_MODE_RECORD) { + return CheckRecorderFormat(config); + } + + AUDIO_ERR_LOG("Check format failed invalid mode."); + return false; +} + sptr AudioServer::CreateAudioProcess(const AudioProcessConfig &config) { Trace trace("AudioServer::CreateAudioProcess"); AudioProcessConfig resetConfig = ResetProcessConfig(config); + CHECK_AND_RETURN_RET_LOG(CheckConfigFormat(resetConfig), nullptr, "AudioProcessConfig format is wrong, please check" + ":%{public}s", ProcessConfig::DumpProcessConfig(resetConfig).c_str()); CHECK_AND_RETURN_RET_LOG(PermissionChecker(resetConfig), nullptr, "Create audio process failed, no permission"); if ((IsNormalIpcStream(resetConfig))) {