blob: 82968e2641e2bc3761e227f0215c82a3545dd3e1 [file] [log] [blame]
/*
* Copyright (C) 2023 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 <inttypes.h>
#include <uapi/err.h>
#include <optional>
#include "device_parameters.h"
#define TLOG_TAG "confui-test"
#include <trusty_unittest.h>
#define MIN_EXPECTED_DRAW_COUNT 1000u
#define MIN_EXPECTED_DRAW_PERCENTAGE 1u
static const char* language_ids[] = {"en"};
static const char* messages[] = {
/* Simple message */
"Android Test Message",
/* Two line message as required by Android design guidelines */
"WM Line 1\nWM Line 2",
/* 100 'W' characters as required by Android design guidelines */
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
/* 8 groups of 12 'W' characters as required by Android design
guidelines */
"WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW"};
TEST(confui, display_count) {
int display_count = devices::getDisplayCount();
EXPECT_GT(display_count, 0);
}
typedef struct {
uint32_t count;
} draw_stats_t;
typedef struct {
const char* lang_id;
const char* message;
bool magnified;
bool inverse;
} confuip_t;
TEST_F_SETUP(confuip) {
const void* const* param_arr = (const void* const*)GetParam();
const bool* magnified = (const bool*)param_arr[0];
const bool* inverse = (const bool*)param_arr[1];
const char** lang_id = (const char**)param_arr[2];
const char** message = (const char**)param_arr[3];
_state->magnified = *magnified;
_state->inverse = *inverse;
_state->lang_id = *lang_id;
_state->message = *message;
}
TEST_F_TEARDOWN(confuip) {}
TEST_P(confuip, display_params) {
int display_count = devices::getDisplayCount();
for (int i = 0; i < display_count; i++) {
std::optional<teeui::context<teeui::ConUIParameters>> params;
params = devices::getDisplayContext(i, _state->magnified);
EXPECT_EQ(params.has_value(), true, "getDisplayContext %d", i);
if (params) {
const uint32_t screen_width =
params->getParam<teeui::RightEdgeOfScreen>()->count() + 1;
const uint32_t screen_height =
params->getParam<teeui::BottomOfScreen>()->count() + 1;
std::optional<std::unique_ptr<teeui::layouts::ILayout>> optlayout;
optlayout = devices::getDisplayLayout(i, _state->inverse, *params);
EXPECT_EQ(optlayout.has_value(), true, "getDisplayLayout %d", i);
/* Configure the layout */
if (optlayout) {
std::unique_ptr<teeui::layouts::ILayout> layout =
std::move(*optlayout);
draw_stats_t stats = {};
/* Configure the layout */
layout->setLanguage(_state->lang_id);
layout->setConfirmationMessage(_state->message);
layout->showInstructions(true /* enable */);
auto drawPixel = teeui::makePixelDrawer(
[&](uint32_t x, uint32_t y,
teeui::Color color) -> teeui::Error {
TLOGD("px %u %u: %08x", x, y, color);
/* Check bounds */
if (x >= screen_width || y >= screen_height) {
return teeui::Error::OutOfBoundsDrawing;
}
/* Count calls, noting there is no check if some
* pixels are written multiple times.
*/
stats.count++;
return teeui::Error::OK;
});
/* Render the layout */
teeui::Error rc = layout->drawElements(drawPixel);
EXPECT_EQ(rc.code(), teeui::Error::OK, "drawElements %d", i);
EXPECT_GT(stats.count, MIN_EXPECTED_DRAW_COUNT,
"pixel count %d", i);
const uint32_t area = screen_width * screen_height;
const uint32_t coverage =
(float)stats.count / (float)area * 1000.0f;
EXPECT_GT(coverage, MIN_EXPECTED_DRAW_PERCENTAGE * 10u,
"pixel coverage %" PRIu32 ".%" PRIu32 "%%",
coverage / 10, coverage % 10);
trusty_unittest_printf("[ DATA ] %" PRIu32 "x%" PRIu32
", %" PRIu32
" plot calls = approx %" PRIu32
".%" PRIu32 "%% coverage\n",
screen_width, screen_height, stats.count,
coverage / 10, coverage % 10);
}
}
}
}
void confuip_to_string(const void* param, char* buf, size_t buf_size) {
const void* const* param_arr = (const void* const*)GetParam();
const bool* magnified = (const bool*)param_arr[0];
const bool* inverse = (const bool*)param_arr[1];
const char** lang_id = (const char**)param_arr[2];
const char** message = (const char**)param_arr[3];
uint8_t msg_index = message - messages;
snprintf(buf, buf_size, "%s/msg%" PRIu8 "%s%s", *lang_id, msg_index,
*magnified ? "/mag" : "", *inverse ? "/inv" : "");
}
INSTANTIATE_TEST_SUITE_P(confui,
confuip,
testing_Combine(testing_Bool(), /* magnified */
testing_Bool(), /* inverse */
testing_ValuesIn(language_ids),
testing_ValuesIn(messages)),
confuip_to_string);
PORT_TEST(confui, "com.android.trusty.confirmationui.test");