| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "services/ui/launcher/launcher_view_tree.h" | 5 #include "services/ui/launcher/launcher_view_tree.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "mojo/public/cpp/application/connect.h" | 8 #include "mojo/public/cpp/application/connect.h" |
| 9 #include "mojo/services/gfx/composition/cpp/formatting.h" | 9 #include "mojo/services/gfx/composition/cpp/formatting.h" |
| 10 #include "mojo/services/ui/views/cpp/formatting.h" | 10 #include "mojo/services/ui/views/cpp/formatting.h" |
| 11 | 11 |
| 12 namespace launcher { | 12 namespace launcher { |
| 13 | 13 |
| 14 constexpr uint32_t kViewSceneResourceId = 1; | |
| 15 constexpr uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId; | |
| 16 constexpr uint32_t kViewNodeId = 1; | |
| 17 constexpr uint32_t kFallbackNodeId = 2; | |
| 18 | |
| 19 LauncherViewTree::LauncherViewTree( | 14 LauncherViewTree::LauncherViewTree( |
| 20 mojo::gfx::composition::Compositor* compositor, | 15 mojo::gfx::composition::Compositor* compositor, |
| 21 mojo::ui::ViewManager* view_manager, | 16 mojo::ui::ViewManager* view_manager, |
| 22 mojo::ContextProviderPtr context_provider, | 17 mojo::ContextProviderPtr context_provider, |
| 23 mojo::ViewportMetricsPtr viewport_metrics, | 18 mojo::ViewportMetricsPtr viewport_metrics, |
| 24 const base::Closure& shutdown_callback) | 19 const base::Closure& shutdown_callback) |
| 25 : compositor_(compositor), | 20 : compositor_(compositor), |
| 26 view_manager_(view_manager), | 21 view_manager_(view_manager), |
| 27 context_provider_(context_provider.Pass()), | 22 context_provider_(context_provider.Pass()), |
| 28 viewport_metrics_(viewport_metrics.Pass()), | 23 viewport_metrics_(viewport_metrics.Pass()), |
| 29 shutdown_callback_(shutdown_callback), | 24 shutdown_callback_(shutdown_callback), |
| 30 scene_listener_binding_(this), | |
| 31 view_tree_listener_binding_(this) { | 25 view_tree_listener_binding_(this) { |
| 32 // Create the renderer. | |
| 33 compositor_->CreateRenderer(context_provider_.Pass(), GetProxy(&renderer_), | |
| 34 "Launcher"); | |
| 35 renderer_.set_connection_error_handler(base::Bind( | |
| 36 &LauncherViewTree::OnRendererConnectionError, base::Unretained(this))); | |
| 37 | |
| 38 // Create the root scene. | |
| 39 compositor_->CreateScene( | |
| 40 mojo::GetProxy(&scene_), "Launcher", | |
| 41 base::Bind(&LauncherViewTree::OnSceneRegistered, base::Unretained(this))); | |
| 42 mojo::gfx::composition::SceneListenerPtr scene_listener; | |
| 43 scene_listener_binding_.Bind(mojo::GetProxy(&scene_listener)); | |
| 44 scene_->SetListener(scene_listener.Pass()); | |
| 45 scene_.set_connection_error_handler(base::Bind( | |
| 46 &LauncherViewTree::OnSceneConnectionError, base::Unretained(this))); | |
| 47 | |
| 48 // Register the view tree. | 26 // Register the view tree. |
| 49 mojo::ui::ViewTreeListenerPtr view_tree_listener; | 27 mojo::ui::ViewTreeListenerPtr view_tree_listener; |
| 50 view_tree_listener_binding_.Bind(mojo::GetProxy(&view_tree_listener)); | 28 view_tree_listener_binding_.Bind(mojo::GetProxy(&view_tree_listener)); |
| 51 view_manager_->CreateViewTree(mojo::GetProxy(&view_tree_), | 29 view_manager_->CreateViewTree(mojo::GetProxy(&view_tree_), |
| 52 view_tree_listener.Pass(), "Launcher"); | 30 view_tree_listener.Pass(), "Launcher"); |
| 53 view_tree_.set_connection_error_handler(base::Bind( | 31 view_tree_.set_connection_error_handler(base::Bind( |
| 54 &LauncherViewTree::OnViewTreeConnectionError, base::Unretained(this))); | 32 &LauncherViewTree::OnViewTreeConnectionError, base::Unretained(this))); |
| 55 | 33 |
| 56 // Get view tree services. | 34 // Get view tree services. |
| 57 mojo::ServiceProviderPtr view_tree_service_provider; | 35 mojo::ServiceProviderPtr view_tree_service_provider; |
| 58 view_tree_->GetServiceProvider(mojo::GetProxy(&view_tree_service_provider)); | 36 view_tree_->GetServiceProvider(mojo::GetProxy(&view_tree_service_provider)); |
| 59 mojo::ConnectToService<mojo::ui::InputDispatcher>( | 37 mojo::ConnectToService<mojo::ui::InputDispatcher>( |
| 60 view_tree_service_provider.get(), &input_dispatcher_); | 38 view_tree_service_provider.get(), &input_dispatcher_); |
| 61 input_dispatcher_.set_connection_error_handler( | 39 input_dispatcher_.set_connection_error_handler( |
| 62 base::Bind(&LauncherViewTree::OnInputDispatcherConnectionError, | 40 base::Bind(&LauncherViewTree::OnInputDispatcherConnectionError, |
| 63 base::Unretained(this))); | 41 base::Unretained(this))); |
| 42 |
| 43 // Attach the renderer. |
| 44 mojo::gfx::composition::RendererPtr renderer; |
| 45 compositor_->CreateRenderer(context_provider_.Pass(), GetProxy(&renderer), |
| 46 "Launcher"); |
| 47 view_tree_->SetRenderer(renderer.Pass()); |
| 64 } | 48 } |
| 65 | 49 |
| 66 LauncherViewTree::~LauncherViewTree() {} | 50 LauncherViewTree::~LauncherViewTree() {} |
| 67 | 51 |
| 68 void LauncherViewTree::SetRoot(mojo::ui::ViewOwnerPtr owner) { | 52 void LauncherViewTree::SetRoot(mojo::ui::ViewOwnerPtr owner) { |
| 69 if (owner) { | 53 if (owner) { |
| 70 view_tree_->SetRoot(++root_key_, owner.Pass()); | 54 view_tree_->SetRoot(++root_key_, owner.Pass()); |
| 71 root_was_set_ = true; | 55 root_was_set_ = true; |
| 72 } else { | 56 } else { |
| 73 view_tree_->ResetRoot(nullptr); | 57 view_tree_->ResetRoot(nullptr); |
| 74 root_was_set_ = false; | 58 root_was_set_ = false; |
| 75 } | 59 } |
| 76 root_layout_info_.reset(); | 60 root_layout_info_.reset(); |
| 77 } | 61 } |
| 78 | 62 |
| 79 void LauncherViewTree::SetViewportMetrics( | 63 void LauncherViewTree::SetViewportMetrics( |
| 80 mojo::ViewportMetricsPtr viewport_metrics) { | 64 mojo::ViewportMetricsPtr viewport_metrics) { |
| 81 viewport_metrics_ = viewport_metrics.Pass(); | 65 viewport_metrics_ = viewport_metrics.Pass(); |
| 82 view_tree_->RequestLayout(); | 66 view_tree_->RequestLayout(); |
| 83 SetRootScene(); | |
| 84 } | 67 } |
| 85 | 68 |
| 86 void LauncherViewTree::DispatchEvent(mojo::EventPtr event) { | 69 void LauncherViewTree::DispatchEvent(mojo::EventPtr event) { |
| 87 if (input_dispatcher_) | 70 if (input_dispatcher_) |
| 88 input_dispatcher_->DispatchEvent(event.Pass()); | 71 input_dispatcher_->DispatchEvent(event.Pass()); |
| 89 } | 72 } |
| 90 | 73 |
| 91 void LauncherViewTree::OnRendererConnectionError() { | |
| 92 LOG(ERROR) << "Renderer connection error."; | |
| 93 Shutdown(); | |
| 94 } | |
| 95 | |
| 96 void LauncherViewTree::OnSceneConnectionError() { | |
| 97 LOG(ERROR) << "Scene connection error."; | |
| 98 Shutdown(); | |
| 99 } | |
| 100 | |
| 101 void LauncherViewTree::OnViewTreeConnectionError() { | 74 void LauncherViewTree::OnViewTreeConnectionError() { |
| 102 LOG(ERROR) << "View tree connection error."; | 75 LOG(ERROR) << "View tree connection error."; |
| 103 Shutdown(); | 76 Shutdown(); |
| 104 } | 77 } |
| 105 | 78 |
| 106 void LauncherViewTree::OnInputDispatcherConnectionError() { | 79 void LauncherViewTree::OnInputDispatcherConnectionError() { |
| 107 // This isn't considered a fatal error right now since it is still useful | 80 // This isn't considered a fatal error right now since it is still useful |
| 108 // to be able to test a view system that has graphics but no input. | 81 // to be able to test a view system that has graphics but no input. |
| 109 LOG(WARNING) << "Input dispatcher connection error, input will not work."; | 82 LOG(WARNING) << "Input dispatcher connection error, input will not work."; |
| 110 input_dispatcher_.reset(); | 83 input_dispatcher_.reset(); |
| 111 } | 84 } |
| 112 | 85 |
| 113 void LauncherViewTree::OnSceneRegistered( | |
| 114 mojo::gfx::composition::SceneTokenPtr scene_token) { | |
| 115 DVLOG(1) << "OnSceneRegistered: scene_token=" << scene_token; | |
| 116 scene_token_ = scene_token.Pass(); | |
| 117 SetRootScene(); | |
| 118 } | |
| 119 | |
| 120 void LauncherViewTree::OnResourceUnavailable( | |
| 121 uint32_t resource_id, | |
| 122 const OnResourceUnavailableCallback& callback) { | |
| 123 LOG(ERROR) << "Resource lost: resource_id=" << resource_id; | |
| 124 } | |
| 125 | |
| 126 void LauncherViewTree::OnLayout(const OnLayoutCallback& callback) { | 86 void LauncherViewTree::OnLayout(const OnLayoutCallback& callback) { |
| 127 LayoutRoot(); | 87 LayoutRoot(); |
| 128 callback.Run(); | 88 callback.Run(); |
| 129 } | 89 } |
| 130 | 90 |
| 131 void LauncherViewTree::OnRootUnavailable( | 91 void LauncherViewTree::OnRootUnavailable( |
| 132 uint32_t root_key, | 92 uint32_t root_key, |
| 133 const OnRootUnavailableCallback& callback) { | 93 const OnRootUnavailableCallback& callback) { |
| 134 if (root_key_ == root_key) { | 94 if (root_key_ == root_key) { |
| 135 LOG(ERROR) << "Root view terminated unexpectedly."; | 95 LOG(ERROR) << "Root view terminated unexpectedly."; |
| 136 Shutdown(); | 96 Shutdown(); |
| 137 } | 97 } |
| 138 callback.Run(); | 98 callback.Run(); |
| 139 } | 99 } |
| 140 | 100 |
| 101 void LauncherViewTree::OnRendererDied(const OnRendererDiedCallback& callback) { |
| 102 LOG(ERROR) << "Renderer died unexpectedly."; |
| 103 Shutdown(); |
| 104 callback.Run(); |
| 105 } |
| 106 |
| 141 void LauncherViewTree::LayoutRoot() { | 107 void LauncherViewTree::LayoutRoot() { |
| 142 if (!root_was_set_) | 108 if (!root_was_set_) |
| 143 return; | 109 return; |
| 144 | 110 |
| 145 auto params = mojo::ui::ViewLayoutParams::New(); | 111 auto params = mojo::ui::ViewLayoutParams::New(); |
| 146 params->constraints = mojo::ui::BoxConstraints::New(); | 112 params->constraints = mojo::ui::BoxConstraints::New(); |
| 147 params->constraints->min_width = viewport_metrics_->size->width; | 113 params->constraints->min_width = viewport_metrics_->size->width; |
| 148 params->constraints->max_width = viewport_metrics_->size->width; | 114 params->constraints->max_width = viewport_metrics_->size->width; |
| 149 params->constraints->min_height = viewport_metrics_->size->height; | 115 params->constraints->min_height = viewport_metrics_->size->height; |
| 150 params->constraints->max_height = viewport_metrics_->size->height; | 116 params->constraints->max_height = viewport_metrics_->size->height; |
| 151 params->device_pixel_ratio = viewport_metrics_->device_pixel_ratio; | 117 params->device_pixel_ratio = viewport_metrics_->device_pixel_ratio; |
| 152 view_tree_->LayoutRoot( | 118 view_tree_->LayoutRoot( |
| 153 params.Pass(), | 119 params.Pass(), |
| 154 base::Bind(&LauncherViewTree::OnLayoutResult, base::Unretained(this))); | 120 base::Bind(&LauncherViewTree::OnLayoutResult, base::Unretained(this))); |
| 155 } | 121 } |
| 156 | 122 |
| 157 void LauncherViewTree::OnLayoutResult(mojo::ui::ViewLayoutInfoPtr info) { | 123 void LauncherViewTree::OnLayoutResult(mojo::ui::ViewLayoutInfoPtr info) { |
| 158 if (!info) { | 124 if (!info) { |
| 159 DVLOG(1) << "Root layout: <stale>"; | 125 DVLOG(1) << "Root layout: <stale>"; |
| 160 return; | 126 return; |
| 161 } | 127 } |
| 162 | 128 |
| 163 DVLOG(1) << "Root layout: size.width=" << info->size->width | 129 DVLOG(1) << "Root layout: size.width=" << info->size->width |
| 164 << ", size.height=" << info->size->height | 130 << ", size.height=" << info->size->height |
| 165 << ", scene_token.value=" << info->scene_token->value; | 131 << ", scene_token.value=" << info->scene_token->value; |
| 166 | 132 |
| 167 root_layout_info_ = info.Pass(); | 133 root_layout_info_ = info.Pass(); |
| 168 PublishFrame(); | |
| 169 } | |
| 170 | |
| 171 void LauncherViewTree::SetRootScene() { | |
| 172 if (scene_token_) { | |
| 173 mojo::Rect viewport; | |
| 174 viewport.width = viewport_metrics_->size->width; | |
| 175 viewport.height = viewport_metrics_->size->height; | |
| 176 scene_version_++; | |
| 177 renderer_->SetRootScene(scene_token_.Clone(), scene_version_, | |
| 178 viewport.Clone()); | |
| 179 PublishFrame(); | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 void LauncherViewTree::PublishFrame() { | |
| 184 mojo::Rect bounds; | |
| 185 bounds.width = viewport_metrics_->size->width; | |
| 186 bounds.height = viewport_metrics_->size->height; | |
| 187 | |
| 188 auto update = mojo::gfx::composition::SceneUpdate::New(); | |
| 189 | |
| 190 if (root_layout_info_) { | |
| 191 auto view_resource = mojo::gfx::composition::Resource::New(); | |
| 192 view_resource->set_scene(mojo::gfx::composition::SceneResource::New()); | |
| 193 view_resource->get_scene()->scene_token = | |
| 194 root_layout_info_->scene_token.Clone(); | |
| 195 update->resources.insert(kViewSceneResourceId, view_resource.Pass()); | |
| 196 | |
| 197 auto view_node = mojo::gfx::composition::Node::New(); | |
| 198 view_node->op = mojo::gfx::composition::NodeOp::New(); | |
| 199 view_node->op->set_scene(mojo::gfx::composition::SceneNodeOp::New()); | |
| 200 view_node->op->get_scene()->scene_resource_id = kViewSceneResourceId; | |
| 201 update->nodes.insert(kViewNodeId, view_node.Pass()); | |
| 202 } else { | |
| 203 update->resources.insert(kViewSceneResourceId, nullptr); | |
| 204 update->nodes.insert(kViewNodeId, nullptr); | |
| 205 } | |
| 206 | |
| 207 auto fallback_node = mojo::gfx::composition::Node::New(); | |
| 208 fallback_node->op = mojo::gfx::composition::NodeOp::New(); | |
| 209 fallback_node->op->set_rect(mojo::gfx::composition::RectNodeOp::New()); | |
| 210 fallback_node->op->get_rect()->content_rect = bounds.Clone(); | |
| 211 fallback_node->op->get_rect()->color = mojo::gfx::composition::Color::New(); | |
| 212 fallback_node->op->get_rect()->color->red = 255; | |
| 213 fallback_node->op->get_rect()->color->alpha = 255; | |
| 214 update->nodes.insert(kFallbackNodeId, fallback_node.Pass()); | |
| 215 | |
| 216 auto root_node = mojo::gfx::composition::Node::New(); | |
| 217 root_node->combinator = mojo::gfx::composition::Node::Combinator::FALLBACK; | |
| 218 if (root_layout_info_) { | |
| 219 root_node->child_node_ids.push_back(kViewNodeId); | |
| 220 } | |
| 221 root_node->child_node_ids.push_back(kFallbackNodeId); | |
| 222 update->nodes.insert(kRootNodeId, root_node.Pass()); | |
| 223 | |
| 224 auto metadata = mojo::gfx::composition::SceneMetadata::New(); | |
| 225 metadata->version = scene_version_; | |
| 226 | |
| 227 scene_->Update(update.Pass()); | |
| 228 scene_->Publish(metadata.Pass()); | |
| 229 } | 134 } |
| 230 | 135 |
| 231 void LauncherViewTree::Shutdown() { | 136 void LauncherViewTree::Shutdown() { |
| 232 shutdown_callback_.Run(); | 137 shutdown_callback_.Run(); |
| 233 } | 138 } |
| 234 | 139 |
| 235 } // namespace launcher | 140 } // namespace launcher |
| OLD | NEW |