1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <android-base/logging.h> 18 #include <android/hardware/tv/tuner/1.0/IDvr.h> 19 #include <android/hardware/tv/tuner/1.0/IDvrCallback.h> 20 #include <android/hardware/tv/tuner/1.0/types.h> 21 #include <android/hardware/tv/tuner/1.1/ITuner.h> 22 #include <fcntl.h> 23 #include <fmq/MessageQueue.h> 24 #include <gtest/gtest.h> 25 #include <hidl/HidlSupport.h> 26 #include <hidl/Status.h> 27 #include <utils/Condition.h> 28 #include <utils/Mutex.h> 29 #include <fstream> 30 #include <iostream> 31 #include <map> 32 33 #include "FilterTests.h" 34 35 using android::Condition; 36 using android::Mutex; 37 using android::sp; 38 using android::hardware::EventFlag; 39 using android::hardware::kSynchronizedReadWrite; 40 using android::hardware::MessageQueue; 41 using android::hardware::MQDescriptorSync; 42 using android::hardware::Return; 43 using android::hardware::Void; 44 using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; 45 using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; 46 using android::hardware::tv::tuner::V1_0::DvrSettings; 47 using android::hardware::tv::tuner::V1_0::DvrType; 48 using android::hardware::tv::tuner::V1_0::IDvr; 49 using android::hardware::tv::tuner::V1_0::IDvrCallback; 50 using android::hardware::tv::tuner::V1_0::PlaybackSettings; 51 using android::hardware::tv::tuner::V1_0::PlaybackStatus; 52 using android::hardware::tv::tuner::V1_0::RecordSettings; 53 using android::hardware::tv::tuner::V1_0::RecordStatus; 54 using android::hardware::tv::tuner::V1_0::Result; 55 using android::hardware::tv::tuner::V1_1::ITuner; 56 57 using namespace std; 58 59 #define WAIT_TIMEOUT 3000000000 60 61 class DvrCallback : public IDvrCallback { 62 public: onRecordStatus(DemuxFilterStatus status)63 virtual Return<void> onRecordStatus(DemuxFilterStatus status) override { 64 ALOGD("[vts] record status %hhu", status); 65 switch (status) { 66 case DemuxFilterStatus::DATA_READY: 67 break; 68 case DemuxFilterStatus::LOW_WATER: 69 break; 70 case DemuxFilterStatus::HIGH_WATER: 71 case DemuxFilterStatus::OVERFLOW: 72 ALOGD("[vts] record overflow. Flushing."); 73 EXPECT_TRUE(mDvr) << "Dvr callback is not set with an IDvr"; 74 if (mDvr) { 75 Result result = mDvr->flush(); 76 ALOGD("[vts] Flushing result %d.", result); 77 } 78 break; 79 } 80 return Void(); 81 } 82 onPlaybackStatus(PlaybackStatus status)83 virtual Return<void> onPlaybackStatus(PlaybackStatus status) override { 84 // android::Mutex::Autolock autoLock(mMsgLock); 85 ALOGD("[vts] playback status %d", status); 86 switch (status) { 87 case PlaybackStatus::SPACE_EMPTY: 88 case PlaybackStatus::SPACE_ALMOST_EMPTY: 89 ALOGD("[vts] keep playback inputing %d", status); 90 mKeepWritingPlaybackFMQ = true; 91 break; 92 case PlaybackStatus::SPACE_ALMOST_FULL: 93 case PlaybackStatus::SPACE_FULL: 94 ALOGD("[vts] stop playback inputing %d", status); 95 mKeepWritingPlaybackFMQ = false; 96 break; 97 } 98 return Void(); 99 } 100 101 void stopPlaybackThread(); 102 void testRecordOutput(); 103 void stopRecordThread(); 104 105 void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings, 106 MQDesc& playbackMQDescriptor); 107 void startRecordOutputThread(RecordSettings recordSettings, MQDesc& recordMQDescriptor); 108 static void* __threadLoopPlayback(void* user); 109 static void* __threadLoopRecord(void* threadArgs); 110 void playbackThreadLoop(); 111 void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ); 112 113 bool readRecordFMQ(); 114 setDvr(sp<IDvr> dvr)115 void setDvr(sp<IDvr> dvr) { mDvr = dvr; } 116 117 private: 118 struct RecordThreadArgs { 119 DvrCallback* user; 120 RecordSettings* recordSettings; 121 bool* keepReadingRecordFMQ; 122 }; 123 // uint16_t mDataLength = 0; 124 std::vector<uint8_t> mDataOutputBuffer; 125 126 std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ; 127 std::unique_ptr<FilterMQ> mPlaybackMQ; 128 std::unique_ptr<FilterMQ> mRecordMQ; 129 std::map<uint32_t, EventFlag*> mFilterMQEventFlag; 130 131 android::Mutex mMsgLock; 132 android::Mutex mPlaybackThreadLock; 133 android::Mutex mRecordThreadLock; 134 android::Condition mMsgCondition; 135 136 bool mKeepWritingPlaybackFMQ = true; 137 bool mKeepReadingRecordFMQ = true; 138 bool mPlaybackThreadRunning; 139 bool mRecordThreadRunning; 140 pthread_t mPlaybackThread; 141 pthread_t mRecordThread; 142 string mInputDataFile; 143 PlaybackSettings mPlaybackSettings; 144 145 sp<IDvr> mDvr = nullptr; 146 147 // int mPidFilterOutputCount = 0; 148 }; 149 150 class DvrTests { 151 public: setService(sp<ITuner> tuner)152 void setService(sp<ITuner> tuner) { mService = tuner; } setDemux(sp<IDemux> demux)153 void setDemux(sp<IDemux> demux) { mDemux = demux; } 154 startPlaybackInputThread(string & dataInputFile,PlaybackSettings & settings)155 void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) { 156 mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings, 157 mDvrPlaybackMQDescriptor); 158 }; 159 startRecordOutputThread(RecordSettings settings)160 void startRecordOutputThread(RecordSettings settings) { 161 mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor); 162 }; 163 stopPlaybackThread()164 void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); } testRecordOutput()165 void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); } stopRecordThread()166 void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); } 167 168 AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize); 169 AssertionResult configDvrPlayback(DvrSettings setting); 170 AssertionResult configDvrRecord(DvrSettings setting); 171 AssertionResult getDvrPlaybackMQDescriptor(); 172 AssertionResult getDvrRecordMQDescriptor(); 173 AssertionResult attachFilterToDvr(sp<IFilter> filter); 174 AssertionResult detachFilterToDvr(sp<IFilter> filter); 175 AssertionResult stopDvrPlayback(); 176 AssertionResult startDvrPlayback(); 177 AssertionResult stopDvrRecord(); 178 AssertionResult startDvrRecord(); 179 void closeDvrPlayback(); 180 void closeDvrRecord(); 181 182 protected: failure()183 static AssertionResult failure() { return ::testing::AssertionFailure(); } 184 success()185 static AssertionResult success() { return ::testing::AssertionSuccess(); } 186 187 sp<ITuner> mService; 188 sp<IDvr> mDvrPlayback; 189 sp<IDvr> mDvrRecord; 190 sp<IDemux> mDemux; 191 sp<DvrCallback> mDvrPlaybackCallback; 192 sp<DvrCallback> mDvrRecordCallback; 193 MQDesc mDvrPlaybackMQDescriptor; 194 MQDesc mDvrRecordMQDescriptor; 195 }; 196