Connect existed TunerFilter/TunerDemux AIDL apis to TunerClient

This CL also resolved some TODO to handle aidl error messages

Test: make
Bug: 159067322
Change-Id: I6da66d1fa3989a501ec58bf1e0553f85a13e18db
diff --git a/media/jni/tuner/ClientHelper.h b/media/jni/tuner/ClientHelper.h
new file mode 100644
index 0000000..185b2f6
--- /dev/null
+++ b/media/jni/tuner/ClientHelper.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_MEDIA_TV_CLIENT_HELPER_H_
+#define _ANDROID_MEDIA_TV_CLIENT_HELPER_H_
+
+#include <android/binder_parcel_utils.h>
+#include <android/hardware/tv/tuner/1.1/types.h>
+
+using Status = ::ndk::ScopedAStatus;
+
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+using namespace std;
+
+namespace android {
+
+struct ClientHelper {
+
+public:
+	static Result getServiceSpecificErrorCode(Status& s) {
+        if (s.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            return static_cast<Result>(s.getServiceSpecificError());
+        } else if (s.isOk()) {
+            return Result::SUCCESS;
+        }
+        return Result::UNKNOWN_ERROR;
+    }
+};
+}  // namespace android
+
+#endif  // _ANDROID_MEDIA_TV_CLIENT_HELPER_H_
\ No newline at end of file
diff --git a/media/jni/tuner/DemuxClient.cpp b/media/jni/tuner/DemuxClient.cpp
index 08b7398..7265dcc 100644
--- a/media/jni/tuner/DemuxClient.cpp
+++ b/media/jni/tuner/DemuxClient.cpp
@@ -23,20 +23,20 @@
 
 using ::aidl::android::media::tv::tuner::TunerFrontendSettings;
 
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
 using ::android::hardware::tv::tuner::V1_0::Result;
 
 namespace android {
 
 /////////////// DemuxClient ///////////////////////
 
-// TODO: pending aidl interface
-DemuxClient::DemuxClient() {
-    //mTunerDemux = tunerDemux;
+DemuxClient::DemuxClient(shared_ptr<ITunerDemux> tunerDemux) {
+    mTunerDemux = tunerDemux;
     mId = -1;
 }
 
 DemuxClient::~DemuxClient() {
-    //mTunerDemux = NULL;
+    mTunerDemux = NULL;
     mDemux = NULL;
     mId = -1;
 }
@@ -47,12 +47,10 @@
 }
 
 Result DemuxClient::setFrontendDataSource(sp<FrontendClient> frontendClient) {
-    // TODO: pending aidl interface
-    /*if (mTunerDemux != NULL) {
-        // TODO: handle error message
-        mTunerDemux->setFrontendDataSource(frontendClient->getAidlFrontend());
-        return (int) Result::SUCCESS;
-    }*/
+    if (mTunerDemux != NULL) {
+        Status s = mTunerDemux->setFrontendDataSource(frontendClient->getAidlFrontend());
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDemux != NULL) {
         Result res = mDemux->setFrontendDataSource(frontendClient->getId());
@@ -64,13 +62,23 @@
 
 sp<FilterClient> DemuxClient::openFilter(DemuxFilterType type, int bufferSize,
         sp<FilterClientCallback> cb) {
-    // TODO: pending aidl interface
+    if (mTunerDemux != NULL) {
+        shared_ptr<ITunerFilter> tunerFilter;
+        shared_ptr<TunerFilterCallback> callback =
+                ::ndk::SharedRefBase::make<TunerFilterCallback>(cb);
+        Status s = mTunerDemux->openFilter((int)type.mainType, getSubType(type),
+                    bufferSize, callback, &tunerFilter);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
+        return new FilterClient(type, tunerFilter);
+    }
 
     if (mDemux != NULL) {
         sp<HidlFilterCallback> callback = new HidlFilterCallback(cb);
         sp<IFilter> hidlFilter = openHidlFilter(type, bufferSize, callback);
         if (hidlFilter != NULL) {
-            sp<FilterClient> filterClient = new FilterClient(type);
+            sp<FilterClient> filterClient = new FilterClient(type, NULL);
             filterClient->setHidlFilter(hidlFilter);
             return filterClient;
         }
@@ -244,4 +252,21 @@
 
     return hidlDvr;
 }
+
+int DemuxClient::getSubType(DemuxFilterType filterType) {
+    switch (filterType.mainType) {
+        case DemuxFilterMainType::TS:
+            return (int)filterType.subType.tsFilterType();
+        case DemuxFilterMainType::MMTP:
+            return (int)filterType.subType.mmtpFilterType();
+        case DemuxFilterMainType::IP:
+            return (int)filterType.subType.ipFilterType();
+        case DemuxFilterMainType::TLV:
+            return (int)filterType.subType.tlvFilterType();
+        case DemuxFilterMainType::ALP:
+            return (int)filterType.subType.alpFilterType();
+        default:
+            return -1;
+    }
+}
 }  // namespace android
diff --git a/media/jni/tuner/DemuxClient.h b/media/jni/tuner/DemuxClient.h
index 2950dd4..ead61301 100644
--- a/media/jni/tuner/DemuxClient.h
+++ b/media/jni/tuner/DemuxClient.h
@@ -17,10 +17,11 @@
 #ifndef _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_
 #define _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_
 
-//#include <aidl/android/media/tv/tuner/ITunerDemux.h>
+#include <aidl/android/media/tv/tuner/ITunerDemux.h>
 #include <android/hardware/tv/tuner/1.0/IDemux.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "DvrClient.h"
 #include "DvrClientCallback.h"
 #include "FilterClient.h"
@@ -28,7 +29,8 @@
 #include "FrontendClient.h"
 #include "TimeFilterClient.h"
 
-//using ::aidl::android::media::tv::tuner::ITunerDemux;
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::ITunerDemux;
 
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterType;
 using ::android::hardware::tv::tuner::V1_0::DvrType;
@@ -42,7 +44,7 @@
 struct DemuxClient : public RefBase {
 
 public:
-    DemuxClient();
+    DemuxClient(shared_ptr<ITunerDemux> tunerDemux);
     ~DemuxClient();
 
     // TODO: remove after migration to Tuner Service is done.
@@ -100,13 +102,13 @@
     sp<IFilter> openHidlFilter(DemuxFilterType type, int bufferSize, sp<HidlFilterCallback> cb);
     sp<ITimeFilter> openHidlTimeFilter();
     sp<IDvr> openHidlDvr(DvrType type, int bufferSize, sp<HidlDvrCallback> cb);
+    int getSubType(DemuxFilterType filterType);
 
     /**
      * An AIDL Tuner Demux Singleton assigned at the first time the Tuner Client
      * opens a demux. Default null when demux is not opened.
      */
-    // TODO: pending on aidl interface
-    //shared_ptr<ITunerDemux> mTunerDemux;
+    shared_ptr<ITunerDemux> mTunerDemux;
 
     /**
      * A Demux HAL interface that is ready before migrating to the TunerDemux.
diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp
index 0aab5fe..f26560b 100644
--- a/media/jni/tuner/FilterClient.cpp
+++ b/media/jni/tuner/FilterClient.cpp
@@ -30,16 +30,14 @@
 
 /////////////// FilterClient ///////////////////////
 
-// TODO: pending aidl interface
-// TODO: add filter callback
-FilterClient::FilterClient(DemuxFilterType type) {
-    //mTunerFilter = tunerFilter;
+FilterClient::FilterClient(DemuxFilterType type, shared_ptr<ITunerFilter> tunerFilter) {
+    mTunerFilter = tunerFilter;
     mAvSharedHandle = NULL;
     checkIsMediaFilter(type);
 }
 
 FilterClient::~FilterClient() {
-    //mTunerFilter = NULL;
+    mTunerFilter = NULL;
     mFilter = NULL;
     mFilter_1_1 = NULL;
     mAvSharedHandle = NULL;
@@ -154,7 +152,12 @@
 }
 
 Result FilterClient::getId(uint32_t& id) {
-    // TODO: pending aidl interface
+    if (mTunerFilter != NULL) {
+        int32_t id32Bit;
+        Status s = mTunerFilter->getId(&id32Bit);
+        id = static_cast<uint32_t>(id32Bit);
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mFilter != NULL) {
         Result res;
@@ -169,7 +172,12 @@
 }
 
 Result FilterClient::getId64Bit(uint64_t& id) {
-    // TODO: pending aidl interface
+    if (mTunerFilter != NULL) {
+        int64_t id64Bit;
+        Status s = mTunerFilter->getId64Bit(&id64Bit);
+        id = static_cast<uint64_t>(id64Bit);
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mFilter_1_1 != NULL) {
         Result res;
@@ -248,6 +256,19 @@
     return Void();
 }
 
+/////////////// TunerFilterCallback ///////////////////////
+
+TunerFilterCallback::TunerFilterCallback(sp<FilterClientCallback> filterClientCallback)
+        : mFilterClientCallback(filterClientCallback) {}
+
+Status TunerFilterCallback::onFilterStatus(int status) {
+    if (mFilterClientCallback != NULL) {
+        mFilterClientCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
+        return Status::ok();
+    }
+    return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
+}
+
 /////////////// FilterClient Helper Methods ///////////////////////
 
 Result FilterClient::getFilterMq() {
diff --git a/media/jni/tuner/FilterClient.h b/media/jni/tuner/FilterClient.h
index 976b2f5..57efcd3 100644
--- a/media/jni/tuner/FilterClient.h
+++ b/media/jni/tuner/FilterClient.h
@@ -17,15 +17,19 @@
 #ifndef _ANDROID_MEDIA_TV_FILTER_CLIENT_H_
 #define _ANDROID_MEDIA_TV_FILTER_CLIENT_H_
 
-//#include <aidl/android/media/tv/tuner/ITunerFilter.h>
+#include <aidl/android/media/tv/tuner/ITunerFilter.h>
+#include <aidl/android/media/tv/tuner/BnTunerFilterCallback.h>
 #include <android/hardware/tv/tuner/1.1/IFilter.h>
 #include <android/hardware/tv/tuner/1.1/IFilterCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 #include <fmq/MessageQueue.h>
 
+#include "ClientHelper.h"
 #include "FilterClientCallback.h"
 
-//using ::aidl::android::media::tv::tuner::ITunerFilter;
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::BnTunerFilterCallback;
+using ::aidl::android::media::tv::tuner::ITunerFilter;
 
 using ::android::hardware::EventFlag;
 using ::android::hardware::MessageQueue;
@@ -51,18 +55,16 @@
     uint64_t size;
 };
 
-// TODO: pending aidl interface
-/*class TunerFilterCallback : public BnTunerFilterCallback {
+class TunerFilterCallback : public BnTunerFilterCallback {
 
 public:
     TunerFilterCallback(sp<FilterClientCallback> filterClientCallback);
-
-    Status onFilterEvent(vector<TunerDemuxFilterEvent> events);
+    // TODO: complete TunerFilterCallback
     Status onFilterStatus(int status);
 
 private:
     sp<FilterClientCallback> mFilterClientCallback;
-};*/
+};
 
 struct HidlFilterCallback : public IFilterCallback {
 
@@ -80,8 +82,7 @@
 struct FilterClient : public RefBase {
 
 public:
-    // TODO: pending aidl interface
-    FilterClient(DemuxFilterType type);
+    FilterClient(DemuxFilterType type, shared_ptr<ITunerFilter> tunerFilter);
     ~FilterClient();
 
     // TODO: remove after migration to Tuner Service is done.
@@ -179,8 +180,7 @@
      * An AIDL Tuner Filter Singleton assigned at the first time when the Tuner Client
      * opens a filter. Default null when Tuner Service does not exist.
      */
-    // TODO: pending on aidl interface
-    //shared_ptr<ITunerFilter> mTunerFilter;
+    shared_ptr<ITunerFilter> mTunerFilter;
 
     /**
      * A 1.0 Filter HAL interface that is ready before migrating to the TunerFilter.
@@ -200,7 +200,6 @@
     EventFlag* mFilterMQEventFlag;
 
     sp<FilterClientCallback> mCallback;
-    //shared_ptr<TunerFilterCallback> mAidlCallback;
     sp<HidlFilterCallback> mHidlCallback;
 
     native_handle_t* mAvSharedHandle;
diff --git a/media/jni/tuner/FrontendClient.cpp b/media/jni/tuner/FrontendClient.cpp
index d6d64f6..ef8f57f 100644
--- a/media/jni/tuner/FrontendClient.cpp
+++ b/media/jni/tuner/FrontendClient.cpp
@@ -89,9 +89,8 @@
         // TODO: parse hidl settings to aidl settings
         // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
         TunerFrontendSettings settings;
-        // TODO: handle error message.
-        mTunerFrontend->tune(settings);
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->tune(settings);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     Result result;
@@ -110,9 +109,8 @@
 
 Result FrontendClient::stopTune() {
     if (mTunerFrontend != NULL) {
-        // TODO: handle error message.
-        mTunerFrontend->stopTune();
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->stopTune();
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mFrontend != NULL) {
@@ -129,9 +127,8 @@
         // TODO: parse hidl settings to aidl settings
         // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
         TunerFrontendSettings settings;
-        // TODO: handle error message.
-        mTunerFrontend->scan(settings, (int)type);
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->scan(settings, (int)type);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     Result result;
@@ -150,9 +147,8 @@
 
 Result FrontendClient::stopScan() {
     if (mTunerFrontend != NULL) {
-        // TODO: handle error message.
-        mTunerFrontend->stopScan();
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->stopScan();
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mFrontend != NULL) {
@@ -284,8 +280,8 @@
 Result FrontendClient::close() {
     if (mTunerFrontend != NULL) {
         // TODO: handle error message.
-        mTunerFrontend->close();
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->close();
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mFrontend != NULL) {
diff --git a/media/jni/tuner/FrontendClient.h b/media/jni/tuner/FrontendClient.h
index 4f95c22..03ebb87 100644
--- a/media/jni/tuner/FrontendClient.h
+++ b/media/jni/tuner/FrontendClient.h
@@ -23,6 +23,7 @@
 #include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "FrontendClientCallback.h"
 #include "LnbClient.h"
 
diff --git a/media/jni/tuner/LnbClient.cpp b/media/jni/tuner/LnbClient.cpp
index df3fd60..8d08c25 100644
--- a/media/jni/tuner/LnbClient.cpp
+++ b/media/jni/tuner/LnbClient.cpp
@@ -19,7 +19,6 @@
 #include <android-base/logging.h>
 #include <utils/Log.h>
 
-#include "TunerClient.h"
 #include "LnbClient.h"
 
 using ::android::hardware::tv::tuner::V1_0::Result;
@@ -48,7 +47,7 @@
     if (mTunerLnb != NULL) {
         mAidlCallback = ::ndk::SharedRefBase::make<TunerLnbCallback>(cb);
         Status s = mTunerLnb->setCallback(mAidlCallback);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -62,7 +61,7 @@
 Result LnbClient::setVoltage(LnbVoltage voltage) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->setVoltage((int)voltage);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -75,7 +74,7 @@
 Result LnbClient::setTone(LnbTone tone) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->setTone((int)tone);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -88,7 +87,7 @@
 Result LnbClient::setSatellitePosition(LnbPosition position) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->setSatellitePosition((int)position);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -101,7 +100,7 @@
 Result LnbClient::sendDiseqcMessage(vector<uint8_t> diseqcMessage) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->sendDiseqcMessage(diseqcMessage);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -114,7 +113,7 @@
 Result LnbClient::close() {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->close();
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
diff --git a/media/jni/tuner/LnbClient.h b/media/jni/tuner/LnbClient.h
index 2465120..e7869e8 100644
--- a/media/jni/tuner/LnbClient.h
+++ b/media/jni/tuner/LnbClient.h
@@ -23,6 +23,7 @@
 #include <android/hardware/tv/tuner/1.0/ILnbCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "LnbClientCallback.h"
 
 using Status = ::ndk::ScopedAStatus;
@@ -45,7 +46,6 @@
 
 namespace android {
 
-// TODO: pending aidl interface
 class TunerLnbCallback : public BnTunerLnbCallback {
 
 public:
diff --git a/media/jni/tuner/TunerClient.cpp b/media/jni/tuner/TunerClient.cpp
index 73a2cf2..4498f54 100644
--- a/media/jni/tuner/TunerClient.cpp
+++ b/media/jni/tuner/TunerClient.cpp
@@ -66,7 +66,7 @@
     if (mTunerService != NULL) {
         vector<int32_t> v;
         Status s = mTunerService->getFrontendIds(&v);
-        if (getServiceSpecificErrorCode(s) != Result::SUCCESS || v.size() == 0) {
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS || v.size() == 0) {
             ids.clear();
             return ids;
         }
@@ -96,18 +96,22 @@
 
 sp<FrontendClient> TunerClient::openFrontend(int frontendHandle) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
         shared_ptr<ITunerFrontend> tunerFrontend;
-        mTunerService->openFrontend(frontendHandle, &tunerFrontend);
-        if (tunerFrontend == NULL) {
+        Status s = mTunerService->openFrontend(frontendHandle, &tunerFrontend);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS
+                || tunerFrontend == NULL) {
             return NULL;
         }
         int id;
-        // TODO: handle error code
-        tunerFrontend->getFrontendId(&id);
+        s = tunerFrontend->getFrontendId(&id);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         TunerFrontendInfo aidlFrontendInfo;
-        // TODO: handle error code
-        mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        s = mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return new FrontendClient(tunerFrontend, frontendHandle, aidlFrontendInfo.type);
     }
 
@@ -133,7 +137,10 @@
     if (mTunerService != NULL) {
         TunerFrontendInfo aidlFrontendInfo;
         // TODO: handle error code
-        mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        Status s = mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
     }
 
@@ -168,17 +175,18 @@
     return NULL;
 }
 
-sp<DemuxClient> TunerClient::openDemux(int /*demuxHandle*/) {
+sp<DemuxClient> TunerClient::openDemux(int demuxHandle) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
-        /*shared_ptr<ITunerDemux> tunerDemux;
-        mTunerService->openDemux(demuxHandle, &tunerDemux);
-        return new DemuxClient(tunerDemux);*/
+        shared_ptr<ITunerDemux> tunerDemux;
+        Status s = mTunerService->openDemux(demuxHandle, &tunerDemux);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
+        return new DemuxClient(tunerDemux);
     }
 
     if (mTuner != NULL) {
-        // TODO: pending aidl interface
-        sp<DemuxClient> demuxClient = new DemuxClient();
+        sp<DemuxClient> demuxClient = new DemuxClient(NULL);
         int demuxId;
         sp<IDemux> hidlDemux = openHidlDemux(demuxId);
         if (hidlDemux != NULL) {
@@ -231,15 +239,16 @@
 
 sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
         shared_ptr<ITunerLnb> tunerLnb;
-        mTunerService->openLnb(lnbHandle, &tunerLnb);
+        Status s = mTunerService->openLnb(lnbHandle, &tunerLnb);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return new LnbClient(tunerLnb);
     }
 
     if (mTuner != NULL) {
         int id = getResourceIdFromHandle(lnbHandle, LNB);
-        // TODO: pending aidl interface
         sp<LnbClient> lnbClient = new LnbClient(NULL);
         sp<ILnb> hidlLnb = openHidlLnbById(id);
         if (hidlLnb != NULL) {
@@ -254,14 +263,15 @@
 
 sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
         shared_ptr<ITunerLnb> tunerLnb;
-        mTunerService->openLnbByName(lnbName, &tunerLnb);
+        Status s = mTunerService->openLnbByName(lnbName, &tunerLnb);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return new LnbClient(tunerLnb);
     }
 
     if (mTuner != NULL) {
-        // TODO: pending aidl interface
         sp<LnbClient> lnbClient = new LnbClient(NULL);
         LnbId id;
         sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
@@ -411,29 +421,8 @@
     return lnb;
 }
 
-sp<IDescrambler> TunerClient::openHidlDescrambler() {
-    sp<IDescrambler> descrambler;
-    Result res;
-
-    mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
-        res = r;
-        descrambler = descramblerSp;
-    });
-
-    if (res != Result::SUCCESS || descrambler == NULL) {
-        return NULL;
-    }
-
-    return descrambler;
-}
-
 vector<int> TunerClient::getLnbHandles() {
     vector<int> lnbHandles;
-
-    if (mTunerService != NULL) {
-        // TODO: pending hidl interface
-    }
-
     if (mTuner != NULL) {
         Result res;
         vector<LnbId> lnbIds;
@@ -453,6 +442,22 @@
     return lnbHandles;
 }
 
+sp<IDescrambler> TunerClient::openHidlDescrambler() {
+    sp<IDescrambler> descrambler;
+    Result res;
+
+    mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
+        res = r;
+        descrambler = descramblerSp;
+    });
+
+    if (res != Result::SUCCESS || descrambler == NULL) {
+        return NULL;
+    }
+
+    return descrambler;
+}
+
 FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerFrontendInfo aidlFrontendInfo) {
     FrontendInfo hidlFrontendInfo {
         .type = static_cast<FrontendType>(aidlFrontendInfo.type),
diff --git a/media/jni/tuner/TunerClient.h b/media/jni/tuner/TunerClient.h
index 733ee6b..04035e4 100644
--- a/media/jni/tuner/TunerClient.h
+++ b/media/jni/tuner/TunerClient.h
@@ -24,6 +24,7 @@
 #include <android/hardware/tv/tuner/1.1/ITuner.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "FrontendClient.h"
 #include "DemuxClient.h"
 #include "DescramblerClient.h"
@@ -135,15 +136,6 @@
      */
     int getHalTunerVersion() { return mTunerVersion; }
 
-    static Result getServiceSpecificErrorCode(Status& s) {
-        if (s.getExceptionCode() == EX_SERVICE_SPECIFIC) {
-            return static_cast<Result>(s.getServiceSpecificError());
-        } else if (s.isOk()) {
-            return Result::SUCCESS;
-        }
-        return Result::UNKNOWN_ERROR;
-    }
-
 private:
     sp<ITuner> getHidlTuner();
     sp<IFrontend> openHidlFrontendById(int id);