1 /*
2 * Copyright 2020, 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 <fstream>
18 #include <getopt.h>
19 #include <gtest/gtest.h>
20 #include <inttypes.h>
21 #include <iostream>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <teeui/example/example.h>
25 #include <unistd.h>
26
27 #include "teeui_device_config.h"
28 #include <teeui/test/teeui_render_test.h>
29
30 #define TeeuiRenderTest_DO_LOG_DEBUG
31
32 namespace teeui {
33
34 namespace test {
35
36 using namespace example;
37
initRenderTest(int argc,char ** argv)38 void initRenderTest(int argc, char** argv) {
39 ::teeui::test::TeeuiRenderTest::Instance()->initFromOptions(argc, argv);
40 }
41
saveToPpm(const uint32_t * data,uint32_t w,uint32_t h,uint32_t linestride)42 void saveToPpm(const uint32_t* data, uint32_t w, uint32_t h, uint32_t linestride) {
43 const testing::TestInfo* const test_info =
44 testing::UnitTest::GetInstance()->current_test_info();
45 std::string testname = test_info->name();
46 std::ofstream out;
47
48 out.open(testname + ".ppm", std::ios::binary);
49 if (out.is_open()) {
50 uint32_t linestart = 0;
51
52 /* Write the header */
53 out << "P6\n" << w << " " << h << "\n255\n";
54
55 /* Write binary Pixel data */
56 for (uint32_t line = 0; line < h; line++) {
57 for (uint32_t col = 0; col < w; col++) {
58 const uint32_t color = data[linestart + col];
59 char rgb[3];
60
61 rgb[0] = color >> 16;
62 rgb[1] = color >> 8;
63 rgb[2] = color;
64
65 out.write(rgb, sizeof(rgb));
66 }
67
68 linestart += linestride;
69 }
70
71 out.close();
72 }
73 }
74
runRenderTest(const char * language,bool magnified,bool inverted,const char * confirmationMessage,const char * layout)75 int runRenderTest(const char* language, bool magnified, bool inverted,
76 const char* confirmationMessage, const char* layout) {
77 std::unique_ptr<ITeeuiExample> sCurrentExample = createExample(
78 (strcmp(layout, kTouchButtonLayout) == 0) ? Examples::TouchButton : Examples::PhysButton);
79
80 DeviceInfo* device_info_ptr = &TeeuiRenderTest::Instance()->device_info;
81 sCurrentExample->setDeviceInfo(*device_info_ptr, magnified, inverted);
82 uint32_t w = device_info_ptr->width_;
83 uint32_t h = device_info_ptr->height_;
84 uint32_t linestride = w;
85 uint32_t buffer_size = h * linestride;
86 std::vector<uint32_t> buffer(buffer_size);
87 sCurrentExample->setConfirmationMessage(confirmationMessage);
88 sCurrentExample->selectLanguage(language);
89
90 int error =
91 sCurrentExample->renderUIIntoBuffer(0, 0, w, h, linestride, buffer.data(), buffer_size);
92
93 if (TeeuiRenderTest::Instance()->saveScreen()) {
94 saveToPpm(buffer.data(), w, h, linestride);
95 }
96
97 return error;
98 }
99
initFromOptions(int argc,char ** argv)100 void TeeuiRenderTest::initFromOptions(int argc, char** argv) {
101
102 int option_index = 0;
103 static struct option options[] = {{"width", required_argument, 0, 'w'},
104 {"height", required_argument, 0, 'l'},
105 {"dp2px", required_argument, 0, 'd'},
106 {"mm2px", required_argument, 0, 'm'},
107 {"powerButtonTop", required_argument, 0, 't'},
108 {"powerButtonBottom", required_argument, 0, 'b'},
109 {"volUpButtonTop", required_argument, 0, 'u'},
110 {"volUpButtonBottom", required_argument, 0, 'v'},
111 {"saveScreen", 0, 0, 's'},
112 {"help", 0, 0, 'h'},
113 {"?", 0, 0, '?'},
114 {0, 0, 0, 0}};
115 while (true) {
116 int c = getopt_long(argc, argv, "w:l:d:m:t:b:u:v:h?", options, &option_index);
117 if (c == -1) break;
118 switch (c) {
119 case 'w':
120 device_info.width_ = strtol(optarg, NULL, 10);
121 break;
122 case 'l':
123 device_info.height_ = strtol(optarg, NULL, 10);
124 break;
125 case 'd':
126 device_info.dp2px_ = strtod(optarg, NULL);
127 break;
128 case 'm':
129 device_info.mm2px_ = strtod(optarg, NULL);
130 break;
131 case 't':
132 device_info.powerButtonTopMm_ = strtod(optarg, NULL);
133 break;
134 case 'b':
135 device_info.powerButtonBottomMm_ = strtod(optarg, NULL);
136 break;
137 case 'u':
138 device_info.volUpButtonTopMm_ = strtod(optarg, NULL);
139 break;
140 case 'v':
141 device_info.volUpButtonBottomMm_ = strtod(optarg, NULL);
142 break;
143 case 's':
144 saveScreen_ = true;
145 break;
146 case '?':
147 case 'h':
148 std::cout << "Options:" << std::endl;
149 std::cout << "--width=<device width in pixels>" << std::endl;
150 std::cout << "--height=<device height in pixels>" << std::endl;
151 std::cout << "--dp2px=<pixel per density independent pixel (px/dp) ratio of the "
152 "device. Typically <width in pixels>/412 >"
153 << std::endl;
154 std::cout << "--mm2px=<pixel per millimeter (px/mm) ratio>" << std::endl;
155 std::cout << "--powerButtonTop=<distance from the top of the power button to the top "
156 "of the screen in mm>"
157 << std::endl;
158 std::cout << "--powerButtonBottom=<distance from the bottom of the power button to the "
159 "top of the screen in mm>"
160 << std::endl;
161 std::cout << "--volUpButtonTop=<distance from the top of the UP volume button to the "
162 "top of the screen in mm>"
163 << std::endl;
164 std::cout << "--volUpButtonBottom=<distance from the bottom of the UP power button to "
165 "the top of the screen in mm>"
166 << std::endl;
167 std::cout << "--saveScreen - save rendered screen to ppm files in working directory"
168 << std::endl;
169 exit(0);
170 }
171 }
172 }
173
174 } // namespace test
175
176 } // namespace teeui
177