1 /*
2  * Copyright (C) 2015 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 "Element.h"
20 #include "Stream.h"
21 #include "Strategy.h"
22 #include "Usage.h"
23 #include "InputSource.h"
24 #include <utils/Errors.h>
25 #include <system/audio.h>
26 #include <utils/Log.h>
27 #include <map>
28 #include <stdint.h>
29 #include <string>
30 
31 namespace android
32 {
33 namespace audio_policy
34 {
35 
36 /**
37  * Collection of policy element as a map indexed with a their UID type.
38  *
39  * @tparam Key type of the policy element indexing the collection.
40  *         Policy Element supported are:
41  *                      - Strategy
42  *                      - Stream
43  *                      - InputSource
44  *                      - Usage.
45  */
46 template <typename Key>
47 class Collection : public std::map<Key, Element<Key> *>
48 {
49 private:
50     typedef std::map<Key, Element<Key> *> Base;
51     typedef Element<Key> T;
52     typedef typename std::map<Key, T *>::iterator CollectionIterator;
53     typedef typename std::map<Key, T *>::const_iterator CollectionConstIterator;
54 
55 public:
Collection()56     Collection()
57     {
58         collectionSupported();
59     }
60 
61     /**
62      * Add a policy element to the collection. Policy elements are streams, strategies, input
63      * sources, ... Compile time error generated if called with not supported collection.
64      * It also set the key as the unique identifier of the policy element.
65      *
66      * @tparam Key indexing the collection of policy element.
67      * @param[in] name of the policy element to find.
68      * @param[in] key to be used to index this new policy element.
69      *
70      * @return NO_ERROR if the policy element has been successfully added to the collection.
71      */
add(const std::string & name,Key key)72     status_t add(const std::string &name, Key key)
73     {
74         if ((*this).find(key) != (*this).end()) {
75             ALOGW("%s: element %s already added", __FUNCTION__, name.c_str());
76             return BAD_VALUE;
77         }
78         (*this)[key] = new T(name);
79         ALOGD("%s: adding element %s to collection", __FUNCTION__, name.c_str());
80         return (*this)[key]->setIdentifier(key);
81     }
82 
83     /**
84      * Get a policy element from the collection by its key. Policy elements are streams, strategies,
85      * input sources, ... Compile time error generated if called with not supported collection.
86      *
87      * @tparam Key indexing the collection of policy element.
88      * @param[in] key of the policy element to find.
89      *
90      * @return valid pointer on policy element if found, NULL otherwise.
91      */
get(Key key)92     T *get(Key key) const
93     {
94         CollectionConstIterator it = (*this).find(key);
95         return (it == (*this).end()) ? NULL : it->second;
96     }
97 
98     /**
99      * Find a policy element from the collection by its name. Policy elements are streams,
100      * strategies, input sources, ...
101      * Compile time error generated if called with not supported collection.
102      *
103      * @tparam Key indexing the collection of policy element.
104      * @param[in] name of the policy element to find.
105      * @param[in] elementsMap maps of policy elements to search into.
106      *
107      * @return valid pointer on element if found, NULL otherwise.
108      */
findByName(const std::string & name)109     T *findByName(const std::string &name) const
110     {
111 
112         CollectionConstIterator it;
113         for (it = (*this).begin(); it != (*this).end(); ++it) {
114             T *element = it->second;
115             if (element->getName() == name) {
116                 return element;
117             }
118         }
119         return NULL;
120     }
121 
122     /**
123      * Removes all the elements from the list and destroy them.
124      */
clear()125     void clear()
126     {
127         CollectionIterator it;
128         for (it = (*this).begin(); it != (*this).end(); ++it) {
129             delete it->second;
130         }
131         Base::clear();
132     }
133 
134 private:
135     /**
136      * provide a compile time error if no specialization is provided for a given type.
137      *
138      * @tparam T: type of the policyElement. Policy Element supported are:
139      *                      - Strategy
140      *                      - Stream
141      *                      - InputSource
142      *                      - Usage.
143      */
144     struct collectionSupported;
145 };
146 
147 template <>
148 struct Collection<audio_stream_type_t>::collectionSupported {};
149 template <>
150 struct Collection<std::string>::collectionSupported {};
151 template <>
152 struct Collection<audio_usage_t>::collectionSupported {};
153 template <>
154 struct Collection<audio_source_t>::collectionSupported {};
155 template <>
156 struct Collection<routing_strategy>::collectionSupported {};
157 
158 typedef Collection<routing_strategy> StrategyCollection;
159 typedef Collection<audio_stream_type_t> StreamCollection;
160 typedef Collection<audio_usage_t> UsageCollection;
161 typedef Collection<audio_source_t> InputSourceCollection;
162 
163 } // namespace audio_policy
164 } // namespace android
165