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