| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "blimp/engine/session/blimp_engine_session.h" | |
| 6 | |
| 7 #include <string> | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/strings/string_number_conversions.h" | |
| 13 #include "base/strings/utf_string_conversions.h" | |
| 14 #include "base/threading/thread_task_runner_handle.h" | |
| 15 #include "base/trace_event/trace_event.h" | |
| 16 #include "blimp/common/blob_cache/in_memory_blob_cache.h" | |
| 17 #include "blimp/common/create_blimp_message.h" | |
| 18 #include "blimp/common/proto/tab_control.pb.h" | |
| 19 #include "blimp/engine/app/blimp_engine_config.h" | |
| 20 #include "blimp/engine/app/settings_manager.h" | |
| 21 #include "blimp/engine/app/switches.h" | |
| 22 #include "blimp/engine/app/ui/blimp_layout_manager.h" | |
| 23 #include "blimp/engine/app/ui/blimp_screen.h" | |
| 24 #include "blimp/engine/app/ui/blimp_window_parenting_client.h" | |
| 25 #include "blimp/engine/app/ui/blimp_window_tree_host.h" | |
| 26 #include "blimp/engine/common/blimp_browser_context.h" | |
| 27 #include "blimp/engine/common/blimp_user_agent.h" | |
| 28 #include "blimp/engine/mojo/blob_channel_service.h" | |
| 29 #include "blimp/engine/session/tab.h" | |
| 30 #include "blimp/net/blimp_connection.h" | |
| 31 #include "blimp/net/blimp_message_multiplexer.h" | |
| 32 #include "blimp/net/blimp_message_thread_pipe.h" | |
| 33 #include "blimp/net/blimp_stats.h" | |
| 34 #include "blimp/net/blob_channel/blob_channel_sender_impl.h" | |
| 35 #include "blimp/net/blob_channel/helium_blob_sender_delegate.h" | |
| 36 #include "blimp/net/browser_connection_handler.h" | |
| 37 #include "blimp/net/common.h" | |
| 38 #include "blimp/net/engine_authentication_handler.h" | |
| 39 #include "blimp/net/engine_connection_manager.h" | |
| 40 #include "blimp/net/null_blimp_message_processor.h" | |
| 41 #include "blimp/net/tcp_engine_transport.h" | |
| 42 #include "blimp/net/thread_pipe_manager.h" | |
| 43 #include "content/public/browser/browser_context.h" | |
| 44 #include "content/public/browser/browser_thread.h" | |
| 45 #include "content/public/browser/navigation_controller.h" | |
| 46 #include "content/public/browser/navigation_entry.h" | |
| 47 #include "content/public/browser/render_view_host.h" | |
| 48 #include "content/public/browser/render_widget_host.h" | |
| 49 #include "content/public/browser/render_widget_host_view.h" | |
| 50 #include "content/public/browser/web_contents.h" | |
| 51 #include "device/geolocation/geolocation_delegate.h" | |
| 52 #include "device/geolocation/geolocation_provider.h" | |
| 53 #include "net/base/ip_address.h" | |
| 54 #include "net/base/net_errors.h" | |
| 55 #include "ui/aura/client/default_capture_client.h" | |
| 56 #include "ui/aura/env.h" | |
| 57 #include "ui/aura/window.h" | |
| 58 #include "ui/aura/window_tree_host.h" | |
| 59 #include "ui/base/ime/input_method.h" | |
| 60 #include "ui/base/ime/text_input_client.h" | |
| 61 #include "ui/gfx/geometry/size.h" | |
| 62 #include "ui/wm/core/base_focus_rules.h" | |
| 63 #include "ui/wm/core/default_activation_client.h" | |
| 64 #include "ui/wm/core/focus_controller.h" | |
| 65 | |
| 66 namespace blimp { | |
| 67 namespace engine { | |
| 68 namespace { | |
| 69 | |
| 70 const float kDefaultScaleFactor = 1.f; | |
| 71 const int kDefaultDisplayWidth = 800; | |
| 72 const int kDefaultDisplayHeight = 600; | |
| 73 const uint16_t kDefaultPort = 25467; | |
| 74 | |
| 75 const char kTcpTransport[] = "tcp"; | |
| 76 const char kGrpcTransport[] = "grpc"; | |
| 77 | |
| 78 // Focus rules that support activating an child window. | |
| 79 class FocusRulesImpl : public wm::BaseFocusRules { | |
| 80 public: | |
| 81 FocusRulesImpl() {} | |
| 82 ~FocusRulesImpl() override {} | |
| 83 | |
| 84 bool SupportsChildActivation(aura::Window* window) const override { | |
| 85 return true; | |
| 86 } | |
| 87 | |
| 88 private: | |
| 89 DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl); | |
| 90 }; | |
| 91 | |
| 92 // Proxies calls to TaskRunner::PostTask while stripping the return value, | |
| 93 // which provides a suitable function prototype for binding a base::Closure. | |
| 94 void PostTask(const scoped_refptr<base::TaskRunner>& task_runner, | |
| 95 const base::Closure& closure) { | |
| 96 task_runner->PostTask(FROM_HERE, closure); | |
| 97 } | |
| 98 | |
| 99 // Returns a closure that quits the current (bind-time) MessageLoop. | |
| 100 base::Closure QuitCurrentMessageLoopClosure() { | |
| 101 return base::Bind(&PostTask, base::ThreadTaskRunnerHandle::Get(), | |
| 102 base::MessageLoop::QuitWhenIdleClosure()); | |
| 103 } | |
| 104 | |
| 105 EngineConnectionManager::EngineTransportType GetTransportType() { | |
| 106 const std::string transport_parsed = | |
| 107 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 108 kEngineTransport); | |
| 109 if (transport_parsed == kTcpTransport || transport_parsed.empty()) { | |
| 110 return EngineConnectionManager::EngineTransportType::TCP; | |
| 111 } else if (transport_parsed == kGrpcTransport) { | |
| 112 return EngineConnectionManager::EngineTransportType::GRPC; | |
| 113 } | |
| 114 LOG(FATAL) << "--engine-transport must either be empty or one of " | |
| 115 << kGrpcTransport << ", " << kTcpTransport; | |
| 116 return EngineConnectionManager::EngineTransportType::TCP; | |
| 117 } | |
| 118 | |
| 119 net::IPAddress GetListeningAddress() { | |
| 120 if (base::CommandLine::ForCurrentProcess()->HasSwitch(kAllowNonLocalhost)) { | |
| 121 return net::IPAddress::IPv4AllZeros(); | |
| 122 } | |
| 123 return net::IPAddress::IPv4Localhost(); | |
| 124 } | |
| 125 | |
| 126 uint16_t GetListeningPort() { | |
| 127 unsigned port_parsed = 0; | |
| 128 if (!base::StringToUint( | |
| 129 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 130 kEnginePort), | |
| 131 &port_parsed)) { | |
| 132 return kDefaultPort; | |
| 133 } | |
| 134 if (port_parsed > 65535) { | |
| 135 LOG(FATAL) << "--engine-port must be a value between 0 and 65535."; | |
| 136 return kDefaultPort; | |
| 137 } | |
| 138 return port_parsed; | |
| 139 } | |
| 140 | |
| 141 } // namespace | |
| 142 | |
| 143 // EngineNetworkComponents is created by the BlimpEngineSession on the UI | |
| 144 // thread, and then used and destroyed on the IO thread. | |
| 145 class EngineNetworkComponents : public ConnectionHandler, | |
| 146 public ConnectionErrorObserver { | |
| 147 public: | |
| 148 // |net_log|: The log to use for network-related events. | |
| 149 explicit EngineNetworkComponents(net::NetLog* net_log); | |
| 150 ~EngineNetworkComponents() override; | |
| 151 | |
| 152 // Sets up network components and starts listening for incoming connection. | |
| 153 // This should be called after all features have been registered so that | |
| 154 // received messages can be properly handled. | |
| 155 void Initialize(scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | |
| 156 base::WeakPtr<BlobChannelSender> blob_channel_sender, | |
| 157 const std::string& client_token); | |
| 158 | |
| 159 // TODO(perumaal): Remove this once gRPC support is ready. | |
| 160 // See crbug.com/659279. | |
| 161 uint16_t GetPortForTesting() { return port_; } | |
| 162 | |
| 163 BrowserConnectionHandler* connection_handler() { | |
| 164 return &connection_handler_; | |
| 165 } | |
| 166 | |
| 167 BlobChannelService* blob_channel_service() { | |
| 168 return blob_channel_service_.get(); | |
| 169 } | |
| 170 | |
| 171 private: | |
| 172 // ConnectionHandler implementation. | |
| 173 void HandleConnection(std::unique_ptr<BlimpConnection> connection) override; | |
| 174 | |
| 175 // ConnectionErrorObserver implementation. | |
| 176 // Signals the engine session that an authenticated connection was | |
| 177 // terminated. | |
| 178 void OnConnectionError(int error) override; | |
| 179 | |
| 180 net::NetLog* net_log_; | |
| 181 uint16_t port_ = 0; | |
| 182 | |
| 183 BrowserConnectionHandler connection_handler_; | |
| 184 std::unique_ptr<EngineAuthenticationHandler> authentication_handler_; | |
| 185 std::unique_ptr<EngineConnectionManager> connection_manager_; | |
| 186 std::unique_ptr<BlobChannelService> blob_channel_service_; | |
| 187 base::Closure quit_closure_; | |
| 188 | |
| 189 DISALLOW_COPY_AND_ASSIGN(EngineNetworkComponents); | |
| 190 }; | |
| 191 | |
| 192 EngineNetworkComponents::EngineNetworkComponents(net::NetLog* net_log) | |
| 193 : net_log_(net_log), quit_closure_(QuitCurrentMessageLoopClosure()) {} | |
| 194 | |
| 195 EngineNetworkComponents::~EngineNetworkComponents() { | |
| 196 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 197 } | |
| 198 | |
| 199 void EngineNetworkComponents::Initialize( | |
| 200 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | |
| 201 base::WeakPtr<BlobChannelSender> blob_channel_sender, | |
| 202 const std::string& client_token) { | |
| 203 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 204 DCHECK(!connection_manager_); | |
| 205 // Plumb authenticated connections from the authentication handler | |
| 206 // to |this| (which will then pass it to |connection_handler_|. | |
| 207 authentication_handler_ = | |
| 208 base::MakeUnique<EngineAuthenticationHandler>(this, client_token); | |
| 209 | |
| 210 // Plumb unauthenticated connections to |authentication_handler_|. | |
| 211 connection_manager_ = base::MakeUnique<EngineConnectionManager>( | |
| 212 authentication_handler_.get(), net_log_); | |
| 213 | |
| 214 blob_channel_service_ = | |
| 215 base::MakeUnique<BlobChannelService>(blob_channel_sender, ui_task_runner); | |
| 216 | |
| 217 // Adds BlimpTransports to connection_manager_. | |
| 218 net::IPEndPoint address(GetListeningAddress(), GetListeningPort()); | |
| 219 connection_manager_->ConnectTransport(&address, GetTransportType()); | |
| 220 port_ = address.port(); | |
| 221 | |
| 222 // Print the engine port for client_engine_integration script, please do not | |
| 223 // remove this log. | |
| 224 DVLOG(1) << "Engine port #: " << port_; | |
| 225 } | |
| 226 | |
| 227 void EngineNetworkComponents::HandleConnection( | |
| 228 std::unique_ptr<BlimpConnection> connection) { | |
| 229 // Observe |connection| for disconnection events. | |
| 230 connection->AddConnectionErrorObserver(this); | |
| 231 connection_handler_.HandleConnection(std::move(connection)); | |
| 232 } | |
| 233 | |
| 234 void EngineNetworkComponents::OnConnectionError(int error) { | |
| 235 DVLOG(1) << "EngineNetworkComponents::OnConnectionError(" << error << ")"; | |
| 236 quit_closure_.Run(); | |
| 237 } | |
| 238 | |
| 239 BlimpEngineSession::BlimpEngineSession( | |
| 240 std::unique_ptr<BlimpBrowserContext> browser_context, | |
| 241 net::NetLog* net_log, | |
| 242 BlimpEngineConfig* engine_config, | |
| 243 SettingsManager* settings_manager) | |
| 244 : screen_(new BlimpScreen), | |
| 245 browser_context_(std::move(browser_context)), | |
| 246 engine_config_(engine_config), | |
| 247 settings_manager_(settings_manager), | |
| 248 settings_feature_(settings_manager_), | |
| 249 render_widget_feature_(settings_manager_), | |
| 250 net_components_(new EngineNetworkComponents(net_log)) { | |
| 251 DCHECK(engine_config_); | |
| 252 DCHECK(settings_manager_); | |
| 253 | |
| 254 screen_->UpdateDisplayScaleAndSize( | |
| 255 kDefaultScaleFactor, | |
| 256 gfx::Size(kDefaultDisplayWidth, kDefaultDisplayHeight)); | |
| 257 | |
| 258 std::unique_ptr<HeliumBlobSenderDelegate> helium_blob_delegate( | |
| 259 new HeliumBlobSenderDelegate); | |
| 260 blob_delegate_ = helium_blob_delegate.get(); | |
| 261 blob_channel_sender_ = base::MakeUnique<BlobChannelSenderImpl>( | |
| 262 base::MakeUnique<InMemoryBlobCache>(), std::move(helium_blob_delegate)); | |
| 263 blob_channel_sender_weak_factory_ = | |
| 264 base::MakeUnique<base::WeakPtrFactory<BlobChannelSenderImpl>>( | |
| 265 blob_channel_sender_.get()); | |
| 266 | |
| 267 device::GeolocationProvider::SetGeolocationDelegate( | |
| 268 geolocation_feature_.CreateGeolocationDelegate()); | |
| 269 } | |
| 270 | |
| 271 BlimpEngineSession::~BlimpEngineSession() { | |
| 272 window_tree_host_->GetInputMethod()->RemoveObserver(this); | |
| 273 | |
| 274 // Ensure that all tabs are torn down first, since teardown will | |
| 275 // trigger RenderViewDeleted callbacks to their observers, which will in turn | |
| 276 // send messages to net_components_, which is already deleted due to the line | |
| 277 // below. | |
| 278 tab_.reset(); | |
| 279 | |
| 280 // Safely delete network components on the IO thread. | |
| 281 content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, | |
| 282 net_components_.release()); | |
| 283 } | |
| 284 | |
| 285 void BlimpEngineSession::Initialize() { | |
| 286 DCHECK(!display::Screen::GetScreen()); | |
| 287 display::Screen::SetScreenInstance(screen_.get()); | |
| 288 | |
| 289 window_tree_host_.reset(new BlimpWindowTreeHost()); | |
| 290 | |
| 291 screen_->set_window_tree_host(window_tree_host_.get()); | |
| 292 window_tree_host_->InitHost(); | |
| 293 window_tree_host_->window()->Show(); | |
| 294 window_tree_host_->window()->SetLayoutManager( | |
| 295 new BlimpLayoutManager(window_tree_host_->window())); | |
| 296 focus_client_.reset(new wm::FocusController(new FocusRulesImpl)); | |
| 297 aura::client::SetFocusClient(window_tree_host_->window(), | |
| 298 focus_client_.get()); | |
| 299 aura::client::SetActivationClient(window_tree_host_->window(), | |
| 300 focus_client_.get()); | |
| 301 capture_client_.reset( | |
| 302 new aura::client::DefaultCaptureClient(window_tree_host_->window())); | |
| 303 | |
| 304 window_parenting_client_.reset( | |
| 305 new BlimpWindowParentingClient(window_tree_host_->window())); | |
| 306 | |
| 307 window_tree_host_->GetInputMethod()->AddObserver(this); | |
| 308 | |
| 309 window_tree_host_->SetBoundsInPixels( | |
| 310 gfx::Rect(screen_->GetPrimaryDisplay().size())); | |
| 311 | |
| 312 RegisterFeatures(); | |
| 313 | |
| 314 // Initialize must only be posted after the RegisterFeature calls have | |
| 315 // completed. | |
| 316 content::BrowserThread::PostTask( | |
| 317 content::BrowserThread::IO, FROM_HERE, | |
| 318 base::Bind(&EngineNetworkComponents::Initialize, | |
| 319 base::Unretained(net_components_.get()), | |
| 320 base::ThreadTaskRunnerHandle::Get(), | |
| 321 blob_channel_sender_weak_factory_->GetWeakPtr(), | |
| 322 engine_config_->client_auth_token())); | |
| 323 } | |
| 324 | |
| 325 BlobChannelService* BlimpEngineSession::GetBlobChannelService() { | |
| 326 return net_components_->blob_channel_service(); | |
| 327 } | |
| 328 | |
| 329 void BlimpEngineSession::GetEnginePortForTesting( | |
| 330 const GetPortCallback& callback) { | |
| 331 content::BrowserThread::PostTaskAndReplyWithResult( | |
| 332 content::BrowserThread::IO, FROM_HERE, | |
| 333 base::Bind(&EngineNetworkComponents::GetPortForTesting, | |
| 334 base::Unretained(net_components_.get())), | |
| 335 callback); | |
| 336 } | |
| 337 | |
| 338 void BlimpEngineSession::RegisterFeatures() { | |
| 339 thread_pipe_manager_.reset( | |
| 340 new ThreadPipeManager(content::BrowserThread::GetTaskRunnerForThread( | |
| 341 content::BrowserThread::IO), | |
| 342 net_components_->connection_handler())); | |
| 343 | |
| 344 // Register features' message senders and receivers. | |
| 345 tab_control_message_sender_ = | |
| 346 thread_pipe_manager_->RegisterFeature(BlimpMessage::kTabControl, this); | |
| 347 navigation_message_sender_ = | |
| 348 thread_pipe_manager_->RegisterFeature(BlimpMessage::kNavigation, this); | |
| 349 render_widget_feature_.set_render_widget_message_sender( | |
| 350 thread_pipe_manager_->RegisterFeature(BlimpMessage::kRenderWidget, | |
| 351 &render_widget_feature_)); | |
| 352 render_widget_feature_.set_input_message_sender( | |
| 353 thread_pipe_manager_->RegisterFeature(BlimpMessage::kInput, | |
| 354 &render_widget_feature_)); | |
| 355 render_widget_feature_.set_compositor_message_sender( | |
| 356 thread_pipe_manager_->RegisterFeature(BlimpMessage::kCompositor, | |
| 357 &render_widget_feature_)); | |
| 358 render_widget_feature_.set_ime_message_sender( | |
| 359 thread_pipe_manager_->RegisterFeature(BlimpMessage::kIme, | |
| 360 &render_widget_feature_)); | |
| 361 geolocation_feature_.set_outgoing_message_processor( | |
| 362 thread_pipe_manager_->RegisterFeature(BlimpMessage::kGeolocation, | |
| 363 &geolocation_feature_)); | |
| 364 blob_delegate_->set_outgoing_message_processor( | |
| 365 thread_pipe_manager_->RegisterFeature(BlimpMessage::kBlobChannel, | |
| 366 blob_delegate_)); | |
| 367 | |
| 368 // The Settings feature does not need an outgoing message processor, since we | |
| 369 // don't send any messages to the client right now. | |
| 370 thread_pipe_manager_->RegisterFeature(BlimpMessage::kSettings, | |
| 371 &settings_feature_); | |
| 372 } | |
| 373 | |
| 374 bool BlimpEngineSession::CreateTab(const int target_tab_id) { | |
| 375 DVLOG(1) << "Create tab " << target_tab_id; | |
| 376 if (tab_) { | |
| 377 return false; | |
| 378 } | |
| 379 | |
| 380 content::WebContents::CreateParams create_params(browser_context_.get(), | |
| 381 nullptr); | |
| 382 std::unique_ptr<content::WebContents> new_contents = | |
| 383 base::WrapUnique(content::WebContents::Create(create_params)); | |
| 384 PlatformSetContents(std::move(new_contents), target_tab_id); | |
| 385 | |
| 386 return true; | |
| 387 } | |
| 388 | |
| 389 void BlimpEngineSession::CloseTab(const int target_tab_id) { | |
| 390 DVLOG(1) << "Close tab " << target_tab_id; | |
| 391 tab_.reset(); | |
| 392 } | |
| 393 | |
| 394 void BlimpEngineSession::HandleResize(float device_pixel_ratio, | |
| 395 const gfx::Size& size) { | |
| 396 DVLOG(1) << "Resize to " << size.ToString() << ", " << device_pixel_ratio; | |
| 397 screen_->UpdateDisplayScaleAndSize(device_pixel_ratio, size); | |
| 398 window_tree_host_->SetBoundsInPixels(gfx::Rect(size)); | |
| 399 if (tab_) { | |
| 400 tab_->Resize(device_pixel_ratio, | |
| 401 screen_->GetPrimaryDisplay().bounds().size()); | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 void BlimpEngineSession::OnTextInputTypeChanged( | |
| 406 const ui::TextInputClient* client) {} | |
| 407 | |
| 408 void BlimpEngineSession::OnFocus() {} | |
| 409 | |
| 410 void BlimpEngineSession::OnBlur() {} | |
| 411 | |
| 412 void BlimpEngineSession::OnCaretBoundsChanged( | |
| 413 const ui::TextInputClient* client) {} | |
| 414 | |
| 415 // Called when either: | |
| 416 // - the TextInputClient is changed (e.g. by a change of focus) | |
| 417 // - the TextInputType of the TextInputClient changes | |
| 418 void BlimpEngineSession::OnTextInputStateChanged( | |
| 419 const ui::TextInputClient* client) { | |
| 420 if (!tab_ || !tab_->web_contents()->GetRenderWidgetHostView()) | |
| 421 return; | |
| 422 | |
| 423 ui::TextInputType type = | |
| 424 client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE; | |
| 425 | |
| 426 // Hide IME, when text input is out of focus, i.e. if the text input type | |
| 427 // changes to ui::TEXT_INPUT_TYPE_NONE. For other text input types, | |
| 428 // OnShowImeIfNeeded is used instead to send show IME request to client. | |
| 429 if (type == ui::TEXT_INPUT_TYPE_NONE) | |
| 430 tab_->HideTextInputUI(); | |
| 431 } | |
| 432 | |
| 433 void BlimpEngineSession::OnInputMethodDestroyed( | |
| 434 const ui::InputMethod* input_method) {} | |
| 435 | |
| 436 // Called when a user input should trigger showing the IME. | |
| 437 void BlimpEngineSession::OnShowImeIfNeeded() { | |
| 438 TRACE_EVENT0("blimp", "BlimpEngineSession::OnShowImeIfNeeded"); | |
| 439 if (!tab_ || !tab_->web_contents()->GetRenderWidgetHostView() || | |
| 440 !window_tree_host_->GetInputMethod()->GetTextInputClient()) | |
| 441 return; | |
| 442 | |
| 443 tab_->ShowTextInputUI(); | |
| 444 } | |
| 445 | |
| 446 void BlimpEngineSession::ProcessMessage( | |
| 447 std::unique_ptr<BlimpMessage> message, | |
| 448 const net::CompletionCallback& callback) { | |
| 449 TRACE_EVENT1("blimp", "BlimpEngineSession::ProcessMessage", "TabId", | |
| 450 message->target_tab_id()); | |
| 451 DCHECK(!callback.is_null()); | |
| 452 DCHECK(BlimpMessage::kTabControl == message->feature_case() || | |
| 453 BlimpMessage::kNavigation == message->feature_case()); | |
| 454 | |
| 455 net::Error result = net::OK; | |
| 456 if (message->has_tab_control()) { | |
| 457 switch (message->tab_control().tab_control_case()) { | |
| 458 case TabControlMessage::kCreateTab: | |
| 459 if (!CreateTab(message->target_tab_id())) | |
| 460 result = net::ERR_FAILED; | |
| 461 break; | |
| 462 case TabControlMessage::kCloseTab: | |
| 463 CloseTab(message->target_tab_id()); | |
| 464 case TabControlMessage::kSize: | |
| 465 HandleResize(message->tab_control().size().device_pixel_ratio(), | |
| 466 gfx::Size(message->tab_control().size().width(), | |
| 467 message->tab_control().size().height())); | |
| 468 break; | |
| 469 default: | |
| 470 NOTIMPLEMENTED(); | |
| 471 result = net::ERR_NOT_IMPLEMENTED; | |
| 472 } | |
| 473 } else if (message->has_navigation()) { | |
| 474 if (tab_) { | |
| 475 switch (message->navigation().type()) { | |
| 476 case NavigationMessage::LOAD_URL: | |
| 477 tab_->LoadUrl(GURL(message->navigation().load_url().url())); | |
| 478 break; | |
| 479 case NavigationMessage::GO_BACK: | |
| 480 tab_->GoBack(); | |
| 481 break; | |
| 482 case NavigationMessage::GO_FORWARD: | |
| 483 tab_->GoForward(); | |
| 484 break; | |
| 485 case NavigationMessage::RELOAD: | |
| 486 tab_->Reload(); | |
| 487 break; | |
| 488 default: | |
| 489 NOTIMPLEMENTED(); | |
| 490 result = net::ERR_NOT_IMPLEMENTED; | |
| 491 } | |
| 492 } else { | |
| 493 VLOG(1) << "Tab " << message->target_tab_id() << " does not exist"; | |
| 494 } | |
| 495 } else { | |
| 496 NOTREACHED(); | |
| 497 result = net::ERR_FAILED; | |
| 498 } | |
| 499 | |
| 500 callback.Run(result); | |
| 501 } | |
| 502 | |
| 503 void BlimpEngineSession::AddNewContents(content::WebContents* source, | |
| 504 content::WebContents* new_contents, | |
| 505 WindowOpenDisposition disposition, | |
| 506 const gfx::Rect& initial_rect, | |
| 507 bool user_gesture, | |
| 508 bool* was_blocked) { | |
| 509 NOTIMPLEMENTED(); | |
| 510 } | |
| 511 | |
| 512 content::WebContents* BlimpEngineSession::OpenURLFromTab( | |
| 513 content::WebContents* source, | |
| 514 const content::OpenURLParams& params) { | |
| 515 // CURRENT_TAB is the only one we implement for now. | |
| 516 if (params.disposition != WindowOpenDisposition::CURRENT_TAB) { | |
| 517 NOTIMPLEMENTED(); | |
| 518 return nullptr; | |
| 519 } | |
| 520 | |
| 521 // TODO(haibinlu): Add helper method to get LoadURLParams from OpenURLParams. | |
| 522 content::NavigationController::LoadURLParams load_url_params(params.url); | |
| 523 load_url_params.source_site_instance = params.source_site_instance; | |
| 524 load_url_params.referrer = params.referrer; | |
| 525 load_url_params.frame_tree_node_id = params.frame_tree_node_id; | |
| 526 load_url_params.transition_type = params.transition; | |
| 527 load_url_params.extra_headers = params.extra_headers; | |
| 528 load_url_params.should_replace_current_entry = | |
| 529 params.should_replace_current_entry; | |
| 530 load_url_params.is_renderer_initiated = params.is_renderer_initiated; | |
| 531 load_url_params.override_user_agent = | |
| 532 content::NavigationController::UA_OVERRIDE_TRUE; | |
| 533 | |
| 534 source->GetController().LoadURLWithParams(load_url_params); | |
| 535 return source; | |
| 536 } | |
| 537 | |
| 538 void BlimpEngineSession::RequestToLockMouse(content::WebContents* web_contents, | |
| 539 bool user_gesture, | |
| 540 bool last_unlocked_by_target) { | |
| 541 web_contents->GotResponseToLockMouseRequest(true); | |
| 542 } | |
| 543 | |
| 544 void BlimpEngineSession::CloseContents(content::WebContents* source) { | |
| 545 if (source == tab_->web_contents()) { | |
| 546 tab_.reset(); | |
| 547 } | |
| 548 } | |
| 549 | |
| 550 void BlimpEngineSession::ActivateContents(content::WebContents* contents) { | |
| 551 contents->GetRenderViewHost()->GetWidget()->Focus(); | |
| 552 } | |
| 553 | |
| 554 void BlimpEngineSession::ForwardCompositorProto( | |
| 555 content::RenderWidgetHost* render_widget_host, | |
| 556 const std::vector<uint8_t>& proto) { | |
| 557 TRACE_EVENT0("blimp", "BlimpEngineSession::ForwardCompositorProto"); | |
| 558 if (!tab_) { | |
| 559 return; | |
| 560 } | |
| 561 render_widget_feature_.SendCompositorMessage(tab_->tab_id(), | |
| 562 render_widget_host, proto); | |
| 563 } | |
| 564 | |
| 565 void BlimpEngineSession::NavigationStateChanged( | |
| 566 content::WebContents* source, | |
| 567 content::InvalidateTypes changed_flags) { | |
| 568 TRACE_EVENT0("blimp", "BlimpEngineSession::NavigationStateChanged"); | |
| 569 if (source == tab_->web_contents()) | |
| 570 tab_->NavigationStateChanged(changed_flags); | |
| 571 } | |
| 572 | |
| 573 void BlimpEngineSession::PlatformSetContents( | |
| 574 std::unique_ptr<content::WebContents> new_contents, | |
| 575 const int target_tab_id) { | |
| 576 new_contents->SetDelegate(this); | |
| 577 | |
| 578 aura::Window* parent = window_tree_host_->window(); | |
| 579 aura::Window* content = new_contents->GetNativeView(); | |
| 580 if (!parent->Contains(content)) | |
| 581 parent->AddChild(content); | |
| 582 content->Show(); | |
| 583 | |
| 584 tab_ = base::MakeUnique<Tab>(std::move(new_contents), target_tab_id, | |
| 585 &render_widget_feature_, | |
| 586 navigation_message_sender_.get()); | |
| 587 } | |
| 588 | |
| 589 } // namespace engine | |
| 590 } // namespace blimp | |
| OLD | NEW |