Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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/extensions/extension_tab_helper.h"
      6 
      7 #include "chrome/browser/extensions/extension_service.h"
      8 #include "chrome/browser/profiles/profile.h"
      9 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
     10 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
     11 #include "chrome/common/extensions/extension_action.h"
     12 #include "chrome/common/extensions/extension_icon_set.h"
     13 #include "chrome/common/extensions/extension_messages.h"
     14 #include "chrome/common/extensions/extension_resource.h"
     15 #include "content/browser/tab_contents/tab_contents.h"
     16 #include "content/browser/tab_contents/navigation_controller.h"
     17 #include "content/common/notification_service.h"
     18 
     19 ExtensionTabHelper::ExtensionTabHelper(TabContentsWrapper* wrapper)
     20     : TabContentsObserver(wrapper->tab_contents()),
     21       extension_app_(NULL),
     22       wrapper_(wrapper) {
     23 }
     24 
     25 ExtensionTabHelper::~ExtensionTabHelper() {
     26 }
     27 
     28 void ExtensionTabHelper::CopyStateFrom(const ExtensionTabHelper& source) {
     29   SetExtensionApp(source.extension_app());
     30   extension_app_icon_ = source.extension_app_icon_;
     31 }
     32 
     33 void ExtensionTabHelper::PageActionStateChanged() {
     34   tab_contents()->NotifyNavigationStateChanged(
     35       TabContents::INVALIDATE_PAGE_ACTIONS);
     36 }
     37 
     38 void ExtensionTabHelper::GetApplicationInfo(int32 page_id) {
     39   Send(new ExtensionMsg_GetApplicationInfo(routing_id(), page_id));
     40 }
     41 
     42 void ExtensionTabHelper::SetExtensionApp(const Extension* extension) {
     43   DCHECK(!extension || extension->GetFullLaunchURL().is_valid());
     44   extension_app_ = extension;
     45 
     46   UpdateExtensionAppIcon(extension_app_);
     47 
     48   NotificationService::current()->Notify(
     49       NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
     50       Source<ExtensionTabHelper>(this),
     51       NotificationService::NoDetails());
     52 }
     53 
     54 void ExtensionTabHelper::SetExtensionAppById(
     55     const std::string& extension_app_id) {
     56   if (extension_app_id.empty())
     57     return;
     58 
     59   ExtensionService* extension_service =
     60       tab_contents()->profile()->GetExtensionService();
     61   if (!extension_service || !extension_service->is_ready())
     62     return;
     63 
     64   const Extension* extension =
     65       extension_service->GetExtensionById(extension_app_id, false);
     66   if (extension)
     67     SetExtensionApp(extension);
     68 }
     69 
     70 SkBitmap* ExtensionTabHelper::GetExtensionAppIcon() {
     71   if (extension_app_icon_.empty())
     72     return NULL;
     73 
     74   return &extension_app_icon_;
     75 }
     76 
     77 void ExtensionTabHelper::DidNavigateMainFramePostCommit(
     78     const NavigationController::LoadCommittedDetails& details,
     79     const ViewHostMsg_FrameNavigate_Params& params) {
     80   if (details.is_in_page)
     81     return;
     82 
     83   ExtensionService* service = tab_contents()->profile()->GetExtensionService();
     84   if (!service)
     85     return;
     86 
     87   for (size_t i = 0; i < service->extensions()->size(); ++i) {
     88     ExtensionAction* browser_action =
     89         service->extensions()->at(i)->browser_action();
     90     if (browser_action) {
     91       browser_action->ClearAllValuesForTab(
     92           tab_contents()->controller().session_id().id());
     93       NotificationService::current()->Notify(
     94           NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
     95           Source<ExtensionAction>(browser_action),
     96           NotificationService::NoDetails());
     97     }
     98 
     99     ExtensionAction* page_action =
    100         service->extensions()->at(i)->page_action();
    101     if (page_action) {
    102       page_action->ClearAllValuesForTab(
    103           tab_contents()->controller().session_id().id());
    104       PageActionStateChanged();
    105     }
    106   }
    107 }
    108 
    109 bool ExtensionTabHelper::OnMessageReceived(const IPC::Message& message) {
    110   bool handled = true;
    111   IPC_BEGIN_MESSAGE_MAP(ExtensionTabHelper, message)
    112     IPC_MESSAGE_HANDLER(ExtensionHostMsg_DidGetApplicationInfo,
    113                         OnDidGetApplicationInfo)
    114     IPC_MESSAGE_HANDLER(ExtensionHostMsg_InstallApplication,
    115                         OnInstallApplication)
    116     IPC_MESSAGE_UNHANDLED(handled = false)
    117   IPC_END_MESSAGE_MAP()
    118   return handled;
    119 }
    120 
    121 void ExtensionTabHelper::OnDidGetApplicationInfo(
    122     int32 page_id, const WebApplicationInfo& info) {
    123   web_app_info_ = info;
    124 
    125   if (wrapper_->delegate())
    126     wrapper_->delegate()->OnDidGetApplicationInfo(wrapper_, page_id);
    127 }
    128 
    129 void ExtensionTabHelper::OnInstallApplication(const WebApplicationInfo& info) {
    130   if (wrapper_->delegate())
    131     wrapper_->delegate()->OnInstallApplication(wrapper_, info);
    132 }
    133 
    134 void ExtensionTabHelper::UpdateExtensionAppIcon(const Extension* extension) {
    135   extension_app_icon_.reset();
    136 
    137   if (extension) {
    138     extension_app_image_loader_.reset(new ImageLoadingTracker(this));
    139     extension_app_image_loader_->LoadImage(
    140         extension,
    141         extension->GetIconResource(Extension::EXTENSION_ICON_SMALLISH,
    142                                    ExtensionIconSet::MATCH_EXACTLY),
    143         gfx::Size(Extension::EXTENSION_ICON_SMALLISH,
    144                   Extension::EXTENSION_ICON_SMALLISH),
    145         ImageLoadingTracker::CACHE);
    146   } else {
    147     extension_app_image_loader_.reset(NULL);
    148   }
    149 }
    150 
    151 void ExtensionTabHelper::SetAppIcon(const SkBitmap& app_icon) {
    152   extension_app_icon_ = app_icon;
    153   tab_contents()->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
    154 }
    155 
    156 void ExtensionTabHelper::OnImageLoaded(SkBitmap* image,
    157                                        const ExtensionResource& resource,
    158                                        int index) {
    159   if (image) {
    160     extension_app_icon_ = *image;
    161     tab_contents()->NotifyNavigationStateChanged(TabContents::INVALIDATE_TAB);
    162   }
    163 }
    164