Define customized program selector/info comparator

Define customized comparators for program selector and program info
in broadcast radio AIDL HAL utils library, which can be used to
sort program list by the order of frequency in HAL implementation of
devices other than emulator.

Bug: 315389663
Test: atest VtsHalBroadcastradioAidlTargetTest
Change-Id: Ie8de342f3c123d896589751a6244f871ee07eb81
diff --git a/broadcastradio/aidl/default/VirtualProgram.cpp b/broadcastradio/aidl/default/VirtualProgram.cpp
index dca431d..fab4a49 100644
--- a/broadcastradio/aidl/default/VirtualProgram.cpp
+++ b/broadcastradio/aidl/default/VirtualProgram.cpp
@@ -93,49 +93,7 @@
 }
 
 bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
-    auto& l = lhs.selector;
-    auto& r = rhs.selector;
-
-    if ((utils::hasId(l, IdentifierType::AMFM_FREQUENCY_KHZ) ||
-         l.primaryId.type == IdentifierType::HD_STATION_ID_EXT) &&
-        (utils::hasId(r, IdentifierType::AMFM_FREQUENCY_KHZ) ||
-         r.primaryId.type == IdentifierType::HD_STATION_ID_EXT)) {
-        uint32_t freq1 = utils::getAmFmFrequency(l);
-        int subChannel1 = l.primaryId.type == IdentifierType::HD_STATION_ID_EXT
-                                  ? utils::getHdSubchannel(l)
-                                  : 0;
-        uint32_t freq2 = utils::getAmFmFrequency(r);
-        int subChannel2 = r.primaryId.type == IdentifierType::HD_STATION_ID_EXT
-                                  ? utils::getHdSubchannel(r)
-                                  : 0;
-        return freq1 < freq2 || (freq1 == freq2 && (l.primaryId.type < r.primaryId.type ||
-                                                    subChannel1 < subChannel2));
-    } else if (l.primaryId.type == IdentifierType::DAB_SID_EXT &&
-               r.primaryId.type == IdentifierType::DAB_SID_EXT) {
-        uint64_t dabFreq1 = utils::getId(l, IdentifierType::DAB_FREQUENCY_KHZ);
-        uint64_t dabFreq2 = utils::getId(r, IdentifierType::DAB_FREQUENCY_KHZ);
-        if (dabFreq1 != dabFreq2) {
-            return dabFreq1 < dabFreq2;
-        }
-        uint32_t ecc1 = utils::getDabEccCode(l);
-        uint32_t ecc2 = utils::getDabEccCode(r);
-        if (ecc1 != ecc2) {
-            return ecc1 < ecc2;
-        }
-        uint64_t dabEnsemble1 = utils::getId(l, IdentifierType::DAB_ENSEMBLE);
-        uint64_t dabEnsemble2 = utils::getId(r, IdentifierType::DAB_ENSEMBLE);
-        if (dabEnsemble1 != dabEnsemble2) {
-            return dabEnsemble1 < dabEnsemble2;
-        }
-        uint32_t sId1 = utils::getDabSId(l);
-        uint32_t sId2 = utils::getDabSId(r);
-        return sId1 < sId2 || (sId1 == sId2 && utils::getDabSCIdS(l) < utils::getDabSCIdS(r));
-    }
-
-    if (l.primaryId.type != r.primaryId.type) {
-        return l.primaryId.type < r.primaryId.type;
-    }
-    return l.primaryId.value < r.primaryId.value;
+    return utils::ProgramSelectorComparator()(lhs.selector, rhs.selector);
 }
 
 }  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index bb43903..3ced685 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -143,6 +143,14 @@
 
 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;
 };
diff --git a/broadcastradio/common/utilsaidl/src/Utils.cpp b/broadcastradio/common/utilsaidl/src/Utils.cpp
index 76c3c6a..b647442 100644
--- a/broadcastradio/common/utilsaidl/src/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/src/Utils.cpp
@@ -355,6 +355,55 @@
     return true;
 }
 
+bool ProgramSelectorComparator::operator()(const ProgramSelector& lhs,
+                                           const ProgramSelector& rhs) const {
+    if ((utils::hasId(lhs, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+         lhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT) &&
+        (utils::hasId(rhs, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+         rhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT)) {
+        uint32_t freq1 = utils::getAmFmFrequency(lhs);
+        int subChannel1 = lhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT
+                                  ? utils::getHdSubchannel(lhs)
+                                  : 0;
+        uint32_t freq2 = utils::getAmFmFrequency(rhs);
+        int subChannel2 = rhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT
+                                  ? utils::getHdSubchannel(rhs)
+                                  : 0;
+        return freq1 < freq2 || (freq1 == freq2 && (lhs.primaryId.type < rhs.primaryId.type ||
+                                                    subChannel1 < subChannel2));
+    }
+    if (lhs.primaryId.type == IdentifierType::DAB_SID_EXT &&
+        rhs.primaryId.type == IdentifierType::DAB_SID_EXT) {
+        uint64_t dabFreq1 = utils::getId(lhs, IdentifierType::DAB_FREQUENCY_KHZ);
+        uint64_t dabFreq2 = utils::getId(rhs, IdentifierType::DAB_FREQUENCY_KHZ);
+        if (dabFreq1 != dabFreq2) {
+            return dabFreq1 < dabFreq2;
+        }
+        uint32_t ecc1 = utils::getDabEccCode(lhs);
+        uint32_t ecc2 = utils::getDabEccCode(rhs);
+        if (ecc1 != ecc2) {
+            return ecc1 < ecc2;
+        }
+        uint64_t dabEnsemble1 = utils::getId(lhs, IdentifierType::DAB_ENSEMBLE);
+        uint64_t dabEnsemble2 = utils::getId(rhs, IdentifierType::DAB_ENSEMBLE);
+        if (dabEnsemble1 != dabEnsemble2) {
+            return dabEnsemble1 < dabEnsemble2;
+        }
+        uint32_t sId1 = utils::getDabSId(lhs);
+        uint32_t sId2 = utils::getDabSId(rhs);
+        return sId1 < sId2 || (sId1 == sId2 && utils::getDabSCIdS(lhs) < utils::getDabSCIdS(rhs));
+    }
+
+    if (lhs.primaryId.type != rhs.primaryId.type) {
+        return lhs.primaryId.type < rhs.primaryId.type;
+    }
+    return lhs.primaryId.value < rhs.primaryId.value;
+}
+
+bool ProgramInfoComparator::operator()(const ProgramInfo& lhs, const ProgramInfo& rhs) const {
+    return ProgramSelectorComparator()(lhs.selector, rhs.selector);
+}
+
 size_t ProgramInfoHasher::operator()(const ProgramInfo& info) const {
     const ProgramIdentifier& id = info.selector.primaryId;