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/IFilter.h> 19 #include <android/hardware/tv/tuner/1.0/IFilterCallback.h> 20 #include <android/hardware/tv/tuner/1.0/ITuner.h> 21 #include <android/hardware/tv/tuner/1.0/types.h> 22 #include <fmq/MessageQueue.h> 23 #include <gtest/gtest.h> 24 #include <hidl/HidlSupport.h> 25 #include <hidl/HidlTransportSupport.h> 26 #include <hidl/Status.h> 27 #include <utils/Condition.h> 28 #include <utils/Mutex.h> 29 #include <map> 30 31 using android::Condition; 32 using android::Mutex; 33 using android::sp; 34 using android::hardware::EventFlag; 35 using android::hardware::hidl_handle; 36 using android::hardware::hidl_string; 37 using android::hardware::hidl_vec; 38 using android::hardware::kSynchronizedReadWrite; 39 using android::hardware::MessageQueue; 40 using android::hardware::MQDescriptorSync; 41 using android::hardware::Return; 42 using android::hardware::Void; 43 using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; 44 using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; 45 using android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent; 46 using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings; 47 using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent; 48 using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; 49 using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent; 50 using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; 51 using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; 52 using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; 53 using android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent; 54 using android::hardware::tv::tuner::V1_0::DemuxFilterType; 55 using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; 56 using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings; 57 using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; 58 using android::hardware::tv::tuner::V1_0::IDemux; 59 using android::hardware::tv::tuner::V1_0::IFilter; 60 using android::hardware::tv::tuner::V1_0::IFilterCallback; 61 using android::hardware::tv::tuner::V1_0::ITimeFilter; 62 using android::hardware::tv::tuner::V1_0::ITuner; 63 using android::hardware::tv::tuner::V1_0::Result; 64 65 using ::testing::AssertionResult; 66 67 using namespace std; 68 69 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>; 70 using MQDesc = MQDescriptorSync<uint8_t>; 71 72 #define WAIT_TIMEOUT 3000000000 73 74 class FilterCallback : public IFilterCallback { 75 public: onFilterEvent(const DemuxFilterEvent & filterEvent)76 virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent) override { 77 android::Mutex::Autolock autoLock(mMsgLock); 78 // Temprarily we treat the first coming back filter data on the matching pid a success 79 // once all of the MQ are cleared, means we got all the expected output 80 mFilterEvent = filterEvent; 81 readFilterEventData(); 82 mPidFilterOutputCount++; 83 // mFilterIdToMQ.erase(filterEvent.filterId); 84 85 // startFilterEventThread(filterEvent); 86 mMsgCondition.signal(); 87 return Void(); 88 } 89 onFilterStatus(const DemuxFilterStatus)90 virtual Return<void> onFilterStatus(const DemuxFilterStatus /*status*/) override { 91 return Void(); 92 } 93 setFilterId(uint32_t filterId)94 void setFilterId(uint32_t filterId) { mFilterId = filterId; } setFilterInterface(sp<IFilter> filter)95 void setFilterInterface(sp<IFilter> filter) { mFilter = filter; } 96 97 void testFilterDataOutput(); 98 99 void startFilterEventThread(DemuxFilterEvent event); 100 static void* __threadLoopFilter(void* threadArgs); 101 void filterThreadLoop(DemuxFilterEvent& event); 102 103 void updateFilterMQ(MQDesc& filterMQDescriptor); 104 void updateGoldenOutputMap(string goldenOutputFile); 105 bool readFilterEventData(); 106 bool dumpAvData(DemuxFilterMediaEvent event); 107 bool readRecordData(DemuxFilterTsRecordEvent event); 108 109 private: 110 struct FilterThreadArgs { 111 FilterCallback* user; 112 DemuxFilterEvent event; 113 }; 114 uint16_t mDataLength = 0; 115 std::vector<uint8_t> mDataOutputBuffer; 116 117 string mFilterIdToGoldenOutput; 118 119 uint32_t mFilterId; 120 sp<IFilter> mFilter; 121 std::unique_ptr<FilterMQ> mFilterMQ; 122 EventFlag* mFilterMQEventFlag; 123 DemuxFilterEvent mFilterEvent; 124 125 android::Mutex mMsgLock; 126 android::Mutex mFilterOutputLock; 127 android::Condition mMsgCondition; 128 android::Condition mFilterOutputCondition; 129 130 pthread_t mFilterThread; 131 132 int mPidFilterOutputCount = 0; 133 }; 134 135 class FilterTests { 136 public: setService(sp<ITuner> tuner)137 void setService(sp<ITuner> tuner) { mService = tuner; } setDemux(sp<IDemux> demux)138 void setDemux(sp<IDemux> demux) { mDemux = demux; } getFilterById(uint32_t filterId)139 sp<IFilter> getFilterById(uint32_t filterId) { return mFilters[filterId]; } 140 getFilterCallbacks()141 std::map<uint32_t, sp<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; } 142 143 AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize); 144 AssertionResult openTimeFilterInDemux(); 145 AssertionResult setTimeStamp(uint64_t timeStamp); 146 AssertionResult getTimeStamp(); 147 AssertionResult getNewlyOpenedFilterId(uint32_t& filterId); 148 AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId); 149 AssertionResult getFilterMQDescriptor(uint32_t filterId, bool getMqDesc); 150 AssertionResult setFilterDataSource(uint32_t sourceFilterId, uint32_t sinkFilterId); 151 AssertionResult setFilterDataSourceToDemux(uint32_t filterId); 152 AssertionResult startFilter(uint32_t filterId); 153 AssertionResult clearTimeStamp(); 154 AssertionResult stopFilter(uint32_t filterId); 155 AssertionResult closeFilter(uint32_t filterId); 156 AssertionResult closeTimeFilter(); 157 158 protected: failure()159 static AssertionResult failure() { return ::testing::AssertionFailure(); } 160 success()161 static AssertionResult success() { return ::testing::AssertionSuccess(); } 162 163 sp<ITuner> mService; 164 sp<IFilter> mFilter; 165 sp<ITimeFilter> mTimeFilter; 166 sp<IDemux> mDemux; 167 std::map<uint32_t, sp<IFilter>> mFilters; 168 std::map<uint32_t, sp<FilterCallback>> mFilterCallbacks; 169 170 sp<FilterCallback> mFilterCallback; 171 MQDesc mFilterMQDescriptor; 172 vector<uint32_t> mUsedFilterIds; 173 174 uint32_t mFilterId = -1; 175 uint64_t mBeginTimeStamp; 176 }; 177