Update Tuner Resources in Tuner Service

Test: atest android.media.tv.tuner.cts
Bug: 159067322
Change-Id: Ieff22f0fe50c0515ca2545485d62defaaa47b88d
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index 6a21b0e..b9e26c4 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -79,6 +79,8 @@
         "libmedia",
         "libutils",
         "tv_tuner_aidl_interface-ndk_platform",
+        "tv_tuner_resource_manager_aidl_interface-ndk_platform",
+        "tv_tuner_resource_manager_aidl_interface-cpp",
     ],
 
     static_libs: [
@@ -113,6 +115,8 @@
         "liblog",
         "libtunerservice",
         "libutils",
+        "tv_tuner_resource_manager_aidl_interface-ndk_platform",
+        "tv_tuner_resource_manager_aidl_interface-cpp",
     ],
 
     static_libs: [
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index cbcea91..da9f541 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -34,7 +34,6 @@
 using ::aidl::android::media::tv::tuner::TunerFrontendIsdbs3Capabilities;
 using ::aidl::android::media::tv::tuner::TunerFrontendIsdbsCapabilities;
 using ::aidl::android::media::tv::tuner::TunerFrontendIsdbtCapabilities;
-using ::android::hardware::hidl_vec;
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
@@ -77,13 +76,10 @@
     if (!getITuner()) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::NOT_INITIALIZED));
     }
-    if (mDemux != nullptr) {
-        *_aidl_return = mDemux->ref<ITunerDemux>();
-        return Status::ok();
-    }
     Result res;
     uint32_t id;
     sp<IDemux> demuxSp = nullptr;
+    shared_ptr<ITunerDemux> tunerDemux = nullptr;
     mTuner->openDemux([&](Result r, uint32_t demuxId, const sp<IDemux>& demux) {
         demuxSp = demux;
         id = demuxId;
@@ -91,13 +87,12 @@
         ALOGD("open demux, id = %d", demuxId);
     });
     if (res == Result::SUCCESS) {
-        mDemux = ::ndk::SharedRefBase::make<TunerDemux>(demuxSp, id);
-        *_aidl_return = mDemux->ref<ITunerDemux>();
+        tunerDemux = ::ndk::SharedRefBase::make<TunerDemux>(demuxSp, id);
+        *_aidl_return = tunerDemux->ref<ITunerDemux>();
         return Status::ok();
     }
 
     ALOGD("open demux failed, res = %d", res);
-    mDemux = nullptr;
     return Status::fromServiceSpecificError(static_cast<int32_t>(res));
 }
 
@@ -141,17 +136,13 @@
     return getQueueDescResult;
 }
 
