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