Merge "Define customized program selector/info comparator" into main
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;