Connect DvrClient with TunerDvr Service and TunerDvrCallback

Test: make libmedia_tv_tuner
Bug: 174095851
Change-Id: I5cbd60882d0fc23d167cc19ebcd3a277b99e8262
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index ee2d83b..eb63d76 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -4116,7 +4116,7 @@
         ALOGD("Failed to GetByteArrayElements");
         return -1;
     }
-    long realSize = dvrClient->readFromBuffer(reinterpret_cast<unsigned char*>(src) + offset, size);
+    long realSize = dvrClient->readFromBuffer(reinterpret_cast<signed char*>(src) + offset, size);
     env->ReleaseByteArrayElements(buffer, src, 0);
     return (jlong) realSize;
 
@@ -4149,7 +4149,7 @@
         return -1;
     }
 
-    long realSize = dvrClient->writeToBuffer(reinterpret_cast<unsigned char*>(dst) + offset, size);
+    long realSize = dvrClient->writeToBuffer(reinterpret_cast<signed char*>(dst) + offset, size);
     env->ReleaseByteArrayElements(buffer, dst, 0);
     return (jlong) realSize;
 }
diff --git a/media/jni/tuner/DemuxClient.cpp b/media/jni/tuner/DemuxClient.cpp
index 7265dcc..e290c60 100644
--- a/media/jni/tuner/DemuxClient.cpp
+++ b/media/jni/tuner/DemuxClient.cpp
@@ -148,7 +148,7 @@
         sp<HidlDvrCallback> callback = new HidlDvrCallback(cb);
         sp<IDvr> hidlDvr = openHidlDvr(dvbType, bufferSize, callback);
         if (hidlDvr != NULL) {
-            sp<DvrClient> dvrClient = new DvrClient();
+            sp<DvrClient> dvrClient = new DvrClient(NULL);
             dvrClient->setHidlDvr(hidlDvr);
             return dvrClient;
         }
diff --git a/media/jni/tuner/DemuxClient.h b/media/jni/tuner/DemuxClient.h
index ead61301..463944a 100644
--- a/media/jni/tuner/DemuxClient.h
+++ b/media/jni/tuner/DemuxClient.h
@@ -21,8 +21,8 @@
 #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 "ClientHelper.h"
 #include "DvrClientCallback.h"
 #include "FilterClient.h"
 #include "FilterClientCallback.h"
diff --git a/media/jni/tuner/DvrClient.cpp b/media/jni/tuner/DvrClient.cpp
index dd08491..be592af 100644
--- a/media/jni/tuner/DvrClient.cpp
+++ b/media/jni/tuner/DvrClient.cpp
@@ -17,8 +17,10 @@
 #define LOG_TAG "DvrClient"
 
 #include <android-base/logging.h>
+#include <fmq/ConvertMQDescriptors.h>
 #include <utils/Log.h>
 
+#include "ClientHelper.h"
 #include "DvrClient.h"
 
 using ::android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;
@@ -28,16 +30,15 @@
 
 /////////////// DvrClient ///////////////////////
 
