| 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 |