tab_helper.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/logging.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_util.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_log.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/declarative_content/content_rules_registry.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/crx_installer.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/extensions/error_console/error_console.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/image_loader.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/page_action_controller.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/script_badge_controller.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/script_bubble_controller.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/script_executor.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_inline_installer.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/webstore_inline_installer_factory.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_id.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/web_applications/web_app_ui.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_icon_set.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_messages.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/feature_switch.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/common/render_messages.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/invalidate_type.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "extensions/browser/extension_error.h"
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/extension_resource.h"
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "extensions/common/extension_urls.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(extensions::TabHelper);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabHelper::ScriptExecutionObserver::ScriptExecutionObserver(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TabHelper* tab_helper)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : tab_helper_(tab_helper) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_helper_->AddScriptExecutionObserver(this);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabHelper::ScriptExecutionObserver::ScriptExecutionObserver()
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : tab_helper_(NULL) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabHelper::ScriptExecutionObserver::~ScriptExecutionObserver() {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tab_helper_)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_helper_->RemoveScriptExecutionObserver(this);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabHelper::TabHelper(content::WebContents* web_contents)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : content::WebContentsObserver(web_contents),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_app_(NULL),
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extension_function_dispatcher_(
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          Profile::FromBrowserContext(web_contents->GetBrowserContext()), this),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_web_app_action_(NONE),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      script_executor_(new ScriptExecutor(web_contents,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          &script_execution_observers_)),
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      image_loader_ptr_factory_(this),
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      webstore_inline_installer_factory_(new WebstoreInlineInstallerFactory()) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The ActiveTabPermissionManager requires a session ID; ensure this
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebContents has one.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SessionTabHelper::CreateForWebContents(web_contents);
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (web_contents->GetRenderViewHost())
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetTabId(web_contents->GetRenderViewHost());
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  active_tab_permission_granter_.reset(new ActiveTabPermissionGranter(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SessionID::IdForTab(web_contents),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile::FromBrowserContext(web_contents->GetBrowserContext())));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FeatureSwitch::script_badges()->IsEnabled()) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location_bar_controller_.reset(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ScriptBadgeController(web_contents, this));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location_bar_controller_.reset(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new PageActionController(web_contents));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FeatureSwitch::script_bubble()->IsEnabled()) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    script_bubble_controller_.reset(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ScriptBubbleController(web_contents, this));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If more classes need to listen to global content script activity, then
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a separate routing class with an observer interface should be written.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddScriptExecutionObserver(ActivityLog::GetInstance(profile_));
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NOTIFICATION_LOAD_STOP,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<NavigationController>(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     &web_contents->GetController()));
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Add(this,
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 chrome::NOTIFICATION_EXTENSION_UNLOADED,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 content::NotificationService::AllSources());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabHelper::~TabHelper() {
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoveScriptExecutionObserver(ActivityLog::GetInstance(profile_));
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::CreateApplicationShortcuts() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CanCreateApplicationShortcuts());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry =
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents()->GetController().GetLastCommittedEntry();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_web_app_action_ = CREATE_SHORTCUT;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start fetching web app info for CreateApplicationShortcut dialog and show
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the dialog when the data is available in OnDidGetApplicationInfo.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetApplicationInfo(entry->GetPageID());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabHelper::CanCreateApplicationShortcuts() const {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_app::IsValidUrl(web_contents()->GetURL()) &&
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_web_app_action_ == NONE;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::SetExtensionApp(const Extension* extension) {
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!extension || AppLaunchInfo::GetFullLaunchURL(extension).is_valid());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_app_ = extension;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateExtensionAppIcon(extension_app_);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<TabHelper>(this),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::SetExtensionAppById(const std::string& extension_app_id) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension = GetExtension(extension_app_id);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetExtensionApp(extension);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::SetExtensionAppIconById(const std::string& extension_app_id) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension = GetExtension(extension_app_id);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateExtensionAppIcon(extension);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap* TabHelper::GetExtensionAppIcon() {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_app_icon_.empty())
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &extension_app_icon_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::RenderViewCreated(RenderViewHost* render_view_host) {
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SetTabId(render_view_host);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::DidNavigateMainFrame(
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::LoadCommittedDetails& details,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::FrameNavigateParams& params) {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ExtensionSystem::Get(profile_)->extension_service() &&
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      RulesRegistryService::Get(profile_)) {
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RulesRegistryService::Get(profile_)->content_rules_registry()->
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DidNavigateMainFrame(web_contents(), details, params);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(ENABLE_EXTENSIONS)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (details.is_in_page)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile =
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* service = profile->GetExtensionService();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!service)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionActionManager* extension_action_manager =
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionActionManager::Get(profile);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionSet::const_iterator it = service->extensions()->begin();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != service->extensions()->end(); ++it) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionAction* browser_action =
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        extension_action_manager->GetBrowserAction(*it->get());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (browser_action) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_action->ClearAllValuesForTab(SessionID::IdForTab(web_contents()));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::current()->Notify(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::Source<ExtensionAction>(browser_action),
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::NotificationService::NoDetails());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabHelper::OnMessageReceived(const IPC::Message& message) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(TabHelper, message)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_DidGetApplicationInfo,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnDidGetApplicationInfo)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_InlineWebstoreInstall,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnInlineWebstoreInstall)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppInstallState,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnGetAppInstallState);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnContentScriptsExecuting)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_OnWatchedPageChange,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnWatchedPageChange)
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DetailedConsoleMessageAdded,
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDetailedConsoleMessageAdded)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::DidCloneToNewWebContents(WebContents* old_web_contents,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         WebContents* new_web_contents) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the WebContents that this is attached to is cloned, give the new clone
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a TabHelper and copy state over.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateForWebContents(new_web_contents);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabHelper* new_helper = FromWebContents(new_web_contents);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_helper->SetExtensionApp(extension_app());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_helper->extension_app_icon_ = extension_app_icon_;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::OnDidGetApplicationInfo(int32 page_id,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const WebApplicationInfo& info) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Android does not implement BrowserWindow.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_app_info_ = info;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry =
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents()->GetController().GetLastCommittedEntry();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry || (entry->GetPageID() != page_id))
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (pending_web_app_action_) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREATE_SHORTCUT: {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::ShowCreateWebAppShortcutsDialog(
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          web_contents()->GetView()->GetTopLevelNativeWindow(),
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          web_contents());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case UPDATE_SHORTCUT: {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_app::UpdateShortcutForTabContents(web_contents());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_web_app_action_ = NONE;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::OnInlineWebstoreInstall(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int install_id,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int return_route_id,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& webstore_item_id,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& requestor_url) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebstoreStandaloneInstaller::Callback callback =
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TabHelper::OnInlineInstallComplete, base::Unretained(this),
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 install_id, return_route_id);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<WebstoreInlineInstaller> installer(
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      webstore_inline_installer_factory_->CreateInstaller(
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          web_contents(),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          webstore_item_id,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          requestor_url,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          callback));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  installer->BeginInstall();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::OnGetAppInstallState(const GURL& requestor_url,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int return_route_id,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int callback_id) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile =
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* extension_service = profile->GetExtensionService();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionSet* extensions = extension_service->extensions();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionSet* disabled = extension_service->disabled_extensions();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string state;
322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (extensions->GetHostedAppByURL(requestor_url))
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = extension_misc::kAppStateInstalled;
324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  else if (disabled->GetHostedAppByURL(requestor_url))
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = extension_misc::kAppStateDisabled;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = extension_misc::kAppStateNotInstalled;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ExtensionMsg_GetAppInstallStateResponse(
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return_route_id, state, callback_id));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::OnRequest(const ExtensionHostMsg_Request_Params& request) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_function_dispatcher_.Dispatch(request,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          web_contents()->GetRenderViewHost());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::OnContentScriptsExecuting(
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ScriptExecutionObserver::ExecutingScriptsMap& executing_scripts_map,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 on_page_id,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& on_url) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ScriptExecutionObserver, script_execution_observers_,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnScriptsExecuted(web_contents(),
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      executing_scripts_map,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      on_page_id,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      on_url));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TabHelper::OnWatchedPageChange(
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& css_selectors) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ExtensionSystem::Get(profile_)->extension_service() &&
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      RulesRegistryService::Get(profile_)) {
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RulesRegistryService::Get(profile_)->content_rules_registry()->Apply(
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        web_contents(), css_selectors);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(ENABLE_EXTENSIONS)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TabHelper::OnDetailedConsoleMessageAdded(
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::string16& message,
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::string16& source,
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const StackTrace& stack_trace,
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int32 severity_level) {
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (IsSourceFromAnExtension(source)) {
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ErrorConsole::Get(profile_)->ReportError(
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        scoped_ptr<ExtensionError>(new RuntimeError(
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            extension_app_ ? extension_app_->id() : EmptyString(),
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            profile_->IsOffTheRecord(),
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            source,
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            message,
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            stack_trace,
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            web_contents() ?
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                web_contents()->GetLastCommittedURL() : GURL::EmptyGURL(),
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            static_cast<logging::LogSeverity>(severity_level))));
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* TabHelper::GetExtension(const std::string& extension_app_id) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_app_id.empty())
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile =
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* extension_service = profile->GetExtensionService();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension_service || !extension_service->is_ready())
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension =
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_service->GetExtensionById(extension_app_id, false);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::UpdateExtensionAppIcon(const Extension* extension) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_app_icon_.reset();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure previously enqueued callbacks are ignored.
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_loader_ptr_factory_.InvalidateWeakPtrs();
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enqueue OnImageLoaded callback.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension) {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile =
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Profile::FromBrowserContext(web_contents()->GetBrowserContext());
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extensions::ImageLoader* loader = extensions::ImageLoader::Get(profile);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    loader->LoadImageAsync(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extension,
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IconsInfo::GetIconResource(extension,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   extension_misc::EXTENSION_ICON_SMALLISH,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   ExtensionIconSet::MATCH_EXACTLY),
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gfx::Size(extension_misc::EXTENSION_ICON_SMALLISH,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  extension_misc::EXTENSION_ICON_SMALLISH),
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&TabHelper::OnImageLoaded,
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   image_loader_ptr_factory_.GetWeakPtr()));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::SetAppIcon(const SkBitmap& app_icon) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_app_icon_ = app_icon;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TITLE);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TabHelper::SetWebstoreInlineInstallerFactoryForTests(
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebstoreInlineInstallerFactory* factory) {
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  webstore_inline_installer_factory_.reset(factory);
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TabHelper::OnImageLoaded(const gfx::Image& image) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image.IsEmpty()) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_app_icon_ = *image.ToSkBitmap();
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowController* TabHelper::GetExtensionWindowController() const  {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ExtensionTabUtil::GetWindowControllerOfTab(web_contents());
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::OnInlineInstallComplete(int install_id,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int return_route_id,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool success,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::string& error) {
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Send(new ExtensionMsg_InlineWebstoreInstallResponse(
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return_route_id, install_id, success, success ? std::string() : error));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContents* TabHelper::GetAssociatedWebContents() const {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_contents();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::GetApplicationInfo(int32 page_id) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ExtensionMsg_GetApplicationInfo(routing_id(), page_id));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabHelper::Observe(int type,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const content::NotificationSource& source,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const content::NotificationDetails& details) {
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case content::NOTIFICATION_LOAD_STOP: {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const NavigationController& controller =
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          *content::Source<NavigationController>(source).ptr();
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK_EQ(controller.GetWebContents(), web_contents());
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (pending_web_app_action_ == UPDATE_SHORTCUT) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Schedule a shortcut update when web application info is available if
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // last committed entry is not NULL. Last committed entry could be NULL
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // when an interstitial page is injected (e.g. bad https certificate,
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // malware site etc). When this happens, we abort the shortcut update.
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NavigationEntry* entry = controller.GetLastCommittedEntry();
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (entry)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetApplicationInfo(entry->GetPageID());
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        else
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          pending_web_app_action_ = NONE;
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (script_bubble_controller_) {
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        script_bubble_controller_->OnExtensionUnloaded(
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            content::Details<extensions::UnloadedExtensionInfo>(
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                details)->extension->id());
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TabHelper::SetTabId(RenderViewHost* render_view_host) {
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  render_view_host->Send(
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new ExtensionMsg_SetTabId(render_view_host->GetRoutingID(),
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                SessionID::IdForTab(web_contents())));
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
494