Put tuner scan handling to a thread.

Bug: 210747502
Fix: 210747502
Test: atest android.media.tv.tuner.cts on AIDL and HILD HALs.
Test: atest VtsHalTvTunerTargetTest
Test: atest VtsHalTvTunerV1_1TargetTest
Test: atest VtsHalTvTunerV1_0TargetTest
Change-Id: Iead93df1dc09ef2a047893037ad2345ad4183b1e
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index d36841c..714612d 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -87,47 +87,60 @@
 ::ndk::ScopedAStatus Frontend::scan(const FrontendSettings& in_settings, FrontendScanType in_type) {
     ALOGV("%s", __FUNCTION__);
 
+    // If it's in middle of scanning, stop it first.
+    if (mScanThread.joinable()) {
+        mScanThread.join();
+    }
+
+    mFrontendSettings = in_settings;
+    mFrontendScanType = in_type;
+    mScanThread = std::thread(&Frontend::scanThreadLoop, this);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void Frontend::scanThreadLoop() {
     if (mIsLocked) {
         FrontendScanMessage msg;
         msg.set<FrontendScanMessage::Tag::isEnd>(true);
         mCallback->onScanMessage(FrontendScanMessageType::END, msg);
-        return ::ndk::ScopedAStatus::ok();
+        return;
     }
 
     int64_t frequency = 0;
-    switch (in_settings.getTag()) {
+    switch (mFrontendSettings.getTag()) {
         case FrontendSettings::Tag::analog:
-            frequency = in_settings.get<FrontendSettings::Tag::analog>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::analog>().frequency;
             break;
         case FrontendSettings::Tag::atsc:
-            frequency = in_settings.get<FrontendSettings::Tag::atsc>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc>().frequency;
             break;
         case FrontendSettings::Tag::atsc3:
-            frequency = in_settings.get<FrontendSettings::Tag::atsc3>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc3>().frequency;
             break;
         case FrontendSettings::Tag::dvbs:
-            frequency = in_settings.get<FrontendSettings::Tag::dvbs>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbs>().frequency;
             break;
         case FrontendSettings::Tag::dvbc:
-            frequency = in_settings.get<FrontendSettings::Tag::dvbc>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbc>().frequency;
             break;
         case FrontendSettings::Tag::dvbt:
-            frequency = in_settings.get<FrontendSettings::Tag::dvbt>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbt>().frequency;
             break;
         case FrontendSettings::Tag::isdbs:
-            frequency = in_settings.get<FrontendSettings::Tag::isdbs>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs>().frequency;
             break;
         case FrontendSettings::Tag::isdbs3:
-            frequency = in_settings.get<FrontendSettings::Tag::isdbs3>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs3>().frequency;
             break;
         case FrontendSettings::Tag::isdbt:
-            frequency = in_settings.get<FrontendSettings::Tag::isdbt>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbt>().frequency;
             break;
         default:
             break;
     }
 
-    if (in_type == FrontendScanType::SCAN_BLIND) {
+    if (mFrontendScanType == FrontendScanType::SCAN_BLIND) {
         frequency += 100 * 1000;
     }
 
@@ -250,13 +263,15 @@
         mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
         mIsLocked = true;
     }
-
-    return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus Frontend::stopScan() {
     ALOGV("%s", __FUNCTION__);
 
+    if (mScanThread.joinable()) {
+        mScanThread.join();
+    }
+
     mIsLocked = false;
     return ::ndk::ScopedAStatus::ok();
 }
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 66ae901..fdedf1e 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -19,6 +19,7 @@
 #include <aidl/android/hardware/tv/tuner/BnFrontend.h>
 #include <fstream>
 #include <iostream>
+#include <thread>
 #include "Tuner.h"
 
 using namespace std;
@@ -60,13 +61,17 @@
   private:
     virtual ~Frontend();
     bool supportsSatellite();
+    void scanThreadLoop();
+
     std::shared_ptr<IFrontendCallback> mCallback;
     std::shared_ptr<Tuner> mTuner;
     FrontendType mType = FrontendType::UNDEFINED;
     int32_t mId = 0;
     bool mIsLocked = false;
     int32_t mCiCamId;
-
+    std::thread mScanThread;
+    FrontendSettings mFrontendSettings;
+    FrontendScanType mFrontendScanType;
     std::ifstream mFrontendData;
 };