| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "blimp/engine/session/tab.h" |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/trace_event/trace_event.h" |
| #include "blimp/common/create_blimp_message.h" |
| #include "blimp/common/proto/blimp_message.pb.h" |
| #include "blimp/common/proto/render_widget.pb.h" |
| #include "blimp/common/proto/tab_control.pb.h" |
| #include "blimp/engine/common/blimp_user_agent.h" |
| #include "blimp/engine/feature/engine_render_widget_feature.h" |
| #include "blimp/net/blimp_message_processor.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/render_widget_host.h" |
| #include "content/public/browser/render_widget_host_view.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/renderer_preferences.h" |
| #include "ui/aura/window.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| namespace blimp { |
| namespace engine { |
| |
| Tab::Tab(std::unique_ptr<content::WebContents> web_contents, |
| const int tab_id, |
| EngineRenderWidgetFeature* render_widget_feature, |
| BlimpMessageProcessor* navigation_message_sender) |
| : web_contents_(std::move(web_contents)), |
| tab_id_(tab_id), |
| render_widget_feature_(render_widget_feature), |
| navigation_message_sender_(navigation_message_sender), |
| page_load_tracker_(web_contents_.get(), this) { |
| DCHECK(render_widget_feature_); |
| DCHECK(navigation_message_sender_); |
| |
| // A Tab is created upon client's request, thus an updated |
| // user agent info (containing client OS info) is available, and we will use |
| // that to override user agent string from BlimpContentRendererClient. |
| web_contents_->SetUserAgentOverride(GetBlimpEngineUserAgent()); |
| |
| render_widget_feature_->SetDelegate(tab_id_, this); |
| |
| Observe(web_contents_.get()); |
| } |
| |
| Tab::~Tab() { |
| render_widget_feature_->RemoveDelegate(tab_id_); |
| } |
| |
| void Tab::Resize(float device_pixel_ratio, const gfx::Size& size_in_dips) { |
| DVLOG(1) << "Resize to " << size_in_dips.ToString() << ", " |
| << device_pixel_ratio; |
| web_contents_->GetNativeView()->SetBounds(gfx::Rect(size_in_dips)); |
| |
| if (web_contents_->GetRenderViewHost() && |
| web_contents_->GetRenderViewHost()->GetWidget()) { |
| web_contents_->GetRenderViewHost()->GetWidget()->WasResized(); |
| } |
| } |
| |
| void Tab::LoadUrl(const GURL& url) { |
| TRACE_EVENT1("blimp", "Tab::LoadUrl", "URL", url.spec()); |
| DVLOG(1) << "Load URL " << url << " in tab " << tab_id_; |
| if (!url.is_valid()) { |
| VLOG(1) << "Dropping invalid URL " << url; |
| return; |
| } |
| |
| content::NavigationController::LoadURLParams params(url); |
| params.transition_type = ui::PageTransitionFromInt( |
| ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); |
| params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; |
| web_contents_->GetController().LoadURLWithParams(params); |
| web_contents_->Focus(); |
| } |
| |
| void Tab::GoBack() { |
| if (!web_contents_->GetController().CanGoBack()) { |
| DLOG(ERROR) << "Ignoring back in tab " << tab_id_; |
| return; |
| } |
| DVLOG(1) << "Back in tab " << tab_id_; |
| web_contents_->GetController().GoBack(); |
| } |
| |
| void Tab::GoForward() { |
| if (!web_contents_->GetController().CanGoForward()) { |
| DLOG(ERROR) << "Ignoring forward in tab " << tab_id_; |
| return; |
| } |
| DVLOG(1) << "Forward in tab " << tab_id_; |
| web_contents_->GetController().GoForward(); |
| } |
| |
| void Tab::Reload() { |
| DVLOG(1) << "Reload in tab " << tab_id_; |
| web_contents_->GetController().Reload(true); |
| } |
| |
| void Tab::RenderViewCreated(content::RenderViewHost* render_view_host) { |
| DCHECK(render_view_host); |
| web_contents_->GetMutableRendererPrefs()->caret_blink_interval = 0; |
| render_view_host->SyncRendererPrefs(); |
| |
| render_widget_feature_->OnRenderWidgetCreated(tab_id_, |
| render_view_host->GetWidget()); |
| } |
| |
| void Tab::RenderViewHostChanged(content::RenderViewHost* old_host, |
| content::RenderViewHost* new_host) { |
| render_widget_feature_->OnRenderWidgetInitialized(tab_id_, |
| new_host->GetWidget()); |
| } |
| |
| void Tab::RenderViewDeleted(content::RenderViewHost* render_view_host) { |
| render_widget_feature_->OnRenderWidgetDeleted(tab_id_, |
| render_view_host->GetWidget()); |
| } |
| |
| void Tab::NavigationStateChanged(content::InvalidateTypes changed_flags) { |
| DCHECK(changed_flags); |
| |
| NavigationMessage* navigation_message; |
| std::unique_ptr<BlimpMessage> message = |
| CreateBlimpMessage(&navigation_message, tab_id_); |
| navigation_message->set_type(NavigationMessage::NAVIGATION_STATE_CHANGED); |
| NavigationStateChangeMessage* details = |
| navigation_message->mutable_navigation_state_changed(); |
| |
| if (changed_flags & content::InvalidateTypes::INVALIDATE_TYPE_URL) |
| details->set_url(web_contents_->GetURL().spec()); |
| |
| if (changed_flags & content::InvalidateTypes::INVALIDATE_TYPE_TAB) { |
| // TODO(dtrainor): Serialize the favicon? crbug.com/597094. |
| DVLOG(3) << "Tab favicon changed"; |
| } |
| |
| if (changed_flags & content::InvalidateTypes::INVALIDATE_TYPE_TITLE) |
| details->set_title(base::UTF16ToUTF8(web_contents_->GetTitle())); |
| |
| if (changed_flags & content::InvalidateTypes::INVALIDATE_TYPE_LOAD) |
| details->set_loading(web_contents_->IsLoading()); |
| |
| navigation_message_sender_->ProcessMessage(std::move(message), |
| net::CompletionCallback()); |
| } |
| |
| void Tab::SendPageLoadStatusUpdate(PageLoadStatus load_status) { |
| NavigationMessage* navigation_message = nullptr; |
| std::unique_ptr<BlimpMessage> message = |
| CreateBlimpMessage(&navigation_message, tab_id_); |
| navigation_message->set_type(NavigationMessage::NAVIGATION_STATE_CHANGED); |
| navigation_message->mutable_navigation_state_changed() |
| ->set_page_load_completed(load_status == PageLoadStatus::LOADED); |
| |
| navigation_message_sender_->ProcessMessage(std::move(message), |
| net::CompletionCallback()); |
| } |
| |
| void Tab::OnWebGestureEvent(content::RenderWidgetHost* render_widget_host, |
| std::unique_ptr<blink::WebGestureEvent> event) { |
| TRACE_EVENT1("blimp", "Tab::OnWebGestureEvent", "type", event->type); |
| render_widget_host->ForwardGestureEvent(*event); |
| } |
| |
| void Tab::OnCompositorMessageReceived( |
| content::RenderWidgetHost* render_widget_host, |
| const std::vector<uint8_t>& message) { |
| TRACE_EVENT0("blimp", "Tab::OnCompositorMessageReceived"); |
| |
| render_widget_host->HandleCompositorProto(message); |
| } |
| |
| } // namespace engine |
| } // namespace blimp |