vrflinger_test.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
  2. #include <android/hardware/configstore/1.1/types.h>
  3. #include <android/hardware_buffer.h>
  4. #include <binder/IServiceManager.h>
  5. #include <binder/Parcel.h>
  6. #include <binder/ProcessState.h>
  7. #include <configstore/Utils.h>
  8. #include <cutils/properties.h>
  9. #include <gtest/gtest.h>
  10. #include <gui/ISurfaceComposer.h>
  11. #include <log/log.h>
  12. #include <utils/StrongPointer.h>
  13. #include <chrono>
  14. #include <memory>
  15. #include <mutex>
  16. #include <optional>
  17. #include <thread>
  18. #include <private/dvr/display_client.h>
  19. using namespace android::hardware::configstore;
  20. using namespace android::hardware::configstore::V1_0;
  21. using android::dvr::display::DisplayClient;
  22. using android::dvr::display::Surface;
  23. using android::dvr::display::SurfaceAttribute;
  24. using android::dvr::display::SurfaceAttributeValue;
  25. namespace android {
  26. namespace dvr {
  27. // The transaction code for asking surface flinger if vr flinger is active. This
  28. // is done as a hidden api since it's only used for tests. See the "case 1028"
  29. // block in SurfaceFlinger::onTransact() in SurfaceFlinger.cpp.
  30. constexpr uint32_t kIsVrFlingerActiveTransactionCode = 1028;
  31. // The maximum amount of time to give vr flinger to activate/deactivate. If the
  32. // switch hasn't completed in this amount of time, the test will fail.
  33. constexpr auto kVrFlingerSwitchMaxTime = std::chrono::seconds(1);
  34. // How long to wait between each check to see if the vr flinger switch
  35. // completed.
  36. constexpr auto kVrFlingerSwitchPollInterval = std::chrono::milliseconds(50);
  37. // How long to wait for a device that boots to VR to have vr flinger ready.
  38. constexpr auto kBootVrFlingerWaitTimeout = std::chrono::seconds(30);
  39. // A Binder connection to surface flinger.
  40. class SurfaceFlingerConnection {
  41. public:
  42. static std::unique_ptr<SurfaceFlingerConnection> Create() {
  43. sp<ISurfaceComposer> surface_flinger = interface_cast<ISurfaceComposer>(
  44. defaultServiceManager()->getService(String16("SurfaceFlinger")));
  45. if (surface_flinger == nullptr) {
  46. return nullptr;
  47. }
  48. return std::unique_ptr<SurfaceFlingerConnection>(
  49. new SurfaceFlingerConnection(surface_flinger));
  50. }
  51. // Returns true if the surface flinger process is still running. We use this
  52. // to detect if surface flinger has crashed.
  53. bool IsAlive() {
  54. IInterface::asBinder(surface_flinger_)->pingBinder();
  55. return IInterface::asBinder(surface_flinger_)->isBinderAlive();
  56. }
  57. // Return true if vr flinger is currently active, false otherwise. If there's
  58. // an error communicating with surface flinger, std::nullopt is returned.
  59. std::optional<bool> IsVrFlingerActive() {
  60. Parcel data, reply;
  61. status_t result =
  62. data.writeInterfaceToken(surface_flinger_->getInterfaceDescriptor());
  63. if (result != OK) {
  64. return std::nullopt;
  65. }
  66. result = IInterface::asBinder(surface_flinger_)
  67. ->transact(kIsVrFlingerActiveTransactionCode, data, &reply);
  68. if (result != OK) {
  69. return std::nullopt;
  70. }
  71. bool vr_flinger_active;
  72. result = reply.readBool(&vr_flinger_active);
  73. if (result != OK) {
  74. return std::nullopt;
  75. }
  76. return vr_flinger_active;
  77. }
  78. enum class VrFlingerSwitchResult : int8_t {
  79. kSuccess,
  80. kTimedOut,
  81. kCommunicationError,
  82. kSurfaceFlingerDied
  83. };
  84. // Wait for vr flinger to become active or inactive.
  85. VrFlingerSwitchResult WaitForVrFlinger(bool wait_active) {
  86. return WaitForVrFlingerTimed(wait_active, kVrFlingerSwitchPollInterval,
  87. kVrFlingerSwitchMaxTime);
  88. }
  89. // Wait for vr flinger to become active or inactive, specifying custom timeouts.
  90. VrFlingerSwitchResult WaitForVrFlingerTimed(bool wait_active,
  91. std::chrono::milliseconds pollInterval, std::chrono::seconds timeout) {
  92. auto start_time = std::chrono::steady_clock::now();
  93. while (1) {
  94. std::this_thread::sleep_for(pollInterval);
  95. if (!IsAlive()) {
  96. return VrFlingerSwitchResult::kSurfaceFlingerDied;
  97. }
  98. std::optional<bool> vr_flinger_active = IsVrFlingerActive();
  99. if (!vr_flinger_active.has_value()) {
  100. return VrFlingerSwitchResult::kCommunicationError;
  101. }
  102. if (vr_flinger_active.value() == wait_active) {
  103. return VrFlingerSwitchResult::kSuccess;
  104. } else if (std::chrono::steady_clock::now() - start_time > timeout) {
  105. return VrFlingerSwitchResult::kTimedOut;
  106. }
  107. }
  108. }
  109. private:
  110. SurfaceFlingerConnection(sp<ISurfaceComposer> surface_flinger)
  111. : surface_flinger_(surface_flinger) {}
  112. sp<ISurfaceComposer> surface_flinger_ = nullptr;
  113. };
  114. // This test activates vr flinger by creating a vr flinger surface, then
  115. // deactivates vr flinger by destroying the surface. We verify that vr flinger
  116. // is activated and deactivated as expected, and that surface flinger doesn't
  117. // crash.
  118. //
  119. // If the device doesn't support vr flinger (as repoted by ConfigStore), the
  120. // test does nothing.
  121. //
  122. // If the device is a standalone vr device, the test also does nothing, since
  123. // this test verifies the behavior of display handoff from surface flinger to vr
  124. // flinger and back, and standalone devices never hand control of the display
  125. // back to surface flinger.
  126. TEST(VrFlingerTest, ActivateDeactivate) {
  127. android::ProcessState::self()->startThreadPool();
  128. // Exit immediately if the device doesn't support vr flinger. This ConfigStore
  129. // check is the same mechanism used by surface flinger to decide if it should
  130. // initialize vr flinger.
  131. bool vr_flinger_enabled =
  132. getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::useVrFlinger>(
  133. false);
  134. if (!vr_flinger_enabled) {
  135. return;
  136. }
  137. // This test doesn't apply to standalone vr devices.
  138. if (property_get_bool("ro.boot.vr", false)) {
  139. return;
  140. }
  141. auto surface_flinger_connection = SurfaceFlingerConnection::Create();
  142. ASSERT_NE(surface_flinger_connection, nullptr);
  143. // Verify we start off with vr flinger disabled.
  144. ASSERT_TRUE(surface_flinger_connection->IsAlive());
  145. auto vr_flinger_active = surface_flinger_connection->IsVrFlingerActive();
  146. ASSERT_TRUE(vr_flinger_active.has_value());
  147. ASSERT_FALSE(vr_flinger_active.value());
  148. // Create a vr flinger surface, and verify vr flinger becomes active.
  149. // Introduce a scope so that, at the end of the scope, the vr flinger surface
  150. // is destroyed, and vr flinger deactivates.
  151. {
  152. auto display_client = DisplayClient::Create();
  153. ASSERT_NE(display_client, nullptr);
  154. auto metrics = display_client->GetDisplayMetrics();
  155. ASSERT_TRUE(metrics.ok());
  156. auto surface = Surface::CreateSurface({
  157. {SurfaceAttribute::Direct, SurfaceAttributeValue(true)},
  158. {SurfaceAttribute::Visible, SurfaceAttributeValue(true)},
  159. });
  160. ASSERT_TRUE(surface.ok());
  161. ASSERT_TRUE(surface.get() != nullptr);
  162. auto queue = surface.get()->CreateQueue(
  163. metrics.get().display_width, metrics.get().display_height,
  164. /*layer_count=*/1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
  165. AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
  166. AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
  167. AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
  168. /*capacity=*/1,
  169. /*metadata_size=*/0);
  170. ASSERT_TRUE(queue.ok());
  171. ASSERT_TRUE(queue.get() != nullptr);
  172. size_t slot;
  173. pdx::LocalHandle release_fence;
  174. auto buffer = queue.get()->Dequeue(/*timeout=*/0, &slot, &release_fence);
  175. ASSERT_TRUE(buffer.ok());
  176. ASSERT_TRUE(buffer.get() != nullptr);
  177. ASSERT_EQ(buffer.get()->width(), metrics.get().display_width);
  178. ASSERT_EQ(buffer.get()->height(), metrics.get().display_height);
  179. void* raw_buf = nullptr;
  180. ASSERT_GE(buffer.get()->buffer()->Lock(
  181. AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, /*x=*/0, /*y=*/0,
  182. buffer.get()->width(), buffer.get()->height(), &raw_buf),
  183. 0);
  184. ASSERT_NE(raw_buf, nullptr);
  185. uint32_t* pixels = static_cast<uint32_t*>(raw_buf);
  186. for (int i = 0; i < buffer.get()->stride() * buffer.get()->height(); ++i) {
  187. pixels[i] = 0x0000ff00;
  188. }
  189. ASSERT_GE(buffer.get()->buffer()->Unlock(), 0);
  190. ASSERT_GE(buffer.get()->Post(/*ready_fence=*/pdx::LocalHandle()), 0);
  191. ASSERT_EQ(
  192. surface_flinger_connection->WaitForVrFlinger(/*wait_active=*/true),
  193. SurfaceFlingerConnection::VrFlingerSwitchResult::kSuccess);
  194. }
  195. // Now that the vr flinger surface is destroyed, vr flinger should deactivate.
  196. ASSERT_EQ(
  197. surface_flinger_connection->WaitForVrFlinger(/*wait_active=*/false),
  198. SurfaceFlingerConnection::VrFlingerSwitchResult::kSuccess);
  199. }
  200. // This test runs only on devices that boot to vr. Such a device should boot to
  201. // a state where vr flinger is running, and the test verifies this after a
  202. // delay.
  203. TEST(BootVrFlingerTest, BootsToVrFlinger) {
  204. // Exit if we are not running on a device that boots to vr.
  205. if (!property_get_bool("ro.boot.vr", false)) {
  206. return;
  207. }
  208. auto surface_flinger_connection = SurfaceFlingerConnection::Create();
  209. ASSERT_NE(surface_flinger_connection, nullptr);
  210. // Verify that vr flinger is enabled.
  211. ASSERT_TRUE(surface_flinger_connection->IsAlive());
  212. auto vr_flinger_active = surface_flinger_connection->IsVrFlingerActive();
  213. ASSERT_TRUE(vr_flinger_active.has_value());
  214. bool active_value = vr_flinger_active.value();
  215. if (!active_value) {
  216. // Try again, but delay up to 30 seconds.
  217. ASSERT_EQ(surface_flinger_connection->WaitForVrFlingerTimed(true,
  218. kVrFlingerSwitchPollInterval, kBootVrFlingerWaitTimeout),
  219. SurfaceFlingerConnection::VrFlingerSwitchResult::kSuccess);
  220. }
  221. }
  222. } // namespace dvr
  223. } // namespace android