blob: 0ccc27664aa16fd512800ddf6337a944150b9107 [file] [log] [blame]
/*
* Copyright (C) 2016 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 <array>
#include <gtest/gtest.h>
#include <dlfcn.h>
#include <hardware/hardware.h>
#define HWC2_INCLUDE_STRINGIFICATION
#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
class Hwc2Test : public testing::Test {
public:
virtual void SetUp()
{
hw_module_t const* hwc2Module;
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwc2Module);
ASSERT_GE(err, 0) << "failed to get hwc hardware module: "
<< strerror(-err);
/* The following method will fail if you have not run
* "adb shell stop" */
err = hwc2_open(hwc2Module, &mHwc2Device);
ASSERT_GE(err, 0) << "failed to open hwc hardware module: "
<< strerror(-err);
}
virtual void TearDown()
{
if (mHwc2Device)
hwc2_close(mHwc2Device);
}
void registerCallback(hwc2_callback_descriptor_t descriptor,
hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer,
hwc2_error_t* outErr = nullptr)
{
auto pfn = reinterpret_cast<HWC2_PFN_REGISTER_CALLBACK>(
getFunction(HWC2_FUNCTION_REGISTER_CALLBACK));
ASSERT_TRUE(pfn) << "failed to get function";
auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, descriptor,
callbackData, pointer));
if (outErr) {
*outErr = err;
} else {
ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to register callback";
}
}
protected:
hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
{
return mHwc2Device->getFunction(mHwc2Device, descriptor);
}
void getCapabilities(std::vector<hwc2_capability_t>* outCapabilities)
{
uint32_t num = 0;
mHwc2Device->getCapabilities(mHwc2Device, &num, nullptr);
outCapabilities->resize(num);
mHwc2Device->getCapabilities(mHwc2Device, &num,
reinterpret_cast<int32_t*>(outCapabilities->data()));
}
hwc2_device_t* mHwc2Device = nullptr;
};
static const std::array<hwc2_function_descriptor_t, 42> requiredFunctions = {{
HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
HWC2_FUNCTION_CREATE_LAYER,
HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
HWC2_FUNCTION_DESTROY_LAYER,
HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
HWC2_FUNCTION_DUMP,
HWC2_FUNCTION_GET_ACTIVE_CONFIG,
HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
HWC2_FUNCTION_GET_COLOR_MODES,
HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
HWC2_FUNCTION_GET_DISPLAY_NAME,
HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
HWC2_FUNCTION_GET_DISPLAY_TYPE,
HWC2_FUNCTION_GET_DOZE_SUPPORT,
HWC2_FUNCTION_GET_HDR_CAPABILITIES,
HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
HWC2_FUNCTION_GET_RELEASE_FENCES,
HWC2_FUNCTION_PRESENT_DISPLAY,
HWC2_FUNCTION_REGISTER_CALLBACK,
HWC2_FUNCTION_SET_ACTIVE_CONFIG,
HWC2_FUNCTION_SET_CLIENT_TARGET,
HWC2_FUNCTION_SET_COLOR_MODE,
HWC2_FUNCTION_SET_COLOR_TRANSFORM,
HWC2_FUNCTION_SET_CURSOR_POSITION,
HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
HWC2_FUNCTION_SET_LAYER_BUFFER,
HWC2_FUNCTION_SET_LAYER_COLOR,
HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
HWC2_FUNCTION_SET_LAYER_DATASPACE,
HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
HWC2_FUNCTION_SET_LAYER_TRANSFORM,
HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
HWC2_FUNCTION_SET_LAYER_Z_ORDER,
HWC2_FUNCTION_SET_OUTPUT_BUFFER,
HWC2_FUNCTION_SET_POWER_MODE,
HWC2_FUNCTION_SET_VSYNC_ENABLED,
HWC2_FUNCTION_VALIDATE_DISPLAY,
}};
/* TESTCASE: Tests that the HWC2 supports all required functions. */
TEST_F(Hwc2Test, GET_FUNCTION)
{
for (hwc2_function_descriptor_t descriptor : requiredFunctions) {
hwc2_function_pointer_t pfn = getFunction(descriptor);
EXPECT_TRUE(pfn) << "failed to get function "
<< getFunctionDescriptorName(descriptor);
}
}
/* TESTCASE: Tests that the HWC2 fails to retrieve and invalid function. */
TEST_F(Hwc2Test, GET_FUNCTION_invalid_function)
{
hwc2_function_pointer_t pfn = getFunction(HWC2_FUNCTION_INVALID);
EXPECT_FALSE(pfn) << "failed to get invalid function";
}
/* TESTCASE: Tests that the HWC2 does not return an invalid capability. */
TEST_F(Hwc2Test, GET_CAPABILITIES)
{
std::vector<hwc2_capability_t> capabilities;
getCapabilities(&capabilities);
EXPECT_EQ(std::count(capabilities.begin(), capabilities.end(),
HWC2_CAPABILITY_INVALID), 0);
}
static const std::array<hwc2_callback_descriptor_t, 3> callbackDescriptors = {{
HWC2_CALLBACK_HOTPLUG,
HWC2_CALLBACK_REFRESH,
HWC2_CALLBACK_VSYNC,
}};
/* TESTCASE: Tests that the HWC2 can successfully register all required
* callback functions. */
TEST_F(Hwc2Test, REGISTER_CALLBACK)
{
hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
const_cast<char*>("data"));
for (auto descriptor : callbackDescriptors) {
ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
[]() { return; }));
}
}
/* TESTCASE: Test that the HWC2 fails to register invalid callbacks. */
TEST_F(Hwc2Test, REGISTER_CALLBACK_bad_parameter)
{
hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
const_cast<char*>("data"));
hwc2_error_t err = HWC2_ERROR_NONE;
ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_INVALID, data,
[]() { return; }, &err));
EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
}
/* TESTCASE: Tests that the HWC2 can register a callback with null data. */
TEST_F(Hwc2Test, REGISTER_CALLBACK_null_data)
{
hwc2_callback_data_t data = nullptr;
for (auto descriptor : callbackDescriptors) {
ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
[]() { return; }));
}
}