1 /*
2  * Copyright (C) 2017 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 <functional>
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include <cutils/properties.h>
27 #include <tinyxml2.h>
28 
29 #include <aidl/android/hardware/audio/effect/Processing.h>
30 #include "effect-impl/EffectTypes.h"
31 
32 namespace aidl::android::hardware::audio::effect {
33 
34 /**
35  *  Library contains a mapping from library name to path.
36  *  Effect contains a mapping from effect name to Libraries and implementation UUID.
37  *  Pre/post processor contains a mapping from processing name to effect names.
38  */
39 class EffectConfig {
40   public:
41     explicit EffectConfig(const std::string& file);
42 
43     struct Library {
44         std::string name;  // library name
45         ::aidl::android::media::audio::common::AudioUuid uuid;  // implementation UUID
46         std::optional<::aidl::android::media::audio::common::AudioUuid> type;  // optional type UUID
47     };
48     // <effects>
49     struct EffectLibraries {
50         std::optional<struct Library> proxyLibrary;
51         std::vector<struct Library> libraries;
52     };
53 
getSkippedElements()54     int getSkippedElements() const { return mSkippedElements; }
getLibraryMap()55     const std::unordered_map<std::string, std::string> getLibraryMap() const { return mLibraryMap; }
getEffectsMap()56     const std::unordered_map<std::string, struct EffectLibraries> getEffectsMap() const {
57         return mEffectsMap;
58     }
59 
60     static bool findUuid(const std::pair<std::string, struct EffectLibraries>& effectElem,
61                          ::aidl::android::media::audio::common::AudioUuid* uuid);
62 
63     using ProcessingLibrariesMap = std::map<Processing::Type, std::vector<struct EffectLibraries>>;
64     const ProcessingLibrariesMap& getProcessingMap() const;
65 
66   private:
67 #ifdef __LP64__
68 #define SOUND_FX_PATH "/lib64/soundfx/"
69 #else
70 #define SOUND_FX_PATH "/lib/soundfx/"
71 #endif
72     static constexpr const char* kEffectLibPath[] =
73       { "/odm" SOUND_FX_PATH, "/vendor" SOUND_FX_PATH, "/system" SOUND_FX_PATH };
74 
75     static constexpr const char* kEffectLibApexPath = SOUND_FX_PATH;
76 #undef SOUND_FX_PATH
77 
78     int mSkippedElements;
79     /* Parsed Libraries result */
80     std::unordered_map<std::string, std::string> mLibraryMap;
81     /* Parsed Effects result */
82     std::unordered_map<std::string, struct EffectLibraries> mEffectsMap;
83     /**
84      * For parsed pre/post processing result: {key: AudioStreamType/AudioSource, value:
85      * EffectLibraries}
86      */
87     ProcessingLibrariesMap mProcessingMap;
88 
89     /** @return all `node`s children that are elements and match the tag if provided. */
90     std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> getChildren(
91             const tinyxml2::XMLNode& node, const char* childTag = nullptr);
92 
93     /** Parse a library xml note and push the result in mLibraryMap or return false on failure. */
94     bool parseLibrary(const tinyxml2::XMLElement& xml);
95 
96     /** Parse an effect from an xml element describing it.
97      * @return true and pushes the effect in mEffectsMap on success, false on failure.
98      */
99     bool parseEffect(const tinyxml2::XMLElement& xml);
100 
101     bool parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml);
102 
103     // Function to parse effect.library name and effect.uuid from xml
104     bool parseLibrary(const tinyxml2::XMLElement& xml, struct Library& library,
105                       bool isProxy = false);
106 
107     const char* dump(const tinyxml2::XMLElement& element,
108                      tinyxml2::XMLPrinter&& printer = {}) const;
109 
110     bool resolveLibrary(const std::string& path, std::string* resolvedPath);
111 
112     std::optional<Processing::Type> stringToProcessingType(Processing::Type::Tag typeTag,
113                                                            const std::string& type);
114 };
115 
116 }  // namespace aidl::android::hardware::audio::effect
117