blob: 96a75419191fc61035e2009af9a63caeae0527fa [file] [log] [blame]
Kalle Raitaa099a242017-01-11 11:17:29 -08001/*
2 * Copyright 2017 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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Kalle Raitaa099a242017-01-11 11:17:29 -080021#define LOG_NDEBUG 0
22#undef LOG_TAG
23#define LOG_TAG "FakeHwcUtil"
24#include <log/log.h>
25
26#include "FakeComposerUtils.h"
27#include "RenderState.h"
28
29#include "SurfaceFlinger.h" // Get the name of the service...
30
31#include <binder/IServiceManager.h>
32
33#include <cutils/properties.h>
34
35#include <iomanip>
36#include <thread>
37
38using android::String16;
39using android::sp;
40using namespace std::chrono_literals;
41using namespace sftest;
42using std::setw;
43
44namespace sftest {
45
46// clang-format off
47inline void printSourceRectAligned(::std::ostream& os, const hwc_frect_t& sourceRect, int align) {
48 os << std::fixed << std::setprecision(1) << "("
49 << setw(align) << sourceRect.left << setw(0) << ","
50 << setw(align) << sourceRect.top << setw(0) << ","
51 << setw(align) << sourceRect.right << setw(0) << ","
52 << setw(align) << sourceRect.bottom << setw(0) << ")";
53}
54
55inline void printDisplayRectAligned(::std::ostream& os, const hwc_rect_t& displayRect, int align) {
56 os << "("
57 << setw(align) << displayRect.left << setw(0) << ","
58 << setw(align) << displayRect.top << setw(0) << ","
59 << setw(align) << displayRect.right << setw(0) << ","
60 << setw(align) << displayRect.bottom << setw(0) << ")";
61}
62// clang-format on
63
64inline ::std::ostream& operator<<(::std::ostream& os, const sftest::RenderState& state) {
65 printSourceRectAligned(os, state.mSourceCrop, 7);
66 os << "->";
67 printDisplayRectAligned(os, state.mDisplayFrame, 5);
68 return os << " Swaps:" << state.mSwapCount << " Alpha:" << std::setprecision(3)
69 << state.mPlaneAlpha << " Xform:" << state.mTransform;
70}
71
72// Helper for verifying the parts of the RenderState
73template <typename T>
74bool valuesMatch(::testing::AssertionResult& message, const T& ref, const T& val,
75 const char* name) {
76 if (ref != val) {
77 message = message << "Expected " << name << ":" << ref << ", got:" << val << ".";
78 return false;
79 }
80 return true;
81}
82
83::testing::AssertionResult rectsAreSame(const RenderState& ref, const RenderState& val) {
84 // TODO: Message could start as success and be assigned as failure.
85 // Only problem is that utility assumes it to be failure and just adds stuff. Would
86 // need still special case the initial failure in the utility?
87 // TODO: ... or would it be possible to break this back to gtest primitives?
88 ::testing::AssertionResult message = ::testing::AssertionFailure();
89 bool passes = true;
90
91 // The work here is mostly about providing good log strings for differences
92 passes &= valuesMatch(message, ref.mDisplayFrame, val.mDisplayFrame, "display frame");
93 passes &= valuesMatch(message, ref.mPlaneAlpha, val.mPlaneAlpha, "alpha");
94 passes &= valuesMatch(message, ref.mSwapCount, val.mSwapCount, "swap count");
95 passes &= valuesMatch(message, ref.mSourceCrop, val.mSourceCrop, "source crop");
96 // ... add more
97 if (passes) {
98 return ::testing::AssertionSuccess();
99 }
100 return message;
101}
102
103::testing::AssertionResult framesAreSame(const std::vector<RenderState>& ref,
104 const std::vector<RenderState>& val) {
105 ::testing::AssertionResult message = ::testing::AssertionFailure();
106 bool passed = true;
107 if (ref.size() != val.size()) {
108 message << "Expected " << ref.size() << " rects, got " << val.size() << ".";
109 passed = false;
110 }
111 for (size_t rectIndex = 0; rectIndex < std::min(ref.size(), val.size()); rectIndex++) {
112 ::testing::AssertionResult rectResult = rectsAreSame(ref[rectIndex], val[rectIndex]);
113 if (rectResult == false) {
114 message << "First different rect at " << rectIndex << ": " << rectResult.message();
115 passed = false;
116 break;
117 }
118 }
119
120 if (passed) {
121 return ::testing::AssertionSuccess();
122 } else {
123 message << "\nReference:";
124 for (auto state = ref.begin(); state != ref.end(); ++state) {
125 message << "\n" << *state;
126 }
127 message << "\nActual:";
128 for (auto state = val.begin(); state != val.end(); ++state) {
129 message << "\n" << *state;
130 }
131 }
132 return message;
133}
134
135void startSurfaceFlinger() {
136 ALOGI("Start SurfaceFlinger");
137 system("start surfaceflinger");
138
139 sp<android::IServiceManager> sm(android::defaultServiceManager());
140 sp<android::IBinder> sf;
141 while (sf == nullptr) {
142 std::this_thread::sleep_for(10ms);
143 sf = sm->checkService(String16(android::SurfaceFlinger::getServiceName()));
144 }
145 ALOGV("SurfaceFlinger running");
146}
147
148void stopSurfaceFlinger() {
149 ALOGI("Stop SurfaceFlinger");
150 system("stop surfaceflinger");
151 sp<android::IServiceManager> sm(android::defaultServiceManager());
152 sp<android::IBinder> sf;
153 while (sf != nullptr) {
154 std::this_thread::sleep_for(10ms);
155 sf = sm->checkService(String16(android::SurfaceFlinger::getServiceName()));
156 }
157 ALOGV("SurfaceFlinger stopped");
158}
159
160////////////////////////////////////////////////
161
162void FakeHwcEnvironment::SetUp() {
163 ALOGI("Test env setup");
164 system("setenforce 0");
165 system("stop");
166 property_set("debug.sf.nobootanimation", "1");
167 {
168 char value[PROPERTY_VALUE_MAX];
169 property_get("debug.sf.nobootanimation", value, "0");
170 LOG_FATAL_IF(atoi(value) != 1, "boot skip not set");
171 }
172 // TODO: Try registering the mock as the default service instead.
173 property_set("debug.sf.hwc_service_name", "mock");
Dominik Laskowskibe148cc2019-09-18 15:28:31 -0700174
175 // This allows tests/SF to register/load a HIDL service not listed in manifest files.
176 setenv("TREBLE_TESTING_OVERRIDE", "true", true);
Kalle Raitaa099a242017-01-11 11:17:29 -0800177 property_set("debug.sf.treble_testing_override", "true");
178}
179
180void FakeHwcEnvironment::TearDown() {
181 ALOGI("Test env tear down");
182 system("stop");
183 // Wait for mock call signaling teardown?
184 property_set("debug.sf.nobootanimation", "0");
185 property_set("debug.sf.hwc_service_name", "default");
Raymond Chiu17f3d252020-02-10 18:02:27 -0800186 system("setenforce 1");
Kalle Raitaa099a242017-01-11 11:17:29 -0800187 ALOGI("Test env tear down - done");
188}
189
190} // namespace sftest
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800191
192// TODO(b/129481165): remove the #pragma below and fix conversion issues
193#pragma clang diagnostic pop // ignored "-Wconversion"