blob: 15ded9acfecd7ecc6e2258bce1221d703b572727 [file] [log] [blame]
Marissa Wall4d600052016-12-15 12:16:01 -08001/*
2 * Copyright (C) 2016 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 <array>
Marissa Wallcfb9a072017-02-17 20:53:18 -080018#include <unordered_set>
Marissa Wall4d600052016-12-15 12:16:01 -080019#include <gtest/gtest.h>
20#include <dlfcn.h>
21#include <hardware/hardware.h>
22
23#define HWC2_INCLUDE_STRINGIFICATION
24#define HWC2_USE_CPP11
25#include <hardware/hwcomposer2.h>
26#undef HWC2_INCLUDE_STRINGIFICATION
27#undef HWC2_USE_CPP11
28
Marissa Wallcfb9a072017-02-17 20:53:18 -080029void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
30 hwc2_display_t display, int32_t connected);
31
Marissa Wall4d600052016-12-15 12:16:01 -080032class Hwc2Test : public testing::Test {
33public:
34
35 virtual void SetUp()
36 {
37 hw_module_t const* hwc2Module;
38
39 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwc2Module);
40 ASSERT_GE(err, 0) << "failed to get hwc hardware module: "
41 << strerror(-err);
42
43 /* The following method will fail if you have not run
44 * "adb shell stop" */
45 err = hwc2_open(hwc2Module, &mHwc2Device);
46 ASSERT_GE(err, 0) << "failed to open hwc hardware module: "
47 << strerror(-err);
Marissa Wallcfb9a072017-02-17 20:53:18 -080048
49 populateDisplays();
Marissa Wall4d600052016-12-15 12:16:01 -080050 }
51
52 virtual void TearDown()
53 {
54 if (mHwc2Device)
55 hwc2_close(mHwc2Device);
56 }
57
Marissa Walla4b01482017-02-17 20:52:03 -080058 void registerCallback(hwc2_callback_descriptor_t descriptor,
59 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer,
60 hwc2_error_t* outErr = nullptr)
61 {
62 auto pfn = reinterpret_cast<HWC2_PFN_REGISTER_CALLBACK>(
63 getFunction(HWC2_FUNCTION_REGISTER_CALLBACK));
64 ASSERT_TRUE(pfn) << "failed to get function";
65
66 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, descriptor,
67 callbackData, pointer));
68 if (outErr) {
69 *outErr = err;
70 } else {
71 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to register callback";
72 }
73 }
74
Marissa Wallcfb9a072017-02-17 20:53:18 -080075 void getDisplayType(hwc2_display_t display, hwc2_display_type_t* outType,
76 hwc2_error_t* outErr = nullptr)
77 {
78 auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_TYPE>(
79 getFunction(HWC2_FUNCTION_GET_DISPLAY_TYPE));
80 ASSERT_TRUE(pfn) << "failed to get function";
81
82 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
83 reinterpret_cast<int32_t*>(outType)));
84 if (outErr) {
85 *outErr = err;
86 } else {
87 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display type";
88 }
89 }
90
91 /* If the populateDisplays function is still receiving displays and the
92 * display is connected, the display handle is stored in mDisplays. */
93 void hotplugCallback(hwc2_display_t display, int32_t connected)
94 {
95 std::lock_guard<std::mutex> lock(mHotplugMutex);
96
97 if (mHotplugStatus != Hwc2TestHotplugStatus::Receiving)
98 return;
99
100 if (connected == HWC2_CONNECTION_CONNECTED)
101 mDisplays.insert(display);
102
103 mHotplugCv.notify_all();
104 }
105
Marissa Wall4d600052016-12-15 12:16:01 -0800106protected:
107 hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
108 {
109 return mHwc2Device->getFunction(mHwc2Device, descriptor);
110 }
111
112 void getCapabilities(std::vector<hwc2_capability_t>* outCapabilities)
113 {
114 uint32_t num = 0;
115
116 mHwc2Device->getCapabilities(mHwc2Device, &num, nullptr);
117
118 outCapabilities->resize(num);
119
120 mHwc2Device->getCapabilities(mHwc2Device, &num,
121 reinterpret_cast<int32_t*>(outCapabilities->data()));
122 }
123
Marissa Wallcfb9a072017-02-17 20:53:18 -0800124 /* Registers a hotplug callback and waits for hotplug callbacks. This
125 * function will have no effect if called more than once. */
126 void populateDisplays()
127 {
128 /* Sets the hotplug status to receiving */
129 {
130 std::lock_guard<std::mutex> lock(mHotplugMutex);
131
132 if (mHotplugStatus != Hwc2TestHotplugStatus::Init)
133 return;
134 mHotplugStatus = Hwc2TestHotplugStatus::Receiving;
135 }
136
137 /* Registers the callback. This function call cannot be locked because
138 * a callback could happen on the same thread */
139 ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_HOTPLUG, this,
140 reinterpret_cast<hwc2_function_pointer_t>(
141 hwc2TestHotplugCallback)));
142
143 /* Waits for hotplug events. If a hotplug event has not come within 1
144 * second, stop waiting. */
145 std::unique_lock<std::mutex> lock(mHotplugMutex);
146
147 while (mHotplugCv.wait_for(lock, std::chrono::seconds(1)) !=
148 std::cv_status::timeout) { }
149
150 /* Sets the hotplug status to done. Future calls will have no effect */
151 mHotplugStatus = Hwc2TestHotplugStatus::Done;
152 }
153
154 void getBadDisplay(hwc2_display_t* outDisplay)
155 {
156 for (hwc2_display_t display = 0; display < UINT64_MAX; display++) {
157 if (mDisplays.count(display) == 0) {
158 *outDisplay = display;
159 return;
160 }
161 }
162 ASSERT_TRUE(false) << "Unable to find bad display. UINT64_MAX displays"
163 " are registered. This should never happen.";
164 }
165
Marissa Wall4d600052016-12-15 12:16:01 -0800166 hwc2_device_t* mHwc2Device = nullptr;
Marissa Wallcfb9a072017-02-17 20:53:18 -0800167
168 enum class Hwc2TestHotplugStatus {
169 Init = 1,
170 Receiving,
171 Done,
172 };
173
174 std::mutex mHotplugMutex;
175 std::condition_variable mHotplugCv;
176 Hwc2TestHotplugStatus mHotplugStatus = Hwc2TestHotplugStatus::Init;
177 std::unordered_set<hwc2_display_t> mDisplays;
Marissa Wall4d600052016-12-15 12:16:01 -0800178};
179
Marissa Wallcfb9a072017-02-17 20:53:18 -0800180void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
181 hwc2_display_t display, int32_t connection)
182{
183 if (callbackData)
184 static_cast<Hwc2Test*>(callbackData)->hotplugCallback(display,
185 connection);
186}
187
Marissa Wall4d600052016-12-15 12:16:01 -0800188
189static const std::array<hwc2_function_descriptor_t, 42> requiredFunctions = {{
190 HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
191 HWC2_FUNCTION_CREATE_LAYER,
192 HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
193 HWC2_FUNCTION_DESTROY_LAYER,
194 HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
195 HWC2_FUNCTION_DUMP,
196 HWC2_FUNCTION_GET_ACTIVE_CONFIG,
197 HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
198 HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
199 HWC2_FUNCTION_GET_COLOR_MODES,
200 HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
201 HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
202 HWC2_FUNCTION_GET_DISPLAY_NAME,
203 HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
204 HWC2_FUNCTION_GET_DISPLAY_TYPE,
205 HWC2_FUNCTION_GET_DOZE_SUPPORT,
206 HWC2_FUNCTION_GET_HDR_CAPABILITIES,
207 HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
208 HWC2_FUNCTION_GET_RELEASE_FENCES,
209 HWC2_FUNCTION_PRESENT_DISPLAY,
210 HWC2_FUNCTION_REGISTER_CALLBACK,
211 HWC2_FUNCTION_SET_ACTIVE_CONFIG,
212 HWC2_FUNCTION_SET_CLIENT_TARGET,
213 HWC2_FUNCTION_SET_COLOR_MODE,
214 HWC2_FUNCTION_SET_COLOR_TRANSFORM,
215 HWC2_FUNCTION_SET_CURSOR_POSITION,
216 HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
217 HWC2_FUNCTION_SET_LAYER_BUFFER,
218 HWC2_FUNCTION_SET_LAYER_COLOR,
219 HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
220 HWC2_FUNCTION_SET_LAYER_DATASPACE,
221 HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
222 HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
223 HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
224 HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
225 HWC2_FUNCTION_SET_LAYER_TRANSFORM,
226 HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
227 HWC2_FUNCTION_SET_LAYER_Z_ORDER,
228 HWC2_FUNCTION_SET_OUTPUT_BUFFER,
229 HWC2_FUNCTION_SET_POWER_MODE,
230 HWC2_FUNCTION_SET_VSYNC_ENABLED,
231 HWC2_FUNCTION_VALIDATE_DISPLAY,
232}};
233
234/* TESTCASE: Tests that the HWC2 supports all required functions. */
235TEST_F(Hwc2Test, GET_FUNCTION)
236{
237 for (hwc2_function_descriptor_t descriptor : requiredFunctions) {
238 hwc2_function_pointer_t pfn = getFunction(descriptor);
239 EXPECT_TRUE(pfn) << "failed to get function "
240 << getFunctionDescriptorName(descriptor);
241 }
242}
243
244/* TESTCASE: Tests that the HWC2 fails to retrieve and invalid function. */
245TEST_F(Hwc2Test, GET_FUNCTION_invalid_function)
246{
247 hwc2_function_pointer_t pfn = getFunction(HWC2_FUNCTION_INVALID);
248 EXPECT_FALSE(pfn) << "failed to get invalid function";
249}
250
251/* TESTCASE: Tests that the HWC2 does not return an invalid capability. */
252TEST_F(Hwc2Test, GET_CAPABILITIES)
253{
254 std::vector<hwc2_capability_t> capabilities;
255
256 getCapabilities(&capabilities);
257
258 EXPECT_EQ(std::count(capabilities.begin(), capabilities.end(),
259 HWC2_CAPABILITY_INVALID), 0);
260}
Marissa Walla4b01482017-02-17 20:52:03 -0800261
262static const std::array<hwc2_callback_descriptor_t, 3> callbackDescriptors = {{
263 HWC2_CALLBACK_HOTPLUG,
264 HWC2_CALLBACK_REFRESH,
265 HWC2_CALLBACK_VSYNC,
266}};
267
268/* TESTCASE: Tests that the HWC2 can successfully register all required
269 * callback functions. */
270TEST_F(Hwc2Test, REGISTER_CALLBACK)
271{
272 hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
273 const_cast<char*>("data"));
274
275 for (auto descriptor : callbackDescriptors) {
276 ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
277 []() { return; }));
278 }
279}
280
281/* TESTCASE: Test that the HWC2 fails to register invalid callbacks. */
282TEST_F(Hwc2Test, REGISTER_CALLBACK_bad_parameter)
283{
284 hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
285 const_cast<char*>("data"));
286 hwc2_error_t err = HWC2_ERROR_NONE;
287
288 ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_INVALID, data,
289 []() { return; }, &err));
290 EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
291}
292
293/* TESTCASE: Tests that the HWC2 can register a callback with null data. */
294TEST_F(Hwc2Test, REGISTER_CALLBACK_null_data)
295{
296 hwc2_callback_data_t data = nullptr;
297
298 for (auto descriptor : callbackDescriptors) {
299 ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
300 []() { return; }));
301 }
302}
Marissa Wallcfb9a072017-02-17 20:53:18 -0800303
304/* TESTCASE: Tests that the HWC2 returns the correct display type for each
305 * physical display. */
306TEST_F(Hwc2Test, GET_DISPLAY_TYPE)
307{
308 for (auto display : mDisplays) {
309 hwc2_display_type_t type;
310
311 ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type));
312 EXPECT_EQ(type, HWC2_DISPLAY_TYPE_PHYSICAL) << "failed to return"
313 " correct display type";
314 }
315}
316
317/* TESTCASE: Tests that the HWC2 returns an error when the display type of a bad
318 * display is requested. */
319TEST_F(Hwc2Test, GET_DISPLAY_TYPE_bad_display)
320{
321 hwc2_display_t display;
322 hwc2_display_type_t type;
323 hwc2_error_t err = HWC2_ERROR_NONE;
324
325 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
326
327 ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type, &err));
328 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
329}