Merge "Remove String8(StaticLinkage) references." am: 19b9aad80d am: 553896d8e7 am: 584e8003c1 am: 8f95ae1218 am: 167ebf38f4
Change-Id: Ife1552bcad9121fcd584aa2118b774282eec3eac
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index b2806c7..67217ab 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -903,6 +903,25 @@
SONIFICATION = 4,
};
+/** Encapsulation mode used for sending audio compressed data. */
+@export(name="audio_encapsulation_mode_t", value_prefix="AUDIO_ENCAPSULATION_MODE_")
+enum AudioEncapsulationMode : int32_t {
+ // Do not change these values without updating their counterparts
+ // in frameworks/base/media/java/android/media/AudioTrack.java
+ /**
+ * No encapsulation mode for metadata.
+ */
+ NONE = 0,
+ /**
+ * Elementary stream payload with metadata
+ */
+ ELEMENTARY_STREAM = 1,
+ /**
+ * Handle-based payload with metadata
+ */
+ HANDLE = 2,
+};
+
/**
* Additional information about the stream passed to hardware decoders.
*/
@@ -918,6 +937,9 @@
uint32_t bitWidth;
uint32_t bufferSize;
AudioUsage usage;
+ AudioEncapsulationMode encapsulationMode;
+ int32_t contentId;
+ int32_t syncId;
};
/**
diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp
index 08002c8..a470c9c 100644
--- a/audio/common/all-versions/default/HidlUtils.cpp
+++ b/audio/common/all-versions/default/HidlUtils.cpp
@@ -28,12 +28,13 @@
namespace CPP_VERSION {
namespace implementation {
-void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
+status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
config->sampleRateHz = halConfig.sample_rate;
config->channelMask = EnumBitfield<AudioChannelMask>(halConfig.channel_mask);
config->format = AudioFormat(halConfig.format);
- audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
+ status_t status = audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
config->frameCount = halConfig.frame_count;
+ return status;
}
void HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) {
@@ -106,8 +107,8 @@
return static_cast<audio_usage_t>(usage);
}
-void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
- AudioOffloadInfo* offload) {
+status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
+ AudioOffloadInfo* offload) {
offload->sampleRateHz = halOffload.sample_rate;
offload->channelMask = EnumBitfield<AudioChannelMask>(halOffload.channel_mask);
offload->format = AudioFormat(halOffload.format);
@@ -119,6 +120,26 @@
offload->bitWidth = halOffload.bit_width;
offload->bufferSize = halOffload.offload_buffer_size;
offload->usage = audioUsageFromHal(halOffload.usage);
+#if MAJOR_VERSION >= 6
+ if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
+ offload->encapsulationMode =
+ static_cast<AudioEncapsulationMode>(halOffload.encapsulation_mode);
+ offload->contentId = halOffload.content_id;
+ offload->syncId = halOffload.sync_id;
+ } else {
+ offload->encapsulationMode = AudioEncapsulationMode::NONE;
+ offload->contentId = 0;
+ offload->syncId = 0;
+ }
+#else
+ // nonzero values here are not compatible with HAL versions below 6.
+ if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2 &&
+ (halOffload.encapsulation_mode != AUDIO_ENCAPSULATION_MODE_NONE ||
+ halOffload.content_id != 0 || halOffload.sync_id != 0)) {
+ return BAD_VALUE;
+ }
+#endif
+ return OK;
}
void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload,
@@ -135,6 +156,14 @@
halOffload->bit_width = offload.bitWidth;
halOffload->offload_buffer_size = offload.bufferSize;
halOffload->usage = audioUsageToHal(offload.usage);
+#if MAJOR_VERSION >= 6
+ halOffload->encapsulation_mode =
+ static_cast<audio_encapsulation_mode_t>(offload.encapsulationMode);
+ halOffload->content_id = offload.contentId;
+ halOffload->sync_id = offload.syncId;
+#else
+ // offload doesn't contain encapsulationMode, contentId, syncId, so this is OK.
+#endif
}
void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig,
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 758a7f4..ef6dee3 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -35,8 +35,11 @@
using namespace ::android::hardware::audio::common::CPP_VERSION;
class HidlUtils {
- public:
- static void audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config);
+ public:
+ // A failure here indicates a platform config that is incompatible with
+ // the compiled HIDL interface version.
+ static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config);
+
static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig);
static void audioGainConfigFromHal(const struct audio_gain_config& halConfig,
AudioGainConfig* config);
@@ -46,8 +49,10 @@
static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain);
static AudioUsage audioUsageFromHal(const audio_usage_t halUsage);
static audio_usage_t audioUsageToHal(const AudioUsage usage);
- static void audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
- AudioOffloadInfo* offload);
+ // A failure here indicates a platform offload info that is incompatible with
+ // the compiled HIDL interface version.
+ static status_t audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
+ AudioOffloadInfo* offload);
static void audioOffloadInfoToHal(const AudioOffloadInfo& offload,
audio_offload_info_t* halOffload);
static void audioPortConfigFromHal(const struct audio_port_config& halConfig,
@@ -58,7 +63,7 @@
const struct audio_port_config* halConfigs,
hidl_vec<AudioPortConfig>* configs);
static std::unique_ptr<audio_port_config[]> audioPortConfigsToHal(
- const hidl_vec<AudioPortConfig>& configs);
+ const hidl_vec<AudioPortConfig>& configs);
static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port);
static void audioPortToHal(const AudioPort& port, struct audio_port* halPort);
static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid);
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 47e31c1..6260ba1 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -171,7 +171,8 @@
streamOut = new StreamOut(this, halStream);
++mOpenedStreamsCount;
}
- HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
}
@@ -198,7 +199,8 @@
streamIn = new StreamIn(this, halStream);
++mOpenedStreamsCount;
}
- HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
}
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index f518a15..677b496 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -20,6 +20,7 @@
#include <algorithm>
#include <array>
+#include <regex>
#include <linux/videodev2.h>
#include "android-base/macros.h"
#include "CameraMetadata.h"
@@ -46,10 +47,20 @@
} // anonymous namespace
+const std::regex kDevicePathRE("/dev/video([0-9]+)");
+
ExternalCameraDevice::ExternalCameraDevice(
- const std::string& cameraId, const ExternalCameraConfig& cfg) :
- mCameraId(cameraId),
- mCfg(cfg) {}
+ const std::string& devicePath, const ExternalCameraConfig& cfg) :
+ mCameraId("-1"),
+ mDevicePath(devicePath),
+ mCfg(cfg) {
+ std::smatch sm;
+ if (std::regex_match(mDevicePath, sm, kDevicePathRE)) {
+ mCameraId = std::to_string(mCfg.cameraIdOffset + std::stoi(sm[1]));
+ } else {
+ ALOGE("%s: device path match failed for %s", __FUNCTION__, mDevicePath.c_str());
+ }
+}
ExternalCameraDevice::~ExternalCameraDevice() {}
@@ -129,20 +140,20 @@
return Void();
}
- unique_fd fd(::open(mCameraId.c_str(), O_RDWR));
+ unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
if (fd.get() < 0) {
int numAttempt = 0;
do {
ALOGW("%s: v4l2 device %s open failed, wait 33ms and try again",
- __FUNCTION__, mCameraId.c_str());
+ __FUNCTION__, mDevicePath.c_str());
usleep(OPEN_RETRY_SLEEP_US); // sleep and try again
- fd.reset(::open(mCameraId.c_str(), O_RDWR));
+ fd.reset(::open(mDevicePath.c_str(), O_RDWR));
numAttempt++;
} while (fd.get() < 0 && numAttempt <= MAX_RETRY);
if (fd.get() < 0) {
ALOGE("%s: v4l2 device open %s failed: %s",
- __FUNCTION__, mCameraId.c_str(), strerror(errno));
+ __FUNCTION__, mDevicePath.c_str(), strerror(errno));
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
@@ -203,9 +214,9 @@
status_t ExternalCameraDevice::initCameraCharacteristics() {
if (mCameraCharacteristics.isEmpty()) {
// init camera characteristics
- unique_fd fd(::open(mCameraId.c_str(), O_RDWR));
+ unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
if (fd.get() < 0) {
- ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mCameraId.c_str());
+ ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mDevicePath.c_str());
return DEAD_OBJECT;
}
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 62a4c87..8f4626c 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -703,6 +703,7 @@
namespace common {
namespace {
+ const int kDefaultCameraIdOffset = 100;
const int kDefaultJpegBufSize = 5 << 20; // 5MB
const int kDefaultNumVideoBuffer = 4;
const int kDefaultNumStillBuffer = 2;
@@ -738,6 +739,11 @@
return ret;
}
+ XMLElement *cameraIdOffset = providerCfg->FirstChildElement("CameraIdOffset");
+ if (cameraIdOffset != nullptr) {
+ ret.cameraIdOffset = std::atoi(cameraIdOffset->GetText());
+ }
+
XMLElement *ignore = providerCfg->FirstChildElement("ignore");
if (ignore == nullptr) {
ALOGI("%s: no internal ignored device specified", __FUNCTION__);
@@ -874,6 +880,7 @@
}
ExternalCameraConfig::ExternalCameraConfig() :
+ cameraIdOffset(kDefaultCameraIdOffset),
maxJpegBufSize(kDefaultJpegBufSize),
numVideoBuffers(kDefaultNumVideoBuffer),
numStillBuffers(kDefaultNumStillBuffer),
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
index 1958fcb..88726f4 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
@@ -149,6 +149,7 @@
bool mInitialized = false;
bool mInitFailed = false;
std::string mCameraId;
+ std::string mDevicePath;
const ExternalCameraConfig& mCfg;
std::vector<SupportedV4L2Format> mSupportedFormats;
CroppingType mCroppingType;
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index 74f75eb..b354406 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -68,6 +68,9 @@
static const char* kDefaultCfgPath;
static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
+ // CameraId base offset for numerical representation
+ uint32_t cameraIdOffset;
+
// List of internal V4L2 video nodes external camera HAL must ignore.
std::unordered_set<std::string> mInternalDevices;
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 2bfced2..64a51f6 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -44,17 +44,19 @@
const char* kDevicePath = "/dev/";
constexpr char kPrefix[] = "video";
constexpr int kPrefixLen = sizeof(kPrefix) - 1;
+constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
-bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
- std::string* cameraId) {
+bool matchDeviceName(int cameraIdOffset,
+ const hidl_string& deviceName, std::string* deviceVersion,
+ std::string* cameraDevicePath) {
std::string deviceNameStd(deviceName.c_str());
std::smatch sm;
if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
if (deviceVersion != nullptr) {
*deviceVersion = sm[1];
}
- if (cameraId != nullptr) {
- *cameraId = sm[2];
+ if (cameraDevicePath != nullptr) {
+ *cameraDevicePath = "/dev/video" + std::to_string(std::stoi(sm[2]) - cameraIdOffset);
}
return true;
}
@@ -146,8 +148,9 @@
const hidl_string& cameraDeviceName,
ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
- std::string cameraId, deviceVersion;
- bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
+ std::string cameraDevicePath, deviceVersion;
+ bool match = matchDeviceName(mCfg.cameraIdOffset, cameraDeviceName,
+ &deviceVersion, &cameraDevicePath);
if (!match) {
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
@@ -164,19 +167,19 @@
case 4: {
ALOGV("Constructing v3.4 external camera device");
deviceImpl = new device::V3_4::implementation::ExternalCameraDevice(
- cameraId, mCfg);
+ cameraDevicePath, mCfg);
break;
}
case 5: {
ALOGV("Constructing v3.5 external camera device");
deviceImpl = new device::V3_5::implementation::ExternalCameraDevice(
- cameraId, mCfg);
+ cameraDevicePath, mCfg);
break;
}
case 6: {
ALOGV("Constructing v3.6 external camera device");
deviceImpl = new device::V3_6::implementation::ExternalCameraDevice(
- cameraId, mCfg);
+ cameraDevicePath, mCfg);
break;
}
default:
@@ -186,7 +189,7 @@
}
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
- ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
+ ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraDevicePath.c_str());
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
@@ -210,12 +213,14 @@
ALOGI("ExtCam: adding %s to External Camera HAL!", devName);
Mutex::Autolock _l(mLock);
std::string deviceName;
+ std::string cameraId = std::to_string(mCfg.cameraIdOffset +
+ std::atoi(devName + kDevicePrefixLen));
if (mPreferredHal3MinorVersion == 6) {
- deviceName = std::string("device@3.6/external/") + devName;
+ deviceName = std::string("device@3.6/external/") + cameraId;
} else if (mPreferredHal3MinorVersion == 5) {
- deviceName = std::string("device@3.5/external/") + devName;
+ deviceName = std::string("device@3.5/external/") + cameraId;
} else {
- deviceName = std::string("device@3.4/external/") + devName;
+ deviceName = std::string("device@3.4/external/") + cameraId;
}
mCameraStatusMap[deviceName] = CameraDeviceStatus::PRESENT;
if (mCallbacks != nullptr) {
@@ -259,12 +264,14 @@
void ExternalCameraProviderImpl_2_4::deviceRemoved(const char* devName) {
Mutex::Autolock _l(mLock);
std::string deviceName;
+ std::string cameraId = std::to_string(mCfg.cameraIdOffset +
+ std::atoi(devName + kDevicePrefixLen));
if (mPreferredHal3MinorVersion == 6) {
- deviceName = std::string("device@3.6/external/") + devName;
+ deviceName = std::string("device@3.6/external/") + cameraId;
} else if (mPreferredHal3MinorVersion == 5) {
- deviceName = std::string("device@3.5/external/") + devName;
+ deviceName = std::string("device@3.5/external/") + cameraId;
} else {
- deviceName = std::string("device@3.4/external/") + devName;
+ deviceName = std::string("device@3.4/external/") + cameraId;
}
if (mCameraStatusMap.find(deviceName) != mCameraStatusMap.end()) {
mCameraStatusMap.erase(deviceName);
diff --git a/current.txt b/current.txt
index 96de2c7..5f5758c 100644
--- a/current.txt
+++ b/current.txt
@@ -613,7 +613,7 @@
2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn
e6cd2b7c1a86b6ca683c0224ffde3b73aa14f6487de9f46833e539d26d1b3b5c android.hardware.audio@6.0::IStreamOut
997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback
-167ed5cfb7d91db2e2bf20f1320c1a9004eeb768e26f535e0f7db94a21867d21 android.hardware.audio.common@6.0::types
+bee662c62d997d8065e2bcb5c1e7a9578931f22ce28fd02c219fdb4d0630abf7 android.hardware.audio.common@6.0::types
817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types
525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect
8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index c78c358..3becace 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -69,9 +69,8 @@
[](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* {
return &settings;
});
- mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers,
- mGraphicBuffer->getNativeBuffer(), true, std::move(bufferFence),
- &readyFence);
+ mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true,
+ std::move(bufferFence), &readyFence);
int fd = readyFence.release();
if (fd != -1) {
ASSERT_EQ(0, sync_wait(fd, -1));
diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp
index dd2f8a6..7e206a7 100644
--- a/tv/tuner/1.0/default/Frontend.cpp
+++ b/tv/tuner/1.0/default/Frontend.cpp
@@ -81,6 +81,10 @@
Return<Result> Frontend::scan(const FrontendSettings& /* settings */, FrontendScanType /* type */) {
ALOGV("%s", __FUNCTION__);
+ FrontendScanMessage msg;
+ msg.isLocked(true);
+ mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+
return Result::SUCCESS;
}
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 820c58c..f693e7c 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -44,6 +44,8 @@
#include <iostream>
#include <map>
+#include "VtsHalTvTunerV1_0TestConfigurations.h"
+
#define WAIT_TIMEOUT 3000000000
#define WAIT_TIMEOUT_data_ready 3000000000 * 4
@@ -84,9 +86,11 @@
using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
using android::hardware::tv::tuner::V1_0::FrontendEventType;
using android::hardware::tv::tuner::V1_0::FrontendId;
+using android::hardware::tv::tuner::V1_0::FrontendInfo;
using android::hardware::tv::tuner::V1_0::FrontendInnerFec;
using android::hardware::tv::tuner::V1_0::FrontendScanMessage;
using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using android::hardware::tv::tuner::V1_0::FrontendScanType;
using android::hardware::tv::tuner::V1_0::FrontendSettings;
using android::hardware::tv::tuner::V1_0::IDemux;
using android::hardware::tv::tuner::V1_0::IDescrambler;
@@ -103,6 +107,8 @@
using android::hardware::tv::tuner::V1_0::RecordStatus;
using android::hardware::tv::tuner::V1_0::Result;
+using ::testing::AssertionResult;
+
namespace {
using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
@@ -150,11 +156,7 @@
// const uint16_t FMQ_SIZE_4K = 0x1000;
const uint32_t FMQ_SIZE_1M = 0x100000;
const uint32_t FMQ_SIZE_16M = 0x1000000;
-
-struct FilterConf {
- DemuxFilterType type;
- DemuxFilterSettings setting;
-};
+const uint8_t FRONTEND_EVENT_CALLBACK_WAIT_COUNT = 4;
enum FilterEventType : uint8_t {
UNDEFINED,
@@ -172,6 +174,7 @@
PlaybackSettings setting;
};
+/******************************** Start FrontendCallback **********************************/
class FrontendCallback : public IFrontendCallback {
public:
virtual Return<void> onEvent(FrontendEventType frontendEventType) override {
@@ -182,28 +185,38 @@
return Void();
}
- virtual Return<void> onScanMessage(FrontendScanMessageType /* type */,
- const FrontendScanMessage& /* message */) override {
+ virtual Return<void> onScanMessage(FrontendScanMessageType type,
+ const FrontendScanMessage& message) override {
android::Mutex::Autolock autoLock(mMsgLock);
+ ALOGD("[vts] scan message. Type: %d", mScanMessageType);
mScanMessageReceived = true;
+ mScanMessageType = type;
+ mScanLockMessageReceived =
+ mScanLockMessageReceived | (type == FrontendScanMessageType::LOCKED);
+ mScanMessage = message;
mMsgCondition.signal();
return Void();
};
- void testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings);
- void testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings);
+ void tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings);
+ void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings);
+ void scanTestOnMessageLock(sp<IFrontend>& frontend, FrontendSettings settings,
+ FrontendScanType type);
private:
bool mEventReceived = false;
- bool mDiseqcMessageReceived = false;
bool mScanMessageReceived = false;
+ bool mScanLockMessageReceived = false;
FrontendEventType mEventType;
+ FrontendScanMessageType mScanMessageType;
+ FrontendScanMessage mScanMessage;
hidl_vec<uint8_t> mEventMessage;
android::Mutex mMsgLock;
android::Condition mMsgCondition;
+ uint8_t mOnEvenRetry = 0;
};
-void FrontendCallback::testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings) {
+void FrontendCallback::tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings) {
Result result = frontend->tune(settings);
EXPECT_TRUE(result == Result::SUCCESS);
@@ -215,29 +228,77 @@
return;
}
}
+ mEventReceived = false;
}
-void FrontendCallback::testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings) {
+void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings) {
Result result = frontend->tune(settings);
EXPECT_TRUE(result == Result::SUCCESS);
android::Mutex::Autolock autoLock(mMsgLock);
- while (!mDiseqcMessageReceived) {
+wait:
+ while (!mEventReceived) {
if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
- EXPECT_TRUE(false) << "diseqc message not received within timeout";
+ EXPECT_TRUE(false) << "event not received within timeout";
return;
}
}
+ if (mEventType != FrontendEventType::LOCKED) {
+ ALOGD("[vts] frontend callback event received. Type: %d", mEventType);
+ mEventReceived = false;
+ if (mOnEvenRetry++ < FRONTEND_EVENT_CALLBACK_WAIT_COUNT) {
+ goto wait;
+ }
+ }
+ EXPECT_TRUE(mEventType == FrontendEventType::LOCKED) << "LOCK event not received";
+ mEventReceived = false;
+ mOnEvenRetry = 0;
}
+void FrontendCallback::scanTestOnMessageLock(sp<IFrontend>& frontend, FrontendSettings settings,
+ FrontendScanType type) {
+ Result result = frontend->scan(settings, type);
+ EXPECT_TRUE(result == Result::SUCCESS);
+ android::Mutex::Autolock autoLock(mMsgLock);
+ int messagesCount = 0;
+
+wait:
+ int count = 0;
+ while (!mScanMessageReceived) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ ALOGD("[vts] waiting for scan message callback...");
+ if (count++ > 10) {
+ EXPECT_TRUE(false) << "WAITING TOO LONG!!";
+ return;
+ }
+ }
+ }
+
+ if (mScanMessageType != FrontendScanMessageType::END) {
+ ALOGD("[vts] frontend scan message received. Type: %d", mScanMessageType);
+ mScanMessageReceived = false;
+ if (messagesCount++ > 3) {
+ EXPECT_TRUE(false) << "WAITING ON TOO MANY MSGS!!";
+ return;
+ }
+ goto wait;
+ }
+
+ EXPECT_TRUE(mScanLockMessageReceived) << "scan lock message not received before scan ended";
+ mScanMessageReceived = false;
+ mScanLockMessageReceived = false;
+}
+/******************************** End FrontendCallback **********************************/
+
+/******************************** Start FilterCallback **********************************/
class FilterCallback : public IFilterCallback {
public:
virtual Return<void> onFilterEvent(const 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
- mFilterIdToEvent = filterEvent;
+ mFilterEvent = filterEvent;
readFilterEventData();
mPidFilterOutputCount++;
// mFilterIdToMQ.erase(filterEvent.filterId);
@@ -276,9 +337,9 @@
uint32_t mFilterId;
FilterEventType mFilterEventType;
- std::unique_ptr<FilterMQ> mFilterIdToMQ;
- EventFlag* mFilterIdToMQEventFlag;
- DemuxFilterEvent mFilterIdToEvent;
+ std::unique_ptr<FilterMQ> mFilterMQ;
+ EventFlag* mFilterMQEventFlag;
+ DemuxFilterEvent mFilterEvent;
android::Mutex mMsgLock;
android::Mutex mFilterOutputLock;
@@ -313,10 +374,10 @@
}
void FilterCallback::updateFilterMQ(MQDesc& filterMQDescriptor) {
- mFilterIdToMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
- EXPECT_TRUE(mFilterIdToMQ);
- EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ->getEventFlagWord(),
- &mFilterIdToMQEventFlag) == android::OK);
+ mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mFilterMQ);
+ EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
+ android::OK);
}
void FilterCallback::updateGoldenOutputMap(string goldenOutputFile) {
@@ -332,7 +393,7 @@
void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
android::Mutex::Autolock autoLock(mFilterOutputLock);
- // Read from mFilterIdToMQ[event.filterId] per event and filter type
+ // Read from mFilterMQ[event.filterId] per event and filter type
// Assemble to filterOutput[filterId]
@@ -345,7 +406,7 @@
bool FilterCallback::readFilterEventData() {
bool result = false;
- DemuxFilterEvent filterEvent = mFilterIdToEvent;
+ DemuxFilterEvent filterEvent = mFilterEvent;
ALOGW("[vts] reading from filter FMQ %d", mFilterId);
// todo separate filter handlers
for (int i = 0; i < filterEvent.events.size(); i++) {
@@ -357,6 +418,7 @@
mDataLength = filterEvent.events[i].pes().dataLength;
break;
case FilterEventType::MEDIA:
+ mDataLength = filterEvent.events[i].media().dataLength;
break;
case FilterEventType::RECORD:
break;
@@ -371,17 +433,19 @@
// match";
mDataOutputBuffer.resize(mDataLength);
- result = mFilterIdToMQ->read(mDataOutputBuffer.data(), mDataLength);
+ result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
EXPECT_TRUE(result) << "can't read from Filter MQ";
/*for (int i = 0; i < mDataLength; i++) {
EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
}*/
}
- mFilterIdToMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+ mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
return result;
}
+/******************************** End FilterCallback **********************************/
+/******************************** Start DvrCallback **********************************/
class DvrCallback : public IDvrCallback {
public:
virtual Return<void> onRecordStatus(DemuxFilterStatus status) override {
@@ -445,11 +509,10 @@
uint16_t mDataLength = 0;
std::vector<uint8_t> mDataOutputBuffer;
- std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterIdToMQ;
+ std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ;
std::unique_ptr<FilterMQ> mPlaybackMQ;
std::unique_ptr<FilterMQ> mRecordMQ;
- std::map<uint32_t, EventFlag*> mFilterIdToMQEventFlag;
- std::map<uint32_t, DemuxFilterEvent> mFilterIdToEvent;
+ std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
android::Mutex mMsgLock;
android::Mutex mPlaybackThreadLock;
@@ -635,22 +698,32 @@
mRecordThreadRunning = false;
android::Mutex::Autolock autoLock(mRecordThreadLock);
}
+/********************************** End DvrCallback ************************************/
+/***************************** Start Test Implementation ******************************/
class TunerHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
+ initFrontendConfig();
+ initFrontendScanConfig();
+ initFilterConfig();
}
sp<ITuner> mService;
protected:
+ static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+ static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
static void description(const std::string& description) {
RecordProperty("description", description);
}
sp<IFrontend> mFrontend;
+ FrontendInfo mFrontendInfo;
sp<FrontendCallback> mFrontendCallback;
sp<IDescrambler> mDescrambler;
sp<IDemux> mDemux;
@@ -661,274 +734,165 @@
sp<FilterCallback> mFilterCallback;
sp<DvrCallback> mDvrCallback;
MQDesc mFilterMQDescriptor;
- MQDesc mPlaybackMQDescriptor;
+ MQDesc mDvrMQDescriptor;
MQDesc mRecordMQDescriptor;
vector<uint32_t> mUsedFilterIds;
+ hidl_vec<FrontendId> mFeIds;
uint32_t mDemuxId;
- uint32_t mFilterId;
+ uint32_t mFilterId = -1;
pthread_t mPlaybackshread;
bool mPlaybackThreadRunning;
- ::testing::AssertionResult createFrontend(int32_t frontendId);
- ::testing::AssertionResult tuneFrontend(int32_t frontendId);
- ::testing::AssertionResult stopTuneFrontend(int32_t frontendId);
- ::testing::AssertionResult closeFrontend(int32_t frontendId);
- ::testing::AssertionResult createDemux();
- ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId,
- FrontendSettings settings);
- ::testing::AssertionResult getPlaybackMQDescriptor();
- ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting);
- ::testing::AssertionResult getRecordMQDescriptor();
- ::testing::AssertionResult addRecordToDemux(RecordSettings setting);
- ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting);
- ::testing::AssertionResult getFilterMQDescriptor();
- ::testing::AssertionResult closeDemux();
- ::testing::AssertionResult createDescrambler();
- ::testing::AssertionResult closeDescrambler();
+ AssertionResult getFrontendIds();
+ AssertionResult getFrontendInfo(uint32_t frontendId);
+ AssertionResult openFrontend(uint32_t frontendId);
+ AssertionResult setFrontendCallback();
+ AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
+ AssertionResult stopScanFrontend();
+ AssertionResult tuneFrontend(FrontendConfig config);
+ AssertionResult stopTuneFrontend();
+ AssertionResult closeFrontend();
- ::testing::AssertionResult playbackDataFlowTest(vector<FilterConf> filterConf,
- PlaybackConf playbackConf,
- vector<string> goldenOutputFiles);
- ::testing::AssertionResult recordDataFlowTest(vector<FilterConf> filterConf,
- RecordSettings recordSetting,
- vector<string> goldenOutputFiles);
- ::testing::AssertionResult broadcastDataFlowTest(vector<FilterConf> filterConf,
- vector<string> goldenOutputFiles);
+ AssertionResult openDemux();
+ AssertionResult setDemuxFrontendDataSource(uint32_t frontendId);
+ AssertionResult closeDemux();
+
+ AssertionResult openDvrInDemux(DvrType type);
+ AssertionResult configDvr(DvrSettings setting);
+ AssertionResult getDvrMQDescriptor();
+
+ AssertionResult openFilterInDemux(DemuxFilterType type);
+ AssertionResult getNewlyOpenedFilterId(uint32_t& filterId);
+ AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId);
+ AssertionResult getFilterMQDescriptor(uint32_t filterId);
+ AssertionResult startFilter(uint32_t filterId);
+ AssertionResult stopFilter(uint32_t filterId);
+ AssertionResult closeFilter(uint32_t filterId);
+
+ AssertionResult createDescrambler();
+ AssertionResult closeDescrambler();
+
+ AssertionResult playbackDataFlowTest(vector<FilterConfig> filterConf, PlaybackConf playbackConf,
+ vector<string> goldenOutputFiles);
+ AssertionResult recordDataFlowTest(vector<FilterConfig> filterConf,
+ RecordSettings recordSetting,
+ vector<string> goldenOutputFiles);
+ AssertionResult broadcastDataFlowTest(vector<string> goldenOutputFiles);
+
+ FilterEventType getFilterEventType(DemuxFilterType type);
};
-::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) {
+/*========================== Start Frontend APIs Tests Implementation ==========================*/
+AssertionResult TunerHidlTest::getFrontendIds() {
Result status;
+ mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+ status = result;
+ mFeIds = frontendIds;
+ });
+ return AssertionResult(status == Result::SUCCESS);
+}
+AssertionResult TunerHidlTest::getFrontendInfo(uint32_t frontendId) {
+ Result status;
+ mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) {
+ mFrontendInfo = frontendInfo;
+ status = result;
+ });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::openFrontend(uint32_t frontendId) {
+ Result status;
mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
mFrontend = frontend;
status = result;
});
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
+ return AssertionResult(status == Result::SUCCESS);
+}
+AssertionResult TunerHidlTest::setFrontendCallback() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
mFrontendCallback = new FrontendCallback();
auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
-
- return ::testing::AssertionResult(callbackStatus.isOk());
+ return AssertionResult(callbackStatus.isOk());
}
-::testing::AssertionResult TunerHidlTest::tuneFrontend(int32_t frontendId) {
- if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
+AssertionResult TunerHidlTest::scanFrontend(FrontendConfig config, FrontendScanType type) {
+ EXPECT_TRUE(mFrontendCallback)
+ << "test with openFrontend/setFrontendCallback/getFrontendInfo first.";
- // Frontend Settings for testing
- FrontendSettings frontendSettings;
- FrontendAtscSettings frontendAtscSettings{
- .frequency = 0,
- .modulation = FrontendAtscModulation::UNDEFINED,
- };
- frontendSettings.atsc(frontendAtscSettings);
- mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
+ EXPECT_TRUE(mFrontendInfo.type == config.type)
+ << "FrontendConfig does not match the frontend info of the given id.";
- FrontendDvbtSettings frontendDvbtSettings{
- .frequency = 0,
- };
- frontendSettings.dvbt(frontendDvbtSettings);
- mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
-
- return ::testing::AssertionResult(true);
+ mFrontendCallback->scanTestOnMessageLock(mFrontend, config.settings, type);
+ return AssertionResult(true);
}
-::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) {
+AssertionResult TunerHidlTest::stopScanFrontend() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
Result status;
- if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
+ status = mFrontend->stopScan();
+ return AssertionResult(status == Result::SUCCESS);
+}
+AssertionResult TunerHidlTest::tuneFrontend(FrontendConfig config) {
+ EXPECT_TRUE(mFrontendCallback)
+ << "test with openFrontend/setFrontendCallback/getFrontendInfo first.";
+
+ EXPECT_TRUE(mFrontendInfo.type == config.type)
+ << "FrontendConfig does not match the frontend info of the given id.";
+
+ mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
+ return AssertionResult(true);
+}
+
+AssertionResult TunerHidlTest::stopTuneFrontend() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
+ Result status;
status = mFrontend->stopTune();
- return ::testing::AssertionResult(status == Result::SUCCESS);
+ return AssertionResult(status == Result::SUCCESS);
}
-::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) {
+AssertionResult TunerHidlTest::closeFrontend() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
Result status;
- if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
status = mFrontend->close();
mFrontend = nullptr;
- return ::testing::AssertionResult(status == Result::SUCCESS);
+ mFrontendCallback = nullptr;
+ return AssertionResult(status == Result::SUCCESS);
}
+/*=========================== End Frontend APIs Tests Implementation ===========================*/
-::testing::AssertionResult TunerHidlTest::createDemux() {
+/*============================ Start Demux APIs Tests Implementation ============================*/
+AssertionResult TunerHidlTest::openDemux() {
Result status;
-
mService->openDemux([&](Result result, uint32_t demuxId, const sp<IDemux>& demux) {
mDemux = demux;
mDemuxId = demuxId;
status = result;
});
- return ::testing::AssertionResult(status == Result::SUCCESS);
+ return AssertionResult(status == Result::SUCCESS);
}
-::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId,
- FrontendSettings settings) {
- Result status;
-
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- mFrontendCallback->testOnEvent(mFrontend, settings);
-
- status = mDemux->setFrontendDataSource(frontendId);
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
+AssertionResult TunerHidlTest::setDemuxFrontendDataSource(uint32_t frontendId) {
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
+ auto status = mDemux->setFrontendDataSource(frontendId);
+ return AssertionResult(status.isOk());
}
-::testing::AssertionResult TunerHidlTest::closeDemux() {
- Result status;
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- status = mDemux->close();
+AssertionResult TunerHidlTest::closeDemux() {
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ auto status = mDemux->close();
mDemux = nullptr;
- return ::testing::AssertionResult(status == Result::SUCCESS);
+ return AssertionResult(status.isOk());
}
-::testing::AssertionResult TunerHidlTest::createDescrambler() {
+AssertionResult TunerHidlTest::openFilterInDemux(DemuxFilterType type) {
Result status;
-
- mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) {
- mDescrambler = descrambler;
- status = result;
- });
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
-
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- status = mDescrambler->setDemuxSource(mDemuxId);
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
-
- // Test if demux source can be set more than once.
- status = mDescrambler->setDemuxSource(mDemuxId);
- return ::testing::AssertionResult(status == Result::INVALID_STATE);
-}
-
-::testing::AssertionResult TunerHidlTest::closeDescrambler() {
- Result status;
- if (!mDescrambler && createDescrambler() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- status = mDescrambler->close();
- mDescrambler = nullptr;
- return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addPlaybackToDemux(PlaybackSettings setting) {
- Result status;
-
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- // Create dvr callback
- mDvrCallback = new DvrCallback();
-
- // Add playback input to the local demux
- mDemux->openDvr(DvrType::PLAYBACK, FMQ_SIZE_1M, mDvrCallback,
- [&](Result result, const sp<IDvr>& dvr) {
- mDvr = dvr;
- status = result;
- });
-
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
-
- DvrSettings dvrSetting;
- dvrSetting.playback(setting);
- status = mDvr->configure(dvrSetting);
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::getPlaybackMQDescriptor() {
- Result status;
-
- if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) {
- return ::testing::AssertionFailure();
- }
-
- mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
- mPlaybackMQDescriptor = dvrMQDesc;
- status = result;
- });
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addRecordToDemux(RecordSettings setting) {
- Result status;
-
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
-
- // Create dvr callback
- mDvrCallback = new DvrCallback();
-
- // Add playback input to the local demux
- mDemux->openDvr(DvrType::RECORD, FMQ_SIZE_1M, mDvrCallback,
- [&](Result result, const sp<IDvr>& dvr) {
- mDvr = dvr;
- status = result;
- });
-
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
-
- DvrSettings dvrSetting;
- dvrSetting.record(setting);
- status = mDvr->configure(dvrSetting);
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::getRecordMQDescriptor() {
- Result status;
-
- if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) {
- return ::testing::AssertionFailure();
- }
-
- mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
- mRecordMQDescriptor = dvrMQDesc;
- status = result;
- });
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addFilterToDemux(DemuxFilterType type,
- DemuxFilterSettings setting) {
- Result status;
-
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
// Create demux callback
mFilterCallback = new FilterCallback();
@@ -940,21 +904,322 @@
status = result;
});
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
+ if (status == Result::SUCCESS) {
+ mFilterCallback->setFilterEventType(getFilterEventType(type));
}
+ return AssertionResult(status == Result::SUCCESS);
+}
+/*============================ End Demux APIs Tests Implementation ============================*/
+
+/*=========================== Start Filter APIs Tests Implementation ===========================*/
+AssertionResult TunerHidlTest::getNewlyOpenedFilterId(uint32_t& filterId) {
+ Result status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first.";
+ EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first.";
+
mFilter->getId([&](Result result, uint32_t filterId) {
mFilterId = filterId;
status = result;
});
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
+ if (status == Result::SUCCESS) {
+ mFilterCallback->setFilterId(mFilterId);
+ mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
+ mFilters[mFilterId] = mFilter;
+ mFilterCallbacks[mFilterId] = mFilterCallback;
+ filterId = mFilterId;
}
- mFilterCallback->setFilterId(mFilterId);
+ return AssertionResult(status == Result::SUCCESS || status == Result::UNAVAILABLE);
+}
+AssertionResult TunerHidlTest::configFilter(DemuxFilterSettings setting, uint32_t filterId) {
+ Result status;
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ status = mFilters[filterId]->configure(setting);
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::getFilterMQDescriptor(uint32_t filterId) {
+ Result status;
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+ mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
+ mFilterMQDescriptor = filterMQDesc;
+ status = result;
+ });
+
+ if (status == Result::SUCCESS) {
+ mFilterCallbacks[filterId]->updateFilterMQ(mFilterMQDescriptor);
+ }
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::startFilter(uint32_t filterId) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status = mFilters[filterId]->start();
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::stopFilter(uint32_t filterId) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status = mFilters[filterId]->stop();
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status = mFilters[filterId]->close();
+ if (status == Result::SUCCESS) {
+ for (int i = 0; i < mUsedFilterIds.size(); i++) {
+ if (mUsedFilterIds[i] == filterId) {
+ mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
+ break;
+ }
+ }
+ mFilterCallbacks.erase(filterId);
+ mFilters.erase(filterId);
+ }
+ return AssertionResult(status == Result::SUCCESS);
+}
+/*=========================== End Filter APIs Tests Implementation ===========================*/
+
+/*======================== Start Descrambler APIs Tests Implementation ========================*/
+AssertionResult TunerHidlTest::createDescrambler() {
+ Result status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) {
+ mDescrambler = descrambler;
+ status = result;
+ });
+ if (status != Result::SUCCESS) {
+ return failure();
+ }
+
+ status = mDescrambler->setDemuxSource(mDemuxId);
+ if (status != Result::SUCCESS) {
+ return failure();
+ }
+
+ // Test if demux source can be set more than once.
+ status = mDescrambler->setDemuxSource(mDemuxId);
+ return AssertionResult(status == Result::INVALID_STATE);
+}
+
+AssertionResult TunerHidlTest::closeDescrambler() {
+ Result status;
+ if (!mDescrambler && createDescrambler() == failure()) {
+ return failure();
+ }
+
+ status = mDescrambler->close();
+ mDescrambler = nullptr;
+ return AssertionResult(status == Result::SUCCESS);
+}
+/*========================= End Descrambler APIs Tests Implementation =========================*/
+
+/*============================ Start Dvr APIs Tests Implementation ============================*/
+AssertionResult TunerHidlTest::openDvrInDemux(DvrType type) {
+ Result status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+
+ // Create dvr callback
+ mDvrCallback = new DvrCallback();
+
+ mDemux->openDvr(type, FMQ_SIZE_1M, mDvrCallback, [&](Result result, const sp<IDvr>& dvr) {
+ mDvr = dvr;
+ status = result;
+ });
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::configDvr(DvrSettings setting) {
+ Result status = mDvr->configure(setting);
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::getDvrMQDescriptor() {
+ Result status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mDvr) << "Test with openDvr first.";
+
+ mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
+ mDvrMQDescriptor = dvrMQDesc;
+ status = result;
+ });
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+/*============================ End Dvr APIs Tests Implementation ============================*/
+
+/*========================== Start Data Flow Tests Implementation ==========================*/
+AssertionResult TunerHidlTest::broadcastDataFlowTest(vector<string> /*goldenOutputFiles*/) {
+ EXPECT_TRUE(mFrontend) << "Test with openFilterInDemux first.";
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mFilterCallback) << "Test with getFilterMQDescriptor first.";
+
+ // Data Verify Module
+ std::map<uint32_t, sp<FilterCallback>>::iterator it;
+ for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+ it->second->testFilterDataOutput();
+ }
+ return success();
+}
+
+/*
+ * TODO: re-enable the tests after finalizing the test refactoring.
+ */
+/*AssertionResult TunerHidlTest::playbackDataFlowTest(
+ vector<FilterConf> filterConf, PlaybackConf playbackConf,
+ vector<string> \/\*goldenOutputFiles\*\/) {
+ Result status;
+ int filterIdsSize;
+ // Filter Configuration Module
+ for (int i = 0; i < filterConf.size(); i++) {
+ if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+ failure() ||
+ // TODO use a map to save the FMQs/EvenFlags and pass to callback
+ getFilterMQDescriptor() == failure()) {
+ return failure();
+ }
+ filterIdsSize = mUsedFilterIds.size();
+ mUsedFilterIds.resize(filterIdsSize + 1);
+ mUsedFilterIds[filterIdsSize] = mFilterId;
+ mFilters[mFilterId] = mFilter;
+ mFilterCallbacks[mFilterId] = mFilterCallback;
+ mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
+ // mDemuxCallback->updateGoldenOutputMap(goldenOutputFiles[i]);
+ status = mFilter->start();
+ if (status != Result::SUCCESS) {
+ return failure();
+ }
+ }
+
+ // Playback Input Module
+ PlaybackSettings playbackSetting = playbackConf.setting;
+ if (addPlaybackToDemux(playbackSetting) == failure() ||
+ getPlaybackMQDescriptor() == failure()) {
+ return failure();
+ }
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
+ return failure();
+ }
+ }
+ mDvrCallback->startPlaybackInputThread(playbackConf, mPlaybackMQDescriptor);
+ status = mDvr->start();
+ if (status != Result::SUCCESS) {
+ return failure();
+ }
+
+ // Data Verify Module
+ std::map<uint32_t, sp<FilterCallback>>::iterator it;
+ for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+ it->second->testFilterDataOutput();
+ }
+ mDvrCallback->stopPlaybackThread();
+
+ // Clean Up Module
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
+ return failure();
+ }
+ }
+ if (mDvr->stop() != Result::SUCCESS) {
+ return failure();
+ }
+ mUsedFilterIds.clear();
+ mFilterCallbacks.clear();
+ mFilters.clear();
+ return closeDemux();
+}
+
+AssertionResult TunerHidlTest::recordDataFlowTest(vector<FilterConf> filterConf,
+ RecordSettings recordSetting,
+ vector<string> goldenOutputFiles) {
+ Result status;
+ hidl_vec<FrontendId> feIds;
+
+ mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+ status = result;
+ feIds = frontendIds;
+ });
+
+ if (feIds.size() == 0) {
+ ALOGW("[ WARN ] Frontend isn't available");
+ return failure();
+ }
+
+ FrontendDvbtSettings dvbt{
+ .frequency = 1000,
+ };
+ FrontendSettings settings;
+ settings.dvbt(dvbt);
+
+ int filterIdsSize;
+ // Filter Configuration Module
+ for (int i = 0; i < filterConf.size(); i++) {
+ if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+ failure() ||
+ // TODO use a map to save the FMQs/EvenFlags and pass to callback
+ getFilterMQDescriptor() == failure()) {
+ return failure();
+ }
+ filterIdsSize = mUsedFilterIds.size();
+ mUsedFilterIds.resize(filterIdsSize + 1);
+ mUsedFilterIds[filterIdsSize] = mFilterId;
+ mFilters[mFilterId] = mFilter;
+ }
+
+ // Record Config Module
+ if (addRecordToDemux(recordSetting) == failure() ||
+ getRecordMQDescriptor() == failure()) {
+ return failure();
+ }
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
+ return failure();
+ }
+ }
+
+ mDvrCallback->startRecordOutputThread(recordSetting, mRecordMQDescriptor);
+ status = mDvr->start();
+ if (status != Result::SUCCESS) {
+ return failure();
+ }
+
+ if (setDemuxFrontendDataSource(feIds[0]) != success()) {
+ return failure();
+ }
+
+ // Data Verify Module
+ mDvrCallback->testRecordOutput();
+
+ // Clean Up Module
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
+ return failure();
+ }
+ }
+ if (mFrontend->stopTune() != Result::SUCCESS) {
+ return failure();
+ }
+ mUsedFilterIds.clear();
+ mFilterCallbacks.clear();
+ mFilters.clear();
+ return closeDemux();
+}*/
+/*========================= End Data Flow Tests Implementation =========================*/
+
+/*=============================== Start Helper Functions ===============================*/
+FilterEventType TunerHidlTest::getFilterEventType(DemuxFilterType type) {
FilterEventType eventType = FilterEventType::UNDEFINED;
switch (type.mainType) {
case DemuxFilterMainType::TS:
@@ -998,358 +1263,151 @@
default:
break;
}
- mFilterCallback->setFilterEventType(eventType);
+ return eventType;
+}
+/*============================== End Helper Functions ==============================*/
+/***************************** End Test Implementation *****************************/
- // Configure the filter
- status = mFilter->configure(setting);
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
+/******************************** Start Test Entry **********************************/
+/*============================== Start Frontend Tests ==============================*/
+TEST_P(TunerHidlTest, getFrontendIds) {
+ description("Get Frontend ids and verify frontends exist");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
}
-::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor() {
- Result status;
+TEST_P(TunerHidlTest, openFrontend) {
+ description("Open all the existing Frontends and close them");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
- if (!mDemux || !mFilter) {
- return ::testing::AssertionFailure();
- }
-
- mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
- mFilterMQDescriptor = filterMQDesc;
- status = result;
- });
-
- return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(
- vector<FilterConf> filterConf, PlaybackConf playbackConf,
- vector<string> /*goldenOutputFiles*/) {
- Result status;
- int filterIdsSize;
- // Filter Configuration Module
- for (int i = 0; i < filterConf.size(); i++) {
- if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
- ::testing::AssertionFailure() ||
- // TODO use a map to save the FMQs/EvenFlags and pass to callback
- getFilterMQDescriptor() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
- filterIdsSize = mUsedFilterIds.size();
- mUsedFilterIds.resize(filterIdsSize + 1);
- mUsedFilterIds[filterIdsSize] = mFilterId;
- mFilters[mFilterId] = mFilter;
- mFilterCallbacks[mFilterId] = mFilterCallback;
- mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
- // mDemuxCallback->updateGoldenOutputMap(goldenOutputFiles[i]);
- status = mFilter->start();
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
-
- // Playback Input Module
- PlaybackSettings playbackSetting = playbackConf.setting;
- if (addPlaybackToDemux(playbackSetting) == ::testing::AssertionFailure() ||
- getPlaybackMQDescriptor() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
- for (int i = 0; i <= filterIdsSize; i++) {
- if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
- mDvrCallback->startPlaybackInputThread(playbackConf, mPlaybackMQDescriptor);
- status = mDvr->start();
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
-
- // Data Verify Module
- std::map<uint32_t, sp<FilterCallback>>::iterator it;
- for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
- it->second->testFilterDataOutput();
- }
- mDvrCallback->stopPlaybackThread();
-
- // Clean Up Module
- for (int i = 0; i <= filterIdsSize; i++) {
- if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
- if (mDvr->stop() != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- mUsedFilterIds.clear();
- mFilterCallbacks.clear();
- mFilters.clear();
- return closeDemux();
-}
-
-::testing::AssertionResult TunerHidlTest::broadcastDataFlowTest(
- vector<FilterConf> filterConf, vector<string> /*goldenOutputFiles*/) {
- Result status;
- hidl_vec<FrontendId> feIds;
-
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return ::testing::AssertionFailure();
- }
-
- FrontendDvbtSettings dvbt{
- .frequency = 1000,
- };
- FrontendSettings settings;
- settings.dvbt(dvbt);
-
- if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) {
- return ::testing::AssertionFailure();
- }
-
- int filterIdsSize;
- // Filter Configuration Module
- for (int i = 0; i < filterConf.size(); i++) {
- if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
- ::testing::AssertionFailure() ||
- // TODO use a map to save the FMQs/EvenFlags and pass to callback
- getFilterMQDescriptor() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
- filterIdsSize = mUsedFilterIds.size();
- mUsedFilterIds.resize(filterIdsSize + 1);
- mUsedFilterIds[filterIdsSize] = mFilterId;
- mFilters[mFilterId] = mFilter;
- mFilterCallbacks[mFilterId] = mFilterCallback;
- mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
- status = mFilter->start();
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
-
- // Data Verify Module
- std::map<uint32_t, sp<FilterCallback>>::iterator it;
- for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
- it->second->testFilterDataOutput();
- }
-
- // Clean Up Module
- for (int i = 0; i <= filterIdsSize; i++) {
- if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
- if (mFrontend->stopTune() != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- mUsedFilterIds.clear();
- mFilterCallbacks.clear();
- mFilters.clear();
- return closeDemux();
-}
-
-::testing::AssertionResult TunerHidlTest::recordDataFlowTest(vector<FilterConf> filterConf,
- RecordSettings recordSetting,
- vector<string> /*goldenOutputFiles*/) {
- Result status;
- hidl_vec<FrontendId> feIds;
-
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return ::testing::AssertionFailure();
- }
-
- FrontendDvbtSettings dvbt{
- .frequency = 1000,
- };
- FrontendSettings settings;
- settings.dvbt(dvbt);
-
- int filterIdsSize;
- // Filter Configuration Module
- for (int i = 0; i < filterConf.size(); i++) {
- if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
- ::testing::AssertionFailure() ||
- // TODO use a map to save the FMQs/EvenFlags and pass to callback
- getFilterMQDescriptor() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
- filterIdsSize = mUsedFilterIds.size();
- mUsedFilterIds.resize(filterIdsSize + 1);
- mUsedFilterIds[filterIdsSize] = mFilterId;
- mFilters[mFilterId] = mFilter;
- }
-
- // Record Config Module
- if (addRecordToDemux(recordSetting) == ::testing::AssertionFailure() ||
- getRecordMQDescriptor() == ::testing::AssertionFailure()) {
- return ::testing::AssertionFailure();
- }
- for (int i = 0; i <= filterIdsSize; i++) {
- if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
-
- mDvrCallback->startRecordOutputThread(recordSetting, mRecordMQDescriptor);
- status = mDvr->start();
- if (status != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
-
- if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) {
- return ::testing::AssertionFailure();
- }
-
- // Data Verify Module
- mDvrCallback->testRecordOutput();
-
- // Clean Up Module
- for (int i = 0; i <= filterIdsSize; i++) {
- if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- }
- if (mFrontend->stopTune() != Result::SUCCESS) {
- return ::testing::AssertionFailure();
- }
- mUsedFilterIds.clear();
- mFilterCallbacks.clear();
- mFilters.clear();
- return closeDemux();
-}
-
-/*
- * API STATUS TESTS
- */
-TEST_P(TunerHidlTest, CreateFrontend) {
- Result status;
- hidl_vec<FrontendId> feIds;
-
- description("Create Frontends");
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return;
- }
-
- for (size_t i = 0; i < feIds.size(); i++) {
- ASSERT_TRUE(createFrontend(feIds[i]));
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(closeFrontend());
}
}
TEST_P(TunerHidlTest, TuneFrontend) {
- Result status;
- hidl_vec<FrontendId> feIds;
-
- description("Tune Frontends and check callback onEvent");
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return;
- }
-
- for (size_t i = 0; i < feIds.size(); i++) {
- ASSERT_TRUE(tuneFrontend(feIds[i]));
+ description("Tune one Frontend with specific setting and check Lock event");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
+ ALOGW("[vts] expected Frontend type is %d", frontendArray[0].type);
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ ALOGW("[vts] Frontend type is %d", mFrontendInfo.type);
+ if (mFrontendInfo.type != frontendArray[0].type) {
+ continue;
+ }
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(stopTuneFrontend());
+ ASSERT_TRUE(tuneFrontend(frontendArray[0]));
+ ASSERT_TRUE(stopTuneFrontend());
+ ASSERT_TRUE(closeFrontend());
+ break;
}
}
-TEST_P(TunerHidlTest, StopTuneFrontend) {
- Result status;
- hidl_vec<FrontendId> feIds;
+TEST_P(TunerHidlTest, AutoScanFrontend) {
+ description("Run an auto frontend scan with specific setting and check lock scanMessage");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
- description("stopTune Frontends");
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return;
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ if (mFrontendInfo.type != frontendArray[0].type) {
+ continue;
+ }
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(stopScanFrontend());
+ ASSERT_TRUE(scanFrontend(frontendScanArray[0], FrontendScanType::SCAN_AUTO));
+ ASSERT_TRUE(stopScanFrontend());
+ ASSERT_TRUE(closeFrontend());
+ break;
}
+}
+/*=============================== End Frontend Tests ===============================*/
- for (size_t i = 0; i < feIds.size(); i++) {
- ASSERT_TRUE(stopTuneFrontend(feIds[i]));
+/*============================ Start Demux/Filter Tests ============================*/
+TEST_P(TunerHidlTest, OpenDemuxWithFrontendDataSource) {
+ description("Open Demux with a Frontend as its data source.");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
+
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ if (mFrontendInfo.type != frontendArray[0].type) {
+ continue;
+ }
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(openDemux());
+ ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+ ASSERT_TRUE(closeDemux());
+ ASSERT_TRUE(closeFrontend());
+ break;
}
}
-TEST_P(TunerHidlTest, CloseFrontend) {
- Result status;
- hidl_vec<FrontendId> feIds;
+TEST_P(TunerHidlTest, OpenFilterInDemux) {
+ description("Open a filter in Demux.");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
- description("Close Frontends");
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return;
- }
-
- for (size_t i = 0; i < feIds.size(); i++) {
- ASSERT_TRUE(closeFrontend(feIds[i]));
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ if (mFrontendInfo.type != frontendArray[0].type) {
+ continue;
+ }
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(openDemux());
+ ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+ ASSERT_TRUE(openFilterInDemux(filterArray[0].type));
+ uint32_t filterId;
+ ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
+ ASSERT_TRUE(closeFilter(filterId));
+ ASSERT_TRUE(closeDemux());
+ ASSERT_TRUE(closeFrontend());
+ break;
}
}
-TEST_P(TunerHidlTest, CreateDemuxWithFrontend) {
- Result status;
- hidl_vec<FrontendId> feIds;
+TEST_P(TunerHidlTest, StartFilterInDemux) {
+ description("Open and start a filter in Demux.");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
- description("Create Demux with Frontend");
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- feIds = frontendIds;
- });
-
- if (feIds.size() == 0) {
- ALOGW("[ WARN ] Frontend isn't available");
- return;
- }
-
- FrontendDvbtSettings dvbt{
- .frequency = 1000,
- };
- FrontendSettings settings;
- settings.dvbt(dvbt);
-
- for (size_t i = 0; i < feIds.size(); i++) {
- ASSERT_TRUE(createDemuxWithFrontend(feIds[i], settings));
- mFrontend->stopTune();
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ if (mFrontendInfo.type != frontendArray[0].type) {
+ continue;
+ }
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(openDemux());
+ ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+ ASSERT_TRUE(openFilterInDemux(filterArray[0].type));
+ uint32_t filterId;
+ ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
+ ASSERT_TRUE(configFilter(filterArray[0].setting, filterId));
+ ASSERT_TRUE(getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(startFilter(filterId));
+ ASSERT_TRUE(stopFilter(filterId));
+ ASSERT_TRUE(closeFilter(filterId));
+ ASSERT_TRUE(closeDemux());
+ ASSERT_TRUE(closeFrontend());
+ break;
}
}
+/*============================ End Demux/Filter Tests ============================*/
-TEST_P(TunerHidlTest, CreateDemux) {
- description("Create Demux");
- ASSERT_TRUE(createDemux());
-}
-
-TEST_P(TunerHidlTest, CloseDemux) {
- description("Close Demux");
- ASSERT_TRUE(closeDemux());
-}
-
-TEST_P(TunerHidlTest, CreateDescrambler) {
+/*============================ Start Descrambler Tests ============================*/
+/*
+ * TODO: re-enable the tests after finalizing the test refactoring.
+ */
+/*TEST_P(TunerHidlTest, CreateDescrambler) {
description("Create Descrambler");
ASSERT_TRUE(createDescrambler());
}
@@ -1357,11 +1415,44 @@
TEST_P(TunerHidlTest, CloseDescrambler) {
description("Close Descrambler");
ASSERT_TRUE(closeDescrambler());
+}*/
+/*============================== End Descrambler Tests ==============================*/
+
+/*============================== Start Data Flow Tests ==============================*/
+TEST_P(TunerHidlTest, BroadcastDataFlowWithAudioFilterTest) {
+ description("Open Demux with a Frontend as its data source.");
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
+
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ if (mFrontendInfo.type != frontendArray[0].type) {
+ continue;
+ }
+ ASSERT_TRUE(openFrontend(mFeIds[i]));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(openDemux());
+ ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+ ASSERT_TRUE(openFilterInDemux(filterArray[0].type));
+ uint32_t filterId;
+ ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
+ ASSERT_TRUE(configFilter(filterArray[0].setting, filterId));
+ ASSERT_TRUE(getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(startFilter(filterId));
+ // tune test
+ ASSERT_TRUE(tuneFrontend(frontendArray[0]));
+ // broadcast data flow test
+ ASSERT_TRUE(broadcastDataFlowTest(goldenOutputFiles));
+ ASSERT_TRUE(stopTuneFrontend());
+ ASSERT_TRUE(stopFilter(filterId));
+ ASSERT_TRUE(closeFilter(filterId));
+ ASSERT_TRUE(closeDemux());
+ ASSERT_TRUE(closeFrontend());
+ break;
+ }
}
/*
- * DATA FLOW TESTS
- *
* TODO: re-enable the tests after finalizing the testing stream.
*/
/*TEST_P(TunerHidlTest, PlaybackDataFlowWithSectionFilterTest) {
@@ -1407,36 +1498,6 @@
ASSERT_TRUE(playbackDataFlowTest(filterConf, playbackConf, goldenOutputFiles));
}
-TEST_P(TunerHidlTest, BroadcastDataFlowWithPesFilterTest) {
- description("Feed ts data from frontend and test with PES filter");
-
- // todo modulize the filter conf parser
- vector<FilterConf> filterConf;
- filterConf.resize(1);
-
- DemuxFilterSettings filterSetting;
- DemuxTsFilterSettings tsFilterSetting{
- .tpid = 119,
- };
- DemuxFilterPesDataSettings pesFilterSetting;
- tsFilterSetting.filterSettings.pesData(pesFilterSetting);
- filterSetting.ts(tsFilterSetting);
-
- DemuxFilterType type{
- .mainType = DemuxFilterMainType::TS,
- };
- type.subType.tsFilterType(DemuxTsFilterType::PES);
- FilterConf pesFilterConf{
- .type = type,
- .setting = filterSetting,
- };
- filterConf[0] = pesFilterConf;
-
- vector<string> goldenOutputFiles;
-
- ASSERT_TRUE(broadcastDataFlowTest(filterConf, goldenOutputFiles));
-}
-
TEST_P(TunerHidlTest, RecordDataFlowWithTsRecordFilterTest) {
description("Feed ts data from frontend to recording and test with ts record filter");
@@ -1474,7 +1535,8 @@
ASSERT_TRUE(recordDataFlowTest(filterConf, recordSetting, goldenOutputFiles));
}*/
-
+/*============================== End Data Flow Tests ==============================*/
+/******************************** End Test Entry **********************************/
} // namespace
INSTANTIATE_TEST_SUITE_P(
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
new file mode 100644
index 0000000..55ca857
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -0,0 +1,137 @@
+/*
+ * 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/IDescrambler.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.0/IFilter.h>
+#include <android/hardware/tv/tuner/1.0/IFilterCallback.h>
+#include <android/hardware/tv/tuner/1.0/IFrontend.h>
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <binder/MemoryDealer.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <fstream>
+#include <iostream>
+#include <map>
+
+using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
+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::DemuxQueueNotifyBits;
+using android::hardware::tv::tuner::V1_0::DemuxTpid;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
+using android::hardware::tv::tuner::V1_0::FrontendSettings;
+using android::hardware::tv::tuner::V1_0::FrontendType;
+
+namespace {
+
+#define frontend_transponders_count 1
+#define channels_count 1
+#define frontend_scan_count 1
+#define filter_count 2
+
+struct FilterConfig {
+ DemuxFilterType type;
+ DemuxFilterSettings setting;
+};
+
+struct FrontendConfig {
+ FrontendType type;
+ FrontendSettings settings;
+};
+
+struct ChannelConfig {
+ int32_t frontendId;
+ int32_t channelId;
+ std::string channelName;
+ DemuxTpid videoPid;
+ DemuxTpid audioPid;
+};
+
+static FrontendConfig frontendArray[frontend_transponders_count];
+static FrontendConfig frontendScanArray[channels_count];
+static ChannelConfig channelArray[frontend_scan_count];
+static FilterConfig filterArray[filter_count];
+static vector<string> goldenOutputFiles;
+
+/** Configuration array for the frontend tune test */
+inline void initFrontendConfig() {
+ FrontendDvbtSettings dvbtSettings{
+ .frequency = 578000,
+ .transmissionMode = FrontendDvbtTransmissionMode::AUTO,
+ .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
+ .constellation = FrontendDvbtConstellation::AUTO,
+ .hierarchy = FrontendDvbtHierarchy::AUTO,
+ .hpCoderate = FrontendDvbtCoderate::AUTO,
+ .lpCoderate = FrontendDvbtCoderate::AUTO,
+ .guardInterval = FrontendDvbtGuardInterval::AUTO,
+ .isHighPriority = true,
+ .standard = FrontendDvbtStandard::T,
+ };
+ frontendArray[0].type = FrontendType::DVBT, frontendArray[0].settings.dvbt(dvbtSettings);
+};
+
+/** Configuration array for the frontend scan test */
+inline void initFrontendScanConfig() {
+ frontendScanArray[0].type = FrontendType::DVBT, frontendScanArray[0].settings.dvbt({
+ .frequency = 577000,
+ });
+};
+
+/** Configuration array for the filter test */
+inline void initFilterConfig() {
+ // TS Video filter setting
+ filterArray[0].type.mainType = DemuxFilterMainType::TS;
+ filterArray[0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+ filterArray[0].setting.ts().tpid = 49;
+ filterArray[0].setting.ts().filterSettings.av({.isPassthrough = false});
+ // TS PES filter setting
+ filterArray[1].type.mainType = DemuxFilterMainType::TS;
+ filterArray[1].type.subType.tsFilterType(DemuxTsFilterType::PES);
+ filterArray[1].setting.ts().tpid = 256;
+ filterArray[1].setting.ts().filterSettings.pesData({
+ .isRaw = true,
+ .streamId = 0xbd,
+ });
+};
+
+} // namespace
\ No newline at end of file