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 <optional>
20 #include <set>
21 #include <string>
22 #include <vector>
23 
24 #include <gtest/gtest.h>
25 #include <utils/Errors.h>
26 
27 // clang-format off
28 #include PATH(android/hardware/audio/FILE_VERSION/types.h)
29 #include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
30 // clang-format on
31 
32 #include <android_audio_policy_configuration_V7_0-enums.h>
33 #include <android_audio_policy_configuration_V7_0.h>
34 
35 using namespace ::android::hardware::audio::common::CPP_VERSION;
36 using namespace ::android::hardware::audio::CPP_VERSION;
37 namespace xsd {
38 using namespace ::android::audio::policy::configuration::CPP_VERSION;
39 using Module = Modules::Module;
40 }
41 
42 class PolicyConfig {
43   public:
PolicyConfig(const std::string & configFileName)44     explicit PolicyConfig(const std::string& configFileName)
45         : mConfigFileName{configFileName},
46           mFilePath{findExistingConfigurationFile(mConfigFileName)},
47           mConfig{xsd::read(mFilePath.c_str())} {
48         init();
49     }
PolicyConfig(const std::string & configPath,const std::string & configFileName)50     PolicyConfig(const std::string& configPath, const std::string& configFileName)
51         : mConfigFileName{configFileName},
52           mFilePath{configPath + "/" + mConfigFileName},
53           mConfig{xsd::read(mFilePath.c_str())} {
54         init();
55     }
getStatus()56     android::status_t getStatus() const { return mStatus; }
57     std::string getError() const;
getFilePath()58     const std::string& getFilePath() const { return mFilePath; }
59     const xsd::Module* getModuleFromName(const std::string& name) const;
getPrimaryModule()60     const xsd::Module* getPrimaryModule() const { return mPrimaryModule; }
getModulesWithDevicesNames()61     const std::set<std::string>& getModulesWithDevicesNames() const {
62         return mModulesWithDevicesNames;
63     }
getAttachedSinkDeviceForMixPort(const std::string & moduleName,const std::string & mixPortName)64     std::string getAttachedSinkDeviceForMixPort(const std::string& moduleName,
65                                                 const std::string& mixPortName) const {
66         return findAttachedDevice(getAttachedDevices(moduleName),
67                                   getSinkDevicesForMixPort(moduleName, mixPortName));
68     }
getAttachedSourceDeviceForMixPort(const std::string & moduleName,const std::string & mixPortName)69     std::string getAttachedSourceDeviceForMixPort(const std::string& moduleName,
70                                                   const std::string& mixPortName) const {
71         return findAttachedDevice(getAttachedDevices(moduleName),
72                                   getSourceDevicesForMixPort(moduleName, mixPortName));
73     }
74     std::optional<DeviceAddress> getSinkDeviceForMixPort(const std::string& moduleName,
75                                                          const std::string& mixPortName) const;
76     std::optional<DeviceAddress> getSourceDeviceForMixPort(const std::string& moduleName,
77                                                            const std::string& mixPortName) const;
78     bool haveInputProfilesInModule(const std::string& name) const;
79 
80   private:
81     static std::string findExistingConfigurationFile(const std::string& fileName);
82     std::string findAttachedDevice(const std::vector<std::string>& attachedDevices,
83                                    const std::set<std::string>& possibleDevices) const;
84     const std::vector<std::string>& getAttachedDevices(const std::string& moduleName) const;
85     std::optional<DeviceAddress> getDeviceAddressOfDevicePort(
86             const std::string& moduleName, const std::string& devicePortName) const;
87     std::string getDevicePortTagNameFromType(const std::string& moduleName,
88                                              const AudioDevice& deviceType) const;
89     std::set<std::string> getSinkDevicesForMixPort(const std::string& moduleName,
90                                                    const std::string& mixPortName) const;
91     std::set<std::string> getSourceDevicesForMixPort(const std::string& moduleName,
92                                                      const std::string& mixPortName) const;
93     void init();
94 
95     const std::string mConfigFileName;
96     const std::string mFilePath;
97     std::optional<xsd::AudioPolicyConfiguration> mConfig;
98     android::status_t mStatus = android::NO_INIT;
99     const xsd::Module* mPrimaryModule;
100     std::set<std::string> mModulesWithDevicesNames;
101 };
102