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