blob: c79c5c553300062688226ed7695614876576e051 [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>
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
34namespace aidl::android::hardware::broadcastradio {
35
36namespace utils {
37
38enum class FrequencyBand {
39 UNKNOWN,
40 FM,
41 AM_LW,
42 AM_MW,
43 AM_SW,
44};
45
46class 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
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 */
78int32_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 */
88FrequencyBand 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 */
100bool 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 */
105bool 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 */
113int64_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 */
120int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue);
121
122/**
123 * Returns all IDs of a given type.
124 */
125std::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 */
134bool isSupported(const Properties& prop, const ProgramSelector& sel);
135
136bool isValid(const ProgramIdentifier& id);
137bool isValid(const ProgramSelector& sel);
138
139ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
140ProgramSelector makeSelectorAmfm(int32_t frequency);
141ProgramSelector makeSelectorDab(int32_t sidExt, int32_t ensemble);
142
143bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
144
145struct ProgramInfoHasher {
146 size_t operator()(const ProgramInfo& info) const;
147};
148
149struct ProgramInfoKeyEqual {
150 bool operator()(const ProgramInfo& info1, const ProgramInfo& info2) const;
151};
152
153typedef std::unordered_set<ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> ProgramInfoSet;
154
155void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list);
156
157std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag);
158
159ProgramIdentifier makeHdRadioStationName(const std::string& name);
160
161template <typename aidl_type>
162inline std::string vectorToString(const std::vector<aidl_type>& in_values) {
163 return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
164 [](const std::string& ls, const aidl_type& rs) {
165 return ls + (ls.empty() ? "" : ",") + toString(rs);
166 });
167}
168
169} // namespace utils
170
171utils::IdentifierIterator begin(const ProgramSelector& sel);
172utils::IdentifierIterator end(const ProgramSelector& sel);
173
174} // namespace aidl::android::hardware::broadcastradio