| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_tab_helper.h" | 5 #include "chrome/browser/extensions/extension_tab_helper.h" |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/crx_installer.h" |
| 7 #include "chrome/browser/extensions/extension_service.h" | 8 #include "chrome/browser/extensions/extension_service.h" |
| 8 #include "chrome/browser/extensions/page_action_controller.h" | 9 #include "chrome/browser/extensions/page_action_controller.h" |
| 9 #include "chrome/browser/extensions/script_badge_controller.h" | 10 #include "chrome/browser/extensions/script_badge_controller.h" |
| 10 #include "chrome/browser/extensions/script_executor_impl.h" | 11 #include "chrome/browser/extensions/script_executor_impl.h" |
| 11 #include "chrome/browser/extensions/webstore_inline_installer.h" | 12 #include "chrome/browser/extensions/webstore_inline_installer.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/sessions/restore_tab_helper.h" | 14 #include "chrome/browser/sessions/restore_tab_helper.h" |
| 14 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/browser/ui/browser_dialogs.h" |
| 15 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 17 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 16 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" | 18 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
| 19 #include "chrome/browser/ui/web_applications/web_app_ui.h" |
| 20 #include "chrome/browser/web_applications/web_app.h" |
| 17 #include "chrome/common/chrome_notification_types.h" | 21 #include "chrome/common/chrome_notification_types.h" |
| 18 #include "chrome/common/extensions/extension_action.h" | 22 #include "chrome/common/extensions/extension_action.h" |
| 19 #include "chrome/common/extensions/extension_constants.h" | 23 #include "chrome/common/extensions/extension_constants.h" |
| 20 #include "chrome/common/extensions/extension_icon_set.h" | 24 #include "chrome/common/extensions/extension_icon_set.h" |
| 21 #include "chrome/common/extensions/extension_messages.h" | 25 #include "chrome/common/extensions/extension_messages.h" |
| 22 #include "chrome/common/extensions/extension_resource.h" | 26 #include "chrome/common/extensions/extension_resource.h" |
| 23 #include "chrome/common/extensions/extension_switch_utils.h" | 27 #include "chrome/common/extensions/extension_switch_utils.h" |
| 24 #include "content/public/browser/invalidate_type.h" | 28 #include "content/public/browser/invalidate_type.h" |
| 29 #include "content/public/browser/navigation_controller.h" |
| 25 #include "content/public/browser/navigation_details.h" | 30 #include "content/public/browser/navigation_details.h" |
| 31 #include "content/public/browser/navigation_entry.h" |
| 26 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 33 #include "content/public/browser/notification_source.h" |
| 34 #include "content/public/browser/notification_types.h" |
| 27 #include "content/public/browser/render_process_host.h" | 35 #include "content/public/browser/render_process_host.h" |
| 28 #include "content/public/browser/render_view_host.h" | 36 #include "content/public/browser/render_view_host.h" |
| 29 #include "content/public/browser/render_widget_host_view.h" | 37 #include "content/public/browser/render_widget_host_view.h" |
| 30 #include "content/public/browser/web_contents.h" | 38 #include "content/public/browser/web_contents.h" |
| 39 #include "content/public/browser/web_contents_view.h" |
| 31 #include "ui/gfx/image/image.h" | 40 #include "ui/gfx/image/image.h" |
| 32 | 41 |
| 42 using content::NavigationController; |
| 43 using content::NavigationEntry; |
| 33 using content::RenderViewHost; | 44 using content::RenderViewHost; |
| 34 using content::WebContents; | 45 using content::WebContents; |
| 35 using extensions::Extension; | 46 using extensions::Extension; |
| 36 using extensions::PageActionController; | 47 using extensions::PageActionController; |
| 37 using extensions::ScriptBadgeController; | 48 using extensions::ScriptBadgeController; |
| 38 using extensions::ScriptExecutorImpl; | 49 using extensions::ScriptExecutorImpl; |
| 39 | 50 |
| 40 namespace { | 51 namespace { |
| 41 | 52 |
| 42 const char kPermissionError[] = "permission_error"; | 53 const char kPermissionError[] = "permission_error"; |
| 43 | 54 |
| 44 } // namespace | 55 } // namespace |
| 45 | 56 |
| 46 ExtensionTabHelper::ExtensionTabHelper(TabContents* tab_contents) | 57 ExtensionTabHelper::ExtensionTabHelper(TabContents* tab_contents) |
| 47 : content::WebContentsObserver(tab_contents->web_contents()), | 58 : content::WebContentsObserver(tab_contents->web_contents()), |
| 48 delegate_(NULL), | |
| 49 extension_app_(NULL), | 59 extension_app_(NULL), |
| 50 ALLOW_THIS_IN_INITIALIZER_LIST( | 60 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 51 extension_function_dispatcher_(tab_contents->profile(), this)), | 61 extension_function_dispatcher_(tab_contents->profile(), this)), |
| 62 pending_web_app_action_(NONE), |
| 52 tab_contents_(tab_contents), | 63 tab_contents_(tab_contents), |
| 53 active_tab_permission_manager_(tab_contents) { | 64 active_tab_permission_manager_(tab_contents) { |
| 54 if (extensions::switch_utils::AreScriptBadgesEnabled()) { | 65 if (extensions::switch_utils::AreScriptBadgesEnabled()) { |
| 55 script_badge_controller_ = new ScriptBadgeController(tab_contents); | 66 script_badge_controller_ = new ScriptBadgeController(tab_contents); |
| 56 } else { | 67 } else { |
| 57 script_executor_.reset( | 68 script_executor_.reset( |
| 58 new ScriptExecutorImpl(tab_contents->web_contents())); | 69 new ScriptExecutorImpl(tab_contents->web_contents())); |
| 59 location_bar_controller_.reset(new PageActionController(tab_contents)); | 70 location_bar_controller_.reset(new PageActionController(tab_contents)); |
| 60 } | 71 } |
| 72 registrar_.Add(this, |
| 73 content::NOTIFICATION_LOAD_STOP, |
| 74 content::Source<NavigationController>( |
| 75 &tab_contents->web_contents()->GetController())); |
| 61 } | 76 } |
| 62 | 77 |
| 63 ExtensionTabHelper::~ExtensionTabHelper() { | 78 ExtensionTabHelper::~ExtensionTabHelper() { |
| 64 } | 79 } |
| 65 | 80 |
| 66 void ExtensionTabHelper::CopyStateFrom(const ExtensionTabHelper& source) { | 81 void ExtensionTabHelper::CopyStateFrom(const ExtensionTabHelper& source) { |
| 67 SetExtensionApp(source.extension_app()); | 82 SetExtensionApp(source.extension_app()); |
| 68 extension_app_icon_ = source.extension_app_icon_; | 83 extension_app_icon_ = source.extension_app_icon_; |
| 69 } | 84 } |
| 70 | 85 |
| 71 void ExtensionTabHelper::GetApplicationInfo(int32 page_id) { | 86 void ExtensionTabHelper::CreateApplicationShortcuts() { |
| 72 Send(new ExtensionMsg_GetApplicationInfo(routing_id(), page_id)); | 87 DCHECK(CanCreateApplicationShortcuts()); |
| 88 NavigationEntry* entry = |
| 89 tab_contents_->web_contents()->GetController().GetLastCommittedEntry(); |
| 90 if (!entry) |
| 91 return; |
| 92 |
| 93 pending_web_app_action_ = CREATE_SHORTCUT; |
| 94 |
| 95 // Start fetching web app info for CreateApplicationShortcut dialog and show |
| 96 // the dialog when the data is available in OnDidGetApplicationInfo. |
| 97 GetApplicationInfo(entry->GetPageID()); |
| 98 } |
| 99 |
| 100 bool ExtensionTabHelper::CanCreateApplicationShortcuts() const { |
| 101 #if defined(OS_MACOSX) |
| 102 return false; |
| 103 #else |
| 104 return web_app::IsValidUrl(tab_contents_->web_contents()->GetURL()) && |
| 105 pending_web_app_action_ == NONE; |
| 106 #endif |
| 73 } | 107 } |
| 74 | 108 |
| 75 int ExtensionTabHelper::tab_id() const { | 109 int ExtensionTabHelper::tab_id() const { |
| 76 return tab_contents_->restore_tab_helper()->session_id().id(); | 110 return tab_contents_->restore_tab_helper()->session_id().id(); |
| 77 } | 111 } |
| 78 | 112 |
| 79 int ExtensionTabHelper::window_id() const { | 113 int ExtensionTabHelper::window_id() const { |
| 80 return tab_contents_->restore_tab_helper()->window_id().id(); | 114 return tab_contents_->restore_tab_helper()->window_id().id(); |
| 81 } | 115 } |
| 82 | 116 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppInstallState, | 205 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppInstallState, |
| 172 OnGetAppInstallState); | 206 OnGetAppInstallState); |
| 173 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) | 207 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) |
| 174 IPC_MESSAGE_UNHANDLED(handled = false) | 208 IPC_MESSAGE_UNHANDLED(handled = false) |
| 175 IPC_END_MESSAGE_MAP() | 209 IPC_END_MESSAGE_MAP() |
| 176 return handled; | 210 return handled; |
| 177 } | 211 } |
| 178 | 212 |
| 179 void ExtensionTabHelper::OnDidGetApplicationInfo( | 213 void ExtensionTabHelper::OnDidGetApplicationInfo( |
| 180 int32 page_id, const WebApplicationInfo& info) { | 214 int32 page_id, const WebApplicationInfo& info) { |
| 215 #if !defined(OS_MACOSX) |
| 181 web_app_info_ = info; | 216 web_app_info_ = info; |
| 182 | 217 |
| 183 if (delegate_) | 218 NavigationEntry* entry = |
| 184 delegate_->OnDidGetApplicationInfo(tab_contents_, page_id); | 219 tab_contents_->web_contents()->GetController().GetLastCommittedEntry(); |
| 220 if (!entry || (entry->GetPageID() != page_id)) |
| 221 return; |
| 222 |
| 223 switch (pending_web_app_action_) { |
| 224 case CREATE_SHORTCUT: { |
| 225 chrome::ShowCreateWebAppShortcutsDialog( |
| 226 tab_contents_->web_contents()->GetView()->GetTopLevelNativeWindow(), |
| 227 tab_contents_); |
| 228 break; |
| 229 } |
| 230 case UPDATE_SHORTCUT: { |
| 231 web_app::UpdateShortcutForTabContents(tab_contents_); |
| 232 break; |
| 233 } |
| 234 default: |
| 235 NOTREACHED(); |
| 236 break; |
| 237 } |
| 238 |
| 239 pending_web_app_action_ = NONE; |
| 240 #endif |
| 185 } | 241 } |
| 186 | 242 |
| 187 void ExtensionTabHelper::OnInstallApplication(const WebApplicationInfo& info) { | 243 void ExtensionTabHelper::OnInstallApplication(const WebApplicationInfo& info) { |
| 188 if (delegate_) | 244 Profile* profile = |
| 189 delegate_->OnInstallApplication(tab_contents_, info); | 245 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| 246 ExtensionService* extension_service = profile->GetExtensionService(); |
| 247 if (!extension_service) |
| 248 return; |
| 249 |
| 250 ExtensionInstallPrompt* prompt = NULL; |
| 251 if (extension_service->show_extensions_prompts()) { |
| 252 gfx::NativeWindow parent = |
| 253 tab_contents_->web_contents()->GetView()->GetTopLevelNativeWindow(); |
| 254 prompt = new ExtensionInstallPrompt(parent, |
| 255 tab_contents_->web_contents(), |
| 256 tab_contents_->profile()); |
| 257 } |
| 258 scoped_refptr<CrxInstaller> installer( |
| 259 CrxInstaller::Create(extension_service, prompt)); |
| 260 installer->InstallWebApp(info); |
| 190 } | 261 } |
| 191 | 262 |
| 192 void ExtensionTabHelper::OnInlineWebstoreInstall( | 263 void ExtensionTabHelper::OnInlineWebstoreInstall( |
| 193 int install_id, | 264 int install_id, |
| 194 int return_route_id, | 265 int return_route_id, |
| 195 const std::string& webstore_item_id, | 266 const std::string& webstore_item_id, |
| 196 const GURL& requestor_url) { | 267 const GURL& requestor_url) { |
| 197 scoped_refptr<WebstoreInlineInstaller> installer(new WebstoreInlineInstaller( | 268 scoped_refptr<WebstoreInlineInstaller> installer(new WebstoreInlineInstaller( |
| 198 web_contents(), | 269 web_contents(), |
| 199 install_id, | 270 install_id, |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 void ExtensionTabHelper::OnInlineInstallFailure(int install_id, | 443 void ExtensionTabHelper::OnInlineInstallFailure(int install_id, |
| 373 int return_route_id, | 444 int return_route_id, |
| 374 const std::string& error) { | 445 const std::string& error) { |
| 375 Send(new ExtensionMsg_InlineWebstoreInstallResponse( | 446 Send(new ExtensionMsg_InlineWebstoreInstallResponse( |
| 376 return_route_id, install_id, false, error)); | 447 return_route_id, install_id, false, error)); |
| 377 } | 448 } |
| 378 | 449 |
| 379 WebContents* ExtensionTabHelper::GetAssociatedWebContents() const { | 450 WebContents* ExtensionTabHelper::GetAssociatedWebContents() const { |
| 380 return web_contents(); | 451 return web_contents(); |
| 381 } | 452 } |
| 453 |
| 454 void ExtensionTabHelper::GetApplicationInfo(int32 page_id) { |
| 455 Send(new ExtensionMsg_GetApplicationInfo(routing_id(), page_id)); |
| 456 } |
| 457 |
| 458 void ExtensionTabHelper::Observe(int type, |
| 459 const content::NotificationSource& source, |
| 460 const content::NotificationDetails& details) { |
| 461 DCHECK(type == content::NOTIFICATION_LOAD_STOP); |
| 462 const NavigationController& controller = |
| 463 *content::Source<NavigationController>(source).ptr(); |
| 464 DCHECK_EQ(controller.GetWebContents(), tab_contents_->web_contents()); |
| 465 |
| 466 if (pending_web_app_action_ == UPDATE_SHORTCUT) { |
| 467 // Schedule a shortcut update when web application info is available if |
| 468 // last committed entry is not NULL. Last committed entry could be NULL |
| 469 // when an interstitial page is injected (e.g. bad https certificate, |
| 470 // malware site etc). When this happens, we abort the shortcut update. |
| 471 NavigationEntry* entry = controller.GetLastCommittedEntry(); |
| 472 if (entry) |
| 473 GetApplicationInfo(entry->GetPageID()); |
| 474 else |
| 475 pending_web_app_action_ = NONE; |
| 476 } |
| 477 } |
| OLD | NEW |