Allow secondary ids missing for DAB selector

Sometimes DAB program selector used in tuning does not have secondary
identifiers such as ensemble and frequency, and HAL will automatically
selector a DAB station with specified ensemble and frequency. Thus,
secondary ids in DAB program selector are not mandatory in HAL. Also
updated broadcast radio AIDL HAL documentation.

Bug: 273804622
Test: atest VtsHalBroadcastradioAidlTargetTest
Change-Id: If05b7eeb79e299667c3a64bf8b931bb6396f9045
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
index a3086c6..f4c6fd3 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
@@ -73,14 +73,15 @@
     /**
      * De-emphasis filter supported/configured.
      *
-     * It is a bitset of de-emphasis values (DEEMPHASIS_D50 and DEEMPHASIS_D75).
+     * It can be a combination of de-emphasis values ({@link #DEEMPHASIS_D50} and
+     * {@link #DEEMPHASIS_D75}).
      */
     int fmDeemphasis;
 
     /**
      * RDS/RBDS variant supported/configured.
      *
-     * It is a bitset of RDS values (RDS and RBDS).
+     * It can be a combination of RDS values ({@link #RDS} and {@link #RBDS}).
      */
     int fmRds;
 }
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
index d650239..7632c81 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -150,6 +150,10 @@
 
     /**
      * Program flags.
+     *
+     * It can be a combination of {@link #FLAG_LIVE}, {@link #FLAG_MUTED},
+     * {@link #FLAG_TRAFFIC_PROGRAM}, {@link #FLAG_TRAFFIC_ANNOUNCEMENT},
+     * {@link #FLAG_TUNABLE}, and {@link #FLAG_STEREO}.
      */
     int infoFlags;
 
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
index 93b0e12..71b824b 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -51,8 +51,7 @@
      *  - analogue AM/FM: AMFM_FREQUENCY_KHZ;
      *  - FM RDS: RDS_PI;
      *  - HD Radio: HD_STATION_ID_EXT;
-     *  - DAB/DMB: DAB_SID_EXT (when used, DAB_ENSEMBLE and DAB_FREQUENCY_KHZ
-     *    must present in secondaryIds);
+     *  - DAB/DMB: DAB_SID_EXT;
      *  - Digital Radio Mondiale: DRMO_SERVICE_ID;
      *  - SiriusXM: SXM_SERVICE_ID;
      *  - vendor-specific: VENDOR_START..VENDOR_END.
@@ -63,13 +62,16 @@
      * Secondary program identifiers.
      *
      * These identifiers are supplementary and can speed up tuning process,
-     * but the primary ID must be sufficient (i.e. RDS PI is enough to select
+     * but the primary ID should be sufficient (i.e. RDS PI is enough to select
      * a station from the list after a full band scan).
      *
      * Two selectors with different secondary IDs, but the same primary ID are
      * considered equal. In particular, secondary IDs array may get updated for
      * an entry on the program list (ie. when a better frequency for a given
      * station is found).
+     *
+     * If DAB_SID_EXT is used as primaryId, using DAB_ENSEMBLE or DAB_FREQUENCY_KHZ
+     * as secondray identifiers can uniquely identify the DAB station.
      */
     ProgramIdentifier[] secondaryIds;
 }
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index 36520fb..c0c475a 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -589,10 +589,11 @@
     }
     ProgramSelector sel = {};
     if (isDab) {
-        if (numArgs != 5) {
+        if (numArgs != 5 && numArgs != 3) {
             dprintf(fd,
                     "Invalid number of arguments: please provide "
-                    "--tune dab <SID> <ENSEMBLE> <FREQUENCY>\n");
+                    "--tune dab <SID> <ENSEMBLE> <FREQUENCY> or "
+                    "--tune dab <SID>\n");
             return STATUS_BAD_VALUE;
         }
         int sid;
@@ -600,17 +601,21 @@
             dprintf(fd, "Non-integer sid provided with tune: %s\n", args[2]);
             return STATUS_BAD_VALUE;
         }
