1 /* 2 * Copyright (C) 2017 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 #ifndef ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H 17 #define ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H 18 19 #include <android/hardware/broadcastradio/2.0/types.h> 20 #include <chrono> 21 #include <optional> 22 #include <queue> 23 #include <thread> 24 #include <unordered_set> 25 26 namespace android { 27 namespace hardware { 28 namespace broadcastradio { 29 namespace utils { 30 31 enum class FrequencyBand { 32 UNKNOWN, 33 FM, 34 AM_LW, 35 AM_MW, 36 AM_SW, 37 }; 38 39 V2_0::IdentifierType getType(uint32_t typeAsInt); 40 V2_0::IdentifierType getType(const V2_0::ProgramIdentifier& id); 41 42 class IdentifierIterator 43 : public std::iterator<std::random_access_iterator_tag, V2_0::ProgramIdentifier, ssize_t, 44 const V2_0::ProgramIdentifier*, const V2_0::ProgramIdentifier&> { 45 using traits = std::iterator_traits<IdentifierIterator>; 46 using ptr_type = typename traits::pointer; 47 using ref_type = typename traits::reference; 48 using diff_type = typename traits::difference_type; 49 50 public: 51 explicit IdentifierIterator(const V2_0::ProgramSelector& sel); 52 53 IdentifierIterator operator++(int); 54 IdentifierIterator& operator++(); 55 ref_type operator*() const; 56 inline ptr_type operator->() const { return &operator*(); } 57 IdentifierIterator operator+(diff_type v) const { return IdentifierIterator(mSel, mPos + v); } 58 bool operator==(const IdentifierIterator& rhs) const; 59 inline bool operator!=(const IdentifierIterator& rhs) const { return !operator==(rhs); }; 60 61 private: 62 explicit IdentifierIterator(const V2_0::ProgramSelector& sel, size_t pos); 63 64 std::reference_wrapper<const V2_0::ProgramSelector> mSel; 65 sel()66 const V2_0::ProgramSelector& sel() const { return mSel.get(); } 67 68 /** 0 is the primary identifier, 1-n are secondary identifiers. */ 69 size_t mPos = 0; 70 }; 71 72 /** 73 * Guesses band from the frequency value. 74 * 75 * The band bounds are not exact to cover multiple regions. 76 * The function is biased towards success, i.e. it never returns 77 * FrequencyBand::UNKNOWN for correct frequency, but a result for 78 * incorrect one is undefined (it doesn't have to return UNKNOWN). 79 */ 80 FrequencyBand getBand(uint64_t frequency); 81 82 /** 83 * Checks, if {@code pointer} tunes to {@channel}. 84 * 85 * For example, having a channel {AMFM_FREQUENCY = 103.3}: 86 * - selector {AMFM_FREQUENCY = 103.3, HD_SUBCHANNEL = 0} can tune to this channel; 87 * - selector {AMFM_FREQUENCY = 103.3, HD_SUBCHANNEL = 1} can't. 88 * 89 * @param pointer selector we're trying to match against channel. 90 * @param channel existing channel. 91 */ 92 bool tunesTo(const V2_0::ProgramSelector& pointer, const V2_0::ProgramSelector& channel); 93 94 bool hasId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type); 95 96 /** 97 * Returns ID (either primary or secondary) for a given program selector. 98 * 99 * If the selector does not contain given type, returns 0 and emits a warning. 100 */ 101 uint64_t getId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type); 102 103 /** 104 * Returns ID (either primary or secondary) for a given program selector. 105 * 106 * If the selector does not contain given type, returns default value. 107 */ 108 uint64_t getId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type, uint64_t defval); 109 110 /** 111 * Returns all IDs of a given type. 112 */ 113 std::vector<uint64_t> getAllIds(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type); 114 115 /** 116 * Checks, if a given selector is supported by the radio module. 117 * 118 * @param prop Module description. 119 * @param sel The selector to check. 120 * @return True, if the selector is supported, false otherwise. 121 */ 122 bool isSupported(const V2_0::Properties& prop, const V2_0::ProgramSelector& sel); 123 124 bool isValid(const V2_0::ProgramIdentifier& id); 125 bool isValid(const V2_0::ProgramSelector& sel); 126 127 V2_0::ProgramIdentifier make_identifier(V2_0::IdentifierType type, uint64_t value); 128 V2_0::ProgramSelector make_selector_amfm(uint32_t frequency); 129 V2_0::ProgramSelector make_selector_dab(uint32_t sidExt, uint32_t ensemble); 130 V2_0::Metadata make_metadata(V2_0::MetadataKey key, int64_t value); 131 V2_0::Metadata make_metadata(V2_0::MetadataKey key, std::string value); 132 133 bool satisfies(const V2_0::ProgramFilter& filter, const V2_0::ProgramSelector& sel); 134 135 struct ProgramInfoHasher { 136 size_t operator()(const V2_0::ProgramInfo& info) const; 137 }; 138 139 struct ProgramInfoKeyEqual { 140 bool operator()(const V2_0::ProgramInfo& info1, const V2_0::ProgramInfo& info2) const; 141 }; 142 143 typedef std::unordered_set<V2_0::ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> 144 ProgramInfoSet; 145 146 void updateProgramList(ProgramInfoSet& list, const V2_0::ProgramListChunk& chunk); 147 148 std::optional<std::string> getMetadataString(const V2_0::ProgramInfo& info, 149 const V2_0::MetadataKey key); 150 151 V2_0::ProgramIdentifier make_hdradio_station_name(const std::string& name); 152 153 } // namespace utils 154 155 namespace V2_0 { 156 157 utils::IdentifierIterator begin(const ProgramSelector& sel); 158 utils::IdentifierIterator end(const ProgramSelector& sel); 159 160 } // namespace V2_0 161 } // namespace broadcastradio 162 } // namespace hardware 163 } // namespace android 164 165 #endif // ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H 166