blob: 87ea7585be055be1625a8ca78824d2ae2c21cebc [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 Wallcf935cb2016-12-15 12:20:47 -0800155 void getDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
156 hwc2_attribute_t attribute, int32_t* outValue,
157 hwc2_error_t* outErr = nullptr)
158 {
159 auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
160 getFunction(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE));
161 ASSERT_TRUE(pfn) << "failed to get function";
162
163 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, config,
164 attribute, outValue));
165
166 if (outErr) {
167 *outErr = err;
168 } else {
169 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display attribute "
170 << getAttributeName(attribute) << " for config " << config;
171 }
172 }
173
174 void getDisplayConfigs(hwc2_display_t display,
175 std::vector<hwc2_config_t>* outConfigs,
176 hwc2_error_t* outErr = nullptr)
177 {
178 auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_CONFIGS>(
179 getFunction(HWC2_FUNCTION_GET_DISPLAY_CONFIGS));
180 ASSERT_TRUE(pfn) << "failed to get function";
181
182 uint32_t numConfigs = 0;
183
184 auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
185 &numConfigs, nullptr));
186
187 if (err == HWC2_ERROR_NONE) {
188 outConfigs->resize(numConfigs);
189
190 err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
191 &numConfigs, outConfigs->data()));
192 }
193
194 if (outErr) {
195 *outErr = err;
196 } else {
197 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get configs for"
198 " display " << display;
199 }
200 }
201
Marissa Wall4d600052016-12-15 12:16:01 -0800202protected:
203 hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
204 {
205 return mHwc2Device->getFunction(mHwc2Device, descriptor);
206 }
207
208 void getCapabilities(std::vector<hwc2_capability_t>* outCapabilities)
209 {
210 uint32_t num = 0;
211
212 mHwc2Device->getCapabilities(mHwc2Device, &num, nullptr);
213
214 outCapabilities->resize(num);
215
216 mHwc2Device->getCapabilities(mHwc2Device, &num,
217 reinterpret_cast<int32_t*>(outCapabilities->data()));
218 }
219
Marissa Wallcfb9a072017-02-17 20:53:18 -0800220 /* Registers a hotplug callback and waits for hotplug callbacks. This
221 * function will have no effect if called more than once. */
222 void populateDisplays()
223 {
224 /* Sets the hotplug status to receiving */
225 {
226 std::lock_guard<std::mutex> lock(mHotplugMutex);
227
228 if (mHotplugStatus != Hwc2TestHotplugStatus::Init)
229 return;
230 mHotplugStatus = Hwc2TestHotplugStatus::Receiving;
231 }
232
233 /* Registers the callback. This function call cannot be locked because
234 * a callback could happen on the same thread */
235 ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_HOTPLUG, this,
236 reinterpret_cast<hwc2_function_pointer_t>(
237 hwc2TestHotplugCallback)));
238
239 /* Waits for hotplug events. If a hotplug event has not come within 1
240 * second, stop waiting. */
241 std::unique_lock<std::mutex> lock(mHotplugMutex);
242
243 while (mHotplugCv.wait_for(lock, std::chrono::seconds(1)) !=
244 std::cv_status::timeout) { }
245
246 /* Sets the hotplug status to done. Future calls will have no effect */
247 mHotplugStatus = Hwc2TestHotplugStatus::Done;
248 }
249
250 void getBadDisplay(hwc2_display_t* outDisplay)
251 {
252 for (hwc2_display_t display = 0; display < UINT64_MAX; display++) {
253 if (mDisplays.count(display) == 0) {
254 *outDisplay = display;
255 return;
256 }
257 }
258 ASSERT_TRUE(false) << "Unable to find bad display. UINT64_MAX displays"
259 " are registered. This should never happen.";
260 }
261
Marissa Wall1db2e372016-12-15 12:19:39 -0800262 /* NOTE: will create min(newlayerCnt, max supported layers) layers */
263 void createLayers(hwc2_display_t display,
264 std::vector<hwc2_layer_t>* outLayers, size_t newLayerCnt)
265 {
266 std::vector<hwc2_layer_t> newLayers;
267 hwc2_layer_t layer;
268 hwc2_error_t err = HWC2_ERROR_NONE;
269
270 for (size_t i = 0; i < newLayerCnt; i++) {
271
272 EXPECT_NO_FATAL_FAILURE(createLayer(display, &layer, &err));
273 if (err == HWC2_ERROR_NO_RESOURCES)
274 break;
275 if (err != HWC2_ERROR_NONE) {
276 newLayers.clear();
277 ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create layer";
278 }
279 newLayers.push_back(layer);
280 }
281
282 *outLayers = std::move(newLayers);
283 }
284
285 void destroyLayers(hwc2_display_t display,
286 std::vector<hwc2_layer_t>&& layers)
287 {
288 for (hwc2_layer_t layer : layers) {
289 EXPECT_NO_FATAL_FAILURE(destroyLayer(display, layer));
290 }
291 }
292
Marissa Wallcf935cb2016-12-15 12:20:47 -0800293 void getInvalidConfig(hwc2_display_t display, hwc2_config_t* outConfig)
294 {
295 std::vector<hwc2_config_t> configs;
296
297 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
298
299 hwc2_config_t CONFIG_MAX = UINT32_MAX;
300
301 ASSERT_LE(configs.size() - 1, CONFIG_MAX) << "every config value"
302 " (2^32 values) has been taken which shouldn't happen";
303
304 hwc2_config_t config;
305 for (config = 0; config < CONFIG_MAX; config++) {
306 if (std::count(configs.begin(), configs.end(), config) == 0)
307 break;
308 }
309
310 *outConfig = config;
311 }
312
Marissa Wall4d600052016-12-15 12:16:01 -0800313 hwc2_device_t* mHwc2Device = nullptr;
Marissa Wallcfb9a072017-02-17 20:53:18 -0800314
315 enum class Hwc2TestHotplugStatus {
316 Init = 1,
317 Receiving,
318 Done,
319 };
320
321 std::mutex mHotplugMutex;
322 std::condition_variable mHotplugCv;
323 Hwc2TestHotplugStatus mHotplugStatus = Hwc2TestHotplugStatus::Init;
324 std::unordered_set<hwc2_display_t> mDisplays;
Marissa Wall1db2e372016-12-15 12:19:39 -0800325
326 /* Store all created layers that have not been destroyed. If an ASSERT_*
327 * fails, then destroy the layers on exit */
328 std::set<std::pair<hwc2_display_t, hwc2_layer_t>> mLayers;
Marissa Wall4d600052016-12-15 12:16:01 -0800329};
330
Marissa Wallcfb9a072017-02-17 20:53:18 -0800331void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
332 hwc2_display_t display, int32_t connection)
333{
334 if (callbackData)
335 static_cast<Hwc2Test*>(callbackData)->hotplugCallback(display,
336 connection);
337}
338
Marissa Wall4d600052016-12-15 12:16:01 -0800339
340static const std::array<hwc2_function_descriptor_t, 42> requiredFunctions = {{
341 HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
342 HWC2_FUNCTION_CREATE_LAYER,
343 HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
344 HWC2_FUNCTION_DESTROY_LAYER,
345 HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
346 HWC2_FUNCTION_DUMP,
347 HWC2_FUNCTION_GET_ACTIVE_CONFIG,
348 HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
349 HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
350 HWC2_FUNCTION_GET_COLOR_MODES,
351 HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
352 HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
353 HWC2_FUNCTION_GET_DISPLAY_NAME,
354 HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
355 HWC2_FUNCTION_GET_DISPLAY_TYPE,
356 HWC2_FUNCTION_GET_DOZE_SUPPORT,
357 HWC2_FUNCTION_GET_HDR_CAPABILITIES,
358 HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
359 HWC2_FUNCTION_GET_RELEASE_FENCES,
360 HWC2_FUNCTION_PRESENT_DISPLAY,
361 HWC2_FUNCTION_REGISTER_CALLBACK,
362 HWC2_FUNCTION_SET_ACTIVE_CONFIG,
363 HWC2_FUNCTION_SET_CLIENT_TARGET,
364 HWC2_FUNCTION_SET_COLOR_MODE,
365 HWC2_FUNCTION_SET_COLOR_TRANSFORM,
366 HWC2_FUNCTION_SET_CURSOR_POSITION,
367 HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
368 HWC2_FUNCTION_SET_LAYER_BUFFER,
369 HWC2_FUNCTION_SET_LAYER_COLOR,
370 HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
371 HWC2_FUNCTION_SET_LAYER_DATASPACE,
372 HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
373 HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
374 HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
375 HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
376 HWC2_FUNCTION_SET_LAYER_TRANSFORM,
377 HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
378 HWC2_FUNCTION_SET_LAYER_Z_ORDER,
379 HWC2_FUNCTION_SET_OUTPUT_BUFFER,
380 HWC2_FUNCTION_SET_POWER_MODE,
381 HWC2_FUNCTION_SET_VSYNC_ENABLED,
382 HWC2_FUNCTION_VALIDATE_DISPLAY,
383}};
384
385/* TESTCASE: Tests that the HWC2 supports all required functions. */
386TEST_F(Hwc2Test, GET_FUNCTION)
387{
388 for (hwc2_function_descriptor_t descriptor : requiredFunctions) {
389 hwc2_function_pointer_t pfn = getFunction(descriptor);
390 EXPECT_TRUE(pfn) << "failed to get function "
391 << getFunctionDescriptorName(descriptor);
392 }
393}
394
395/* TESTCASE: Tests that the HWC2 fails to retrieve and invalid function. */
396TEST_F(Hwc2Test, GET_FUNCTION_invalid_function)
397{
398 hwc2_function_pointer_t pfn = getFunction(HWC2_FUNCTION_INVALID);
399 EXPECT_FALSE(pfn) << "failed to get invalid function";
400}
401
402/* TESTCASE: Tests that the HWC2 does not return an invalid capability. */
403TEST_F(Hwc2Test, GET_CAPABILITIES)
404{
405 std::vector<hwc2_capability_t> capabilities;
406
407 getCapabilities(&capabilities);
408
409 EXPECT_EQ(std::count(capabilities.begin(), capabilities.end(),
410 HWC2_CAPABILITY_INVALID), 0);
411}
Marissa Walla4b01482017-02-17 20:52:03 -0800412
413static const std::array<hwc2_callback_descriptor_t, 3> callbackDescriptors = {{
414 HWC2_CALLBACK_HOTPLUG,
415 HWC2_CALLBACK_REFRESH,
416 HWC2_CALLBACK_VSYNC,
417}};
418
419/* TESTCASE: Tests that the HWC2 can successfully register all required
420 * callback functions. */
421TEST_F(Hwc2Test, REGISTER_CALLBACK)
422{
423 hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
424 const_cast<char*>("data"));
425
426 for (auto descriptor : callbackDescriptors) {
427 ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
428 []() { return; }));
429 }
430}
431
432/* TESTCASE: Test that the HWC2 fails to register invalid callbacks. */
433TEST_F(Hwc2Test, REGISTER_CALLBACK_bad_parameter)
434{
435 hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
436 const_cast<char*>("data"));
437 hwc2_error_t err = HWC2_ERROR_NONE;
438
439 ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_INVALID, data,
440 []() { return; }, &err));
441 EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
442}
443
444/* TESTCASE: Tests that the HWC2 can register a callback with null data. */
445TEST_F(Hwc2Test, REGISTER_CALLBACK_null_data)
446{
447 hwc2_callback_data_t data = nullptr;
448
449 for (auto descriptor : callbackDescriptors) {
450 ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
451 []() { return; }));
452 }
453}
Marissa Wallcfb9a072017-02-17 20:53:18 -0800454
455/* TESTCASE: Tests that the HWC2 returns the correct display type for each
456 * physical display. */
457TEST_F(Hwc2Test, GET_DISPLAY_TYPE)
458{
459 for (auto display : mDisplays) {
460 hwc2_display_type_t type;
461
462 ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type));
463 EXPECT_EQ(type, HWC2_DISPLAY_TYPE_PHYSICAL) << "failed to return"
464 " correct display type";
465 }
466}
467
468/* TESTCASE: Tests that the HWC2 returns an error when the display type of a bad
469 * display is requested. */
470TEST_F(Hwc2Test, GET_DISPLAY_TYPE_bad_display)
471{
472 hwc2_display_t display;
473 hwc2_display_type_t type;
474 hwc2_error_t err = HWC2_ERROR_NONE;
475
476 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
477
478 ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type, &err));
479 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
480}
Marissa Wall1db2e372016-12-15 12:19:39 -0800481
482/* TESTCASE: Tests that the HWC2 can create and destroy layers. */
483TEST_F(Hwc2Test, CREATE_DESTROY_LAYER)
484{
485 for (auto display : mDisplays) {
486 hwc2_layer_t layer;
487
488 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
489
490 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
491 }
492}
493
494/* TESTCASE: Tests that the HWC2 cannot create a layer for a bad display */
495TEST_F(Hwc2Test, CREATE_LAYER_bad_display)
496{
497 hwc2_display_t display;
498 hwc2_layer_t layer;
499 hwc2_error_t err = HWC2_ERROR_NONE;
500
501 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
502
503 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer, &err));
504 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
505}
506
507/* TESTCASE: Tests that the HWC2 will either support a large number of resources
508 * or will return no resources. */
509TEST_F(Hwc2Test, CREATE_LAYER_no_resources)
510{
511 const size_t layerCnt = 1000;
512
513 for (auto display : mDisplays) {
514 std::vector<hwc2_layer_t> layers;
515
516 ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
517
518 ASSERT_NO_FATAL_FAILURE(destroyLayers(display, std::move(layers)));
519 }
520}
521
522/* TESTCASE: Tests that the HWC2 cannot destroy a layer for a bad display */
523TEST_F(Hwc2Test, DESTROY_LAYER_bad_display)
524{
525 hwc2_display_t badDisplay;
526
527 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&badDisplay));
528
529 for (auto display : mDisplays) {
530 hwc2_layer_t layer = 0;
531 hwc2_error_t err = HWC2_ERROR_NONE;
532
533 ASSERT_NO_FATAL_FAILURE(destroyLayer(badDisplay, layer, &err));
534 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
535
536 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
537
538 ASSERT_NO_FATAL_FAILURE(destroyLayer(badDisplay, layer, &err));
539 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
540
541 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
542 }
543}
544
545/* TESTCASE: Tests that the HWC2 cannot destory a bad layer */
546TEST_F(Hwc2Test, DESTROY_LAYER_bad_layer)
547{
548 for (auto display : mDisplays) {
549 hwc2_layer_t layer;
550 hwc2_error_t err = HWC2_ERROR_NONE;
551
552 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX / 2, &err));
553 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
554
555 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, 0, &err));
556 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
557
558 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX - 1, &err));
559 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
560
561 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, 1, &err));
562 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
563
564 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX, &err));
565 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
566
567 ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
568
569 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer + 1, &err));
570 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
571
572 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
573
574 ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer, &err));
575 EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
576 }
577}
Marissa Wallcf935cb2016-12-15 12:20:47 -0800578
579static const std::array<hwc2_attribute_t, 2> requiredAttributes = {{
580 HWC2_ATTRIBUTE_WIDTH,
581 HWC2_ATTRIBUTE_HEIGHT,
582}};
583
584static const std::array<hwc2_attribute_t, 3> optionalAttributes = {{
585 HWC2_ATTRIBUTE_VSYNC_PERIOD,
586 HWC2_ATTRIBUTE_DPI_X,
587 HWC2_ATTRIBUTE_DPI_Y,
588}};
589
590/* TESTCASE: Tests that the HWC2 can return display attributes for a valid
591 * config. */
592TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE)
593{
594 for (auto display : mDisplays) {
595 std::vector<hwc2_config_t> configs;
596
597 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
598
599 for (auto config : configs) {
600 int32_t value;
601
602 for (auto attribute : requiredAttributes) {
603 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
604 attribute, &value));
605 EXPECT_GE(value, 0) << "missing required attribute "
606 << getAttributeName(attribute) << " for config "
607 << config;
608 }
609 for (auto attribute : optionalAttributes) {
610 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
611 attribute, &value));
612 }
613 }
614 }
615}
616
617/* TESTCASE: Tests that the HWC2 will return a value of -1 for an invalid
618 * attribute */
619TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE_invalid_attribute)
620{
621 const hwc2_attribute_t attribute = HWC2_ATTRIBUTE_INVALID;
622
623 for (auto display : mDisplays) {
624 std::vector<hwc2_config_t> configs;
625
626 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
627
628 for (auto config : configs) {
629 int32_t value;
630 hwc2_error_t err = HWC2_ERROR_NONE;
631
632 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
633 attribute, &value, &err));
634 EXPECT_EQ(value, -1) << "failed to return -1 for an invalid"
635 " attribute for config " << config;
636 }
637 }
638}
639
640/* TESTCASE: Tests that the HWC2 will fail to get attributes for a bad display */
641TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE_bad_display)
642{
643 hwc2_display_t display;
644 const hwc2_config_t config = 0;
645 int32_t value;
646 hwc2_error_t err = HWC2_ERROR_NONE;
647
648 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
649
650 for (auto attribute : requiredAttributes) {
651 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config, attribute,
652 &value, &err));
653 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
654 }
655
656 for (auto attribute : optionalAttributes) {
657 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config, attribute,
658 &value, &err));
659 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
660 }
661}
662
663/* TESTCASE: Tests that the HWC2 will fail to get attributes for a bad config */
664TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE_bad_config)
665{
666 for (auto display : mDisplays) {
667 hwc2_config_t config;
668 int32_t value;
669 hwc2_error_t err = HWC2_ERROR_NONE;
670
671 ASSERT_NO_FATAL_FAILURE(getInvalidConfig(display, &config));
672
673 for (auto attribute : requiredAttributes) {
674 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
675 attribute, &value, &err));
676 EXPECT_EQ(err, HWC2_ERROR_BAD_CONFIG) << "returned wrong error code";
677 }
678
679 for (auto attribute : optionalAttributes) {
680 ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
681 attribute, &value, &err));
682 EXPECT_EQ(err, HWC2_ERROR_BAD_CONFIG) << "returned wrong error code";
683 }
684 }
685}
686
687/* TESTCASE: Tests that the HWC2 will get display configs for active displays */
688TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS)
689{
690 for (auto display : mDisplays) {
691 std::vector<hwc2_config_t> configs;
692
693 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
694 }
695}
696
697/* TESTCASE: Tests that the HWC2 will not get display configs for bad displays */
698TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS_bad_display)
699{
700 hwc2_display_t display;
701 std::vector<hwc2_config_t> configs;
702 hwc2_error_t err = HWC2_ERROR_NONE;
703
704 ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
705
706 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs, &err));
707
708 EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
709 EXPECT_TRUE(configs.empty()) << "returned configs for bad display";
710}
711
712/* TESTCASE: Tests that the HWC2 will return the same config list multiple
713 * times in a row. */
714TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS_same)
715{
716 for (auto display : mDisplays) {
717 std::vector<hwc2_config_t> configs1, configs2;
718
719 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs1));
720 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs2));
721
722 EXPECT_TRUE(std::is_permutation(configs1.begin(), configs1.end(),
723 configs2.begin())) << "returned two different config sets";
724 }
725}
726
727/* TESTCASE: Tests that the HWC2 does not return duplicate display configs */
728TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS_duplicate)
729{
730 for (auto display : mDisplays) {
731 std::vector<hwc2_config_t> configs;
732
733 ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
734
735 std::unordered_set<hwc2_config_t> configsSet(configs.begin(),
736 configs.end());
737 EXPECT_EQ(configs.size(), configsSet.size()) << "returned duplicate"
738 " configs";
739 }
740}