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 19ExtensionTabHelper::ExtensionTabHelper(TabContentsWrapper* wrapper) 20 : TabContentsObserver(wrapper->tab_contents()), 21 extension_app_(NULL), 22 wrapper_(wrapper) { 23} 24 25ExtensionTabHelper::~ExtensionTabHelper() { 26} 27 28void ExtensionTabHelper::CopyStateFrom(const ExtensionTabHelper& source) { 29 SetExtensionApp(source.extension_app()); 30 extension_app_icon_ = source.extension_app_icon_; 31} 32 33void ExtensionTabHelper::PageActionStateChanged() { 34 tab_contents()->NotifyNavigationStateChanged( 35 TabContents::INVALIDATE_PAGE_ACTIONS); 36} 37 38void ExtensionTabHelper::GetApplicationInfo(int32 page_id) { 39 Send(new ExtensionMsg_GetApplicationInfo(routing_id(), page_id)); 40} 41 42void 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 54void 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 70SkBitmap* ExtensionTabHelper::GetExtensionAppIcon() { 71 if (extension_app_icon_.empty()) 72 return NULL; 73 74 return &extension_app_icon_; 75} 76 77void 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 109bool 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 121void 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 129void ExtensionTabHelper::OnInstallApplication(const WebApplicationInfo& info) { 130 if (wrapper_->delegate()) 131 wrapper_->delegate()->OnInstallApplication(wrapper_, info); 132} 133 134void 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 151void ExtensionTabHelper::SetAppIcon(const SkBitmap& app_icon) { 152 extension_app_icon_ = app_icon; 153 tab_contents()->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE); 154} 155 156void 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