Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(354)

Side by Side Diff: components/mus/mus_app.cc

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/mus/mus_app.h ('k') | components/mus/public/cpp/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "components/mus/mus_app.h"
6
7 #include <set>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/threading/platform_thread.h"
14 #include "build/build_config.h"
15 #include "components/mus/clipboard/clipboard_impl.h"
16 #include "components/mus/common/switches.h"
17 #include "components/mus/gles2/gpu_impl.h"
18 #include "components/mus/gpu/gpu_service_impl.h"
19 #include "components/mus/gpu/gpu_service_mus.h"
20 #include "components/mus/ws/display.h"
21 #include "components/mus/ws/display_binding.h"
22 #include "components/mus/ws/display_manager.h"
23 #include "components/mus/ws/platform_screen.h"
24 #include "components/mus/ws/user_activity_monitor.h"
25 #include "components/mus/ws/user_display_manager.h"
26 #include "components/mus/ws/window_server.h"
27 #include "components/mus/ws/window_server_test_impl.h"
28 #include "components/mus/ws/window_tree.h"
29 #include "components/mus/ws/window_tree_binding.h"
30 #include "components/mus/ws/window_tree_factory.h"
31 #include "components/mus/ws/window_tree_host_factory.h"
32 #include "mojo/public/c/system/main.h"
33 #include "services/catalog/public/cpp/resource_loader.h"
34 #include "services/shell/public/cpp/connection.h"
35 #include "services/shell/public/cpp/connector.h"
36 #include "services/tracing/public/cpp/tracing_impl.h"
37 #include "ui/base/resource/resource_bundle.h"
38 #include "ui/base/ui_base_paths.h"
39 #include "ui/events/event_switches.h"
40 #include "ui/events/platform/platform_event_source.h"
41 #include "ui/gfx/geometry/rect.h"
42 #include "ui/gl/gl_surface.h"
43
44 #if defined(USE_X11)
45 #include <X11/Xlib.h>
46 #include "ui/platform_window/x11/x11_window.h"
47 #elif defined(USE_OZONE)
48 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
49 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
50 #include "ui/ozone/public/ozone_platform.h"
51 #endif
52
53 using shell::Connection;
54 using mojo::InterfaceRequest;
55 using mus::mojom::Gpu;
56 using mus::mojom::WindowServerTest;
57 using mus::mojom::WindowTreeHostFactory;
58
59 namespace mus {
60
61 namespace {
62
63 const char kResourceFileStrings[] = "mus_app_resources_strings.pak";
64 const char kResourceFile100[] = "mus_app_resources_100.pak";
65 const char kResourceFile200[] = "mus_app_resources_200.pak";
66
67 } // namespace
68
69 // TODO(sky): this is a pretty typical pattern, make it easier to do.
70 struct MusApp::PendingRequest {
71 shell::Connection* connection;
72 std::unique_ptr<mojom::WindowTreeFactoryRequest> wtf_request;
73 std::unique_ptr<mojom::DisplayManagerRequest> dm_request;
74 };
75
76 struct MusApp::UserState {
77 std::unique_ptr<clipboard::ClipboardImpl> clipboard;
78 std::unique_ptr<ws::WindowTreeHostFactory> window_tree_host_factory;
79 };
80
81 MusApp::MusApp()
82 : test_config_(false),
83 // TODO(penghuang): Kludge: Use mojo command buffer when running on
84 // Windows since chrome command buffer breaks unit tests
85 #if defined(OS_WIN)
86 use_chrome_gpu_command_buffer_(false),
87 #else
88 use_chrome_gpu_command_buffer_(true),
89 #endif
90 platform_screen_(ws::PlatformScreen::Create()),
91 weak_ptr_factory_(this) {}
92
93 MusApp::~MusApp() {
94 // Destroy |window_server_| first, since it depends on |event_source_|.
95 // WindowServer (or more correctly its Displays) may have state that needs to
96 // be destroyed before GpuState as well.
97 window_server_.reset();
98
99 if (platform_display_init_params_.gpu_state)
100 platform_display_init_params_.gpu_state->StopThreads();
101 }
102
103 void MusApp::InitializeResources(shell::Connector* connector) {
104 if (ui::ResourceBundle::HasSharedInstance())
105 return;
106
107 std::set<std::string> resource_paths;
108 resource_paths.insert(kResourceFileStrings);
109 resource_paths.insert(kResourceFile100);
110 resource_paths.insert(kResourceFile200);
111
112 catalog::ResourceLoader loader;
113 filesystem::mojom::DirectoryPtr directory;
114 connector->ConnectToInterface("mojo:catalog", &directory);
115 CHECK(loader.OpenFiles(std::move(directory), resource_paths));
116
117 ui::RegisterPathProvider();
118
119 // Initialize resource bundle with 1x and 2x cursor bitmaps.
120 ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
121 loader.TakeFile(kResourceFileStrings),
122 base::MemoryMappedFile::Region::kWholeFile);
123 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
124 rb.AddDataPackFromFile(loader.TakeFile(kResourceFile100),
125 ui::SCALE_FACTOR_100P);
126 rb.AddDataPackFromFile(loader.TakeFile(kResourceFile200),
127 ui::SCALE_FACTOR_200P);
128 }
129
130 MusApp::UserState* MusApp::GetUserState(shell::Connection* connection) {
131 const ws::UserId& user_id = connection->GetRemoteIdentity().user_id();
132 auto it = user_id_to_user_state_.find(user_id);
133 if (it != user_id_to_user_state_.end())
134 return it->second.get();
135 user_id_to_user_state_[user_id] = base::WrapUnique(new UserState);
136 return user_id_to_user_state_[user_id].get();
137 }
138
139 void MusApp::AddUserIfNecessary(shell::Connection* connection) {
140 window_server_->user_id_tracker()->AddUserId(
141 connection->GetRemoteIdentity().user_id());
142 }
143
144 void MusApp::Initialize(shell::Connector* connector,
145 const shell::Identity& identity,
146 uint32_t id) {
147 platform_display_init_params_.surfaces_state = new SurfacesState;
148
149 base::PlatformThread::SetName("mus");
150 tracing_.Initialize(connector, identity.name());
151 TRACE_EVENT0("mus", "MusApp::Initialize started");
152
153 test_config_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
154 switches::kUseTestConfig);
155 // TODO(penghuang): Kludge: use mojo command buffer when running on Windows
156 // since Chrome command buffer breaks unit tests
157 #if defined(OS_WIN)
158 use_chrome_gpu_command_buffer_ = false;
159 #else
160 use_chrome_gpu_command_buffer_ =
161 !base::CommandLine::ForCurrentProcess()->HasSwitch(
162 switches::kUseMojoGpuCommandBufferInMus);
163 #endif
164 #if defined(USE_X11)
165 XInitThreads();
166 if (test_config_)
167 ui::test::SetUseOverrideRedirectWindowByDefault(true);
168 #endif
169
170 InitializeResources(connector);
171
172 #if defined(USE_OZONE)
173 // The ozone platform can provide its own event source. So initialize the
174 // platform before creating the default event source.
175 // Because GL libraries need to be initialized before entering the sandbox,
176 // in MUS, |InitializeForUI| will load the GL libraries.
177 ui::OzonePlatform::InitParams params;
178 params.connector = connector;
179 params.single_process = false;
180
181 ui::OzonePlatform::InitializeForUI(params);
182
183 // TODO(kylechar): We might not always want a US keyboard layout.
184 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
185 ->SetCurrentLayoutByName("us");
186 client_native_pixmap_factory_ = ui::ClientNativePixmapFactory::Create();
187 ui::ClientNativePixmapFactory::SetInstance(
188 client_native_pixmap_factory_.get());
189
190 DCHECK(ui::ClientNativePixmapFactory::GetInstance());
191 #endif
192
193 // TODO(rjkroege): Enter sandbox here before we start threads in GpuState
194 // http://crbug.com/584532
195
196 #if !defined(OS_ANDROID)
197 event_source_ = ui::PlatformEventSource::CreateDefault();
198 #endif
199
200 // This needs to happen after DeviceDataManager has been constructed. That
201 // happens either during OzonePlatform or PlatformEventSource initialization,
202 // so keep this line below both of those.
203 input_device_server_.RegisterAsObserver();
204
205 if (use_chrome_gpu_command_buffer_) {
206 GpuServiceMus::GetInstance();
207 } else {
208 // TODO(rjkroege): It is possible that we might want to generalize the
209 // GpuState object.
210 platform_display_init_params_.gpu_state = new GpuState();
211 }
212
213 // Gpu must be running before the PlatformScreen can be initialized.
214 platform_screen_->Init();
215 window_server_.reset(
216 new ws::WindowServer(this, platform_display_init_params_.surfaces_state));
217
218 // DeviceDataManager must be initialized before TouchController. On non-Linux
219 // platforms there is no DeviceDataManager so don't create touch controller.
220 if (ui::DeviceDataManager::HasInstance())
221 touch_controller_.reset(
222 new ws::TouchController(window_server_->display_manager()));
223 }
224
225 bool MusApp::AcceptConnection(Connection* connection) {
226 connection->AddInterface<mojom::Clipboard>(this);
227 connection->AddInterface<mojom::DisplayManager>(this);
228 connection->AddInterface<mojom::UserAccessManager>(this);
229 connection->AddInterface<mojom::UserActivityMonitor>(this);
230 connection->AddInterface<WindowTreeHostFactory>(this);
231 connection->AddInterface<mojom::WindowManagerWindowTreeFactory>(this);
232 connection->AddInterface<mojom::WindowTreeFactory>(this);
233 if (test_config_)
234 connection->AddInterface<WindowServerTest>(this);
235
236 if (use_chrome_gpu_command_buffer_) {
237 connection->AddInterface<mojom::GpuService>(this);
238 } else {
239 connection->AddInterface<Gpu>(this);
240 }
241
242 // On non-Linux platforms there will be no DeviceDataManager instance and no
243 // purpose in adding the Mojo interface to connect to.
244 if (input_device_server_.IsRegisteredAsObserver())
245 input_device_server_.AddInterface(connection);
246
247 #if defined(USE_OZONE)
248 ui::OzonePlatform::GetInstance()->AddInterfaces(connection);
249 #endif
250
251 return true;
252 }
253
254 void MusApp::OnFirstDisplayReady() {
255 PendingRequests requests;
256 requests.swap(pending_requests_);
257 for (auto& request : requests) {
258 if (request->wtf_request)
259 Create(request->connection, std::move(*request->wtf_request));
260 else
261 Create(request->connection, std::move(*request->dm_request));
262 }
263 }
264
265 void MusApp::OnNoMoreDisplays() {
266 // We may get here from the destructor, in which case there is no messageloop.
267 if (base::MessageLoop::current())
268 base::MessageLoop::current()->QuitWhenIdle();
269 }
270
271 bool MusApp::IsTestConfig() const {
272 return test_config_;
273 }
274
275 void MusApp::CreateDefaultDisplays() {
276 // An asynchronous callback will create the Displays once the physical
277 // displays are ready.
278 platform_screen_->ConfigurePhysicalDisplay(base::Bind(
279 &MusApp::OnCreatedPhysicalDisplay, weak_ptr_factory_.GetWeakPtr()));
280 }
281
282 void MusApp::Create(shell::Connection* connection,
283 mojom::ClipboardRequest request) {
284 UserState* user_state = GetUserState(connection);
285 if (!user_state->clipboard)
286 user_state->clipboard.reset(new clipboard::ClipboardImpl);
287 user_state->clipboard->AddBinding(std::move(request));
288 }
289
290 void MusApp::Create(shell::Connection* connection,
291 mojom::DisplayManagerRequest request) {
292 // DisplayManagerObservers generally expect there to be at least one display.
293 if (!window_server_->display_manager()->has_displays()) {
294 std::unique_ptr<PendingRequest> pending_request(new PendingRequest);
295 pending_request->connection = connection;
296 pending_request->dm_request.reset(
297 new mojom::DisplayManagerRequest(std::move(request)));
298 pending_requests_.push_back(std::move(pending_request));
299 return;
300 }
301 window_server_->display_manager()
302 ->GetUserDisplayManager(connection->GetRemoteIdentity().user_id())
303 ->AddDisplayManagerBinding(std::move(request));
304 }
305
306 void MusApp::Create(shell::Connection* connection, mojom::GpuRequest request) {
307 if (use_chrome_gpu_command_buffer_)
308 return;
309 DCHECK(platform_display_init_params_.gpu_state);
310 new GpuImpl(std::move(request), platform_display_init_params_.gpu_state);
311 }
312
313 void MusApp::Create(shell::Connection* connection,
314 mojom::GpuServiceRequest request) {
315 if (!use_chrome_gpu_command_buffer_)
316 return;
317 new GpuServiceImpl(std::move(request), connection);
318 }
319
320 void MusApp::Create(shell::Connection* connection,
321 mojom::UserAccessManagerRequest request) {
322 window_server_->user_id_tracker()->Bind(std::move(request));
323 }
324
325 void MusApp::Create(shell::Connection* connection,
326 mojom::UserActivityMonitorRequest request) {
327 AddUserIfNecessary(connection);
328 const ws::UserId& user_id = connection->GetRemoteIdentity().user_id();
329 window_server_->GetUserActivityMonitorForUser(user_id)->Add(
330 std::move(request));
331 }
332
333 void MusApp::Create(shell::Connection* connection,
334 mojom::WindowManagerWindowTreeFactoryRequest request) {
335 AddUserIfNecessary(connection);
336 window_server_->window_manager_window_tree_factory_set()->Add(
337 connection->GetRemoteIdentity().user_id(), std::move(request));
338 }
339
340 void MusApp::Create(Connection* connection,
341 mojom::WindowTreeFactoryRequest request) {
342 AddUserIfNecessary(connection);
343 if (!window_server_->display_manager()->has_displays()) {
344 std::unique_ptr<PendingRequest> pending_request(new PendingRequest);
345 pending_request->connection = connection;
346 pending_request->wtf_request.reset(
347 new mojom::WindowTreeFactoryRequest(std::move(request)));
348 pending_requests_.push_back(std::move(pending_request));
349 return;
350 }
351 AddUserIfNecessary(connection);
352 new ws::WindowTreeFactory(
353 window_server_.get(), connection->GetRemoteIdentity().user_id(),
354 connection->GetRemoteIdentity().name(), std::move(request));
355 }
356
357 void MusApp::Create(Connection* connection,
358 mojom::WindowTreeHostFactoryRequest request) {
359 UserState* user_state = GetUserState(connection);
360 if (!user_state->window_tree_host_factory) {
361 user_state->window_tree_host_factory.reset(new ws::WindowTreeHostFactory(
362 window_server_.get(), connection->GetRemoteIdentity().user_id(),
363 platform_display_init_params_));
364 }
365 user_state->window_tree_host_factory->AddBinding(std::move(request));
366 }
367
368 void MusApp::Create(Connection* connection,
369 mojom::WindowServerTestRequest request) {
370 if (!test_config_)
371 return;
372 new ws::WindowServerTestImpl(window_server_.get(), std::move(request));
373 }
374
375 void MusApp::OnCreatedPhysicalDisplay(int64_t id, const gfx::Rect& bounds) {
376 platform_display_init_params_.display_bounds = bounds;
377 platform_display_init_params_.display_id = id;
378
379 // Display manages its own lifetime.
380 ws::Display* host_impl =
381 new ws::Display(window_server_.get(), platform_display_init_params_);
382 host_impl->Init(nullptr);
383
384 if (touch_controller_)
385 touch_controller_->UpdateTouchTransforms();
386 }
387
388 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/mus_app.h ('k') | components/mus/public/cpp/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698