• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <set>
20 #include <string>
21 
22 #include <AudioPolicyConfig.h>
23 #include <DeviceDescriptor.h>
24 #include <HwModule.h>
25 #include <gtest/gtest.h>
26 #include <system/audio_config.h>
27 
28 #include "DeviceManager.h"
29 
30 using ::android::sp;
31 using ::android::status_t;
32 
33 class PolicyConfig {
34   public:
PolicyConfig(const std::string & configPath,const std::string & configFileName)35     PolicyConfig(const std::string& configPath, const std::string& configFileName)
36         : mInitialFilePath(configPath.empty() ? configFileName
37                                               : configPath + "/" + configFileName) {
38         auto result = android::AudioPolicyConfig::loadFromCustomXmlConfigForVtsTests(
39                 configPath, configFileName);
40         if (result.ok()) {
41             mStatus = ::android::OK;
42             mConfig = result.value();
43             init();
44         } else {
45             mStatus = result.error();
46         }
47     }
getStatus()48     status_t getStatus() const { return mStatus; }
getError()49     std::string getError() const {
50         if (mConfig == nullptr) {
51             return std::string{"Could not find "} + mInitialFilePath +
52                    " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
53         } else {
54             return "Invalid config file: " + mConfig->getSource();
55         }
56     }
getFilePath()57     const std::string& getFilePath() const {
58         return mConfig != nullptr ? mConfig->getSource() : mInitialFilePath;
59     }
getModuleFromName(const std::string & name)60     sp<const android::HwModule> getModuleFromName(const std::string& name) const {
61         return mConfig->getHwModules().getModuleFromName(name.c_str());
62     }
getPrimaryModule()63     sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; }
getModulesWithDevicesNames()64     const std::set<std::string>& getModulesWithDevicesNames() const {
65         return mModulesWithDevicesNames;
66     }
getAttachedSinkDeviceForMixPort(const std::string & moduleName,const std::string & mixPortName)67     std::string getAttachedSinkDeviceForMixPort(const std::string& moduleName,
68                                                 const std::string& mixPortName) const {
69         return findAttachedDevice(getAttachedDevices(moduleName),
70                                   getSinkDevicesForMixPort(moduleName, mixPortName));
71     }
getAttachedSourceDeviceForMixPort(const std::string & moduleName,const std::string & mixPortName)72     std::string getAttachedSourceDeviceForMixPort(const std::string& moduleName,
73                                                   const std::string& mixPortName) const {
74         return findAttachedDevice(getAttachedDevices(moduleName),
75                                   getSourceDevicesForMixPort(moduleName, mixPortName));
76     }
getInputDevices()77     const android::DeviceVector& getInputDevices() const { return mConfig->getInputDevices(); }
getOutputDevices()78     const android::DeviceVector& getOutputDevices() const { return mConfig->getOutputDevices(); }
haveInputProfilesInModule(const std::string & name)79     bool haveInputProfilesInModule(const std::string& name) const {
80         auto module = getModuleFromName(name);
81         return module && !module->getInputProfiles().empty();
82     }
83 
84   private:
init()85     void init() {
86         mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
87         // Available devices are not 'attached' to modules at this moment.
88         // Need to go over available devices and find their module.
89         for (const auto& device : mConfig->getOutputDevices()) {
90             for (const auto& module : mConfig->getHwModules()) {
91                 if (module->getDeclaredDevices().indexOf(device) >= 0) {
92                     mModulesWithDevicesNames.insert(module->getName());
93                     mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName());
94                     break;
95                 }
96             }
97         }
98         for (const auto& device : mConfig->getInputDevices()) {
99             for (const auto& module : mConfig->getHwModules()) {
100                 if (module->getDeclaredDevices().indexOf(device) >= 0) {
101                     mModulesWithDevicesNames.insert(module->getName());
102                     mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName());
103                     break;
104                 }
105             }
106         }
107     }
findAttachedDevice(const std::vector<std::string> & attachedDevices,const std::set<std::string> & possibleDevices)108     std::string findAttachedDevice(const std::vector<std::string>& attachedDevices,
109                                    const std::set<std::string>& possibleDevices) const {
110         for (const auto& device : attachedDevices) {
111             if (possibleDevices.count(device)) return device;
112         }
113         return {};
114     }
getAttachedDevices(const std::string & moduleName)115     std::vector<std::string> getAttachedDevices(const std::string& moduleName) const {
116         if (auto iter = mAttachedDevicesPerModule.find(moduleName);
117             iter != mAttachedDevicesPerModule.end()) {
118             return iter->second;
119         }
120         return {};
121     }
getSinkDevicesForMixPort(const std::string & moduleName,const std::string & mixPortName)122     std::set<std::string> getSinkDevicesForMixPort(const std::string& moduleName,
123                                                    const std::string& mixPortName) const {
124         std::set<std::string> result;
125         auto module = getModuleFromName(moduleName);
126         if (module != nullptr) {
127             for (const auto& route : module->getRoutes()) {
128                 for (const auto& source : route->getSources()) {
129                     if (source->getTagName() == mixPortName) {
130                         result.insert(route->getSink()->getTagName());
131                     }
132                 }
133             }
134         }
135         return result;
136     }
getSourceDevicesForMixPort(const std::string & moduleName,const std::string & mixPortName)137     std::set<std::string> getSourceDevicesForMixPort(const std::string& moduleName,
138                                                      const std::string& mixPortName) const {
139         std::set<std::string> result;
140         auto module = getModuleFromName(moduleName);
141         if (module != nullptr) {
142             for (const auto& route : module->getRoutes()) {
143                 if (route->getSink()->getTagName() == mixPortName) {
144                     const auto& sources = route->getSources();
145                     std::transform(sources.begin(), sources.end(),
146                                    std::inserter(result, result.end()),
147                                    [](const auto& source) { return source->getTagName(); });
148                 }
149             }
150         }
151         return result;
152     }
153 
154     const std::string mInitialFilePath;
155     status_t mStatus = android::NO_INIT;
156     sp<android::AudioPolicyConfig> mConfig;
157     sp<const android::HwModule> mPrimaryModule;
158     std::set<std::string> mModulesWithDevicesNames;
159     std::map<std::string, std::vector<std::string>> mAttachedDevicesPerModule;
160 };
161