1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/run_loop.h"
7 #include "base/threading/platform_thread.h"
8 #include "build/build_config.h"
9 #if defined(OS_WIN)
10 #include "chrome/browser/vr/win/vr_browser_renderer_thread_win.h"
11 #endif // defined(OS_WIN)
12 #include "chrome/browser/vr/test/browser_test_browser_renderer_browser_interface.h"
13 #include "chrome/browser/vr/test/ui_utils.h"
14 #include "chrome/browser/vr/test/xr_browser_test.h"
15
16 namespace vr {
17
UiUtils()18 UiUtils::UiUtils()
19 : ui_operation_results_(std::vector<UiTestOperationResult>(
20 static_cast<int>(UiTestOperationType::kNumUiTestOperationTypes))),
21 ui_operation_callbacks_(std::vector<base::OnceCallback<void()>>(
22 static_cast<int>(UiTestOperationType::kNumUiTestOperationTypes))),
23 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
24 auto* renderer = GetBrowserRenderer();
25 DCHECK(renderer) << "Failed to get a BrowserRenderer. Consider using "
26 << "UiUtils::Create() instead.";
27
28 interface_ =
29 std::make_unique<BrowserTestBrowserRendererBrowserInterface>(this);
30 renderer->SetBrowserRendererBrowserInterfaceForTesting(interface_.get());
31 }
32
~UiUtils()33 UiUtils::~UiUtils() {
34 auto* renderer = GetBrowserRenderer();
35 if (renderer != nullptr) {
36 renderer->SetBrowserRendererBrowserInterfaceForTesting(nullptr);
37 }
38 }
39
Create()40 std::unique_ptr<UiUtils> UiUtils::Create() {
41 base::RunLoop wait_loop(base::RunLoop::Type::kNestableTasksAllowed);
42 base::ThreadTaskRunnerHandle::Get()->PostTask(
43 FROM_HERE, base::BindOnce(&UiUtils::PollForBrowserRenderer, &wait_loop));
44 wait_loop.Run();
45
46 return std::make_unique<UiUtils>();
47 }
48
PollForBrowserRenderer(base::RunLoop * wait_loop)49 void UiUtils::PollForBrowserRenderer(base::RunLoop* wait_loop) {
50 if (GetBrowserRenderer() == nullptr) {
51 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
52 FROM_HERE, base::BindOnce(&UiUtils::PollForBrowserRenderer, wait_loop),
53 XrBrowserTestBase::kPollCheckIntervalShort);
54 return;
55 }
56 wait_loop->Quit();
57 }
58
PerformActionAndWaitForVisibilityStatus(const UserFriendlyElementName & element_name,const bool & visible,base::OnceCallback<void ()> action)59 void UiUtils::PerformActionAndWaitForVisibilityStatus(
60 const UserFriendlyElementName& element_name,
61 const bool& visible,
62 base::OnceCallback<void()> action) {
63 ui_operation_results_[static_cast<int>(
64 UiTestOperationType::kElementVisibilityStatus)] =
65 UiTestOperationResult::kUnreported;
66 base::RunLoop wait_loop(base::RunLoop::Type::kNestableTasksAllowed);
67 ui_operation_callbacks_[static_cast<int>(
68 UiTestOperationType::kElementVisibilityStatus)] =
69 base::BindOnce([](base::RunLoop* loop) { loop->Quit(); }, &wait_loop);
70
71 VisibilityChangeExpectation visibility_expectation;
72 visibility_expectation.element_name = element_name;
73 visibility_expectation.timeout_ms = kDefaultUiQuiescenceTimeout;
74 visibility_expectation.visibility = visible;
75
76 main_thread_task_runner_->PostTask(
77 FROM_HERE,
78 base::BindOnce(&UiUtils::WatchElementForVisibilityStatusForTesting,
79 base::Unretained(this), visibility_expectation));
80
81 wait_loop.Run();
82
83 auto result = ui_operation_results_[static_cast<int>(
84 UiTestOperationType::kElementVisibilityStatus)];
85 CHECK(result == UiTestOperationResult::kVisibilityMatch)
86 << "UI reported non-visibility-matched result '"
87 << UiTestOperationResultToString(result) << "'";
88 }
89
WatchElementForVisibilityStatusForTesting(VisibilityChangeExpectation visibility_expectation)90 void UiUtils::WatchElementForVisibilityStatusForTesting(
91 VisibilityChangeExpectation visibility_expectation) {
92 BrowserRenderer* browser_renderer = UiUtils::GetBrowserRenderer();
93 if (browser_renderer) {
94 interface_ =
95 std::make_unique<BrowserTestBrowserRendererBrowserInterface>(this);
96 browser_renderer->SetBrowserRendererBrowserInterfaceForTesting(
97 interface_.get());
98 browser_renderer->WatchElementForVisibilityStatusForTesting(
99 visibility_expectation);
100 }
101 }
102
ReportUiOperationResult(const UiTestOperationType & action_type,const UiTestOperationResult & result)103 void UiUtils::ReportUiOperationResult(const UiTestOperationType& action_type,
104 const UiTestOperationResult& result) {
105 ui_operation_results_[static_cast<int>(action_type)] = result;
106 std::move(ui_operation_callbacks_[static_cast<int>(action_type)]).Run();
107 }
108
DisableFrameTimeoutForTesting()109 void UiUtils::DisableFrameTimeoutForTesting() {
110 #if defined(OS_WIN)
111 VRBrowserRendererThreadWin::DisableFrameTimeoutForTesting();
112 #else
113 NOTREACHED();
114 #endif // defined(OS_WIN)
115 }
116
UiTestOperationResultToString(UiTestOperationResult & result)117 std::string UiUtils::UiTestOperationResultToString(
118 UiTestOperationResult& result) {
119 switch (result) {
120 case UiTestOperationResult::kUnreported:
121 return "Unreported";
122 case UiTestOperationResult::kQuiescent:
123 return "Quiescent";
124 case UiTestOperationResult::kTimeoutNoStart:
125 return "Timeout (UI activity not started)";
126 case UiTestOperationResult::kTimeoutNoEnd:
127 return "Timeout (UI activity not stopped)";
128 case UiTestOperationResult::kVisibilityMatch:
129 return "Visibility match";
130 case UiTestOperationResult::kTimeoutNoVisibilityMatch:
131 return "Timeout (Element visibility did not match)";
132 }
133 }
134
GetRendererThread()135 VRBrowserRendererThreadWin* UiUtils::GetRendererThread() {
136 #if defined(OS_WIN)
137 return VRBrowserRendererThreadWin::GetInstanceForTesting();
138 #else
139 NOTREACHED();
140 #endif // defined(OS_WIN)
141 }
142
GetBrowserRenderer()143 BrowserRenderer* UiUtils::GetBrowserRenderer() {
144 #if defined(OS_WIN)
145 auto* renderer_thread = GetRendererThread();
146 if (renderer_thread == nullptr)
147 return nullptr;
148 return static_cast<VRBrowserRendererThreadWin*>(renderer_thread)
149 ->GetBrowserRendererForTesting();
150 #else
151 NOTREACHED();
152 #endif // defined(OS_WIN)
153 }
154
155 } // namespace vr
156