-Status TunerService::getFrontendIds(vector<int32_t>* ids, int32_t* /* _aidl_return */) {
+Status TunerService::getFrontendIds(vector<int32_t>* ids) {
     if (!getITuner()) {
         return Status::fromServiceSpecificError(
                 static_cast<int32_t>(Result::NOT_INITIALIZED));
     }
     hidl_vec<FrontendId> feIds;
-    Result res;
-    mTuner->getFrontendIds([&](Result r, const hidl_vec<FrontendId>& frontendIds) {
-        feIds = frontendIds;
-        res = r;
-    });
+    Result res = getHidlFrontendIds(feIds);
     if (res != Result::SUCCESS) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
@@ -169,13 +160,9 @@
                 static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
-    Result res;
     FrontendInfo info;
     int feId = getResourceIdFromHandle(frontendHandle, FRONTEND);
-    mTuner->getFrontendInfo(feId, [&](Result r, const FrontendInfo& feInfo) {
-        info = feInfo;
-        res = r;
-    });
+    Result res = getHidlFrontendInfo(feId, info);
     if (res != Result::SUCCESS) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
@@ -224,8 +211,8 @@
 }
 
 Status TunerService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
-    if (mTuner == nullptr) {
-        ALOGE("ITuner service is not init.");
+    if (!getITuner()) {
+        ALOGD("get ITuner failed");
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
@@ -245,8 +232,8 @@
 }
 
 Status TunerService::openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) {
-    if (mTuner == nullptr) {
-        ALOGE("ITuner service is not init.");
+    if (!getITuner()) {
+        ALOGE("get ITuner failed");
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
@@ -266,6 +253,96 @@
     return Status::ok();
 }
 
+Status TunerService::updateTunerResources() {
+    if (!getITuner()) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    // Connect with Tuner Resource Manager.
+    ::ndk::SpAIBinder binder(AServiceManager_getService("tv_tuner_resource_mgr"));
+    mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
+
+    updateFrontendResources();
+    updateLnbResources();
+    // TODO: update Demux, Descrambler.
+    return Status::ok();
+}
+
+void TunerService::updateFrontendResources() {
+    hidl_vec<FrontendId> ids;
+    Result res = getHidlFrontendIds(ids);
+    if (res != Result::SUCCESS) {
+        return;
+    }
+    vector<TunerFrontendInfo> infos;
+    for (int i = 0; i < ids.size(); i++) {
+        FrontendInfo frontendInfo;
+        Result res = getHidlFrontendInfo((int)ids[i], frontendInfo);
+        if (res != Result::SUCCESS) {
+            continue;
+        }
+        TunerFrontendInfo tunerFrontendInfo{
+            .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
+            .type = static_cast<int>(frontendInfo.type),
+            .exclusiveGroupId = static_cast<int>(frontendInfo.exclusiveGroupId),
+        };
+        infos.push_back(tunerFrontendInfo);
+    }
+    mTunerResourceManager->setFrontendInfoList(infos);
+}
+
+void TunerService::updateLnbResources() {
+    vector<int> handles = getLnbHandles();
+    if (handles.size() == 0) {
+        return;
+    }
+    mTunerResourceManager->setLnbInfoList(handles);
+}
+
+vector<int> TunerService::getLnbHandles() {
+    vector<int> lnbHandles;
+    if (mTuner != NULL) {
+        Result res;
+        vector<LnbId> lnbIds;
+        mTuner->getLnbIds([&](Result r, const hardware::hidl_vec<LnbId>& ids) {
+            lnbIds = ids;
+            res = r;
+        });
+        if (res != Result::SUCCESS || lnbIds.size() == 0) {
+        } else {
+            for (int i = 0; i < lnbIds.size(); i++) {
+                lnbHandles.push_back(getResourceHandleFromId((int)lnbIds[i], LNB));
+            }
+        }
+    }
+
+    return lnbHandles;
+}
+
+Result TunerService::getHidlFrontendIds(hidl_vec<FrontendId>& ids) {
+    if (mTuner == NULL) {
+        return Result::NOT_INITIALIZED;
+    }
+    Result res;
+    mTuner->getFrontendIds([&](Result r, const hidl_vec<FrontendId>& frontendIds) {
+        ids = frontendIds;
+        res = r;
+    });
+    return res;
+}
+
+Result TunerService::getHidlFrontendInfo(int id, FrontendInfo& info) {
+    if (mTuner == NULL) {
+        return Result::NOT_INITIALIZED;
+    }
+    Result res;
+    mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& feInfo) {
+        info = feInfo;
+        res = r;
+    });
+    return res;
+}
+
 TunerFrontendInfo TunerService::convertToAidlFrontendInfo(FrontendInfo halInfo) {
     TunerFrontendInfo info{
         .type = (int)halInfo.type,
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 856b54a..942d409 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_MEDIA_TUNERSERVICE_H
 #define ANDROID_MEDIA_TUNERSERVICE_H
 
+#include <aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.h>
 #include <aidl/android/media/tv/tuner/BnTunerService.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
 #include <fmq/AidlMessageQueue.h>
@@ -31,10 +32,12 @@
 using ::aidl::android::media::tv::tuner::ITunerFrontend;
 using ::aidl::android::media::tv::tuner::ITunerLnb;
 using ::aidl::android::media::tv::tuner::TunerFrontendInfo;
+using ::aidl::android::media::tv::tunerresourcemanager::ITunerResourceManager;
 
 using ::android::hardware::details::logError;
-using ::android::hardware::EventFlag;
+using ::android::hardware::hidl_vec;
 using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::EventFlag;
 using ::android::hardware::MessageQueue;
 using ::android::hardware::MQDescriptorSync;
 using ::android::hardware::Return;
@@ -94,7 +97,14 @@
         return (resourceHandle & 0x00ff0000) >> 16;
     }
 
-    Status getFrontendIds(vector<int32_t>* ids, int32_t* _aidl_return) override;
+    int getResourceHandleFromId(int id, int resourceType) {
+        // TODO: build up randomly generated id to handle mapping
+        return (resourceType & 0x000000ff) << 24
+                | (id << 16)
+                | (mResourceRequestCount++ & 0xffff);
+    }
+
+    Status getFrontendIds(vector<int32_t>* ids) override;
     Status getFrontendInfo(int32_t frontendHandle, TunerFrontendInfo* _aidl_return) override;
     Status openFrontend(
             int32_t frontendHandle, shared_ptr<ITunerFrontend>* _aidl_return) override;
@@ -103,19 +113,30 @@
     Status openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) override;
     Status openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) override;
     Status openDemux(int32_t demuxHandle, std::shared_ptr<ITunerDemux>* _aidl_return) override;
