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