-        int ensemble;
-        if (!utils::parseArgInt(string(args[3]), &ensemble)) {
-            dprintf(fd, "Non-integer ensemble provided with tune: %s\n", args[3]);
-            return STATUS_BAD_VALUE;
+        if (numArgs == 3) {
+            sel = utils::makeSelectorDab(sid);
+        } else {
+            int ensemble;
+            if (!utils::parseArgInt(string(args[3]), &ensemble)) {
+                dprintf(fd, "Non-integer ensemble provided with tune: %s\n", args[3]);
+                return STATUS_BAD_VALUE;
+            }
+            int freq;
+            if (!utils::parseArgInt(string(args[4]), &freq)) {
+                dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[4]);
+                return STATUS_BAD_VALUE;
+            }
+            sel = utils::makeSelectorDab(sid, ensemble, freq);
         }
-        int freq;
-        if (!utils::parseArgInt(string(args[4]), &freq)) {
-            dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[4]);
-            return STATUS_BAD_VALUE;
-        }
-        sel = utils::makeSelectorDab(sid, ensemble, freq);
     } else {
         if (numArgs != 3) {
             dprintf(fd, "Invalid number of arguments: please provide --tune amfm <FREQUENCY>\n");
diff --git a/broadcastradio/common/utilsaidl/Utils.cpp b/broadcastradio/common/utilsaidl/Utils.cpp
index ad82366..0551bad 100644
--- a/broadcastradio/common/utilsaidl/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/Utils.cpp
@@ -136,9 +136,18 @@
             return getHdSubchannel(b) == 0 &&
                    haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY_KHZ);
         case IdentifierType::DAB_SID_EXT:
-            return haveEqualIds(a, b, IdentifierType::DAB_SID_EXT) &&
-                   haveEqualIds(a, b, IdentifierType::DAB_ENSEMBLE) &&
-                   haveEqualIds(a, b, IdentifierType::DAB_FREQUENCY_KHZ);
+            if (!haveEqualIds(a, b, IdentifierType::DAB_SID_EXT)) {
+                return false;
+            }
+            if (hasId(a, IdentifierType::DAB_ENSEMBLE) &&
+                !haveEqualIds(a, b, IdentifierType::DAB_ENSEMBLE)) {
+                return false;
+            }
+            if (hasId(a, IdentifierType::DAB_FREQUENCY_KHZ) &&
+                !haveEqualIds(a, b, IdentifierType::DAB_FREQUENCY_KHZ)) {
+                return false;
+            }
+            return true;
         case IdentifierType::DRMO_SERVICE_ID:
             return haveEqualIds(a, b, IdentifierType::DRMO_SERVICE_ID);
         case IdentifierType::SXM_SERVICE_ID:
@@ -289,25 +298,7 @@
          sel.primaryId.type > IdentifierType::VENDOR_END)) {
         return false;
     }
-    if (!isValid(sel.primaryId)) {
-        return false;
-    }
-
-    bool isDab = sel.primaryId.type == IdentifierType::DAB_SID_EXT;
-    bool hasDabEnsemble = false;
-    bool hasDabFrequency = false;
-    for (auto it = sel.secondaryIds.begin(); it != sel.secondaryIds.end(); it++) {
-        if (!isValid(*it)) {
-            return false;
-        }
-        if (isDab && it->type == IdentifierType::DAB_ENSEMBLE) {
-            hasDabEnsemble = true;
-        }
-        if (isDab && it->type == IdentifierType::DAB_FREQUENCY_KHZ) {
-            hasDabFrequency = true;
-        }
-    }
-    return !isDab || (hasDabEnsemble && hasDabFrequency);
+    return isValid(sel.primaryId);
 }
 
 ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value) {
@@ -320,6 +311,12 @@
     return sel;
 }
 
+ProgramSelector makeSelectorDab(int64_t sidExt) {
+    ProgramSelector sel = {};
+    sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
+    return sel;
+}
+
 ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq) {
     ProgramSelector sel = {};
     sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index beebd03..ad075f2 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -138,6 +138,7 @@
 
 ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
 ProgramSelector makeSelectorAmfm(int32_t frequency);
+ProgramSelector makeSelectorDab(int64_t sidExt);
 ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq);
 
 bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);