OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/ui/panels/panel_host.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/location.h" | |
11 #include "base/logging.h" | |
12 #include "base/single_thread_task_runner.h" | |
13 #include "base/threading/thread_task_runner_handle.h" | |
14 #include "chrome/browser/chrome_notification_types.h" | |
15 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" | |
16 #include "chrome/browser/extensions/window_controller.h" | |
17 #include "chrome/browser/favicon/favicon_utils.h" | |
18 #include "chrome/browser/profiles/profile.h" | |
19 #include "chrome/browser/sessions/session_tab_helper.h" | |
20 #include "chrome/browser/ui/browser_navigator.h" | |
21 #include "chrome/browser/ui/browser_navigator_params.h" | |
22 #include "chrome/browser/ui/panels/panel.h" | |
23 #include "chrome/browser/ui/prefs/prefs_tab_helper.h" | |
24 #include "components/favicon/content/content_favicon_driver.h" | |
25 #include "components/zoom/page_zoom.h" | |
26 #include "components/zoom/zoom_controller.h" | |
27 #include "content/public/browser/invalidate_type.h" | |
28 #include "content/public/browser/navigation_controller.h" | |
29 #include "content/public/browser/notification_service.h" | |
30 #include "content/public/browser/notification_source.h" | |
31 #include "content/public/browser/notification_types.h" | |
32 #include "content/public/browser/site_instance.h" | |
33 #include "content/public/browser/user_metrics.h" | |
34 #include "content/public/browser/web_contents.h" | |
35 #include "extensions/browser/view_type_utils.h" | |
36 #include "ipc/ipc_message.h" | |
37 #include "ipc/ipc_message_macros.h" | |
38 #include "ui/gfx/geometry/rect.h" | |
39 #include "ui/gfx/image/image.h" | |
40 | |
41 using base::UserMetricsAction; | |
42 | |
43 PanelHost::PanelHost(Panel* panel, Profile* profile) | |
44 : panel_(panel), | |
45 profile_(profile), | |
46 weak_factory_(this) { | |
47 } | |
48 | |
49 PanelHost::~PanelHost() { | |
50 } | |
51 | |
52 void PanelHost::Init(const GURL& url, | |
53 content::SiteInstance* source_site_instance) { | |
54 if (url.is_empty()) | |
55 return; | |
56 | |
57 scoped_refptr<content::SiteInstance> instance = | |
58 source_site_instance ? source_site_instance->GetRelatedSiteInstance(url) | |
59 : content::SiteInstance::CreateForURL(profile_, url); | |
60 content::WebContents::CreateParams create_params(profile_, | |
61 std::move(instance)); | |
62 web_contents_.reset(content::WebContents::Create(create_params)); | |
63 extensions::SetViewType(web_contents_.get(), extensions::VIEW_TYPE_PANEL); | |
64 web_contents_->SetDelegate(this); | |
65 // web_contents_ may be passed to PageZoom::Zoom(), so it needs | |
66 // a ZoomController. | |
67 zoom::ZoomController::CreateForWebContents(web_contents_.get()); | |
68 content::WebContentsObserver::Observe(web_contents_.get()); | |
69 | |
70 // Needed to give the web contents a Tab ID. Extension APIs | |
71 // expect web contents to have a Tab ID. | |
72 SessionTabHelper::CreateForWebContents(web_contents_.get()); | |
73 SessionTabHelper::FromWebContents(web_contents_.get())->SetWindowID( | |
74 panel_->session_id()); | |
75 | |
76 favicon::CreateContentFaviconDriverForWebContents(web_contents_.get()); | |
77 PrefsTabHelper::CreateForWebContents(web_contents_.get()); | |
78 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( | |
79 web_contents_.get()); | |
80 extensions::ExtensionWebContentsObserver::GetForWebContents( | |
81 web_contents_.get())->dispatcher()->set_delegate(this); | |
82 | |
83 web_contents_->GetController().LoadURL( | |
84 url, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | |
85 } | |
86 | |
87 void PanelHost::DestroyWebContents() { | |
88 // Cannot do a web_contents_.reset() because web_contents_.get() will | |
89 // still return the pointer when we CHECK in WebContentsDestroyed (or if | |
90 // we get called back in the middle of web contents destruction, which | |
91 // WebView might do when it detects the web contents is destroyed). | |
92 content::WebContents* contents = web_contents_.release(); | |
93 delete contents; | |
94 } | |
95 | |
96 gfx::Image PanelHost::GetPageIcon() const { | |
97 if (!web_contents_.get()) | |
98 return gfx::Image(); | |
99 | |
100 favicon::FaviconDriver* favicon_driver = | |
101 favicon::ContentFaviconDriver::FromWebContents(web_contents_.get()); | |
102 CHECK(favicon_driver); | |
103 return favicon_driver->GetFavicon(); | |
104 } | |
105 | |
106 content::WebContents* PanelHost::OpenURLFromTab( | |
107 content::WebContents* source, | |
108 const content::OpenURLParams& params) { | |
109 // These dispositions aren't really navigations. | |
110 if (params.disposition == SAVE_TO_DISK || params.disposition == IGNORE_ACTION) | |
111 return NULL; | |
112 | |
113 // Only allow clicks on links. | |
114 if (!ui::PageTransitionCoreTypeIs(params.transition, | |
115 ui::PAGE_TRANSITION_LINK)) { | |
116 return NULL; | |
117 } | |
118 | |
119 // Force all links to open in a new tab. | |
120 chrome::NavigateParams navigate_params(profile_, | |
121 params.url, | |
122 params.transition); | |
123 switch (params.disposition) { | |
124 case NEW_BACKGROUND_TAB: | |
125 case NEW_WINDOW: | |
126 case OFF_THE_RECORD: | |
127 navigate_params.disposition = params.disposition; | |
128 break; | |
129 default: | |
130 navigate_params.disposition = NEW_FOREGROUND_TAB; | |
131 break; | |
132 } | |
133 chrome::Navigate(&navigate_params); | |
134 return navigate_params.target_contents; | |
135 } | |
136 | |
137 void PanelHost::NavigationStateChanged(content::WebContents* source, | |
138 content::InvalidateTypes changed_flags) { | |
139 // Only need to update the title if the title changed while not loading, | |
140 // because the title is also updated when loading state changes. | |
141 if ((changed_flags & content::INVALIDATE_TYPE_TAB) || | |
142 ((changed_flags & content::INVALIDATE_TYPE_TITLE) && | |
143 !source->IsLoading())) | |
144 panel_->UpdateTitleBar(); | |
145 } | |
146 | |
147 void PanelHost::AddNewContents(content::WebContents* source, | |
148 content::WebContents* new_contents, | |
149 WindowOpenDisposition disposition, | |
150 const gfx::Rect& initial_rect, | |
151 bool user_gesture, | |
152 bool* was_blocked) { | |
153 chrome::NavigateParams navigate_params(profile_, new_contents->GetURL(), | |
154 ui::PAGE_TRANSITION_LINK); | |
155 navigate_params.target_contents = new_contents; | |
156 | |
157 // Force all links to open in a new tab, even if they were trying to open a | |
158 // window. | |
159 navigate_params.disposition = | |
160 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; | |
161 | |
162 navigate_params.window_bounds = initial_rect; | |
163 navigate_params.user_gesture = user_gesture; | |
164 navigate_params.extension_app_id = panel_->extension_id(); | |
165 chrome::Navigate(&navigate_params); | |
166 } | |
167 | |
168 void PanelHost::ActivateContents(content::WebContents* contents) { | |
169 panel_->Activate(); | |
170 } | |
171 | |
172 void PanelHost::LoadingStateChanged(content::WebContents* source, | |
173 bool to_different_document) { | |
174 bool is_loading = source->IsLoading() && to_different_document; | |
175 panel_->LoadingStateChanged(is_loading); | |
176 } | |
177 | |
178 void PanelHost::CloseContents(content::WebContents* source) { | |
179 panel_->Close(); | |
180 } | |
181 | |
182 void PanelHost::MoveContents(content::WebContents* source, | |
183 const gfx::Rect& pos) { | |
184 panel_->SetBounds(pos); | |
185 } | |
186 | |
187 bool PanelHost::IsPopupOrPanel(const content::WebContents* source) const { | |
188 return true; | |
189 } | |
190 | |
191 void PanelHost::ContentsZoomChange(bool zoom_in) { | |
192 Zoom(zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT); | |
193 } | |
194 | |
195 void PanelHost::HandleKeyboardEvent( | |
196 content::WebContents* source, | |
197 const content::NativeWebKeyboardEvent& event) { | |
198 return panel_->HandleKeyboardEvent(event); | |
199 } | |
200 | |
201 void PanelHost::ResizeDueToAutoResize(content::WebContents* web_contents, | |
202 const gfx::Size& new_size) { | |
203 panel_->OnContentsAutoResized(new_size); | |
204 } | |
205 | |
206 void PanelHost::RenderProcessGone(base::TerminationStatus status) { | |
207 CloseContents(web_contents_.get()); | |
208 } | |
209 | |
210 void PanelHost::WebContentsDestroyed() { | |
211 // Web contents should only be destroyed by us. | |
212 CHECK(!web_contents_.get()); | |
213 | |
214 // Close the panel after we return to the message loop (not immediately, | |
215 // otherwise, it may destroy this object before the stack has a chance | |
216 // to cleanly unwind.) | |
217 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
218 FROM_HERE, | |
219 base::Bind(&PanelHost::ClosePanel, weak_factory_.GetWeakPtr())); | |
220 } | |
221 | |
222 void PanelHost::ClosePanel() { | |
223 panel_->Close(); | |
224 } | |
225 | |
226 extensions::WindowController* PanelHost::GetExtensionWindowController() const { | |
227 return panel_->extension_window_controller(); | |
228 } | |
229 | |
230 content::WebContents* PanelHost::GetAssociatedWebContents() const { | |
231 return web_contents_.get(); | |
232 } | |
233 | |
234 void PanelHost::Reload() { | |
235 content::RecordAction(UserMetricsAction("Reload")); | |
236 web_contents_->GetController().Reload(true); | |
237 } | |
238 | |
239 void PanelHost::ReloadBypassingCache() { | |
240 content::RecordAction(UserMetricsAction("ReloadBypassingCache")); | |
241 web_contents_->GetController().ReloadBypassingCache(true); | |
242 } | |
243 | |
244 void PanelHost::StopLoading() { | |
245 content::RecordAction(UserMetricsAction("Stop")); | |
246 web_contents_->Stop(); | |
247 } | |
248 | |
249 void PanelHost::Zoom(content::PageZoom zoom) { | |
250 zoom::PageZoom::Zoom(web_contents_.get(), zoom); | |
251 } | |
OLD | NEW |