1a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk/* 2a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Copyright (C) 2017 The Android Open Source Project 3a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 4a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Licensed under the Apache License, Version 2.0 (the "License"); 5a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * you may not use this file except in compliance with the License. 6a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * You may obtain a copy of the License at 7a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 8a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * http://www.apache.org/licenses/LICENSE-2.0 9a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 10a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Unless required by applicable law or agreed to in writing, software 11a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * distributed under the License is distributed on an "AS IS" BASIS, 12a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * See the License for the specific language governing permissions and 14a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * limitations under the License. 15a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk */ 1606100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk#ifndef ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H 1706100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk#define ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H 18a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 1906100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk#include <android/hardware/broadcastradio/2.0/types.h> 20a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk#include <chrono> 21c71624f8ed57962fe85656aac5b687d8394dfdc0Tomasz Wasilczyk#include <optional> 22a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk#include <queue> 23a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk#include <thread> 24bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk#include <unordered_set> 25a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 26a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace android { 27a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace hardware { 28a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace broadcastradio { 29a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace utils { 30a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 318b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczykenum class FrequencyBand { 328b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk UNKNOWN, 338b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk FM, 348b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk AM_LW, 358b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk AM_MW, 368b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk AM_SW, 378b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk}; 388b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk 39bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz WasilczykV2_0::IdentifierType getType(uint32_t typeAsInt); 4006100b39db99dd5b7860a6e981ba9f8d511793faTomasz WasilczykV2_0::IdentifierType getType(const V2_0::ProgramIdentifier& id); 415be4c2b6e3bd1c6c30b5ecf8debd1db441805a3eTomasz Wasilczyk 42bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczykclass IdentifierIterator 43bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk : public std::iterator<std::random_access_iterator_tag, V2_0::ProgramIdentifier, ssize_t, 44bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk const V2_0::ProgramIdentifier*, const V2_0::ProgramIdentifier&> { 45bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk using traits = std::iterator_traits<IdentifierIterator>; 46bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk using ptr_type = typename traits::pointer; 47bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk using ref_type = typename traits::reference; 48bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk using diff_type = typename traits::difference_type; 49bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 50bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk public: 51bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk explicit IdentifierIterator(const V2_0::ProgramSelector& sel); 52bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 53bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk IdentifierIterator operator++(int); 54bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk IdentifierIterator& operator++(); 55bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk ref_type operator*() const; 56bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk inline ptr_type operator->() const { return &operator*(); } 57bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk IdentifierIterator operator+(diff_type v) const { return IdentifierIterator(mSel, mPos + v); } 58bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk bool operator==(const IdentifierIterator& rhs) const; 59bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk inline bool operator!=(const IdentifierIterator& rhs) const { return !operator==(rhs); }; 60bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 61bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk private: 62bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk explicit IdentifierIterator(const V2_0::ProgramSelector& sel, size_t pos); 63bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 64bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk std::reference_wrapper<const V2_0::ProgramSelector> mSel; 65bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 66bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk const V2_0::ProgramSelector& sel() const { return mSel.get(); } 67bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 68bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk /** 0 is the primary identifier, 1-n are secondary identifiers. */ 69bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk size_t mPos = 0; 70bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk}; 71bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 72a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk/** 738b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk * Guesses band from the frequency value. 748b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk * 758b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk * The band bounds are not exact to cover multiple regions. 768b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk * The function is biased towards success, i.e. it never returns 778b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk * FrequencyBand::UNKNOWN for correct frequency, but a result for 788b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk * incorrect one is undefined (it doesn't have to return UNKNOWN). 798b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk */ 808b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz WasilczykFrequencyBand getBand(uint64_t frequency); 818b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk 828b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczyk/** 83a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Checks, if {@code pointer} tunes to {@channel}. 84a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 85a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * For example, having a channel {AMFM_FREQUENCY = 103.3}: 86a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * - selector {AMFM_FREQUENCY = 103.3, HD_SUBCHANNEL = 0} can tune to this channel; 87a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * - selector {AMFM_FREQUENCY = 103.3, HD_SUBCHANNEL = 1} can't. 88a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 89a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * @param pointer selector we're trying to match against channel. 90a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * @param channel existing channel. 91a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk */ 9206100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczykbool tunesTo(const V2_0::ProgramSelector& pointer, const V2_0::ProgramSelector& channel); 93a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 9406100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczykbool hasId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type); 95a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 96a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk/** 97a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Returns ID (either primary or secondary) for a given program selector. 98a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 99a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * If the selector does not contain given type, returns 0 and emits a warning. 100a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk */ 10106100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczykuint64_t getId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type); 102a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 103a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk/** 104a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Returns ID (either primary or secondary) for a given program selector. 105a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 106a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * If the selector does not contain given type, returns default value. 107a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk */ 10806100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczykuint64_t getId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type, uint64_t defval); 109a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 11006100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk/** 11131e8632d10fa1ea047557c496e0fe9329da75240Tomasz Wasilczyk * Returns all IDs of a given type. 11231e8632d10fa1ea047557c496e0fe9329da75240Tomasz Wasilczyk */ 11331e8632d10fa1ea047557c496e0fe9329da75240Tomasz Wasilczykstd::vector<uint64_t> getAllIds(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type); 11431e8632d10fa1ea047557c496e0fe9329da75240Tomasz Wasilczyk 11531e8632d10fa1ea047557c496e0fe9329da75240Tomasz Wasilczyk/** 11606100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk * Checks, if a given selector is supported by the radio module. 11706100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk * 11806100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk * @param prop Module description. 11906100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk * @param sel The selector to check. 12006100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk * @return True, if the selector is supported, false otherwise. 12106100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk */ 12206100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczykbool isSupported(const V2_0::Properties& prop, const V2_0::ProgramSelector& sel); 123a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 1248b70ee43b071df7d942ff695d6b87a1de7e3cf29Tomasz Wasilczykbool isValid(const V2_0::ProgramIdentifier& id); 12506100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczykbool isValid(const V2_0::ProgramSelector& sel); 126a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 12706100b39db99dd5b7860a6e981ba9f8d511793faTomasz WasilczykV2_0::ProgramIdentifier make_identifier(V2_0::IdentifierType type, uint64_t value); 12806100b39db99dd5b7860a6e981ba9f8d511793faTomasz WasilczykV2_0::ProgramSelector make_selector_amfm(uint32_t frequency); 12906100b39db99dd5b7860a6e981ba9f8d511793faTomasz WasilczykV2_0::Metadata make_metadata(V2_0::MetadataKey key, int64_t value); 13006100b39db99dd5b7860a6e981ba9f8d511793faTomasz WasilczykV2_0::Metadata make_metadata(V2_0::MetadataKey key, std::string value); 131a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 132bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczykbool satisfies(const V2_0::ProgramFilter& filter, const V2_0::ProgramSelector& sel); 133bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 134bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczykstruct ProgramInfoHasher { 135bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk size_t operator()(const V2_0::ProgramInfo& info) const; 136bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk}; 137bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 138bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczykstruct ProgramInfoKeyEqual { 139bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk bool operator()(const V2_0::ProgramInfo& info1, const V2_0::ProgramInfo& info2) const; 140bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk}; 141bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 142bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyktypedef std::unordered_set<V2_0::ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> 143bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk ProgramInfoSet; 144bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 145bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczykvoid updateProgramList(ProgramInfoSet& list, const V2_0::ProgramListChunk& chunk); 146bceb88585dc6c89c6689956b8354b630c8425ae5Tomasz Wasilczyk 147c71624f8ed57962fe85656aac5b687d8394dfdc0Tomasz Wasilczykstd::optional<std::string> getMetadataString(const V2_0::ProgramInfo& info, 148c71624f8ed57962fe85656aac5b687d8394dfdc0Tomasz Wasilczyk const V2_0::MetadataKey key); 149c71624f8ed57962fe85656aac5b687d8394dfdc0Tomasz Wasilczyk 150c71624f8ed57962fe85656aac5b687d8394dfdc0Tomasz WasilczykV2_0::ProgramIdentifier make_hdradio_station_name(const std::string& name); 151c71624f8ed57962fe85656aac5b687d8394dfdc0Tomasz Wasilczyk 152a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace utils 153cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczyk 154cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczyknamespace V2_0 { 155cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczyk 156cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczykutils::IdentifierIterator begin(const ProgramSelector& sel); 157cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczykutils::IdentifierIterator end(const ProgramSelector& sel); 158cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczyk 159cea64964dcdcaaed8dfb9f96ac1b35429e9e703cTomasz Wasilczyk} // namespace V2_0 160a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace broadcastradio 161a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace hardware 162a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace android 163a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 16406100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk#endif // ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H 165