blob: bc6db86f9cf38d7c1170ba3e64c00adada05ebef [file] [log] [blame]
/*
* Copyright 2020 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.
*/
#include <android-base/logging.h>
#include <android/hardware/tv/tuner/1.0/IDemux.h>
#include <android/hardware/tv/tuner/1.0/IFilter.h>
#include <android/hardware/tv/tuner/1.0/types.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/ITuner.h>
#include <android/hardware/tv/tuner/1.1/types.h>
#include <fmq/MessageQueue.h>
#include <gtest/gtest.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/Status.h>
#include <inttypes.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <map>
using android::Condition;
using android::Mutex;
using android::sp;
using android::hardware::EventFlag;
using android::hardware::hidl_handle;
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
using android::hardware::kSynchronizedReadWrite;
using android::hardware::MessageQueue;
using android::hardware::MQDescriptorSync;
using android::hardware::Return;
using android::hardware::Void;
using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
using android::hardware::tv::tuner::V1_0::DemuxFilterType;
using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
using android::hardware::tv::tuner::V1_0::IDemux;
using android::hardware::tv::tuner::V1_0::IFilter;
using android::hardware::tv::tuner::V1_0::Result;
using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt;
using android::hardware::tv::tuner::V1_1::IFilterCallback;
using android::hardware::tv::tuner::V1_1::ITuner;
using ::testing::AssertionResult;
using namespace std;
enum FilterEventType : uint8_t {
UNDEFINED,
SECTION,
MEDIA,
PES,
RECORD,
MMTPRECORD,
DOWNLOAD,
TEMI,
};
using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using MQDesc = MQDescriptorSync<uint8_t>;
#define WAIT_TIMEOUT 3000000000
class FilterCallback : public IFilterCallback {
public:
virtual Return<void> onFilterEvent_1_1(const DemuxFilterEvent& filterEvent,
const DemuxFilterEventExt& filterEventExt) override {
android::Mutex::Autolock autoLock(mMsgLock);
// Temprarily we treat the first coming back filter data on the matching pid a success
// once all of the MQ are cleared, means we got all the expected output
mFilterEvent = filterEvent;
mFilterEventExt = filterEventExt;
readFilterEventData();
mPidFilterOutputCount++;
mMsgCondition.signal();
return Void();
}
virtual Return<void> onFilterEvent(
const android::hardware::tv::tuner::V1_0::DemuxFilterEvent& filterEvent) override {
android::Mutex::Autolock autoLock(mMsgLock);
// Temprarily we treat the first coming back filter data on the matching pid a success
// once all of the MQ are cleared, means we got all the expected output
mFilterEvent = filterEvent;
readFilterEventData();
mPidFilterOutputCount++;
mMsgCondition.signal();
return Void();
}
virtual Return<void> onFilterStatus(const DemuxFilterStatus /*status*/) override {
return Void();
}
void setFilterId(uint32_t filterId) { mFilterId = filterId; }
void setFilterInterface(sp<IFilter> filter) { mFilter = filter; }
void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
void setSharedHandle(hidl_handle sharedHandle) { mAvSharedHandle = sharedHandle; }
void setMemSize(uint64_t size) { mAvSharedMemSize = size; }
void testFilterDataOutput();
void readFilterEventData();
bool dumpAvData(DemuxFilterMediaEvent event);
private:
uint32_t mFilterId;
sp<IFilter> mFilter;
FilterEventType mFilterEventType;
DemuxFilterEvent mFilterEvent;
DemuxFilterEventExt mFilterEventExt;
hidl_handle mAvSharedHandle = NULL;
uint64_t mAvSharedMemSize = -1;
android::Mutex mMsgLock;
android::Mutex mFilterOutputLock;
android::Condition mMsgCondition;
int mPidFilterOutputCount = 0;
};
class FilterTests {
public:
void setService(sp<ITuner> tuner) { mService = tuner; }
void setDemux(sp<IDemux> demux) { mDemux = demux; }
sp<IFilter> getFilterById(uint64_t filterId) { return mFilters[filterId]; }
map<uint64_t, sp<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; }
AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize);
AssertionResult getNewlyOpenedFilterId_64bit(uint64_t& filterId);
AssertionResult getSharedAvMemoryHandle(uint64_t filterId);
AssertionResult releaseShareAvHandle(uint64_t filterId);
AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId);
AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId);
AssertionResult getFilterMQDescriptor(uint64_t filterId);
AssertionResult startFilter(uint64_t filterId);
AssertionResult stopFilter(uint64_t filterId);
AssertionResult closeFilter(uint64_t filterId);
FilterEventType getFilterEventType(DemuxFilterType type) {
FilterEventType eventType = FilterEventType::UNDEFINED;
switch (type.mainType) {
case DemuxFilterMainType::TS:
switch (type.subType.tsFilterType()) {
case DemuxTsFilterType::UNDEFINED:
break;
case DemuxTsFilterType::SECTION:
eventType = FilterEventType::SECTION;
break;
case DemuxTsFilterType::PES:
eventType = FilterEventType::PES;
break;
case DemuxTsFilterType::TS:
break;
case DemuxTsFilterType::AUDIO:
case DemuxTsFilterType::VIDEO:
eventType = FilterEventType::MEDIA;
break;
case DemuxTsFilterType::PCR:
break;
case DemuxTsFilterType::RECORD:
eventType = FilterEventType::RECORD;
break;
case DemuxTsFilterType::TEMI:
eventType = FilterEventType::TEMI;
break;
}
break;
case DemuxFilterMainType::MMTP:
/*mmtpSettings*/
break;
case DemuxFilterMainType::IP:
/*ipSettings*/
break;
case DemuxFilterMainType::TLV:
/*tlvSettings*/
break;
case DemuxFilterMainType::ALP:
/*alpSettings*/
break;
default:
break;
}
return eventType;
}
protected:
static AssertionResult failure() { return ::testing::AssertionFailure(); }
static AssertionResult success() { return ::testing::AssertionSuccess(); }
sp<ITuner> mService;
sp<IFilter> mFilter;
sp<IDemux> mDemux;
map<uint64_t, sp<IFilter>> mFilters;
map<uint64_t, sp<FilterCallback>> mFilterCallbacks;
sp<FilterCallback> mFilterCallback;
MQDesc mFilterMQDescriptor;
vector<uint64_t> mUsedFilterIds;
hidl_handle mAvSharedHandle = NULL;
uint64_t mFilterId = -1;
};