+    Status updateTunerResources() override;
 
 private:
     bool getITuner();
     Result configFilter();
 
+    void updateFrontendResources();
+    void updateLnbResources();
+    Result getHidlFrontendIds(hidl_vec<FrontendId>& ids);
+    Result getHidlFrontendInfo(int id, FrontendInfo& info);
+    vector<int> getLnbHandles();
+
+    TunerFrontendInfo convertToAidlFrontendInfo(FrontendInfo halInfo);
+
     sp<ITuner> mTuner;
-    std::shared_ptr<ITunerDemux> mDemux;
     sp<IFilter> mFilter;
+
+    shared_ptr<ITunerResourceManager> mTunerResourceManager;
+    int mResourceRequestCount = 0;
+
     AidlMessageQueue* mAidlMq;
     MQDescriptorSync<uint8_t> mFilterMQDesc;
     AidlMQDesc mAidlMQDesc;
     EventFlag* mEventFlag;
-    TunerFrontendInfo convertToAidlFrontendInfo(FrontendInfo halInfo);
 };
 
 } // namespace android
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index ac6eaab..2fabbe5 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -34,10 +34,8 @@
 
     /**
      * Gets frontend IDs.
-     *
-     * @return the result code of the operation.
      */
-    int getFrontendIds(out int[] ids);
+    void getFrontendIds(out int[] ids);
 
     /**
      * Retrieve the frontend's information.
@@ -82,4 +80,10 @@
      * Create a new instance of Demux.
      */
     ITunerDemux openDemux(in int demuxHandle);
+
+    /**
+     * Update Tuner Resources in TunerResourceManager.
+     */
+    // TODO: b/178124017 update TRM in TunerService independently.
+    void updateTunerResources();
 }
diff --git a/services/tuner/mediatuner.rc b/services/tuner/mediatuner.rc
index b0347be..fd30618 100644
--- a/services/tuner/mediatuner.rc
+++ b/services/tuner/mediatuner.rc
@@ -1,6 +1,5 @@
 service media.tuner /system/bin/mediatuner
     class main
-    user media
     group media
     ioprio rt 4
-    task_profiles ProcessCapacityHigh HighPerformance
\ No newline at end of file
+    task_profiles ProcessCapacityHigh HighPerformance