| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <aidl/android/hardware/broadcastradio/IdentifierType.h> |
| #include <aidl/android/hardware/broadcastradio/ProgramFilter.h> |
| #include <aidl/android/hardware/broadcastradio/ProgramIdentifier.h> |
| #include <aidl/android/hardware/broadcastradio/ProgramInfo.h> |
| #include <aidl/android/hardware/broadcastradio/ProgramListChunk.h> |
| #include <aidl/android/hardware/broadcastradio/ProgramSelector.h> |
| #include <aidl/android/hardware/broadcastradio/Properties.h> |
| #include <aidl/android/hardware/broadcastradio/Result.h> |
| |
| #include <numeric> |
| #include <optional> |
| #include <thread> |
| #include <unordered_set> |
| |
| namespace aidl::android::hardware::broadcastradio { |
| |
| namespace utils { |
| |
| enum class FrequencyBand { |
| UNKNOWN, |
| FM, |
| AM_LW, |
| AM_MW, |
| AM_SW, |
| }; |
| |
| class IdentifierIterator final |
| : public std::iterator<std::random_access_iterator_tag, ProgramIdentifier, ssize_t, |
| const ProgramIdentifier*, const ProgramIdentifier&> { |
| using ptrType = typename std::iterator_traits<IdentifierIterator>::pointer; |
| using refType = typename std::iterator_traits<IdentifierIterator>::reference; |
| using diffType = typename std::iterator_traits<IdentifierIterator>::difference_type; |
| |
| public: |
| explicit IdentifierIterator(const ProgramSelector& sel); |
| |
| const IdentifierIterator operator++(int); |
| IdentifierIterator& operator++(); |
| refType operator*() const; |
| inline ptrType operator->() const { return &operator*(); } |
| IdentifierIterator operator+(diffType v) const { return IdentifierIterator(mSel, mPos + v); } |
| bool operator==(const IdentifierIterator& rhs) const; |
| inline bool operator!=(const IdentifierIterator& rhs) const { return !operator==(rhs); }; |
| |
| private: |
| explicit IdentifierIterator(const ProgramSelector& sel, size_t pos); |
| |
| std::reference_wrapper<const ProgramSelector> mSel; |
| |
| const ProgramSelector& getSelector() const { return mSel.get(); } |
| |
| /** 0 is the primary identifier, 1-n are secondary identifiers. */ |
| size_t mPos = 0; |
| }; |
| |
| /** |
| * Convert Result to int |
| */ |
| int32_t resultToInt(Result result); |
| |
| /** |
| * Guesses band from the frequency value. |
| * |
| * The band bounds are not exact to cover multiple regions. |
| * The function is biased towards success, i.e. it never returns |
| * FrequencyBand::UNKNOWN for correct frequency, but a result for |
| * incorrect one is undefined (it doesn't have to return UNKNOWN). |
| */ |
| FrequencyBand getBand(int64_t frequency); |
| |
| /** |
| * Checks, if {@code pointer} tunes to {@channel}. |
| * |
| * For example, having a channel {AMFM_FREQUENCY_KHZ = 103.3}: |
| * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 0} can tune to this channel; |
| * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 1} can't. |
| * |
| * @param pointer selector we're trying to match against channel. |
| * @param channel existing channel. |
| */ |
| bool tunesTo(const ProgramSelector& pointer, const ProgramSelector& channel); |
| |
| /** |
| * Checks whether a given program selector has the given ID (either primary or secondary). |
| */ |
| bool hasId(const ProgramSelector& sel, const IdentifierType& type); |
| |
| /** |
| * Returns ID (either primary or secondary) for a given program selector. |
| * |
| * If the selector does not contain given type, returns kValueForNotFoundIdentifier |
| * and emits a warning. |
| */ |
| int64_t getId(const ProgramSelector& sel, const IdentifierType& type); |
| |
| /** |
| * Returns ID (either primary or secondary) for a given program selector. |
| * |
| * If the selector does not contain given type, returns default value. |
| */ |
| int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue); |
| |
| /** |
| * Returns all IDs of a given type. |
| */ |
| std::vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type); |
| |
| /** |
| * Checks, if a given selector is supported by the radio module. |
| * |
| * @param prop Module description. |
| * @param sel The selector to check. |
| * @return True, if the selector is supported, false otherwise. |
| */ |
| bool isSupported(const Properties& prop, const ProgramSelector& sel); |
| |
| bool isValid(const ProgramIdentifier& id); |
| bool isValid(const ProgramSelector& sel); |
| |
| ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value); |
| ProgramSelector makeSelectorAmfm(uint32_t frequency); |
| ProgramSelector makeSelectorDab(uint64_t sidExt); |
| ProgramSelector makeSelectorDab(uint64_t sidExt, uint32_t ensemble, uint64_t freq); |
| ProgramSelector makeSelectorHd(uint64_t stationId, uint64_t subChannel, uint64_t frequency); |
| |
| bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel); |
| |
| struct ProgramSelectorComparator { |
| bool operator()(const ProgramSelector& lhs, const ProgramSelector& rhs) const; |
| }; |
| |
| struct ProgramInfoComparator { |
| bool operator()(const ProgramInfo& lhs, const ProgramInfo& rhs) const; |
| }; |
| |
| struct ProgramInfoHasher { |
| size_t operator()(const ProgramInfo& info) const; |
| }; |
| |
| struct ProgramInfoKeyEqual { |
| bool operator()(const ProgramInfo& info1, const ProgramInfo& info2) const; |
| }; |
| |
| typedef std::unordered_set<ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> ProgramInfoSet; |
| |
| void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list); |
| |
| std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag); |
| |
| ProgramIdentifier makeHdRadioStationName(const std::string& name); |
| |
| uint32_t getHdFrequency(const ProgramSelector& sel); |
| |
| int getHdSubchannel(const ProgramSelector& sel); |
| |
| uint32_t getDabSId(const ProgramSelector& sel); |
| |
| int getDabEccCode(const ProgramSelector& sel); |
| |
| int getDabSCIdS(const ProgramSelector& sel); |
| |
| bool hasAmFmFrequency(const ProgramSelector& sel); |
| |
| uint32_t getAmFmFrequency(const ProgramSelector& sel); |
| |
| template <typename aidl_type> |
| inline std::string vectorToString(const std::vector<aidl_type>& in_values) { |
| return std::accumulate(std::begin(in_values), std::end(in_values), std::string{}, |
| [](const std::string& ls, const aidl_type& rs) { |
| return ls + (ls.empty() ? "" : ",") + toString(rs); |
| }); |
| } |
| |
| IdentifierType getType(int typeAsInt); |
| |
| bool parseArgInt(const std::string& s, int* out); |
| |
| bool parseArgLong(const std::string& s, long* out); |
| |
| bool parseArgBool(const std::string& s, bool* out); |
| |
| bool parseArgDirection(const std::string& s, bool* out); |
| |
| bool parseArgIdentifierTypeArray(const std::string& s, std::vector<IdentifierType>* out); |
| |
| bool parseProgramIdentifierList(const std::string& s, std::vector<ProgramIdentifier>* out); |
| |
| } // namespace utils |
| |
| utils::IdentifierIterator begin(const ProgramSelector& sel); |
| utils::IdentifierIterator end(const ProgramSelector& sel); |
| |
| } // namespace aidl::android::hardware::broadcastradio |