Clean Up Playback Thread in DVR Test Implementation

Bug: 194476544
Test: atest VtsHalTvTunerV1_0TargetTest && atest
VtsHalTvTunerV1_1TargetTest

Change-Id: I639e8314a499c07758c4927fa10cb4ff0e6dcb50
diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp
index c62b878..40879f2 100644
--- a/tv/tuner/1.0/default/Dvr.cpp
+++ b/tv/tuner/1.0/default/Dvr.cpp
@@ -37,7 +37,10 @@
     mDemux = demux;
 }
 
-Dvr::~Dvr() {}
+Dvr::~Dvr() {
+    // make sure thread has joined
+    close();
+}
 
 Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) {
     ALOGV("%s", __FUNCTION__);
@@ -112,8 +115,7 @@
     }
 
     if (mType == DvrType::PLAYBACK) {
-        pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this);
-        pthread_setname_np(mDvrThread, "playback_waiting_loop");
+        mDvrThread = std::thread(&Dvr::playbackThreadLoop, this);
     } else if (mType == DvrType::RECORD) {
         mRecordStatus = RecordStatus::DATA_READY;
         mDemux->setIsRecording(mType == DvrType::RECORD);
@@ -128,9 +130,11 @@
     ALOGV("%s", __FUNCTION__);
 
     mDvrThreadRunning = false;
-
-    lock_guard<mutex> lock(mDvrThreadLock);
-
+    if (mDvrThread.joinable()) {
+        mDvrThread.join();
+    }
+    // thread should always be joinable if it is running,
+    // so it should be safe to assume recording stopped.
     mDemux->setIsRecording(false);
 
     return Result::SUCCESS;
@@ -146,7 +150,7 @@
 
 Return<Result> Dvr::close() {
     ALOGV("%s", __FUNCTION__);
-
+    stop();
     return Result::SUCCESS;
 }
 
@@ -173,15 +177,8 @@
     return mDvrEventFlag;
 }
 
-void* Dvr::__threadLoopPlayback(void* user) {
-    Dvr* const self = static_cast<Dvr*>(user);
-    self->playbackThreadLoop();
-    return 0;
-}
-
 void Dvr::playbackThreadLoop() {
     ALOGD("[Dvr] playback threadLoop start.");
-    lock_guard<mutex> lock(mDvrThreadLock);
     mDvrThreadRunning = true;
 
     while (mDvrThreadRunning) {
diff --git a/tv/tuner/1.0/default/Dvr.h b/tv/tuner/1.0/default/Dvr.h
index fc4cb21..264268a 100644
--- a/tv/tuner/1.0/default/Dvr.h
+++ b/tv/tuner/1.0/default/Dvr.h
@@ -20,7 +20,9 @@
 #include <android/hardware/tv/tuner/1.0/IDvr.h>
 #include <fmq/MessageQueue.h>
 #include <math.h>
+#include <atomic>
 #include <set>
+#include <thread>
 #include "Demux.h"
 #include "Frontend.h"
 #include "Tuner.h"
@@ -119,7 +121,6 @@
      * Each filter handler handles the data filtering/output writing/filterEvent updating.
      */
     void startTpidFilter(vector<uint8_t> data);
-    static void* __threadLoopPlayback(void* user);
     static void* __threadLoopRecord(void* user);
     void playbackThreadLoop();
     void recordThreadLoop();
@@ -133,7 +134,7 @@
     DvrSettings mDvrSettings;
 
     // Thread handlers
-    pthread_t mDvrThread;
+    std::thread mDvrThread;
 
     // FMQ status local records
     PlaybackStatus mPlaybackStatus;
@@ -141,7 +142,7 @@
     /**
      * If a specific filter's writing loop is still running
      */
-    bool mDvrThreadRunning;
+    std::atomic<bool> mDvrThreadRunning;
     bool mKeepFetchingDataFromFrontend;
     /**
      * Lock to protect writes to the FMQs
@@ -152,7 +153,6 @@
      */
     std::mutex mPlaybackStatusLock;
     std::mutex mRecordStatusLock;
-    std::mutex mDvrThreadLock;
 
     const bool DEBUG_DVR = false;
 };
diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp
index fd84d49..fdb66c1 100644
--- a/tv/tuner/1.1/default/Dvr.cpp
+++ b/tv/tuner/1.1/default/Dvr.cpp
@@ -38,8 +38,8 @@
 }
 
 Dvr::~Dvr() {
-    mDvrThreadRunning = false;
-    lock_guard<mutex> lock(mDvrThreadLock);
+    // make sure thread has joined
+    close();
 }
 
 Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) {
@@ -134,8 +134,7 @@
 
     if (mType == DvrType::PLAYBACK) {
         mDvrThreadRunning = true;
-        pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this);
-        pthread_setname_np(mDvrThread, "playback_waiting_loop");
+        mDvrThread = std::thread(&Dvr::playbackThreadLoop, this);
     } else if (mType == DvrType::RECORD) {
         mRecordStatus = RecordStatus::DATA_READY;
         mDemux->setIsRecording(mType == DvrType::RECORD);
@@ -150,8 +149,11 @@
     ALOGV("%s", __FUNCTION__);
 
     mDvrThreadRunning = false;
-    lock_guard<mutex> lock(mDvrThreadLock);
-
+    if (mDvrThread.joinable()) {
+        mDvrThread.join();
+    }
+    // thread should always be joinable if it is running,
+    // so it should be safe to assume recording stopped.
     mDemux->setIsRecording(false);
 
     return Result::SUCCESS;
@@ -167,9 +169,7 @@
 
 Return<Result> Dvr::close() {
     ALOGV("%s", __FUNCTION__);
-
-    mDvrThreadRunning = false;
-    lock_guard<mutex> lock(mDvrThreadLock);
+    stop();
     return Result::SUCCESS;
 }
 
@@ -196,15 +196,8 @@
     return mDvrEventFlag;
 }
 
