Implement HD signal acquisition state in radio HAL

Implemented HD signal acquisition status change using program info flag
in the reference broadcast radio HAL.

Bug: 309694368
Test: seek/tune to an HD radio station in radio KS app
Change-Id: Ibde570429d4c21b2f894f8658de1b37001541f3a
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index f82e767..3af560f 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -245,7 +245,10 @@
         }
         programInfo = makeSampleProgramInfo(sel);
     }
-    mIsTuneCompleted = true;
+    programInfo.infoFlags |= ProgramInfo::FLAG_SIGNAL_ACQUISITION;
+    if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+        mIsTuneCompleted = true;
+    }
     if (adjustAmFmRangeLocked()) {
         startProgramListUpdatesLocked({});
     }
@@ -276,6 +279,32 @@
     return ScopedAStatus::ok();
 }
 
+void BroadcastRadio::handleProgramInfoUpdateRadioCallback(
+        ProgramInfo programInfo, const std::shared_ptr<ITunerCallback>& callback) {
+    callback->onCurrentProgramInfoChanged(programInfo);
+    if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+        return;
+    }
+    ProgramSelector sel = programInfo.selector;
+    auto cancelTask = [sel, callback]() { callback->onTuneFailed(Result::CANCELED, sel); };
+    programInfo.infoFlags |= ProgramInfo::FLAG_HD_SIS_ACQUISITION;
+    auto sisAcquiredTask = [this, callback, programInfo, cancelTask]() {
+        callback->onCurrentProgramInfoChanged(programInfo);
+        auto audioAcquiredTask = [this, callback, programInfo]() {
+            ProgramInfo hdProgramInfoWithAudio = programInfo;
+            hdProgramInfoWithAudio.infoFlags |= ProgramInfo::FLAG_HD_AUDIO_ACQUISITION;
+            callback->onCurrentProgramInfoChanged(hdProgramInfoWithAudio);
+            lock_guard<mutex> lk(mMutex);
+            mIsTuneCompleted = true;
+        };
+        lock_guard<mutex> lk(mMutex);
+        mTuningThread->schedule(audioAcquiredTask, cancelTask, kTuneDelayTimeMs);
+    };
+
+    lock_guard<mutex> lk(mMutex);
+    mTuningThread->schedule(sisAcquiredTask, cancelTask, kTuneDelayTimeMs);
+}
+
 ScopedAStatus BroadcastRadio::tune(const ProgramSelector& program) {
     LOG(DEBUG) << __func__ << ": tune to " << program.toString() << "...";
 
@@ -308,7 +337,7 @@
             lock_guard<mutex> lk(mMutex);
             programInfo = tuneInternalLocked(program);
         }
-        callback->onCurrentProgramInfoChanged(programInfo);
+        handleProgramInfoUpdateRadioCallback(programInfo, callback);
     };
     auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
     mTuningThread->schedule(task, cancelTask, kTuneDelayTimeMs);
@@ -456,7 +485,7 @@
             lock_guard<mutex> lk(mMutex);
             programInfo = tuneInternalLocked(nextProgram.selector);
         }
-        callback->onCurrentProgramInfoChanged(programInfo);
+        handleProgramInfoUpdateRadioCallback(programInfo, callback);
     };
     mTuningThread->schedule(task, cancelTask, kSeekDelayTimeMs);
 
@@ -512,7 +541,7 @@
             lock_guard<mutex> lk(mMutex);
             programInfo = tuneInternalLocked(utils::makeSelectorAmfm(stepTo));
         }
-        callback->onCurrentProgramInfoChanged(programInfo);
+        handleProgramInfoUpdateRadioCallback(programInfo, callback);
     };
     auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
     mTuningThread->schedule(task, cancelTask, kStepDelayTimeMs);