-// TODO: pending aidl interface
-DvrClient::DvrClient() {
-    //mTunerDvr = tunerDvr;
+DvrClient::DvrClient(shared_ptr<ITunerDvr> tunerDvr) {
+    mTunerDvr = tunerDvr;
     mFd = -1;
     mDvrMQ = NULL;
     mDvrMQEventFlag = NULL;
 }
 
 DvrClient::~DvrClient() {
-    //mTunerDvr = NULL;
+    mTunerDvr = NULL;
     mDvr = NULL;
     mFd = -1;
     mDvrMQ = NULL;
@@ -66,7 +67,7 @@
     long available = mDvrMQ->availableToWrite();
     long write = min(size, available);
 
-    MQ::MemTransaction tx;
+    AidlMQ::MemTransaction tx;
     long ret = 0;
     if (mDvrMQ->beginWrite(write, &tx)) {
         auto first = tx.getFirstRegion();
@@ -105,7 +106,7 @@
     return ret;
 }
 
-long DvrClient::readFromBuffer(uint8_t* buffer, long size) {
+long DvrClient::readFromBuffer(int8_t* buffer, long size) {
     if (mDvrMQ == NULL || mDvrMQEventFlag == NULL) {
         ALOGE("Failed to readFromBuffer. DVR mq is not configured");
         return -1;
@@ -141,7 +142,7 @@
     long toRead = min(size, available);
 
     long ret = 0;
-    MQ::MemTransaction tx;
+    AidlMQ::MemTransaction tx;
     if (mDvrMQ->beginRead(toRead, &tx)) {
         auto first = tx.getFirstRegion();
         auto data = first.getAddress();
@@ -178,7 +179,7 @@
     return ret;
 }
 
-long DvrClient::writeToBuffer(uint8_t* buffer, long size) {
+long DvrClient::writeToBuffer(int8_t* buffer, long size) {
     if (mDvrMQ == NULL || mDvrMQEventFlag == NULL) {
         ALOGE("Failed to writetoBuffer. DVR mq is not configured");
         return -1;
@@ -201,7 +202,25 @@
 }
 
 Result DvrClient::configure(DvrSettings settings) {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        TunerDvrSettings dvrSettings = getAidlDvrSettingsFromHidl(settings);
+        Status s = mTunerDvr->configure(dvrSettings);
+        Result res = ClientHelper::getServiceSpecificErrorCode(s);
+        if (res != Result::SUCCESS) {
+            return res;
+        }
+
+        AidlMQDesc* aidlMqDesc = NULL;
+        s = mTunerDvr->getQueueDesc(aidlMqDesc);
+        res = ClientHelper::getServiceSpecificErrorCode(s);
+        if (res != Result::SUCCESS) {
+            return res;
+        }
+
+        mDvrMQ = new (nothrow) AidlMQ(*aidlMqDesc);
+        EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrMQEventFlag);
+        return res;
+    }
 
     if (mDvr != NULL) {
         Result res = mDvr->configure(settings);
@@ -209,7 +228,10 @@
             MQDescriptorSync<uint8_t> dvrMQDesc;
             res = getQueueDesc(dvrMQDesc);
             if (res == Result::SUCCESS) {
-                mDvrMQ = make_unique<MQ>(dvrMQDesc, true);
+                AidlMQDesc aidlMQDesc;
+                unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(
+                        dvrMQDesc,  &aidlMQDesc);
+                mDvrMQ = new (nothrow) AidlMessageQueue(aidlMQDesc);
                 EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrMQEventFlag);
             }
         }
@@ -220,7 +242,10 @@
 }
 
 Result DvrClient::attachFilter(sp<FilterClient> filterClient) {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        Status s = mTunerDvr->attachFilter(filterClient->getAidlFilter());
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDvr != NULL) {
         sp<IFilter> hidlFilter = filterClient->getHalFilter();
@@ -234,7 +259,10 @@
 }
 
 Result DvrClient::detachFilter(sp<FilterClient> filterClient) {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        Status s = mTunerDvr->detachFilter(filterClient->getAidlFilter());
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDvr != NULL) {
         sp<IFilter> hidlFilter = filterClient->getHalFilter();
@@ -248,7 +276,10 @@
 }
 
 Result DvrClient::start() {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        Status s = mTunerDvr->start();
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDvr != NULL) {
         return mDvr->start();
@@ -258,7 +289,10 @@
 }
 
 Result DvrClient::stop() {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        Status s = mTunerDvr->stop();
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDvr != NULL) {
         return mDvr->stop();
@@ -268,7 +302,10 @@
 }
 
 Result DvrClient::flush() {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        Status s = mTunerDvr->flush();
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDvr != NULL) {
         return mDvr->flush();
@@ -278,7 +315,10 @@
 }
 
 Result DvrClient::close() {
-    // pending aidl interface
+    if (mTunerDvr != NULL) {
+        Status s = mTunerDvr->close();
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDvr != NULL) {
         Result res = mDvr->close();
@@ -310,11 +350,30 @@
     return Void();
 }
 
+/////////////// TunerDvrCallback ///////////////////////
+
+TunerDvrCallback::TunerDvrCallback(sp<DvrClientCallback> dvrClientCallback)
+        : mDvrClientCallback(dvrClientCallback) {}
+
+Status TunerDvrCallback::onRecordStatus(int status) {
+    if (mDvrClientCallback != NULL) {
+        mDvrClientCallback->onRecordStatus(static_cast<RecordStatus>(status));
+        return Status::ok();
+    }
+    return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
+}
+
+Status TunerDvrCallback::onPlaybackStatus(int status) {
+    if (mDvrClientCallback != NULL) {
+        mDvrClientCallback->onPlaybackStatus(static_cast<PlaybackStatus>(status));
+        return Status::ok();
+    }
+    return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
+}
+
 /////////////// DvrClient Helper Methods ///////////////////////
 
 Result DvrClient::getQueueDesc(MQDesc& dvrMQDesc) {
-    // pending aidl interface
-
     if (mDvr != NULL) {
         Result res = Result::UNKNOWN_ERROR;
         mDvr->getQueueDesc([&](Result r, const MQDesc& desc) {
@@ -326,4 +385,29 @@
 
     return Result::INVALID_STATE;
 }
+
+TunerDvrSettings DvrClient::getAidlDvrSettingsFromHidl(DvrSettings settings) {
+    TunerDvrSettings s;
+    switch (settings.getDiscriminator()) {
+        case DvrSettings::hidl_discriminator::record: {
+            s.statusMask = static_cast<int>(settings.record().statusMask);
+            s.lowThreshold = static_cast<int>(settings.record().lowThreshold);
+            s.highThreshold = static_cast<int>(settings.record().highThreshold);
+            s.dataFormat = static_cast<int>(settings.record().dataFormat);
+            s.packetSize = static_cast<int>(settings.record().packetSize);
+            return s;
+        }
+        case DvrSettings::hidl_discriminator::playback: {
+            s.statusMask = static_cast<int>(settings.playback().statusMask);
+            s.lowThreshold = static_cast<int>(settings.playback().lowThreshold);
+            s.highThreshold = static_cast<int>(settings.playback().highThreshold);
+            s.dataFormat = static_cast<int>(settings.playback().dataFormat);
+            s.packetSize = static_cast<int>(settings.playback().packetSize);
+            return s;
+        }
+        default:
+            break;
+    }
+    return s;
+}
 }  // namespace android
diff --git a/media/jni/tuner/DvrClient.h b/media/jni/tuner/DvrClient.h
index 2aba5e0..252554e 100644
--- a/media/jni/tuner/DvrClient.h
+++ b/media/jni/tuner/DvrClient.h
@@ -17,16 +17,22 @@
 #ifndef _ANDROID_MEDIA_TV_DVR_CLIENT_H_
 #define _ANDROID_MEDIA_TV_DVR_CLIENT_H_
 
-//#include <aidl/android/media/tv/tuner/ITunerDvr.h>
+#include <aidl/android/media/tv/tuner/BnTunerDvrCallback.h>
+#include <aidl/android/media/tv/tuner/ITunerDvr.h>
 #include <android/hardware/tv/tuner/1.0/IDvr.h>
 #include <android/hardware/tv/tuner/1.0/IDvrCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
+#include <fmq/AidlMessageQueue.h>
 #include <fmq/MessageQueue.h>
 
 #include "DvrClientCallback.h"
 #include "FilterClient.h"
 
-//using ::aidl::android::media::tv::tuner::ITunerDvr;
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::media::tv::tuner::BnTunerDvrCallback;
+using ::aidl::android::media::tv::tuner::ITunerDvr;
+using ::aidl::android::media::tv::tuner::TunerDvrSettings;
 
 using ::android::hardware::EventFlag;
 using ::android::hardware::MQDescriptorSync;
@@ -37,13 +43,14 @@
 
 using namespace std;
 
-using MQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-using MQDesc = MQDescriptorSync<uint8_t>;
-
 namespace android {
 
-// TODO: pending aidl interface
-/*class TunerDvrCallback : public BnTunerDvrCallback {
+using MQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using MQDesc = MQDescriptorSync<uint8_t>;
+using AidlMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+using AidlMQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;
+
+class TunerDvrCallback : public BnTunerDvrCallback {
 
 public:
     TunerDvrCallback(sp<DvrClientCallback> dvrClientCallback);
@@ -53,7 +60,7 @@
 
 private:
     sp<DvrClientCallback> mDvrClientCallback;
-};*/
+};
 
 struct HidlDvrCallback : public IDvrCallback {
 
@@ -69,7 +76,7 @@
 struct DvrClient : public RefBase {
 
 public:
-    DvrClient();
+    DvrClient(shared_ptr<ITunerDvr> tunerDvr);
     ~DvrClient();
 
     // TODO: remove after migration to Tuner Service is done.
@@ -88,7 +95,7 @@
     /**
      * Read data from the given buffer with given size. Return the actual read size.
      */
-    long readFromBuffer(uint8_t* buffer, long size);
+    long readFromBuffer(int8_t* buffer, long size);
 
     /**
      * Write data to file with given size. Return the actual write size.
@@ -98,7 +105,7 @@
     /**
      * Write data to the given buffer with given size. Return the actual write size.
      */
-    long writeToBuffer(uint8_t* buffer, long size);
+    long writeToBuffer(int8_t* buffer, long size);
 
     /**
      * Configure the DVR.
@@ -137,13 +144,13 @@
 
 private:
     Result getQueueDesc(MQDesc& dvrMQDesc);
+    TunerDvrSettings getAidlDvrSettingsFromHidl(DvrSettings settings);
 
     /**
      * An AIDL Tuner Dvr Singleton assigned at the first time the Tuner Client
      * opens a dvr. Default null when dvr is not opened.
      */
-    // TODO: pending on aidl interface
-    //shared_ptr<ITunerDvr> mTunerDvr;
+    shared_ptr<ITunerDvr> mTunerDvr;
 
     /**
      * A Dvr HAL interface that is ready before migrating to the TunerDvr.
@@ -152,7 +159,7 @@
      */
     sp<IDvr> mDvr;
 
-    unique_ptr<MQ> mDvrMQ;
+    AidlMQ* mDvrMQ;
     EventFlag* mDvrMQEventFlag;
     string mFilePath;
     int mFd;
diff --git a/media/jni/tuner/FilterClient.h b/media/jni/tuner/FilterClient.h
index 6af33f7..7c85125 100644
--- a/media/jni/tuner/FilterClient.h
+++ b/media/jni/tuner/FilterClient.h
@@ -166,7 +166,7 @@
     /**
      * Get the Aidl filter to build up filter linkage.
      */
-    //shared_ptr<ITunerFilter> getAidlFilter() { return mTunerFilter; }
+    shared_ptr<ITunerFilter> getAidlFilter() { return mTunerFilter; }
 
     /**
      * Close a new interface of ITunerFilter.
diff --git a/media/jni/tuner/TunerClient.h b/media/jni/tuner/TunerClient.h
index 04035e4..6ce6661 100644
--- a/media/jni/tuner/TunerClient.h
+++ b/media/jni/tuner/TunerClient.h
@@ -24,9 +24,9 @@
 #include <android/hardware/tv/tuner/1.1/ITuner.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "DemuxClient.h"
 #include "ClientHelper.h"
 #include "FrontendClient.h"
-#include "DemuxClient.h"
 #include "DescramblerClient.h"
 #include "LnbClient.h"