[Extensions] Clean up the handling of ExtensionHostMsg_Request
[chromium-blink-merge.git] / chrome / browser / ui / panels / panel_host.cc
bloba334dbd11286889cfb95f9114b61e115e170429e
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/panels/panel_host.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
12 #include "chrome/browser/extensions/window_controller.h"
13 #include "chrome/browser/favicon/favicon_helper.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/sessions/session_tab_helper.h"
16 #include "chrome/browser/ui/browser_navigator.h"
17 #include "chrome/browser/ui/panels/panel.h"
18 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
19 #include "components/favicon/content/content_favicon_driver.h"
20 #include "components/ui/zoom/page_zoom.h"
21 #include "components/ui/zoom/zoom_controller.h"
22 #include "content/public/browser/invalidate_type.h"
23 #include "content/public/browser/navigation_controller.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/site_instance.h"
29 #include "content/public/browser/user_metrics.h"
30 #include "content/public/browser/web_contents.h"
31 #include "extensions/browser/view_type_utils.h"
32 #include "extensions/common/extension_messages.h"
33 #include "ipc/ipc_message.h"
34 #include "ipc/ipc_message_macros.h"
35 #include "ui/gfx/geometry/rect.h"
36 #include "ui/gfx/image/image.h"
38 using base::UserMetricsAction;
40 PanelHost::PanelHost(Panel* panel, Profile* profile)
41 : panel_(panel),
42 profile_(profile),
43 weak_factory_(this) {
46 PanelHost::~PanelHost() {
49 void PanelHost::Init(const GURL& url) {
50 if (url.is_empty())
51 return;
53 content::WebContents::CreateParams create_params(
54 profile_, content::SiteInstance::CreateForURL(profile_, url));
55 web_contents_.reset(content::WebContents::Create(create_params));
56 extensions::SetViewType(web_contents_.get(), extensions::VIEW_TYPE_PANEL);
57 web_contents_->SetDelegate(this);
58 // web_contents_ may be passed to PageZoom::Zoom(), so it needs
59 // a ZoomController.
60 ui_zoom::ZoomController::CreateForWebContents(web_contents_.get());
61 content::WebContentsObserver::Observe(web_contents_.get());
63 // Needed to give the web contents a Tab ID. Extension APIs
64 // expect web contents to have a Tab ID.
65 SessionTabHelper::CreateForWebContents(web_contents_.get());
66 SessionTabHelper::FromWebContents(web_contents_.get())->SetWindowID(
67 panel_->session_id());
69 favicon::CreateContentFaviconDriverForWebContents(web_contents_.get());
70 PrefsTabHelper::CreateForWebContents(web_contents_.get());
71 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
72 web_contents_.get());
73 extensions::ExtensionWebContentsObserver::GetForWebContents(
74 web_contents_.get())->dispatcher()->set_delegate(this);
76 web_contents_->GetController().LoadURL(
77 url, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
80 void PanelHost::DestroyWebContents() {
81 // Cannot do a web_contents_.reset() because web_contents_.get() will
82 // still return the pointer when we CHECK in WebContentsDestroyed (or if
83 // we get called back in the middle of web contents destruction, which
84 // WebView might do when it detects the web contents is destroyed).
85 content::WebContents* contents = web_contents_.release();
86 delete contents;
89 gfx::Image PanelHost::GetPageIcon() const {
90 if (!web_contents_.get())
91 return gfx::Image();
93 favicon::FaviconDriver* favicon_driver =
94 favicon::ContentFaviconDriver::FromWebContents(web_contents_.get());
95 CHECK(favicon_driver);
96 return favicon_driver->GetFavicon();
99 content::WebContents* PanelHost::OpenURLFromTab(
100 content::WebContents* source,
101 const content::OpenURLParams& params) {
102 // These dispositions aren't really navigations.
103 if (params.disposition == SUPPRESS_OPEN ||
104 params.disposition == SAVE_TO_DISK ||
105 params.disposition == IGNORE_ACTION)
106 return NULL;
108 // Only allow clicks on links.
109 if (params.transition != ui::PAGE_TRANSITION_LINK)
110 return NULL;
112 // Force all links to open in a new tab.
113 chrome::NavigateParams navigate_params(profile_,
114 params.url,
115 params.transition);
116 switch (params.disposition) {
117 case NEW_BACKGROUND_TAB:
118 case NEW_WINDOW:
119 case OFF_THE_RECORD:
120 navigate_params.disposition = params.disposition;
121 break;
122 default:
123 navigate_params.disposition = NEW_FOREGROUND_TAB;
124 break;
126 chrome::Navigate(&navigate_params);
127 return navigate_params.target_contents;
130 void PanelHost::NavigationStateChanged(content::WebContents* source,
131 content::InvalidateTypes changed_flags) {
132 // Only need to update the title if the title changed while not loading,
133 // because the title is also updated when loading state changes.
134 if ((changed_flags & content::INVALIDATE_TYPE_TAB) ||
135 ((changed_flags & content::INVALIDATE_TYPE_TITLE) &&
136 !source->IsLoading()))
137 panel_->UpdateTitleBar();
140 void PanelHost::AddNewContents(content::WebContents* source,
141 content::WebContents* new_contents,
142 WindowOpenDisposition disposition,
143 const gfx::Rect& initial_rect,
144 bool user_gesture,
145 bool* was_blocked) {
146 chrome::NavigateParams navigate_params(profile_, new_contents->GetURL(),
147 ui::PAGE_TRANSITION_LINK);
148 navigate_params.target_contents = new_contents;
150 // Force all links to open in a new tab, even if they were trying to open a
151 // window.
152 navigate_params.disposition =
153 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB;
155 navigate_params.window_bounds = initial_rect;
156 navigate_params.user_gesture = user_gesture;
157 navigate_params.extension_app_id = panel_->extension_id();
158 chrome::Navigate(&navigate_params);
161 void PanelHost::ActivateContents(content::WebContents* contents) {
162 panel_->Activate();
165 void PanelHost::DeactivateContents(content::WebContents* contents) {
166 panel_->Deactivate();
169 void PanelHost::LoadingStateChanged(content::WebContents* source,
170 bool to_different_document) {
171 bool is_loading = source->IsLoading() && to_different_document;
172 panel_->LoadingStateChanged(is_loading);
175 void PanelHost::CloseContents(content::WebContents* source) {
176 panel_->Close();
179 void PanelHost::MoveContents(content::WebContents* source,
180 const gfx::Rect& pos) {
181 panel_->SetBounds(pos);
184 bool PanelHost::IsPopupOrPanel(const content::WebContents* source) const {
185 return true;
188 void PanelHost::ContentsZoomChange(bool zoom_in) {
189 Zoom(zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT);
192 void PanelHost::HandleKeyboardEvent(
193 content::WebContents* source,
194 const content::NativeWebKeyboardEvent& event) {
195 return panel_->HandleKeyboardEvent(event);
198 void PanelHost::ResizeDueToAutoResize(content::WebContents* web_contents,
199 const gfx::Size& new_size) {
200 panel_->OnContentsAutoResized(new_size);
203 void PanelHost::RenderViewCreated(content::RenderViewHost* render_view_host) {
204 extensions::WindowController* window = GetExtensionWindowController();
205 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId(
206 render_view_host->GetRoutingID(), window->GetWindowId()));
209 void PanelHost::RenderProcessGone(base::TerminationStatus status) {
210 CloseContents(web_contents_.get());
213 void PanelHost::WebContentsDestroyed() {
214 // Web contents should only be destroyed by us.
215 CHECK(!web_contents_.get());
217 // Close the panel after we return to the message loop (not immediately,
218 // otherwise, it may destroy this object before the stack has a chance
219 // to cleanly unwind.)
220 base::MessageLoop::current()->PostTask(
221 FROM_HERE,
222 base::Bind(&PanelHost::ClosePanel, weak_factory_.GetWeakPtr()));
225 void PanelHost::ClosePanel() {
226 panel_->Close();
229 extensions::WindowController* PanelHost::GetExtensionWindowController() const {
230 return panel_->extension_window_controller();
233 content::WebContents* PanelHost::GetAssociatedWebContents() const {
234 return web_contents_.get();
237 void PanelHost::Reload() {
238 content::RecordAction(UserMetricsAction("Reload"));
239 web_contents_->GetController().Reload(true);
242 void PanelHost::ReloadIgnoringCache() {
243 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
244 web_contents_->GetController().ReloadIgnoringCache(true);
247 void PanelHost::StopLoading() {
248 content::RecordAction(UserMetricsAction("Stop"));
249 web_contents_->Stop();
252 void PanelHost::Zoom(content::PageZoom zoom) {
253 ui_zoom::PageZoom::Zoom(web_contents_.get(), zoom);