• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 <aidl/android/hardware/broadcastradio/IdentifierType.h>
20 #include <aidl/android/hardware/broadcastradio/Metadata.h>
21 #include <aidl/android/hardware/broadcastradio/ProgramFilter.h>
22 #include <aidl/android/hardware/broadcastradio/ProgramIdentifier.h>
23 #include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
24 #include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
25 #include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
26 #include <aidl/android/hardware/broadcastradio/Properties.h>
27 #include <aidl/android/hardware/broadcastradio/Result.h>
28 
29 #include <numeric>
30 #include <optional>
31 #include <thread>
32 #include <unordered_set>
33 
34 namespace aidl::android::hardware::broadcastradio {
35 
36 namespace utils {
37 
38 enum class FrequencyBand {
39     UNKNOWN,
40     FM,
41     AM_LW,
42     AM_MW,
43     AM_SW,
44 };
45 
46 class IdentifierIterator final
47     : public std::iterator<std::random_access_iterator_tag, ProgramIdentifier, ssize_t,
48                            const ProgramIdentifier*, const ProgramIdentifier&> {
49     using ptrType = typename std::iterator_traits<IdentifierIterator>::pointer;
50     using refType = typename std::iterator_traits<IdentifierIterator>::reference;
51     using diffType = typename std::iterator_traits<IdentifierIterator>::difference_type;
52 
53   public:
54     explicit IdentifierIterator(const ProgramSelector& sel);
55 
56     const IdentifierIterator operator++(int);
57     IdentifierIterator& operator++();
58     refType operator*() const;
59     inline ptrType operator->() const { return &operator*(); }
60     IdentifierIterator operator+(diffType v) const { return IdentifierIterator(mSel, mPos + v); }
61     bool operator==(const IdentifierIterator& rhs) const;
62     inline bool operator!=(const IdentifierIterator& rhs) const { return !operator==(rhs); };
63 
64   private:
65     explicit IdentifierIterator(const ProgramSelector& sel, size_t pos);
66 
67     std::reference_wrapper<const ProgramSelector> mSel;
68 
getSelector()69     const ProgramSelector& getSelector() const { return mSel.get(); }
70 
71     /** 0 is the primary identifier, 1-n are secondary identifiers. */
72     size_t mPos = 0;
73 };
74 
75 /**
76  * Convert Result to int
77  */
78 int32_t resultToInt(Result result);
79 
80 /**
81  * Guesses band from the frequency value.
82  *
83  * The band bounds are not exact to cover multiple regions.
84  * The function is biased towards success, i.e. it never returns
85  * FrequencyBand::UNKNOWN for correct frequency, but a result for
86  * incorrect one is undefined (it doesn't have to return UNKNOWN).
87  */
88 FrequencyBand getBand(int64_t frequency);
89 
90 /**
91  * Checks, if {@code pointer} tunes to {@channel}.
92  *
93  * For example, having a channel {AMFM_FREQUENCY_KHZ = 103.3}:
94  * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 0} can tune to this channel;
95  * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 1} can't.
96  *
97  * @param pointer selector we're trying to match against channel.
98  * @param channel existing channel.
99  */
100 bool tunesTo(const ProgramSelector& pointer, const ProgramSelector& channel);
101 
102 /**
103  * Checks whether a given program selector has the given ID (either primary or secondary).
104  */
105 bool hasId(const ProgramSelector& sel, const IdentifierType& type);
106 
107 /**
108  * Returns ID (either primary or secondary) for a given program selector.
109  *
110  * If the selector does not contain given type, returns kValueForNotFoundIdentifier
111  * and emits a warning.
112  */
113 int64_t getId(const ProgramSelector& sel, const IdentifierType& type);
114 
115 /**
116  * Returns ID (either primary or secondary) for a given program selector.
117  *
118  * If the selector does not contain given type, returns default value.
119  */
120 int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue);
121 
122 /**
123  * Returns all IDs of a given type.
124  */
125 std::vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type);
126 
127 /**
128  * Checks, if a given selector is supported by the radio module.
129  *
130  * @param prop Module description.
131  * @param sel The selector to check.
132  * @return True, if the selector is supported, false otherwise.
133  */
134 bool isSupported(const Properties& prop, const ProgramSelector& sel);
135 
136 bool isValid(const ProgramIdentifier& id);
137 bool isValid(const ProgramSelector& sel);
138 
139 ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
140 ProgramSelector makeSelectorAmfm(uint32_t frequency);
141 ProgramSelector makeSelectorDab(uint64_t sidExt);
142 ProgramSelector makeSelectorDab(uint64_t sidExt, uint32_t ensemble, uint64_t freq);
143 
144 bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
145 
146 struct ProgramInfoHasher {
147     size_t operator()(const ProgramInfo& info) const;
148 };
149 
150 struct ProgramInfoKeyEqual {
151     bool operator()(const ProgramInfo& info1, const ProgramInfo& info2) const;
152 };
153 
154 typedef std::unordered_set<ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> ProgramInfoSet;
155 
156 void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list);
157 
158 std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag);
159 
160 ProgramIdentifier makeHdRadioStationName(const std::string& name);
161 
162 template <typename aidl_type>
vectorToString(const std::vector<aidl_type> & in_values)163 inline std::string vectorToString(const std::vector<aidl_type>& in_values) {
164     return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
165                            [](const std::string& ls, const aidl_type& rs) {
166                                return ls + (ls.empty() ? "" : ",") + toString(rs);
167                            });
168 }
169 
170 IdentifierType getType(int typeAsInt);
171 
172 bool parseArgInt(const std::string& s, int* out);
173 
174 bool parseArgLong(const std::string& s, long* out);
175 
176 bool parseArgBool(const std::string& s, bool* out);
177 
178 bool parseArgDirection(const std::string& s, bool* out);
179 
180 bool parseArgIdentifierTypeArray(const std::string& s, std::vector<IdentifierType>* out);
181 
182 bool parseProgramIdentifierList(const std::string& s, std::vector<ProgramIdentifier>* out);
183 
184 }  // namespace utils
185 
186 utils::IdentifierIterator begin(const ProgramSelector& sel);
187 utils::IdentifierIterator end(const ProgramSelector& sel);
188 
189 }  // namespace aidl::android::hardware::broadcastradio
190