Fix boadcastradio HAL 1.1 tuneByProgramSelector implementation.

It was not compliant with the HAL definition - it didn't auto-change
band if necessary.

Bug: 74353024
Test: manual
Change-Id: I015faffc42778fa27fca3030306f31b0abe409c7
diff --git a/broadcastradio/1.1/default/Tuner.cpp b/broadcastradio/1.1/default/Tuner.cpp
index 2be070d..ae01879 100644
--- a/broadcastradio/1.1/default/Tuner.cpp
+++ b/broadcastradio/1.1/default/Tuner.cpp
@@ -58,8 +58,10 @@
     milliseconds tune = 150ms;
 } gDefaultDelay;
 
-Tuner::Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& callback)
-    : mClassId(classId),
+Tuner::Tuner(const sp<BroadcastRadio> module, V1_0::Class classId,
+             const sp<V1_0::ITunerCallback>& callback)
+    : mModule(module),
+      mClassId(classId),
       mCallback(callback),
       mCallback1_1(V1_1::ITunerCallback::castFrom(callback).withDefault(nullptr)),
       mVirtualRadio(getRadio(classId)),
@@ -71,6 +73,33 @@
     mThread.cancelAll();
 }
 
+void Tuner::setConfigurationInternalLocked(const BandConfig& config) {
+    mAmfmConfig = config;
+    mAmfmConfig.antennaConnected = true;
+    mCurrentProgram = utils::make_selector(mAmfmConfig.type, mAmfmConfig.lowerLimit);
+
+    if (utils::isFm(mAmfmConfig.type)) {
+        mVirtualRadio = std::ref(getFmRadio());
+    } else {
+        mVirtualRadio = std::ref(getAmRadio());
+    }
+
+    mIsAmfmConfigSet = true;
+    mCallback->configChange(Result::OK, mAmfmConfig);
+}
+
+bool Tuner::autoConfigureLocked(uint64_t frequency) {
+    for (auto&& config : mModule->getAmFmBands()) {
+        // The check here is rather poor, but it's enough for default implementation.
+        if (config.lowerLimit <= frequency && config.upperLimit >= frequency) {
+            ALOGI("Auto-switching band to %s", toString(config).c_str());
+            setConfigurationInternalLocked(config);
+            return true;
+        }
+    }
+    return false;
+}
+
 Return<Result> Tuner::setConfiguration(const BandConfig& config) {
     ALOGV("%s", __func__);
     lock_guard<mutex> lk(mMut);
@@ -85,19 +114,7 @@
     auto task = [this, config]() {
         ALOGI("Setting AM/FM config");
         lock_guard<mutex> lk(mMut);
-
-        mAmfmConfig = move(config);
-        mAmfmConfig.antennaConnected = true;
-        mCurrentProgram = utils::make_selector(mAmfmConfig.type, mAmfmConfig.lowerLimit);
-
-        if (utils::isFm(mAmfmConfig.type)) {
-            mVirtualRadio = std::ref(getFmRadio());
-        } else {
-            mVirtualRadio = std::ref(getAmRadio());
-        }
-
-        mIsAmfmConfigSet = true;
-        mCallback->configChange(Result::OK, mAmfmConfig);
+        setConfigurationInternalLocked(config);
     };
     mThread.schedule(task, gDefaultDelay.config);
 
@@ -276,7 +293,7 @@
 
         auto freq = utils::getId(sel, IdentifierType::AMFM_FREQUENCY);
         if (freq < mAmfmConfig.lowerLimit || freq > mAmfmConfig.upperLimit) {
-            return Result::INVALID_ARGUMENTS;
+            if (!autoConfigureLocked(freq)) return Result::INVALID_ARGUMENTS;
         }
     } else if (programType == ProgramType::DAB) {
         if (!utils::hasId(sel, IdentifierType::DAB_SIDECC)) return Result::INVALID_ARGUMENTS;