-void* Dvr::__threadLoopPlayback(void* user) {
-    Dvr* const self = static_cast<Dvr*>(user);
-    self->playbackThreadLoop();
-    return 0;
-}
-
 void Dvr::playbackThreadLoop() {
     ALOGD("[Dvr] playback threadLoop start.");
-    lock_guard<mutex> lock(mDvrThreadLock);
 
     while (mDvrThreadRunning) {
         uint32_t efState = 0;
diff --git a/tv/tuner/1.1/default/Dvr.h b/tv/tuner/1.1/default/Dvr.h
index 9fabb49..bf46c1e 100644
--- a/tv/tuner/1.1/default/Dvr.h
+++ b/tv/tuner/1.1/default/Dvr.h
@@ -19,7 +19,9 @@
 
 #include <fmq/MessageQueue.h>
 #include <math.h>
+#include <atomic>
 #include <set>
+#include <thread>
 #include "Demux.h"
 #include "Frontend.h"
 #include "Tuner.h"
@@ -115,7 +117,6 @@
      * Each filter handler handles the data filtering/output writing/filterEvent updating.
      */
     void startTpidFilter(vector<uint8_t> data);
-    static void* __threadLoopPlayback(void* user);
     static void* __threadLoopRecord(void* user);
     void playbackThreadLoop();
     void recordThreadLoop();
@@ -129,7 +130,7 @@
     DvrSettings mDvrSettings;
 
     // Thread handlers
-    pthread_t mDvrThread;
+    std::thread mDvrThread;
 
     // FMQ status local records
     PlaybackStatus mPlaybackStatus;
@@ -137,7 +138,7 @@
     /**
      * If a specific filter's writing loop is still running
      */
-    bool mDvrThreadRunning;
+    std::atomic<bool> mDvrThreadRunning;
     bool mKeepFetchingDataFromFrontend;
     /**
      * Lock to protect writes to the FMQs
@@ -148,7 +149,6 @@
      */
     std::mutex mPlaybackStatusLock;
     std::mutex mRecordStatusLock;
-    std::mutex mDvrThreadLock;
 
     const bool DEBUG_DVR = false;
 };