Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "mojo/examples/keyboard/keyboard.mojom.h" | 7 #include "mojo/examples/keyboard/keyboard.mojom.h" |
| 8 #include "mojo/examples/window_manager/debug_panel.h" | 8 #include "mojo/examples/window_manager/debug_panel.h" |
| 9 #include "mojo/examples/window_manager/window_manager.mojom.h" | 9 #include "mojo/examples/window_manager/window_manager.mojom.h" |
| 10 #include "mojo/public/cpp/application/application_connection.h" | 10 #include "mojo/public/cpp/application/application_connection.h" |
| 11 #include "mojo/public/cpp/application/application_delegate.h" | 11 #include "mojo/public/cpp/application/application_delegate.h" |
| 12 #include "mojo/public/cpp/application/application_impl.h" | 12 #include "mojo/public/cpp/application/application_impl.h" |
| 13 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h" | 13 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h" |
| 14 #include "mojo/services/public/cpp/input_events/input_events_type_converters.h" | 14 #include "mojo/services/public/cpp/input_events/input_events_type_converters.h" |
| 15 #include "mojo/services/public/cpp/view_manager/node.h" | 15 #include "mojo/services/public/cpp/view_manager/node.h" |
| 16 #include "mojo/services/public/cpp/view_manager/node_observer.h" | 16 #include "mojo/services/public/cpp/view_manager/node_observer.h" |
| 17 #include "mojo/services/public/cpp/view_manager/view.h" | 17 #include "mojo/services/public/cpp/view_manager/view.h" |
| 18 #include "mojo/services/public/cpp/view_manager/view_event_dispatcher.h" | 18 #include "mojo/services/public/cpp/view_manager/view_event_dispatcher.h" |
| 19 #include "mojo/services/public/cpp/view_manager/view_manager.h" | 19 #include "mojo/services/public/cpp/view_manager/view_manager.h" |
| 20 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" | 20 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" |
| 21 #include "mojo/services/public/interfaces/input_events/input_events.mojom.h" | 21 #include "mojo/services/public/interfaces/input_events/input_events.mojom.h" |
| 22 #include "mojo/services/public/interfaces/launcher/launcher.mojom.h" | 22 #include "mojo/services/public/interfaces/launcher/launcher.mojom.h" |
| 23 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" | 23 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" |
| 24 #include "mojo/views/views_init.h" | 24 #include "mojo/views/views_init.h" |
| 25 #include "ui/events/event.h" | 25 #include "ui/events/event.h" |
| 26 #include "ui/events/event_constants.h" | 26 #include "ui/events/event_constants.h" |
| 27 #include "ui/gfx/geometry/size_conversions.h" | |
| 27 | 28 |
| 28 #if defined CreateWindow | 29 #if defined CreateWindow |
| 29 #undef CreateWindow | 30 #undef CreateWindow |
| 30 #endif | 31 #endif |
| 31 | 32 |
| 32 using mojo::view_manager::Id; | 33 using mojo::view_manager::Id; |
| 33 using mojo::view_manager::Node; | 34 using mojo::view_manager::Node; |
| 34 using mojo::view_manager::NodeObserver; | 35 using mojo::view_manager::NodeObserver; |
| 35 using mojo::view_manager::View; | 36 using mojo::view_manager::View; |
| 36 using mojo::view_manager::ViewEventDispatcher; | 37 using mojo::view_manager::ViewEventDispatcher; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 const mojo::String& url) OVERRIDE; | 84 const mojo::String& url) OVERRIDE; |
| 84 virtual void RequestNavigate( | 85 virtual void RequestNavigate( |
| 85 uint32 source_node_id, | 86 uint32 source_node_id, |
| 86 navigation::Target target, | 87 navigation::Target target, |
| 87 navigation::NavigationDetailsPtr nav_details) OVERRIDE; | 88 navigation::NavigationDetailsPtr nav_details) OVERRIDE; |
| 88 WindowManager* window_manager_; | 89 WindowManager* window_manager_; |
| 89 | 90 |
| 90 DISALLOW_COPY_AND_ASSIGN(NavigatorHost); | 91 DISALLOW_COPY_AND_ASSIGN(NavigatorHost); |
| 91 }; | 92 }; |
| 92 | 93 |
| 93 class KeyboardManager : public KeyboardClient { | 94 class KeyboardManager : public KeyboardClient, |
| 95 public NodeObserver { | |
| 94 public: | 96 public: |
| 95 KeyboardManager() : view_manager_(NULL), node_(NULL) { | 97 KeyboardManager() : view_manager_(NULL), node_(NULL) { |
| 96 } | 98 } |
| 97 virtual ~KeyboardManager() { | 99 virtual ~KeyboardManager() { |
| 98 } | 100 } |
| 99 | 101 |
| 100 Node* node() { return node_; } | 102 Node* node() { return node_; } |
| 101 | 103 |
| 102 void Init(ApplicationImpl* application, | 104 void Init(ApplicationImpl* application, |
| 103 ViewManager* view_manager, | 105 ViewManager* view_manager, |
| 104 Node* parent, | 106 Node* parent, |
| 105 const gfx::Rect& bounds) { | 107 const gfx::Rect& bounds) { |
| 106 view_manager_ = view_manager; | 108 view_manager_ = view_manager; |
| 107 node_ = Node::Create(view_manager); | 109 node_ = Node::Create(view_manager); |
| 108 node_->SetBounds(bounds); | 110 node_->SetBounds(bounds); |
| 109 parent->AddChild(node_); | 111 parent->AddChild(node_); |
| 110 node_->Embed("mojo:mojo_keyboard"); | 112 node_->Embed("mojo:mojo_keyboard"); |
| 111 application->ConnectToService("mojo:mojo_keyboard", &keyboard_service_); | 113 application->ConnectToService("mojo:mojo_keyboard", &keyboard_service_); |
| 112 keyboard_service_.set_client(this); | 114 keyboard_service_.set_client(this); |
| 115 parent->AddObserver(this); | |
|
sky
2014/07/14 19:15:28
Same thing about removing.
hansmuller
2014/07/14 22:16:43
Done.
| |
| 113 } | 116 } |
| 114 | 117 |
| 115 void Show(Id view_id, const gfx::Rect& bounds) { | 118 void Show(Id view_id, const gfx::Rect& bounds) { |
| 116 keyboard_service_->SetTarget(view_id); | 119 keyboard_service_->SetTarget(view_id); |
| 117 node_->SetVisible(true); | 120 node_->SetVisible(true); |
| 118 } | 121 } |
| 119 | 122 |
| 120 void Hide(Id view_id) { | 123 void Hide(Id view_id) { |
| 121 keyboard_service_->SetTarget(0); | 124 keyboard_service_->SetTarget(0); |
| 122 node_->SetVisible(false); | 125 node_->SetVisible(false); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 140 Event::From(ui::KeyEvent(ui::ET_KEY_PRESSED, | 143 Event::From(ui::KeyEvent(ui::ET_KEY_PRESSED, |
| 141 static_cast<ui::KeyboardCode>(code), | 144 static_cast<ui::KeyboardCode>(code), |
| 142 flags, is_char))); | 145 flags, is_char))); |
| 143 view_manager_->DispatchEvent( | 146 view_manager_->DispatchEvent( |
| 144 view, | 147 view, |
| 145 Event::From(ui::KeyEvent(ui::ET_KEY_RELEASED, | 148 Event::From(ui::KeyEvent(ui::ET_KEY_RELEASED, |
| 146 static_cast<ui::KeyboardCode>(code), | 149 static_cast<ui::KeyboardCode>(code), |
| 147 flags, false))); | 150 flags, false))); |
| 148 } | 151 } |
| 149 | 152 |
| 153 virtual void OnNodeBoundsChanged(Node*, | |
| 154 const gfx::Rect& old_bounds, | |
| 155 const gfx::Rect& new_bounds) OVERRIDE { | |
| 156 gfx::Rect keyboard_bounds(node_->bounds()); | |
| 157 keyboard_bounds.set_y(new_bounds.bottom() - keyboard_bounds.height()); | |
| 158 keyboard_bounds.set_width(keyboard_bounds.width() + | |
| 159 new_bounds.width() - old_bounds.width()); | |
| 160 node_->SetBounds(keyboard_bounds); | |
| 161 } | |
| 162 | |
| 150 KeyboardServicePtr keyboard_service_; | 163 KeyboardServicePtr keyboard_service_; |
| 151 ViewManager* view_manager_; | 164 ViewManager* view_manager_; |
| 152 | 165 |
| 153 // Node the keyboard is attached to. | 166 // Node the keyboard is attached to. |
| 154 Node* node_; | 167 Node* node_; |
| 155 | 168 |
| 156 DISALLOW_COPY_AND_ASSIGN(KeyboardManager); | 169 DISALLOW_COPY_AND_ASSIGN(KeyboardManager); |
| 157 }; | 170 }; |
| 158 | 171 |
| 159 class RootLayoutManager : public NodeObserver { | 172 class RootLayoutManager : public NodeObserver { |
| 160 public: | 173 public: |
| 161 explicit RootLayoutManager(ViewManager* view_manager, | 174 RootLayoutManager(ViewManager* view_manager, Node* root, |
|
sky
2014/07/14 19:15:28
Style guide says when you can't fit all the argume
hansmuller
2014/07/14 22:16:43
Done.
| |
| 162 Node* root, | 175 Id content_node_id, |
| 163 Id content_node_id) | 176 Id launcher_ui_node_id, |
| 164 : root_(root), | 177 Id control_panel_node_id) |
| 165 view_manager_(view_manager), | 178 : root_(root), |
|
sky
2014/07/14 19:15:28
Style guide says the : should be indented 4 spaces
hansmuller
2014/07/14 22:16:42
Done.
| |
| 166 content_node_id_(content_node_id) {} | 179 view_manager_(view_manager), |
| 180 content_node_id_(content_node_id), | |
| 181 launcher_ui_node_id_(launcher_ui_node_id), | |
| 182 control_panel_node_id_(control_panel_node_id) {} | |
| 167 virtual ~RootLayoutManager() {} | 183 virtual ~RootLayoutManager() {} |
| 168 | 184 |
| 169 private: | 185 private: |
| 170 // Overridden from NodeObserver: | 186 // Overridden from NodeObserver: |
| 171 virtual void OnNodeBoundsChanged(Node* node, | 187 virtual void OnNodeBoundsChanged(Node* node, |
| 172 const gfx::Rect& /*old_bounds*/, | 188 const gfx::Rect& old_bounds, |
| 173 const gfx::Rect& new_bounds) OVERRIDE { | 189 const gfx::Rect& new_bounds) OVERRIDE { |
| 174 DCHECK_EQ(node, root_); | 190 DCHECK_EQ(node, root_); |
| 191 | |
| 175 Node* content_node = view_manager_->GetNodeById(content_node_id_); | 192 Node* content_node = view_manager_->GetNodeById(content_node_id_); |
| 176 content_node->SetBounds(new_bounds); | 193 content_node->SetBounds(new_bounds); |
| 177 // Force the view's bitmap to be recreated | 194 // Force the view's bitmap to be recreated |
| 178 content_node->active_view()->SetColor(SK_ColorBLUE); | 195 content_node->active_view()->SetColor(SK_ColorBLUE); |
| 179 // TODO(hansmuller): Do Layout | 196 |
| 197 int delta_width = new_bounds.width() - old_bounds.width(); | |
| 198 int delta_height = new_bounds.height() - old_bounds.height(); | |
| 199 | |
| 200 Node* launcher_ui_node = | |
| 201 view_manager_->GetNodeById(launcher_ui_node_id_); | |
|
sky
2014/07/14 19:15:28
indent 2 more.
hansmuller
2014/07/14 22:16:42
Done.
| |
| 202 gfx::Rect launcher_ui_bounds(launcher_ui_node->bounds()); | |
| 203 launcher_ui_bounds.set_width(launcher_ui_bounds.width() + delta_width); | |
| 204 launcher_ui_node->SetBounds(launcher_ui_bounds); | |
| 205 | |
| 206 Node* control_panel_node = | |
| 207 view_manager_->GetNodeById(control_panel_node_id_); | |
| 208 gfx::Rect control_panel_bounds(control_panel_node->bounds()); | |
| 209 control_panel_bounds.set_x(control_panel_bounds.x() + delta_width); | |
| 210 control_panel_node->SetBounds(control_panel_bounds); | |
| 211 | |
| 212 for (Node* node : content_node->children()) { | |
|
sky
2014/07/14 19:15:28
We're not yet using c++11 yet.
hansmuller
2014/07/14 22:16:43
Done.
| |
| 213 if (node->id() == control_panel_node->id() || | |
| 214 node->id() == launcher_ui_node->id()) | |
| 215 continue; | |
| 216 gfx::Rect node_bounds(node->bounds()); | |
| 217 node_bounds.set_width(node_bounds.width() + delta_width); | |
| 218 node_bounds.set_height(node_bounds.height() + delta_height); | |
| 219 node->SetBounds(node_bounds); | |
| 220 } | |
| 180 } | 221 } |
| 181 | 222 |
| 182 Node* root_; | 223 Node* root_; |
| 183 ViewManager* view_manager_; | 224 ViewManager* view_manager_; |
| 184 Id content_node_id_; | 225 Id content_node_id_; |
| 226 Id launcher_ui_node_id_; | |
|
sky
2014/07/14 19:15:28
I believe you can make these const.
hansmuller
2014/07/14 22:16:42
Done.
| |
| 227 Id control_panel_node_id_; | |
| 185 | 228 |
| 186 DISALLOW_COPY_AND_ASSIGN(RootLayoutManager); | 229 DISALLOW_COPY_AND_ASSIGN(RootLayoutManager); |
| 187 }; | 230 }; |
| 188 | 231 |
| 189 class WindowManager : public ApplicationDelegate, | 232 class WindowManager : public ApplicationDelegate, |
| 190 public DebugPanel::Delegate, | 233 public DebugPanel::Delegate, |
| 191 public ViewManagerDelegate, | 234 public ViewManagerDelegate, |
| 192 public ViewEventDispatcher { | 235 public ViewEventDispatcher { |
| 193 public: | 236 public: |
| 194 WindowManager() | 237 WindowManager() |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 virtual void OnRootAdded(ViewManager* view_manager, Node* root) OVERRIDE { | 319 virtual void OnRootAdded(ViewManager* view_manager, Node* root) OVERRIDE { |
| 277 DCHECK(!view_manager_); | 320 DCHECK(!view_manager_); |
| 278 view_manager_ = view_manager; | 321 view_manager_ = view_manager; |
| 279 view_manager_->SetEventDispatcher(this); | 322 view_manager_->SetEventDispatcher(this); |
| 280 | 323 |
| 281 Node* node = Node::Create(view_manager_); | 324 Node* node = Node::Create(view_manager_); |
| 282 root->AddChild(node); | 325 root->AddChild(node); |
| 283 node->SetBounds(gfx::Rect(root->bounds().size())); | 326 node->SetBounds(gfx::Rect(root->bounds().size())); |
| 284 content_node_id_ = node->id(); | 327 content_node_id_ = node->id(); |
| 285 | 328 |
| 286 root_layout_manager_.reset( | |
| 287 new RootLayoutManager(view_manager_, root, content_node_id_)); | |
| 288 root->AddObserver(root_layout_manager_.get()); | |
| 289 | |
| 290 View* view = View::Create(view_manager_); | 329 View* view = View::Create(view_manager_); |
| 291 node->SetActiveView(view); | 330 node->SetActiveView(view); |
| 292 view->SetColor(SK_ColorBLUE); | 331 view->SetColor(SK_ColorBLUE); |
| 293 | 332 |
| 294 CreateLauncherUI(); | 333 Id launcher_ui_id = CreateLauncherUI(); |
| 295 CreateControlPanel(node); | 334 Id control_panel_id = CreateControlPanel(node); |
| 335 | |
| 336 root_layout_manager_.reset( | |
| 337 new RootLayoutManager(view_manager, root, | |
| 338 content_node_id_, | |
| 339 launcher_ui_id, | |
| 340 control_panel_id)); | |
| 341 root->AddObserver(root_layout_manager_.get()); | |
| 296 } | 342 } |
| 297 virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE { | 343 virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE { |
| 298 DCHECK_EQ(view_manager_, view_manager); | 344 DCHECK_EQ(view_manager_, view_manager); |
| 299 view_manager_ = NULL; | 345 view_manager_ = NULL; |
| 300 base::MessageLoop::current()->Quit(); | 346 base::MessageLoop::current()->Quit(); |
| 301 } | 347 } |
| 302 | 348 |
| 303 // Overridden from ViewEventDispatcher: | 349 // Overridden from ViewEventDispatcher: |
| 304 virtual void DispatchEvent(View* target, EventPtr event) OVERRIDE { | 350 virtual void DispatchEvent(View* target, EventPtr event) OVERRIDE { |
| 305 // TODO(beng): More sophisticated focus handling than this is required! | 351 // TODO(beng): More sophisticated focus handling than this is required! |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 dest_node = windows_.back(); | 388 dest_node = windows_.back(); |
| 343 } | 389 } |
| 344 | 390 |
| 345 if (dest_node) | 391 if (dest_node) |
| 346 Embed(dest_node, handler_url, nav_details.Pass(), response.Pass()); | 392 Embed(dest_node, handler_url, nav_details.Pass(), response.Pass()); |
| 347 else | 393 else |
| 348 CreateWindow(handler_url, nav_details.Pass(), response.Pass()); | 394 CreateWindow(handler_url, nav_details.Pass(), response.Pass()); |
| 349 } | 395 } |
| 350 | 396 |
| 351 // TODO(beng): proper layout manager!! | 397 // TODO(beng): proper layout manager!! |
| 352 void CreateLauncherUI() { | 398 Id CreateLauncherUI() { |
| 353 navigation::NavigationDetailsPtr nav_details; | 399 navigation::NavigationDetailsPtr nav_details; |
| 354 navigation::ResponseDetailsPtr response; | 400 navigation::ResponseDetailsPtr response; |
| 355 Node* node = view_manager_->GetNodeById(content_node_id_); | 401 Node* node = view_manager_->GetNodeById(content_node_id_); |
| 356 gfx::Rect bounds = node->bounds(); | 402 gfx::Rect bounds = node->bounds(); |
| 357 bounds.Inset(kBorderInset, kBorderInset); | 403 bounds.Inset(kBorderInset, kBorderInset); |
| 358 bounds.set_height(kTextfieldHeight); | 404 bounds.set_height(kTextfieldHeight); |
| 359 launcher_ui_ = CreateChild(content_node_id_, "mojo:mojo_browser", bounds, | 405 launcher_ui_ = CreateChild(content_node_id_, "mojo:mojo_browser", bounds, |
| 360 nav_details.Pass(), response.Pass()); | 406 nav_details.Pass(), response.Pass()); |
| 407 return launcher_ui_->id(); | |
| 361 } | 408 } |
| 362 | 409 |
| 363 void CreateWindow(const std::string& handler_url, | 410 void CreateWindow(const std::string& handler_url, |
| 364 navigation::NavigationDetailsPtr nav_details, | 411 navigation::NavigationDetailsPtr nav_details, |
| 365 navigation::ResponseDetailsPtr response) { | 412 navigation::ResponseDetailsPtr response) { |
| 366 Node* node = view_manager_->GetNodeById(content_node_id_); | 413 Node* node = view_manager_->GetNodeById(content_node_id_); |
| 367 gfx::Rect bounds(kBorderInset, | 414 gfx::Rect bounds(kBorderInset, |
| 368 2 * kBorderInset + kTextfieldHeight, | 415 2 * kBorderInset + kTextfieldHeight, |
| 369 node->bounds().width() - 3 * kBorderInset - | 416 node->bounds().width() - 3 * kBorderInset - |
| 370 kControlPanelWidth, | 417 kControlPanelWidth, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 app_->ConnectToService(app_url, &navigator); | 449 app_->ConnectToService(app_url, &navigator); |
| 403 navigator->Navigate(node->id(), nav_details.Pass(), response.Pass()); | 450 navigator->Navigate(node->id(), nav_details.Pass(), response.Pass()); |
| 404 } | 451 } |
| 405 } | 452 } |
| 406 | 453 |
| 407 bool IsDescendantOfKeyboard(View* target) { | 454 bool IsDescendantOfKeyboard(View* target) { |
| 408 return keyboard_manager_.get() && | 455 return keyboard_manager_.get() && |
| 409 keyboard_manager_->node()->Contains(target->node()); | 456 keyboard_manager_->node()->Contains(target->node()); |
| 410 } | 457 } |
| 411 | 458 |
| 412 void CreateControlPanel(view_manager::Node* root) { | 459 Id CreateControlPanel(view_manager::Node* root) { |
| 413 Node* node = Node::Create(view_manager_); | 460 Node* node = Node::Create(view_manager_); |
| 414 View* view = view_manager::View::Create(view_manager_); | 461 View* view = view_manager::View::Create(view_manager_); |
| 415 root->AddChild(node); | 462 root->AddChild(node); |
| 416 node->SetActiveView(view); | 463 node->SetActiveView(view); |
| 417 | 464 |
| 418 gfx::Rect bounds(root->bounds().width() - kControlPanelWidth - | 465 gfx::Rect bounds(root->bounds().width() - kControlPanelWidth - |
| 419 kBorderInset, | 466 kBorderInset, |
| 420 kBorderInset * 2 + kTextfieldHeight, | 467 kBorderInset * 2 + kTextfieldHeight, |
| 421 kControlPanelWidth, | 468 kControlPanelWidth, |
| 422 root->bounds().height() - kBorderInset * 3 - | 469 root->bounds().height() - kBorderInset * 3 - |
| 423 kTextfieldHeight); | 470 kTextfieldHeight); |
| 424 node->SetBounds(bounds); | 471 node->SetBounds(bounds); |
| 425 | 472 |
| 426 debug_panel_ = new DebugPanel(this, node); | 473 debug_panel_ = new DebugPanel(this, node); |
| 474 return node->id(); | |
| 427 } | 475 } |
| 428 | 476 |
| 429 scoped_ptr<ViewsInit> views_init_; | 477 scoped_ptr<ViewsInit> views_init_; |
| 430 DebugPanel* debug_panel_; | 478 DebugPanel* debug_panel_; |
| 431 launcher::LauncherPtr launcher_; | 479 launcher::LauncherPtr launcher_; |
| 432 Node* launcher_ui_; | 480 Node* launcher_ui_; |
| 433 std::vector<Node*> windows_; | 481 std::vector<Node*> windows_; |
| 434 ViewManager* view_manager_; | 482 ViewManager* view_manager_; |
| 435 scoped_ptr<RootLayoutManager> root_layout_manager_; | 483 scoped_ptr<RootLayoutManager> root_layout_manager_; |
| 436 | 484 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 } | 516 } |
| 469 | 517 |
| 470 } // namespace examples | 518 } // namespace examples |
| 471 | 519 |
| 472 // static | 520 // static |
| 473 ApplicationDelegate* ApplicationDelegate::Create() { | 521 ApplicationDelegate* ApplicationDelegate::Create() { |
| 474 return new examples::WindowManager; | 522 return new examples::WindowManager; |
| 475 } | 523 } |
| 476 | 524 |
| 477 } // namespace mojo | 525 } // namespace mojo |
| OLD | NEW |