FakeComposerUtils.cpp 6.4 KB

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