OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "ui/views/mus/views_mus_test_suite.h" | |
6 | |
7 #include <memory> | |
8 #include <string> | |
9 | |
10 #include "base/command_line.h" | |
11 #include "base/files/file_path.h" | |
12 #include "base/memory/ptr_util.h" | |
13 #include "base/run_loop.h" | |
14 #include "base/synchronization/waitable_event.h" | |
15 #include "base/threading/simple_thread.h" | |
16 #include "base/threading/thread.h" | |
17 #include "services/service_manager/background/background_service_manager.h" | |
18 #include "services/service_manager/public/cpp/connector.h" | |
19 #include "services/service_manager/public/cpp/service.h" | |
20 #include "services/service_manager/public/cpp/service_context.h" | |
21 #include "services/ui/common/switches.h" | |
22 #include "testing/gtest/include/gtest/gtest.h" | |
23 #include "ui/aura/window.h" | |
24 #include "ui/views/mus/window_manager_connection.h" | |
25 #include "ui/views/test/platform_test_helper.h" | |
26 #include "ui/views/views_delegate.h" | |
27 | |
28 namespace views { | |
29 namespace { | |
30 | |
31 void EnsureCommandLineSwitch(const std::string& name) { | |
32 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | |
33 if (!cmd_line->HasSwitch(name)) | |
34 cmd_line->AppendSwitch(name); | |
35 } | |
36 | |
37 class DefaultService : public service_manager::Service { | |
38 public: | |
39 DefaultService() {} | |
40 ~DefaultService() override {} | |
41 | |
42 // service_manager::Service: | |
43 bool OnConnect(const service_manager::ServiceInfo& remote_info, | |
44 service_manager::InterfaceRegistry* registry) override { | |
45 return false; | |
46 } | |
47 | |
48 private: | |
49 DISALLOW_COPY_AND_ASSIGN(DefaultService); | |
50 }; | |
51 | |
52 class PlatformTestHelperMus : public PlatformTestHelper { | |
53 public: | |
54 PlatformTestHelperMus(service_manager::Connector* connector, | |
55 const service_manager::Identity& identity) { | |
56 // It is necessary to recreate the WindowManagerConnection for each test, | |
57 // since a new MessageLoop is created for each test. | |
58 connection_ = WindowManagerConnection::Create(connector, identity); | |
59 } | |
60 ~PlatformTestHelperMus() override {} | |
61 | |
62 // PlatformTestHelper: | |
63 void SimulateNativeDestroy(Widget* widget) override { | |
64 delete widget->GetNativeView(); | |
65 } | |
66 | |
67 private: | |
68 std::unique_ptr<WindowManagerConnection> connection_; | |
69 | |
70 DISALLOW_COPY_AND_ASSIGN(PlatformTestHelperMus); | |
71 }; | |
72 | |
73 std::unique_ptr<PlatformTestHelper> CreatePlatformTestHelper( | |
74 const service_manager::Identity& identity, | |
75 const base::Callback<service_manager::Connector*(void)>& callback) { | |
76 return base::MakeUnique<PlatformTestHelperMus>(callback.Run(), identity); | |
77 } | |
78 | |
79 } // namespace | |
80 | |
81 class ServiceManagerConnection { | |
82 public: | |
83 ServiceManagerConnection() | |
84 : thread_("Persistent service_manager connections") { | |
85 base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
86 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
87 base::Thread::Options options; | |
88 thread_.StartWithOptions(options); | |
89 thread_.task_runner()->PostTask( | |
90 FROM_HERE, base::Bind(&ServiceManagerConnection::SetUpConnections, | |
91 base::Unretained(this), &wait)); | |
92 wait.Wait(); | |
93 | |
94 // WindowManagerConnection cannot be created from here yet, although the | |
95 // connector and identity are available at this point. This is because | |
96 // WindowManagerConnection needs a ViewsDelegate and a MessageLoop to have | |
97 // been installed first. So delay the creation until the necessary | |
98 // dependencies have been met. | |
99 PlatformTestHelper::set_factory( | |
100 base::Bind(&CreatePlatformTestHelper, service_manager_identity_, | |
101 base::Bind(&ServiceManagerConnection::GetConnector, | |
102 base::Unretained(this)))); | |
103 } | |
104 | |
105 ~ServiceManagerConnection() { | |
106 base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
107 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
108 thread_.task_runner()->PostTask( | |
109 FROM_HERE, base::Bind(&ServiceManagerConnection::TearDownConnections, | |
110 base::Unretained(this), &wait)); | |
111 wait.Wait(); | |
112 } | |
113 | |
114 private: | |
115 service_manager::Connector* GetConnector() { | |
116 service_manager_connector_.reset(); | |
117 base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
118 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
119 thread_.task_runner()->PostTask( | |
120 FROM_HERE, base::Bind(&ServiceManagerConnection::CloneConnector, | |
121 base::Unretained(this), &wait)); | |
122 wait.Wait(); | |
123 DCHECK(service_manager_connector_); | |
124 return service_manager_connector_.get(); | |
125 } | |
126 | |
127 void CloneConnector(base::WaitableEvent* wait) { | |
128 service_manager_connector_ = context_->connector()->Clone(); | |
129 wait->Signal(); | |
130 } | |
131 | |
132 void SetUpConnections(base::WaitableEvent* wait) { | |
133 background_service_manager_ = | |
134 base::MakeUnique<service_manager::BackgroundServiceManager>(); | |
135 background_service_manager_->Init(nullptr); | |
136 context_ = | |
137 base::MakeUnique<service_manager::ServiceContext>( | |
138 base::MakeUnique<DefaultService>(), | |
139 background_service_manager_->CreateServiceRequest(GetTestName())); | |
140 | |
141 // ui/views/mus requires a WindowManager running, so launch test_wm. | |
142 service_manager::Connector* connector = context_->connector(); | |
143 connector->Connect("test_wm"); | |
144 service_manager_connector_ = connector->Clone(); | |
145 service_manager_identity_ = context_->identity(); | |
146 wait->Signal(); | |
147 } | |
148 | |
149 void TearDownConnections(base::WaitableEvent* wait) { | |
150 context_.reset(); | |
151 wait->Signal(); | |
152 } | |
153 | |
154 // Returns the name of the test executable, e.g. | |
155 // "views_mus_unittests". | |
156 std::string GetTestName() { | |
157 base::FilePath executable = base::CommandLine::ForCurrentProcess() | |
158 ->GetProgram() | |
159 .BaseName() | |
160 .RemoveExtension(); | |
161 return std::string("") + executable.MaybeAsASCII(); | |
162 } | |
163 | |
164 base::Thread thread_; | |
165 std::unique_ptr<service_manager::BackgroundServiceManager> | |
166 background_service_manager_; | |
167 std::unique_ptr<service_manager::ServiceContext> context_; | |
168 std::unique_ptr<service_manager::Connector> service_manager_connector_; | |
169 service_manager::Identity service_manager_identity_; | |
170 | |
171 DISALLOW_COPY_AND_ASSIGN(ServiceManagerConnection); | |
172 }; | |
173 | |
174 ViewsMusTestSuite::ViewsMusTestSuite(int argc, char** argv) | |
175 : ViewsTestSuite(argc, argv) {} | |
176 | |
177 ViewsMusTestSuite::~ViewsMusTestSuite() {} | |
178 | |
179 void ViewsMusTestSuite::Initialize() { | |
180 PlatformTestHelper::SetIsMus(); | |
181 // Let other services know that we're running in tests. Do this with a | |
182 // command line flag to avoid making blocking calls to other processes for | |
183 // setup for tests (e.g. to unlock the screen in the window manager). | |
184 EnsureCommandLineSwitch(ui::switches::kUseTestConfig); | |
185 | |
186 ViewsTestSuite::Initialize(); | |
187 service_manager_connections_ = base::MakeUnique<ServiceManagerConnection>(); | |
188 } | |
189 | |
190 void ViewsMusTestSuite::Shutdown() { | |
191 service_manager_connections_.reset(); | |
192 ViewsTestSuite::Shutdown(); | |
193 } | |
194 | |
195 } // namespace views | |
OLD | NEW |