| /****************************************************************************** |
| * |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * 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 <stdint.h> |
| #include <sys/wait.h> |
| #include <unistd.h> |
| #include <algorithm> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include <Serializer.h> |
| #include <android-base/file.h> |
| #include <android/content/AttributionSourceState.h> |
| #include <libxml/parser.h> |
| #include <libxml/xinclude.h> |
| #include <media/AudioPolicy.h> |
| #include <media/AudioProfile.h> |
| #include <media/PatchBuilder.h> |
| #include <media/RecordingActivityTracker.h> |
| |
| #include <AudioPolicyInterface.h> |
| #include <android_audio_policy_configuration_V7_0-enums.h> |
| #include <fuzzer/FuzzedDataProvider.h> |
| #include <tests/AudioPolicyManagerTestClient.h> |
| #include <tests/AudioPolicyTestClient.h> |
| #include <tests/AudioPolicyTestManager.h> |
| #include <xsdc/XsdcSupport.h> |
| |
| using namespace android; |
| |
| namespace xsd { |
| using namespace ::android::audio::policy::configuration::V7_0; |
| } |
| |
| using content::AttributionSourceState; |
| |
| static const std::vector<audio_format_t> kAudioFormats = [] { |
| std::vector<audio_format_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioFormat>{}) { |
| audio_format_t audioFormatHal; |
| std::string audioFormat = toString(enumVal); |
| if (audio_format_from_string(audioFormat.c_str(), &audioFormatHal)) { |
| result.push_back(audioFormatHal); |
| } |
| } |
| return result; |
| }(); |
| |
| static const std::vector<audio_channel_mask_t> kAudioChannelOutMasks = [] { |
| std::vector<audio_channel_mask_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioChannelMask>{}) { |
| audio_channel_mask_t audioChannelMaskHal; |
| std::string audioChannelMask = toString(enumVal); |
| if (enumVal != xsd::AudioChannelMask::AUDIO_CHANNEL_NONE && |
| audioChannelMask.find("_IN_") == std::string::npos && |
| audio_channel_mask_from_string(audioChannelMask.c_str(), &audioChannelMaskHal)) { |
| result.push_back(audioChannelMaskHal); |
| } |
| } |
| return result; |
| }(); |
| |
| static const std::vector<audio_channel_mask_t> kAudioChannelInMasks = [] { |
| std::vector<audio_channel_mask_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioChannelMask>{}) { |
| audio_channel_mask_t audioChannelMaskHal; |
| std::string audioChannelMask = toString(enumVal); |
| if (enumVal != xsd::AudioChannelMask::AUDIO_CHANNEL_NONE && |
| audioChannelMask.find("_OUT_") == std::string::npos && |
| audio_channel_mask_from_string(audioChannelMask.c_str(), &audioChannelMaskHal)) { |
| result.push_back(audioChannelMaskHal); |
| } |
| } |
| return result; |
| }(); |
| |
| static const std::vector<audio_output_flags_t> kAudioOutputFlags = [] { |
| std::vector<audio_output_flags_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) { |
| audio_output_flags_t audioOutputFlagHal; |
| std::string audioOutputFlag = toString(enumVal); |
| if (audioOutputFlag.find("_OUTPUT_") != std::string::npos && |
| audio_output_flag_from_string(audioOutputFlag.c_str(), &audioOutputFlagHal)) { |
| result.push_back(audioOutputFlagHal); |
| } |
| } |
| return result; |
| }(); |
| |
| static const std::vector<audio_devices_t> kAudioDevices = [] { |
| std::vector<audio_devices_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioDevice>{}) { |
| audio_devices_t audioDeviceHal; |
| std::string audioDevice = toString(enumVal); |
| if (audio_device_from_string(audioDevice.c_str(), &audioDeviceHal)) { |
| result.push_back(audioDeviceHal); |
| } |
| } |
| return result; |
| }(); |
| |
| static const std::vector<audio_usage_t> kAudioUsages = [] { |
| std::vector<audio_usage_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioUsage>{}) { |
| audio_usage_t audioUsageHal; |
| std::string audioUsage = toString(enumVal); |
| if (audio_usage_from_string(audioUsage.c_str(), &audioUsageHal)) { |
| result.push_back(audioUsageHal); |
| } |
| } |
| return result; |
| }(); |
| |
| /** |
| * AudioSource - AUDIO_SOURCE_VOICE_COMMUNICATION and AUDIO_SOURCE_HOTWORD |
| * are excluded from kAudioSources[] in order to avoid the abort triggered |
| * for these two types of AudioSource in Engine::getDeviceForInputSource() |
| */ |
| static const std::vector<audio_source_t> kAudioSources = [] { |
| std::vector<audio_source_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioSource>{}) { |
| audio_source_t audioSourceHal; |
| std::string audioSource = toString(enumVal); |
| if (enumVal != xsd::AudioSource::AUDIO_SOURCE_VOICE_COMMUNICATION && |
| enumVal != xsd::AudioSource::AUDIO_SOURCE_HOTWORD && |
| audio_source_from_string(audioSource.c_str(), &audioSourceHal)) { |
| result.push_back(audioSourceHal); |
| } |
| } |
| return result; |
| }(); |
| |
| static const std::vector<audio_content_type_t> kAudioContentTypes = [] { |
| std::vector<audio_content_type_t> result; |
| for (const auto enumVal : xsdc_enum_range<xsd::AudioContentType>{}) { |
| audio_content_type_t audioContentTypeHal; |
| std::string audioContentType = toString(enumVal); |
| if (audio_content_type_from_string(audioContentType.c_str(), &audioContentTypeHal)) { |
| result.push_back(audioContentTypeHal); |
| } |
| } |
| return result; |
| }(); |
| |
| std::vector<int> kMixTypes = {MIX_TYPE_PLAYERS, MIX_TYPE_RECORDERS}; |
| |
| std::vector<int> kMixRouteFlags = {MIX_ROUTE_FLAG_RENDER, MIX_ROUTE_FLAG_LOOP_BACK, |
| MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER, MIX_ROUTE_FLAG_ALL}; |
| |
| std::vector<audio_flags_mask_t> kAudioFlagMasks = { |
| AUDIO_FLAG_NONE, AUDIO_FLAG_AUDIBILITY_ENFORCED, |
| AUDIO_FLAG_SECURE, AUDIO_FLAG_SCO, |
| AUDIO_FLAG_BEACON, AUDIO_FLAG_HW_AV_SYNC, |
| AUDIO_FLAG_HW_HOTWORD, AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY, |
| AUDIO_FLAG_BYPASS_MUTE, AUDIO_FLAG_LOW_LATENCY, |
| AUDIO_FLAG_DEEP_BUFFER, AUDIO_FLAG_NO_MEDIA_PROJECTION, |
| AUDIO_FLAG_MUTE_HAPTIC, AUDIO_FLAG_NO_SYSTEM_CAPTURE, |
| AUDIO_FLAG_CAPTURE_PRIVATE, AUDIO_FLAG_CONTENT_SPATIALIZED, |
| AUDIO_FLAG_NEVER_SPATIALIZE, |
| }; |
| |
| std::vector<audio_policy_dev_state_t> kAudioPolicyDeviceStates = { |
| AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, |
| AUDIO_POLICY_DEVICE_STATE_AVAILABLE, |
| AUDIO_POLICY_DEVICE_STATE_CNT, |
| }; |
| |
| std::vector<uint32_t> kSamplingRates = {8000, 16000, 44100, 48000, 88200, 96000}; |
| |
| template <typename T> |
| T getValueFromVector(FuzzedDataProvider *fdp, std::vector<T> arr) { |
| if (fdp->ConsumeBool()) { |
| return arr[fdp->ConsumeIntegralInRange<int32_t>(0, arr.size() - 1)]; |
| } else { |
| return (T)fdp->ConsumeIntegral<uint32_t>(); |
| } |
| } |
| |
| class AudioPolicyManagerFuzzer { |
| public: |
| explicit AudioPolicyManagerFuzzer(FuzzedDataProvider *fdp); |
| virtual ~AudioPolicyManagerFuzzer() = default; |
| virtual bool initialize(); |
| virtual void SetUpManagerConfig(); |
| bool getOutputForAttr(audio_port_handle_t *selectedDeviceId, audio_format_t format, |
| audio_channel_mask_t channelMask, int sampleRate, |
| audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, |
| audio_io_handle_t *output = nullptr, |
| audio_port_handle_t *portId = nullptr, audio_attributes_t attr = {}); |
| bool getInputForAttr(const audio_attributes_t &attr, audio_unique_id_t riid, |
| audio_port_handle_t *selectedDeviceId, audio_format_t format, |
| audio_channel_mask_t channelMask, int sampleRate, |
| audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, |
| audio_port_handle_t *portId = nullptr); |
| bool findDevicePort(audio_port_role_t role, audio_devices_t deviceType, |
| const std::string &address, audio_port_v7 *foundPort); |
| static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch *patch); |
| audio_patch createFuzzedPatch(); |
| void fuzzPatchCreation(); |
| virtual void process(); |
| |
| protected: |
| sp<AudioPolicyConfig> mConfig{AudioPolicyConfig::createWritableForTests()}; |
| std::unique_ptr<AudioPolicyManagerTestClient> mClient{new AudioPolicyManagerTestClient}; |
| std::unique_ptr<AudioPolicyTestManager> mManager; |
| FuzzedDataProvider *mFdp; |
| }; |
| |
| AudioPolicyManagerFuzzer::AudioPolicyManagerFuzzer(FuzzedDataProvider *fdp) |
| : mFdp(fdp) {} |
| |
| bool AudioPolicyManagerFuzzer::initialize() { |
| if (mFdp->remaining_bytes() < 1) { |
| return false; |
| } |
| // init code |
| SetUpManagerConfig(); |
| if (mConfig == nullptr) { |
| return false; |
| } |
| mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get())); |
| if (mManager->initialize() != NO_ERROR) { |
| return false; |
| } |
| if (mManager->initCheck() != NO_ERROR) { |
| return false; |
| } |
| return true; |
| } |
| |
| void AudioPolicyManagerFuzzer::SetUpManagerConfig() { mConfig->setDefault(); } |
| |
| bool AudioPolicyManagerFuzzer::getOutputForAttr( |
| audio_port_handle_t *selectedDeviceId, audio_format_t format, audio_channel_mask_t channelMask, |
| int sampleRate, audio_output_flags_t flags, audio_io_handle_t *output, |
| audio_port_handle_t *portId, audio_attributes_t attr) { |
| audio_io_handle_t localOutput; |
| if (!output) output = &localOutput; |
| *output = AUDIO_IO_HANDLE_NONE; |
| audio_stream_type_t stream = AUDIO_STREAM_DEFAULT; |
| audio_config_t config = AUDIO_CONFIG_INITIALIZER; |
| config.sample_rate = sampleRate; |
| config.channel_mask = channelMask; |
| config.format = format; |
| audio_port_handle_t localPortId; |
| if (!portId) portId = &localPortId; |
| *portId = AUDIO_PORT_HANDLE_NONE; |
| AudioPolicyInterface::output_type_t outputType; |
| bool isSpatialized; |
| bool isBitPerfect; |
| |
| // TODO b/182392769: use attribution source util |
| AttributionSourceState attributionSource; |
| attributionSource.uid = 0; |
| attributionSource.token = sp<BBinder>::make(); |
| if (mManager->getOutputForAttr(&attr, output, AUDIO_SESSION_NONE, &stream, attributionSource, |
| &config, &flags, selectedDeviceId, portId, {}, &outputType, &isSpatialized, |
| &isBitPerfect) != OK) { |
| return false; |
| } |
| if (*output == AUDIO_IO_HANDLE_NONE || *portId == AUDIO_PORT_HANDLE_NONE) { |
| return false; |
| } |
| return true; |
| } |
| |
| bool AudioPolicyManagerFuzzer::getInputForAttr( |
| const audio_attributes_t &attr, audio_unique_id_t riid, audio_port_handle_t *selectedDeviceId, |
| audio_format_t format, audio_channel_mask_t channelMask, int sampleRate, |
| audio_input_flags_t flags, audio_port_handle_t *portId) { |
| audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; |
| audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER; |
| config.sample_rate = sampleRate; |
| config.channel_mask = channelMask; |
| config.format = format; |
| audio_port_handle_t localPortId; |
| if (!portId) portId = &localPortId; |
| *portId = AUDIO_PORT_HANDLE_NONE; |
| AudioPolicyInterface::input_type_t inputType; |
| |
| AttributionSourceState attributionSource; |
| attributionSource.uid = 0; |
| attributionSource.token = sp<BBinder>::make(); |
| if (mManager->getInputForAttr(&attr, &input, riid, AUDIO_SESSION_NONE, attributionSource, |
| &config, flags, selectedDeviceId, &inputType, portId) != OK) { |
| return false; |
| } |
| if (*portId == AUDIO_PORT_HANDLE_NONE || input == AUDIO_IO_HANDLE_NONE) { |
| return false; |
| } |
| return true; |
| } |
| |
| bool AudioPolicyManagerFuzzer::findDevicePort(audio_port_role_t role, audio_devices_t deviceType, |
| const std::string &address, |
| audio_port_v7 *foundPort) { |
| uint32_t numPorts = 0; |
| uint32_t generation1; |
| status_t ret; |
| |
| ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1); |
| if (ret != NO_ERROR) { |
| return false; |
| } |
| |
| uint32_t generation2; |
| struct audio_port_v7 ports[numPorts]; |
| ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation2); |
| if (ret != NO_ERROR) { |
| return false; |
| } |
| |
| for (const auto &port : ports) { |
| if (port.role == role && port.ext.device.type == deviceType && |
| (strncmp(port.ext.device.address, address.c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == |
| 0)) { |
| if (foundPort) *foundPort = port; |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| audio_port_handle_t AudioPolicyManagerFuzzer::getDeviceIdFromPatch( |
| const struct audio_patch *patch) { |
| if (patch->num_sources != 0 && patch->num_sinks != 0) { |
| if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { |
| return patch->sinks[0].id; |
| } else { |
| return patch->sources[0].id; |
| } |
| } |
| return AUDIO_PORT_HANDLE_NONE; |
| } |
| |
| audio_patch AudioPolicyManagerFuzzer::createFuzzedPatch() { |
| audio_patch patch{}; |
| patch.id = mFdp->ConsumeIntegral<uint32_t>(); |
| patch.num_sources = mFdp->ConsumeIntegralInRange(0, AUDIO_PATCH_PORTS_MAX); |
| for (int i = 0; i < patch.num_sources; ++i) { |
| audio_port_config config{}; |
| std::vector<uint8_t> bytes = mFdp->ConsumeBytes<uint8_t>(sizeof(config)); |
| memcpy(reinterpret_cast<uint8_t *>(&config), &bytes[0], bytes.size()); |
| patch.sources[i] = config; |
| } |
| patch.num_sinks = mFdp->ConsumeIntegralInRange(0, AUDIO_PATCH_PORTS_MAX); |
| for (int i = 0; i < patch.num_sinks; ++i) { |
| audio_port_config config{}; |
| std::vector<uint8_t> bytes = mFdp->ConsumeBytes<uint8_t>(sizeof(config)); |
| memcpy(reinterpret_cast<uint8_t *>(&config), &bytes[0], bytes.size()); |
| patch.sinks[i] = config; |
| } |
| return patch; |
| } |
| |
| void AudioPolicyManagerFuzzer::fuzzPatchCreation() { |
| if (mFdp->remaining_bytes()) { |
| audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE; |
| uid_t uid = mFdp->ConsumeIntegral<uint32_t>(); |
| |
| // create a fuzzed patch |
| handle = AUDIO_PATCH_HANDLE_NONE; |
| audio_patch patch = createFuzzedPatch(); |
| uid = mFdp->ConsumeIntegral<uint32_t>(); |
| if (mManager->createAudioPatch(&patch, &handle, uid) == NO_ERROR) { |
| mManager->releaseAudioPatch(handle, uid); |
| } |
| } |
| } |
| |
| void AudioPolicyManagerFuzzer::process() { |
| if (initialize()) { |
| fuzzPatchCreation(); |
| } |
| } |
| |
| class AudioPolicyManagerFuzzerWithConfigurationFile : public AudioPolicyManagerFuzzer { |
| public: |
| explicit AudioPolicyManagerFuzzerWithConfigurationFile(FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzer(fdp){}; |
| |
| protected: |
| void SetUpManagerConfig() override; |
| virtual std::string getConfigFile(); |
| void traverseAndFuzzXML(xmlDocPtr pDoc, xmlNodePtr curr); |
| std::string fuzzXML(std::string xmlPath); |
| |
| static inline const std::string sExecutableDir = base::GetExecutableDirectory() + "/"; |
| static inline const std::string sDefaultConfig = |
| sExecutableDir + "data/test_audio_policy_configuration.xml"; |
| static inline const std::string sFuzzedConfig = sExecutableDir + "fuzzed.xml";; |
| }; |
| |
| std::string AudioPolicyManagerFuzzerWithConfigurationFile::getConfigFile() { |
| return fuzzXML(sDefaultConfig); |
| } |
| |
| void AudioPolicyManagerFuzzerWithConfigurationFile::SetUpManagerConfig() { |
| const std::string configFilePath = getConfigFile(); |
| auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(configFilePath); |
| mConfig = result.ok() ? mConfig = result.value() : nullptr; |
| ALOGE_IF(!result.ok(), "%s: Failed to deserialize \"%s\": %d", |
| __func__, configFilePath.c_str(), result.error()); |
| } |
| |
| void AudioPolicyManagerFuzzerWithConfigurationFile::traverseAndFuzzXML(xmlDocPtr pDoc, |
| xmlNodePtr curr) { |
| if (curr == nullptr) { |
| return; |
| } |
| |
| xmlAttr *attribute = curr->properties; |
| while (attribute) { |
| if (!xmlStrcmp(attribute->name, reinterpret_cast<const xmlChar *>("format"))) { |
| const char *newFormat = |
| audio_format_to_string(getValueFromVector<audio_format_t>(mFdp, kAudioFormats)); |
| xmlSetProp(curr, attribute->name, reinterpret_cast<const xmlChar *>(newFormat)); |
| } |
| if (!xmlStrcmp(attribute->name, reinterpret_cast<const xmlChar *>("flags"))) { |
| std::string newFlag = ""; |
| uint16_t numFlags = std::max((uint16_t)1, mFdp->ConsumeIntegral<uint16_t>()); |
| for (uint16_t i = 0; i < numFlags; ++i) { |
| newFlag += std::string(audio_output_flag_to_string( |
| getValueFromVector<audio_output_flags_t>(mFdp, kAudioOutputFlags))); |
| if (i != (numFlags - 1)) { |
| newFlag += std::string("|"); |
| } |
| } |
| xmlSetProp(curr, attribute->name, reinterpret_cast<const xmlChar *>(newFlag.c_str())); |
| } |
| if (!xmlStrcmp(attribute->name, reinterpret_cast<const xmlChar *>("samplingRates"))) { |
| std::string newRate = ""; |
| uint16_t numRates = std::max((uint16_t)1, mFdp->ConsumeIntegral<uint16_t>()); |
| for (uint16_t i = 0; i < numRates; ++i) { |
| newRate += std::to_string(getValueFromVector<uint32_t>(mFdp, kSamplingRates)); |
| if (i != (numRates - 1)) { |
| newRate += std::string(","); |
| } |
| } |
| xmlSetProp(curr, attribute->name, reinterpret_cast<const xmlChar *>(newRate.c_str())); |
| } |
| if (!xmlStrcmp(attribute->name, reinterpret_cast<const xmlChar *>("channelMasks"))) { |
| int isOutMask = -1; |
| char *value = |
| reinterpret_cast<char *>(xmlNodeListGetString(pDoc, attribute->children, 1)); |
| if (std::string(value).find(std::string("_OUT_")) != std::string::npos) { |
| // OUT mask |
| isOutMask = 1; |
| } else if (std::string(value).find(std::string("_IN_")) != std::string::npos) { |
| // IN mask |
| isOutMask = 0; |
| } |
| if (isOutMask != -1) { |
| std::string newMask = ""; |
| uint16_t numMasks = std::max((uint16_t)1, mFdp->ConsumeIntegral<uint16_t>()); |
| for (uint16_t i = 0; i < numMasks; ++i) { |
| if (isOutMask) { |
| newMask += std::string(audio_channel_out_mask_to_string( |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks))); |
| } else { |
| newMask += std::string(audio_channel_in_mask_to_string( |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelInMasks))); |
| } |
| if (i != (numMasks - 1)) { |
| newMask += std::string(","); |
| } |
| } |
| xmlSetProp(curr, attribute->name, |
| reinterpret_cast<const xmlChar *>(newMask.c_str())); |
| } |
| xmlFree(value); |
| } |
| attribute = attribute->next; |
| } |
| |
| curr = curr->xmlChildrenNode; |
| while (curr != nullptr) { |
| traverseAndFuzzXML(pDoc, curr); |
| curr = curr->next; |
| } |
| } |
| |
| std::string AudioPolicyManagerFuzzerWithConfigurationFile::fuzzXML(std::string xmlPath) { |
| std::string outPath = sFuzzedConfig; |
| |
| // Load in the xml file from disk |
| xmlDocPtr pDoc = xmlParseFile(xmlPath.c_str()); |
| xmlNodePtr root = xmlDocGetRootElement(pDoc); |
| |
| traverseAndFuzzXML(pDoc, root); |
| |
| // Save the document back out to disk. |
| xmlSaveFileEnc(outPath.c_str(), pDoc, "UTF-8"); |
| xmlFreeDoc(pDoc); |
| |
| return outPath; |
| } |
| |
| class AudioPolicyManagerFuzzerMsd : public AudioPolicyManagerFuzzerWithConfigurationFile { |
| public: |
| explicit AudioPolicyManagerFuzzerMsd(FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerWithConfigurationFile(fdp) {} |
| |
| protected: |
| std::string getConfigFile() override; |
| |
| static inline const std::string sMsdConfig = |
| sExecutableDir + "data/test_audio_policy_msd_configuration.xml"; |
| }; |
| |
| std::string AudioPolicyManagerFuzzerMsd::getConfigFile() { return fuzzXML(sMsdConfig); } |
| |
| using PolicyMixTuple = std::tuple<audio_usage_t, audio_source_t, uint32_t>; |
| |
| class AudioPolicyManagerFuzzerDynamicPolicy : public AudioPolicyManagerFuzzerWithConfigurationFile { |
| public: |
| explicit AudioPolicyManagerFuzzerDynamicPolicy(FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerWithConfigurationFile(fdp){}; |
| ~AudioPolicyManagerFuzzerDynamicPolicy() override; |
| void process() override; |
| |
| protected: |
| status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType, |
| std::string mixAddress, const audio_config_t &audioConfig, |
| const std::vector<PolicyMixTuple> &rules); |
| void clearPolicyMix(); |
| void registerPolicyMixes(); |
| void unregisterPolicyMixes(); |
| |
| Vector<AudioMix> mAudioMixes; |
| const std::string mMixAddress = "remote_submix_media"; |
| }; |
| |
| AudioPolicyManagerFuzzerDynamicPolicy::~AudioPolicyManagerFuzzerDynamicPolicy() { |
| clearPolicyMix(); |
| } |
| |
| status_t AudioPolicyManagerFuzzerDynamicPolicy::addPolicyMix( |
| int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress, |
| const audio_config_t &audioConfig, const std::vector<PolicyMixTuple> &rules) { |
| std::vector<AudioMixMatchCriterion> myMixMatchCriteria; |
| |
| myMixMatchCriteria.reserve(rules.size()); |
| for (const auto &rule : rules) { |
| myMixMatchCriteria.push_back( |
| AudioMixMatchCriterion(std::get<0>(rule), std::get<1>(rule), std::get<2>(rule))); |
| } |
| |
| AudioMix myAudioMix(myMixMatchCriteria, mixType, audioConfig, mixFlag, |
| String8(mixAddress.c_str()), 0); |
| myAudioMix.mDeviceType = deviceType; |
| // Clear mAudioMix before add new one to make sure we don't add already existing mixes. |
| mAudioMixes.clear(); |
| mAudioMixes.add(myAudioMix); |
| |
| // As the policy mixes registration may fail at some case, |
| // caller need to check the returned status. |
| status_t ret = mManager->registerPolicyMixes(mAudioMixes); |
| return ret; |
| } |
| |
| void AudioPolicyManagerFuzzerDynamicPolicy::clearPolicyMix() { |
| if (mManager != nullptr) { |
| mManager->unregisterPolicyMixes(mAudioMixes); |
| } |
| mAudioMixes.clear(); |
| } |
| |
| void AudioPolicyManagerFuzzerDynamicPolicy::registerPolicyMixes() { |
| const uint32_t numPolicies = mFdp->ConsumeIntegralInRange<uint32_t>(1, MAX_MIXES_PER_POLICY); |
| |
| for (int i = 0; i < numPolicies; ++i) { |
| audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER; |
| audioConfig.channel_mask = getValueFromVector<audio_channel_mask_t>( |
| mFdp, mFdp->ConsumeBool() ? kAudioChannelInMasks : kAudioChannelOutMasks); |
| audioConfig.format = getValueFromVector<audio_format_t>(mFdp, kAudioFormats); |
| audioConfig.sample_rate = getValueFromVector<uint32_t>(mFdp, kSamplingRates); |
| addPolicyMix(getValueFromVector<int>(mFdp, kMixTypes), |
| getValueFromVector<int>(mFdp, kMixRouteFlags), |
| getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), "", audioConfig, |
| std::vector<PolicyMixTuple>()); |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDynamicPolicy::unregisterPolicyMixes() { |
| mManager->unregisterPolicyMixes(mAudioMixes); |
| } |
| |
| void AudioPolicyManagerFuzzerDynamicPolicy::process() { |
| if (initialize()) { |
| registerPolicyMixes(); |
| fuzzPatchCreation(); |
| unregisterPolicyMixes(); |
| } |
| } |
| |
| class AudioPolicyManagerFuzzerDPNoRemoteSubmixModule |
| : public AudioPolicyManagerFuzzerDynamicPolicy { |
| public: |
| explicit AudioPolicyManagerFuzzerDPNoRemoteSubmixModule(FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerDynamicPolicy(fdp){}; |
| |
| protected: |
| std::string getConfigFile() override; |
| |
| static inline const std::string sPrimaryOnlyConfig = |
| sExecutableDir + "data/test_audio_policy_primary_only_configuration.xml"; |
| }; |
| |
| std::string AudioPolicyManagerFuzzerDPNoRemoteSubmixModule::getConfigFile() { |
| return fuzzXML(sPrimaryOnlyConfig); |
| } |
| |
| class AudioPolicyManagerFuzzerDPPlaybackReRouting : public AudioPolicyManagerFuzzerDynamicPolicy { |
| public: |
| explicit AudioPolicyManagerFuzzerDPPlaybackReRouting(FuzzedDataProvider *fdp); |
| ~AudioPolicyManagerFuzzerDPPlaybackReRouting() override; |
| void process() override; |
| |
| protected: |
| bool initialize() override; |
| void playBackReRouting(); |
| |
| std::unique_ptr<RecordingActivityTracker> mTracker; |
| |
| std::vector<PolicyMixTuple> mUsageRules = { |
| {AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE}, |
| {AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE}}; |
| |
| struct audio_port_v7 mInjectionPort; |
| audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE; |
| audio_config_t mAudioConfig; |
| }; |
| |
| AudioPolicyManagerFuzzerDPPlaybackReRouting::AudioPolicyManagerFuzzerDPPlaybackReRouting( |
| FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerDynamicPolicy(fdp) { |
| const uint32_t numRules = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numRules; ++i) { |
| PolicyMixTuple rule = {getValueFromVector<audio_usage_t>(mFdp, kAudioUsages), |
| getValueFromVector<audio_source_t>(mFdp, kAudioSources), |
| RULE_MATCH_ATTRIBUTE_USAGE}; |
| mUsageRules.push_back(rule); |
| } |
| } |
| |
| AudioPolicyManagerFuzzerDPPlaybackReRouting::~AudioPolicyManagerFuzzerDPPlaybackReRouting() { |
| if (mManager) { |
| mManager->stopInput(mPortId); |
| } |
| } |
| |
| bool AudioPolicyManagerFuzzerDPPlaybackReRouting::initialize() { |
| if (!AudioPolicyManagerFuzzerDynamicPolicy::initialize()) { |
| return false; |
| } |
| mTracker.reset(new RecordingActivityTracker()); |
| |
| mAudioConfig = AUDIO_CONFIG_INITIALIZER; |
| mAudioConfig.channel_mask = |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks); |
| mAudioConfig.format = getValueFromVector<audio_format_t>(mFdp, kAudioFormats); |
| mAudioConfig.sample_rate = getValueFromVector<uint32_t>(mFdp, kSamplingRates); |
| status_t ret = addPolicyMix(getValueFromVector<int>(mFdp, kMixTypes), |
| getValueFromVector<int>(mFdp, kMixRouteFlags), |
| getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), |
| mMixAddress, mAudioConfig, mUsageRules); |
| if (ret != NO_ERROR) { |
| return false; |
| } |
| |
| struct audio_port_v7 extractionPort; |
| findDevicePort(AUDIO_PORT_ROLE_SOURCE, getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), |
| mMixAddress, &extractionPort); |
| |
| audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; |
| audio_source_t source = getValueFromVector<audio_source_t>(mFdp, kAudioSources); |
| audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source, |
| AUDIO_FLAG_NONE, ""}; |
| std::string tags = "addr=" + mMixAddress; |
| strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1); |
| getInputForAttr(attr, mTracker->getRiid(), &selectedDeviceId, mAudioConfig.format, |
| mAudioConfig.channel_mask, mAudioConfig.sample_rate, AUDIO_INPUT_FLAG_NONE, |
| &mPortId); |
| |
| ret = mManager->startInput(mPortId); |
| if (ret != NO_ERROR) { |
| return false; |
| } |
| if (!findDevicePort(AUDIO_PORT_ROLE_SINK, |
| getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), mMixAddress, |
| &mInjectionPort)) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| void AudioPolicyManagerFuzzerDPPlaybackReRouting::playBackReRouting() { |
| const uint32_t numTestCases = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numTestCases; ++i) { |
| audio_attributes_t attr; |
| attr.content_type = getValueFromVector<audio_content_type_t>(mFdp, kAudioContentTypes); |
| attr.usage = getValueFromVector<audio_usage_t>(mFdp, kAudioUsages); |
| attr.source = getValueFromVector<audio_source_t>(mFdp, kAudioSources); |
| attr.flags = getValueFromVector<audio_flags_mask_t>(mFdp, kAudioFlagMasks); |
| std::string tags(mFdp->ConsumeBool() ? "" : "addr=remote_submix_media"); |
| strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1); |
| |
| audio_port_handle_t playbackRoutedPortId = AUDIO_PORT_HANDLE_NONE; |
| getOutputForAttr(&playbackRoutedPortId, mAudioConfig.format, mAudioConfig.channel_mask, |
| mAudioConfig.sample_rate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, |
| nullptr /*portId*/, attr); |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDPPlaybackReRouting::process() { |
| if (initialize()) { |
| playBackReRouting(); |
| registerPolicyMixes(); |
| fuzzPatchCreation(); |
| unregisterPolicyMixes(); |
| } |
| } |
| |
| class AudioPolicyManagerFuzzerDPMixRecordInjection : public AudioPolicyManagerFuzzerDynamicPolicy { |
| public: |
| explicit AudioPolicyManagerFuzzerDPMixRecordInjection(FuzzedDataProvider *fdp); |
| ~AudioPolicyManagerFuzzerDPMixRecordInjection() override; |
| void process() override; |
| |
| protected: |
| bool initialize() override; |
| void recordingInjection(); |
| |
| std::unique_ptr<RecordingActivityTracker> mTracker; |
| |
| std::vector<PolicyMixTuple> mSourceRules = { |
| {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_CAMCORDER, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}, |
| {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_MIC, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}, |
| {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_VOICE_COMMUNICATION, |
| RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}}; |
| |
| struct audio_port_v7 mExtractionPort; |
| audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE; |
| audio_config_t mAudioConfig; |
| }; |
| |
| AudioPolicyManagerFuzzerDPMixRecordInjection::AudioPolicyManagerFuzzerDPMixRecordInjection( |
| FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerDynamicPolicy(fdp) { |
| const uint32_t numRules = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numRules; ++i) { |
| PolicyMixTuple rule = {getValueFromVector<audio_usage_t>(mFdp, kAudioUsages), |
| getValueFromVector<audio_source_t>(mFdp, kAudioSources), |
| RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}; |
| mSourceRules.push_back(rule); |
| } |
| } |
| |
| AudioPolicyManagerFuzzerDPMixRecordInjection::~AudioPolicyManagerFuzzerDPMixRecordInjection() { |
| if (mManager) { |
| mManager->stopOutput(mPortId); |
| } |
| } |
| |
| bool AudioPolicyManagerFuzzerDPMixRecordInjection::initialize() { |
| if (!AudioPolicyManagerFuzzerDynamicPolicy::initialize()) { |
| return false; |
| } |
| |
| mTracker.reset(new RecordingActivityTracker()); |
| |
| mAudioConfig = AUDIO_CONFIG_INITIALIZER; |
| mAudioConfig.channel_mask = |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelInMasks); |
| mAudioConfig.format = getValueFromVector<audio_format_t>(mFdp, kAudioFormats); |
| mAudioConfig.sample_rate = getValueFromVector<uint32_t>(mFdp, kSamplingRates); |
| status_t ret = addPolicyMix(getValueFromVector<int>(mFdp, kMixTypes), |
| getValueFromVector<int>(mFdp, kMixRouteFlags), |
| getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), |
| mMixAddress, mAudioConfig, mSourceRules); |
| if (ret != NO_ERROR) { |
| return false; |
| } |
| |
| struct audio_port_v7 injectionPort; |
| findDevicePort(AUDIO_PORT_ROLE_SINK, getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), |
| mMixAddress, &injectionPort); |
| |
| audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; |
| audio_usage_t usage = getValueFromVector<audio_usage_t>(mFdp, kAudioUsages); |
| audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, usage, AUDIO_SOURCE_DEFAULT, |
| AUDIO_FLAG_NONE, ""}; |
| std::string tags = std::string("addr=") + mMixAddress; |
| strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1); |
| getOutputForAttr(&selectedDeviceId, mAudioConfig.format, mAudioConfig.channel_mask, |
| mAudioConfig.sample_rate /*sampleRate*/, AUDIO_OUTPUT_FLAG_NONE, |
| nullptr /*output*/, &mPortId, attr); |
| ret = mManager->startOutput(mPortId); |
| if (ret != NO_ERROR) { |
| return false; |
| } |
| getDeviceIdFromPatch(mClient->getLastAddedPatch()); |
| if (!findDevicePort(AUDIO_PORT_ROLE_SOURCE, |
| getValueFromVector<audio_devices_t>(mFdp, kAudioDevices), mMixAddress, |
| &mExtractionPort)) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| void AudioPolicyManagerFuzzerDPMixRecordInjection::recordingInjection() { |
| const uint32_t numTestCases = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numTestCases; ++i) { |
| audio_attributes_t attr; |
| attr.content_type = getValueFromVector<audio_content_type_t>(mFdp, kAudioContentTypes); |
| attr.usage = getValueFromVector<audio_usage_t>(mFdp, kAudioUsages); |
| attr.source = getValueFromVector<audio_source_t>(mFdp, kAudioSources); |
| attr.flags = getValueFromVector<audio_flags_mask_t>(mFdp, kAudioFlagMasks); |
| std::string tags(mFdp->ConsumeBool() ? "" : "addr=remote_submix_media"); |
| strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1); |
| |
| audio_port_handle_t captureRoutedPortId = AUDIO_PORT_HANDLE_NONE; |
| audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE; |
| getInputForAttr(attr, mTracker->getRiid(), &captureRoutedPortId, mAudioConfig.format, |
| mAudioConfig.channel_mask, mAudioConfig.sample_rate, AUDIO_INPUT_FLAG_NONE, |
| &portId); |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDPMixRecordInjection::process() { |
| if (initialize()) { |
| recordingInjection(); |
| registerPolicyMixes(); |
| fuzzPatchCreation(); |
| unregisterPolicyMixes(); |
| } |
| } |
| |
| using DeviceConnectionTestParams = |
| std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/>; |
| |
| class AudioPolicyManagerFuzzerDeviceConnection |
| : public AudioPolicyManagerFuzzerWithConfigurationFile { |
| public: |
| explicit AudioPolicyManagerFuzzerDeviceConnection(FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerWithConfigurationFile(fdp){}; |
| void process() override; |
| |
| void fuzzGetDirectPlaybackSupport(); |
| void fuzzGetDirectProfilesForAttributes(); |
| |
| protected: |
| void setDeviceConnectionState(); |
| void explicitlyRoutingAfterConnection(); |
| }; |
| |
| void AudioPolicyManagerFuzzerDeviceConnection::setDeviceConnectionState() { |
| const uint32_t numTestCases = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numTestCases; ++i) { |
| const audio_devices_t type = getValueFromVector<audio_devices_t>(mFdp, kAudioDevices); |
| const std::string name = mFdp->ConsumeRandomLengthString(); |
| const std::string address = mFdp->ConsumeRandomLengthString(); |
| mManager->setDeviceConnectionState( |
| type, getValueFromVector<audio_policy_dev_state_t>(mFdp, kAudioPolicyDeviceStates), |
| address.c_str(), name.c_str(), getValueFromVector<audio_format_t>(mFdp, kAudioFormats)); |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDeviceConnection::explicitlyRoutingAfterConnection() { |
| const uint32_t numTestCases = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numTestCases; ++i) { |
| const audio_devices_t type = getValueFromVector<audio_devices_t>(mFdp, kAudioDevices); |
| const std::string name = mFdp->ConsumeRandomLengthString(); |
| const std::string address = mFdp->ConsumeRandomLengthString(); |
| mManager->setDeviceConnectionState( |
| type, getValueFromVector<audio_policy_dev_state_t>(mFdp, kAudioPolicyDeviceStates), |
| address.c_str(), name.c_str(), getValueFromVector<audio_format_t>(mFdp, kAudioFormats)); |
| |
| audio_port_v7 devicePort; |
| const audio_port_role_t role = |
| audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE; |
| findDevicePort(role, type, address, &devicePort); |
| |
| audio_port_handle_t routedPortId = devicePort.id; |
| // Try start input or output according to the device type |
| if (audio_is_output_devices(type)) { |
| getOutputForAttr(&routedPortId, getValueFromVector<audio_format_t>(mFdp, kAudioFormats), |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks), |
| getValueFromVector<uint32_t>(mFdp, kSamplingRates), |
| AUDIO_OUTPUT_FLAG_NONE); |
| } else if (audio_is_input_device(type)) { |
| RecordingActivityTracker tracker; |
| getInputForAttr({}, tracker.getRiid(), &routedPortId, |
| getValueFromVector<audio_format_t>(mFdp, kAudioFormats), |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelInMasks), |
| getValueFromVector<uint32_t>(mFdp, kSamplingRates), |
| AUDIO_INPUT_FLAG_NONE); |
| } |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDeviceConnection::fuzzGetDirectPlaybackSupport() { |
| const uint32_t numTestCases = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numTestCases; ++i) { |
| audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER; |
| attr.content_type = getValueFromVector<audio_content_type_t>(mFdp, kAudioContentTypes); |
| attr.usage = getValueFromVector<audio_usage_t>(mFdp, kAudioUsages); |
| attr.source = getValueFromVector<audio_source_t>(mFdp, kAudioSources); |
| attr.flags = getValueFromVector<audio_flags_mask_t>(mFdp, kAudioFlagMasks); |
| audio_config_t config = AUDIO_CONFIG_INITIALIZER; |
| config.channel_mask = getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks); |
| config.format = getValueFromVector<audio_format_t>(mFdp, kAudioFormats); |
| config.sample_rate = getValueFromVector<uint32_t>(mFdp, kSamplingRates); |
| mManager->getDirectPlaybackSupport(&attr, &config); |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDeviceConnection::fuzzGetDirectProfilesForAttributes() { |
| const uint32_t numTestCases = mFdp->ConsumeIntegralInRange<uint32_t>(1, 10); |
| for (int i = 0; i < numTestCases; ++i) { |
| AudioProfileVector audioProfiles; |
| audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER; |
| attr.content_type = getValueFromVector<audio_content_type_t>(mFdp, kAudioContentTypes); |
| attr.usage = getValueFromVector<audio_usage_t>(mFdp, kAudioUsages); |
| attr.source = getValueFromVector<audio_source_t>(mFdp, kAudioSources); |
| attr.flags = getValueFromVector<audio_flags_mask_t>(mFdp, kAudioFlagMasks); |
| mManager->getDirectProfilesForAttributes(&attr, audioProfiles); |
| } |
| } |
| |
| void AudioPolicyManagerFuzzerDeviceConnection::process() { |
| if (initialize()) { |
| setDeviceConnectionState(); |
| explicitlyRoutingAfterConnection(); |
| fuzzGetDirectPlaybackSupport(); |
| fuzzGetDirectProfilesForAttributes(); |
| fuzzPatchCreation(); |
| } |
| } |
| |
| class AudioPolicyManagerTVFuzzer : public AudioPolicyManagerFuzzerWithConfigurationFile { |
| public: |
| explicit AudioPolicyManagerTVFuzzer(FuzzedDataProvider *fdp) |
| : AudioPolicyManagerFuzzerWithConfigurationFile(fdp){}; |
| void process() override; |
| |
| protected: |
| std::string getConfigFile(); |
| void testHDMIPortSelection(audio_output_flags_t flags); |
| |
| static inline const std::string sTvConfig = |
| AudioPolicyManagerTVFuzzer::sExecutableDir + "data/test_tv_apm_configuration.xml"; |
| }; |
| |
| std::string AudioPolicyManagerTVFuzzer::getConfigFile() { return fuzzXML(sTvConfig); } |
| |
| void AudioPolicyManagerTVFuzzer::testHDMIPortSelection(audio_output_flags_t flags) { |
| audio_devices_t audioDevice = getValueFromVector<audio_devices_t>(mFdp, kAudioDevices); |
| audio_format_t audioFormat = getValueFromVector<audio_format_t>(mFdp, kAudioFormats); |
| status_t ret = mManager->setDeviceConnectionState( |
| audioDevice, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, "" /*address*/, "" /*name*/, audioFormat); |
| if (ret != NO_ERROR) { |
| return; |
| } |
| audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; |
| audio_io_handle_t output; |
| audio_port_handle_t portId; |
| getOutputForAttr(&selectedDeviceId, getValueFromVector<audio_format_t>(mFdp, kAudioFormats), |
| getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks), |
| getValueFromVector<uint32_t>(mFdp, kSamplingRates), flags, &output, &portId); |
| sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output); |
| if (outDesc.get() == nullptr) { |
| return; |
| } |
| audio_port_v7 port = {}; |
| outDesc->toAudioPort(&port); |
| mManager->releaseOutput(portId); |
| mManager->setDeviceConnectionState(audioDevice, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, |
| "" /*address*/, "" /*name*/, audioFormat); |
| } |
| |
| void AudioPolicyManagerTVFuzzer::process() { |
| if (initialize()) { |
| testHDMIPortSelection(getValueFromVector<audio_output_flags_t>(mFdp, kAudioOutputFlags)); |
| fuzzPatchCreation(); |
| } |
| } |
| |
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
| if (size < 1) { |
| return 0; |
| } |
| FuzzedDataProvider fdp = FuzzedDataProvider(data, size); |
| while (fdp.remaining_bytes() > 0) { |
| AudioPolicyManagerFuzzer audioPolicyManagerFuzzer(&fdp); |
| audioPolicyManagerFuzzer.process(); |
| |
| AudioPolicyManagerFuzzerMsd audioPolicyManagerFuzzerMsd(&fdp); |
| audioPolicyManagerFuzzerMsd.process(); |
| |
| AudioPolicyManagerFuzzerWithConfigurationFile audioPolicyManagerFuzzerWithConfigurationFile( |
| &fdp); |
| audioPolicyManagerFuzzerWithConfigurationFile.process(); |
| |
| AudioPolicyManagerFuzzerDynamicPolicy audioPolicyManagerFuzzerDynamicPolicy(&fdp); |
| audioPolicyManagerFuzzerDynamicPolicy.process(); |
| |
| AudioPolicyManagerFuzzerDPNoRemoteSubmixModule |
| audioPolicyManagerFuzzerDPNoRemoteSubmixModule(&fdp); |
| audioPolicyManagerFuzzerDPNoRemoteSubmixModule.process(); |
| |
| AudioPolicyManagerFuzzerDPPlaybackReRouting audioPolicyManagerFuzzerDPPlaybackReRouting( |
| &fdp); |
| audioPolicyManagerFuzzerDPPlaybackReRouting.process(); |
| |
| AudioPolicyManagerFuzzerDPMixRecordInjection audioPolicyManagerFuzzerDPMixRecordInjection( |
| &fdp); |
| audioPolicyManagerFuzzerDPMixRecordInjection.process(); |
| |
| AudioPolicyManagerFuzzerDeviceConnection audioPolicyManagerFuzzerDeviceConnection(&fdp); |
| audioPolicyManagerFuzzerDeviceConnection.process(); |
| |
| AudioPolicyManagerTVFuzzer audioPolicyManagerTVFuzzer(&fdp); |
| audioPolicyManagerTVFuzzer.process(); |
| } |
| return 0; |
| } |