blob: 57bf681b6974cb8ba96a517b639ebd385f15fbc6 [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 {
Marissa Wall1db2e372016-12-15 12:19:39 -080054
55 for (auto itr = mLayers.begin(); itr != mLayers.end();) {
56 hwc2_display_t display = itr->first;
57 hwc2_layer_t layer = itr->second;
58 itr++;
59 /* Destroys and removes the layer from mLayers */
60 destroyLayer(display, layer);
61 }
62
Marissa Wall4d600052016-12-15 12:16:01 -080063 if (mHwc2Device)
64 hwc2_close(mHwc2Device);
65 }
66
Marissa Walla4b01482017-02-17 20:52:03 -080067 void registerCallback(hwc2_callback_descriptor_t descriptor,
68 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer,
69 hwc2_error_t* outErr = nullptr)
70 {
71 auto pfn = reinterpret_cast<HWC2_PFN_REGISTER_CALLBACK>(
72 getFunction(HWC2_FUNCTION_REGISTER_CALLBACK));
73 ASSERT_TRUE(pfn) << "failed to get function";
74
75 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, descriptor,
76 callbackData, pointer));
77 if (outErr) {
78 *outErr = err;
79 } else {
80 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to register callback";
81 }
82 }
83
Marissa Wallcfb9a072017-02-17 20:53:18 -080084 void getDisplayType(hwc2_display_t display, hwc2_display_type_t* outType,
85 hwc2_error_t* outErr = nullptr)
86 {
87 auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_TYPE>(
88 getFunction(HWC2_FUNCTION_GET_DISPLAY_TYPE));
89 ASSERT_TRUE(pfn) << "failed to get function";
90
91 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
92 reinterpret_cast<int32_t*>(outType)));
93 if (outErr) {
94 *outErr = err;
95 } else {
96 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display type";
97 }
98 }
99
100 /* If the populateDisplays function is still receiving displays and the
101 * display is connected, the display handle is stored in mDisplays. */
102 void hotplugCallback(hwc2_display_t display, int32_t connected)
103 {
104 std::lock_guard<std::mutex> lock(mHotplugMutex);
105
106 if (mHotplugStatus != Hwc2TestHotplugStatus::Receiving)
107 return;
108
109 if (connected == HWC2_CONNECTION_CONNECTED)
110 mDisplays.insert(display);
111
112 mHotplugCv.notify_all();
113 }
114
Marissa Wall1db2e372016-12-15 12:19:39 -0800115 void createLayer(hwc2_display_t display, hwc2_layer_t* outLayer,
116 hwc2_error_t* outErr = nullptr)
117 {
118 auto pfn = reinterpret_cast<HWC2_PFN_CREATE_LAYER>(
119 getFunction(HWC2_FUNCTION_CREATE_LAYER));
120 ASSERT_TRUE(pfn) << "failed to get function";
121
122 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
123 outLayer));
124
125 if (err == HWC2_ERROR_NONE)
126 mLayers.insert(std::make_pair(display, *outLayer));
127
128 if (outErr) {
129 *outErr = err;
130 } else {
131 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create layer";
132 }
133 }
134
135 void destroyLayer(hwc2_display_t display, hwc2_layer_t layer,
136 hwc2_error_t* outErr = nullptr)
137 {
138 auto pfn = reinterpret_cast<HWC2_PFN_DESTROY_LAYER>(
139 getFunction(HWC2_FUNCTION_DESTROY_LAYER));
140 ASSERT_TRUE(pfn) << "failed to get function";
141
142 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer));
143
144 if (err == HWC2_ERROR_NONE)
145 mLayers.erase(std::make_pair(display, layer));
146
147 if (outErr) {
148 *outErr = err;
149 } else {
150 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to destroy layer "
151 << layer;
152 }
153 }
154
Marissa Wall4d600052016-12-15 12:16:01 -0800155protected:
156 hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
157 {
158 return mHwc2Device->getFunction(mHwc2Device, descriptor);
159 }
160
161 void getCapabilities(std::vector<hwc2_capability_t>* outCapabilities)
162 {
163 uint32_t num = 0;
164
165 mHwc2Device->getCapabilities(mHwc2Device, &num, nullptr);
166
167 outCapabilities->resize(num);
168
169 mHwc2Device->getCapabilities(mHwc2Device, &num,
170 reinterpret_cast<int32_t*>(outCapabilities->data()));
171 }
172
Marissa Wallcfb9a072017-02-17 20:53:18 -0800173 /* Registers a hotplug callback and waits for hotplug callbacks. This
174 * function will have no effect if called more than once. */
175 void populateDisplays()
176 {
177 /* Sets the hotplug status to receiving */
178 {
179 std::lock_guard<std::mutex> lock(mHotplugMutex);
180
181 if (mHotplugStatus != Hwc2TestHotplugStatus::Init)
182 return;
183 mHotplugStatus = Hwc2TestHotplugStatus::Receiving;
184 }
185
186 /* Registers the callback. This function call cannot be locked because
187 * a callback could happen on the same thread */
188 ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_HOTPLUG, this,
189 reinterpret_cast<hwc2_function_pointer_t>(
190 hwc2TestHotplugCallback)));
191
192 /* Waits for hotplug events. If a hotplug event has not come within 1
193 * second, stop waiting. */
194 std::unique_lock<std::mutex> lock(mHotplugMutex);
195
196 while (mHotplugCv.wait_for(lock, std::chrono::seconds(1)) !=
197 std::cv_status::timeout) { }
198
199 /* Sets the hotplug status to done. Future calls will have no effect */
200 mHotplugStatus = Hwc2TestHotplugStatus::Done;
201 }
202
203 void getBadDisplay(hwc2_display_t* outDisplay)
204 {
205 for (hwc2_display_t display = 0; display < UINT64_MAX; display++) {
206 if (mDisplays.count(display) == 0) {
207 *outDisplay = display;
208 return;
209 }
210 }
211 ASSERT_TRUE(false) << "Unable to find bad display. UINT64_MAX displays"
212 " are registered. This should never happen.";
213 }
214
Marissa Wall1db2e372016-12-15 12:19:39 -0800215 /* NOTE: will create min(newlayerCnt, max supported layers) layers */
216 void createLayers(hwc2_display_t display,
217 std::vector<hwc2_layer_t>* outLayers, size_t newLayerCnt)
218 {
219 std::vector<hwc2_layer_t> newLayers;
220 hwc2_layer_t layer;
221 hwc2_error_t err = HWC2_ERROR_NONE;
222
223 for (size_t i = 0; i < newLayerCnt; i++) {
224
225 EXPECT_NO_FATAL_FAILURE(createLayer(display, &layer, &err));
226 if (err == HWC2_ERROR_NO_RESOURCES)
227 break;
228 if (err != HWC2_ERROR_NONE) {
229 newLayers.clear();
230 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create layer";
231 }
232 newLayers.push_back(layer);
233 }
234
235 *outLayers = std::move(newLayers);
236 }
237
238 void destroyLayers(hwc2_display_t display,
239 std::vector<hwc2_layer_t>&& layers)
240 {
241 for (hwc2_layer_t layer : layers) {
242 EXPECT_NO_FATAL_FAILURE(destroyLayer(display, layer));
243 }
244 }
245
Marissa Wall4d600052016-12-15 12:16:01 -0800246 hwc2_device_t* mHwc2Device = nullptr;
Marissa Wallcfb9a072017-02-17 20:53:18 -0800247
248 enum class Hwc2TestHotplugStatus {
249 Init = 1,
250 Receiving,
251 Done,
252 };
253
254 std::mutex mHotplugMutex;
255 std::condition_variable mHotplugCv;
256 Hwc2TestHotplugStatus mHotplugStatus = Hwc2TestHotplugStatus::Init;
257 std::unordered_set<hwc2_display_t> mDisplays;
Marissa Wall1db2e372016-12-15 12:19:39 -0800258
259 /* Store all created layers that have not been destroyed. If an ASSERT_*
260 * fails, then destroy the layers on exit */
261 std::set<std::pair<hwc2_display_t, hwc2_layer_t>> mLayers;
Marissa Wall4d600052016-12-15 12:16:01 -0800262};
263
Marissa Wallcfb9a072017-02-17 20:53:18 -0800264void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
265 hwc2_display_t display, int32_t connection)
266{
267 if (callbackData)
268 static_cast<Hwc2Test*>(callbackData)->hotplugCallback(display,
269 connection);
270}
271
Marissa Wall4d600052016-12-15 12:16:01 -0800272
273static const std::array<hwc2_function_descriptor_t, 42> requiredFunctions = {{
274 HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
275 HWC2_FUNCTION_CREATE_LAYER,
276 HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
277 HWC2_FUNCTION_DESTROY_LAYER,
278 HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
279 HWC2_FUNCTION_DUMP,
280 HWC2_FUNCTION_GET_ACTIVE_CONFIG,
281 HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
282 HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
283 HWC2_FUNCTION_GET_COLOR_MODES,
284 HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
285 HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
286 HWC2_FUNCTION_GET_DISPLAY_NAME,
287 HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
288 HWC2_FUNCTION_GET_DISPLAY_TYPE,
289 HWC2_FUNCTION_GET_DOZE_SUPPORT,
290 HWC2_FUNCTION_GET_HDR_CAPABILITIES,
291 HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
292 HWC2_FUNCTION_GET_RELEASE_FENCES,
293 HWC2_FUNCTION_PRESENT_DISPLAY,
294 HWC2_FUNCTION_REGISTER_CALLBACK,
295 HWC2_FUNCTION_SET_ACTIVE_CONFIG,
296 HWC2_FUNCTION_SET_CLIENT_TARGET,
297 HWC2_FUNCTION_SET_COLOR_MODE,
298 HWC2_FUNCTION_SET_COLOR_TRANSFORM,
299 HWC2_FUNCTION_SET_CURSOR_POSITION,
300 HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
301 HWC2_FUNCTION_SET_LAYER_BUFFER,
302 HWC2_FUNCTION_SET_LAYER_COLOR,
303 HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
304 HWC2_FUNCTION_SET_LAYER_DATASPACE,
305 HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
306 HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
307 HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
308 HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
309 HWC2_FUNCTION_SET_LAYER_TRANSFORM,
310 HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
311 HWC2_FUNCTION_SET_LAYER_Z_ORDER,
312 HWC2_FUNCTION_SET_OUTPUT_BUFFER,
313 HWC2_FUNCTION_SET_POWER_MODE,
314 HWC2_FUNCTION_SET_VSYNC_ENABLED,
315 HWC2_FUNCTION_VALIDATE_DISPLAY,
316}};
317
318/* TESTCASE: Tests that the HWC2 supports all required functions. */
319TEST_F(Hwc2Test, GET_FUNCTION)
320{
321 for (hwc2_function_descriptor_t descriptor : requiredFunctions) {
322 hwc2_function_pointer_t pfn = getFunction(descriptor);
323 EXPECT_TRUE(pfn) << "failed to get function "
324 << getFunctionDescriptorName(descriptor);
325 }
326}
327
328/* TESTCASE: Tests that the HWC2 fails to retrieve and invalid function. */
329TEST_F(Hwc2Test, GET_FUNCTION_invalid_function)
330{
331 hwc2_function_pointer_t pfn = getFunction(HWC2_FUNCTION_INVALID);
332 EXPECT_FALSE(pfn) << "failed to get invalid function";
333}
334
335/* TESTCASE: Tests that the HWC2 does not return an invalid capability. */
336TEST_F(Hwc2Test, GET_CAPABILITIES)
337{
338 std::vector<hwc2_capability_t> capabilities;
339
340 getCapabilities(&capabilities);
341
342 EXPECT_EQ(std::count(capabilities.begin(), capabilities.end(),
343 HWC2_CAPABILITY_INVALID), 0);
344}
Marissa Walla4b01482017-02-17 20:52:03 -0800345
346static const std::array<hwc2_callback_descriptor_t, 3> callbackDescriptors = {{
347 HWC2_CALLBACK_HOTPLUG,
348 HWC2_CALLBACK_REFRESH,
349 HWC2_CALLBACK_VSYNC,
350}};
351
352/* TESTCASE: Tests that the HWC2 can successfully register all required
353 * callback functions. */
354TEST_F(Hwc2Test, REGISTER_CALLBACK)
355{
356 hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
357 const_cast<char*>("data"));
358
359 for (auto descriptor : callbackDescriptors) {
360 ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
361 []() { return; }));
362 }
363}
364
365/* TESTCASE: Test that the HWC2 fails to register invalid callbacks. */
366TEST_F(Hwc2Test, REGISTER_CALLBACK_bad_parameter)
367{
368 hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
369 const_cast<char*>("data"));
370 hwc2_error_t err = HWC2_ERROR_NONE;
371
372 ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_INVALID, data,
373 []() { return; }, &err));
374 EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
375}
376
377/* TESTCASE: Tests that the HWC2 can register a callback with null data. */
378TEST_F(Hwc2Test, REGISTER_CALLBACK_null_data)
379{
380 hwc2_callback_data_t data = nullptr;
381
382 for (auto descriptor : callbackDescriptors) {
383 ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
384 []() { return; }));
385 }
386}
Marissa Wallcfb9a072017-02-17 20:53:18 -0800387
388/* TESTCASE: Tests that the HWC2 returns the correct display type for each
389 * physical display. */
390TEST_F(Hwc2Test, GET_DISPLAY_TYPE)
391{
392 for (auto display : mDisplays) {
393 hwc2_display_type_t type;
394
395 ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type));
396 EXPECT_EQ(type, HWC2_DISPLAY_TYPE_PHYSICAL) << "failed to return"
397 " correct display type";
398 }
399}
400
401/* TESTCASE: Tests that the HWC2 returns an error when the display type of a bad
402 * display is requested. */
403TEST_F(Hwc2Test, GET_DISPLAY_TYPE_bad_display)
404{
405 hwc2_display_t display;
406 hwc2_display_type_t type;
407 hwc2_error_t err = HWC2_ERROR_NONE;
408
409 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
410
411 ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type, &err));
412 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
413}
Marissa Wall1db2e372016-12-15 12:19:39 -0800414
415/* TESTCASE: Tests that the HWC2 can create and destroy layers. */
416TEST_F(Hwc2Test, CREATE_DESTROY_LAYER)
417{
418 for (auto display : mDisplays) {
419 hwc2_layer_t layer;
420
421 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
422
423 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
424 }
425}
426
427/* TESTCASE: Tests that the HWC2 cannot create a layer for a bad display */
428TEST_F(Hwc2Test, CREATE_LAYER_bad_display)
429{
430 hwc2_display_t display;
431 hwc2_layer_t layer;
432 hwc2_error_t err = HWC2_ERROR_NONE;
433
434 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
435
436 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer, &err));
437 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
438}
439
440/* TESTCASE: Tests that the HWC2 will either support a large number of resources
441 * or will return no resources. */
442TEST_F(Hwc2Test, CREATE_LAYER_no_resources)
443{
444 const size_t layerCnt = 1000;
445
446 for (auto display : mDisplays) {
447 std::vector<hwc2_layer_t> layers;
448
449 ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
450
451 ASSERT_NO_FATAL_FAILURE(destroyLayers(display, std::move(layers)));
452 }
453}
454
455/* TESTCASE: Tests that the HWC2 cannot destroy a layer for a bad display */
456TEST_F(Hwc2Test, DESTROY_LAYER_bad_display)
457{
458 hwc2_display_t badDisplay;
459
460 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&badDisplay));
461
462 for (auto display : mDisplays) {
463 hwc2_layer_t layer = 0;
464 hwc2_error_t err = HWC2_ERROR_NONE;
465
466 ASSERT_NO_FATAL_FAILURE(destroyLayer(badDisplay, layer, &err));
467 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
468
469 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
470
471 ASSERT_NO_FATAL_FAILURE(destroyLayer(badDisplay, layer, &err));
472 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
473
474 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
475 }
476}
477
478/* TESTCASE: Tests that the HWC2 cannot destory a bad layer */
479TEST_F(Hwc2Test, DESTROY_LAYER_bad_layer)
480{
481 for (auto display : mDisplays) {
482 hwc2_layer_t layer;
483 hwc2_error_t err = HWC2_ERROR_NONE;
484
485 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX / 2, &err));
486 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
487
488 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, 0, &err));
489 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
490
491 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX - 1, &err));
492 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
493
494 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, 1, &err));
495 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
496
497 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX, &err));
498 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
499
500 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
501
502 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer + 1, &err));
503 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
504
505 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
506
507 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer, &err));
508 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
509 }
510}