| 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/script_badge_controller.h" | 5 #include "chrome/browser/extensions/script_badge_controller.h" |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/extension_service.h" | 7 #include "chrome/browser/extensions/extension_service.h" |
| 8 #include "chrome/browser/extensions/extension_system.h" | 8 #include "chrome/browser/extensions/extension_system.h" |
| 9 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 9 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 10 #include "chrome/common/extensions/extension.h" | 10 #include "chrome/common/extensions/extension.h" |
| 11 #include "chrome/common/extensions/extension_action.h" | 11 #include "chrome/common/extensions/extension_action.h" |
| 12 #include "chrome/common/extensions/extension_messages.h" | 12 #include "chrome/common/extensions/extension_messages.h" |
| 13 #include "chrome/common/extensions/extension_set.h" | 13 #include "chrome/common/extensions/extension_set.h" |
| 14 #include "chrome/common/chrome_notification_types.h" | 14 #include "chrome/common/chrome_notification_types.h" |
| 15 #include "content/public/browser/navigation_controller.h" | 15 #include "content/public/browser/navigation_controller.h" |
| 16 #include "content/public/browser/navigation_entry.h" | 16 #include "content/public/browser/navigation_entry.h" |
| 17 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
| 18 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
| 19 #include "ipc/ipc_message.h" | 19 #include "ipc/ipc_message.h" |
| 20 #include "ipc/ipc_message_macros.h" | 20 #include "ipc/ipc_message_macros.h" |
| 21 | 21 |
| 22 namespace extensions { | 22 namespace extensions { |
| 23 | 23 |
| 24 ScriptBadgeController::ScriptBadgeController(TabContents* tab_contents) | 24 ScriptBadgeController::ScriptBadgeController(TabContents* tab_contents) |
| 25 : content::WebContentsObserver(tab_contents->web_contents()), | 25 : content::WebContentsObserver(tab_contents->web_contents()), |
| 26 script_executor_(tab_contents->web_contents()), | 26 script_executor_(tab_contents->web_contents()), |
| 27 tab_contents_(tab_contents) {} | 27 tab_contents_(tab_contents) { |
| 28 registrar_.Add(this, |
| 29 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 30 content::Source<Profile>(tab_contents->profile())); |
| 31 } |
| 28 | 32 |
| 29 ScriptBadgeController::~ScriptBadgeController() {} | 33 ScriptBadgeController::~ScriptBadgeController() {} |
| 30 | 34 |
| 31 scoped_ptr<std::vector<ExtensionAction*> > | 35 std::vector<ExtensionAction*> ScriptBadgeController::GetCurrentActions() { |
| 32 ScriptBadgeController::GetCurrentActions() { | 36 return current_actions_; |
| 33 scoped_ptr<std::vector<ExtensionAction*> > current_actions( | |
| 34 new std::vector<ExtensionAction*>()); | |
| 35 | |
| 36 ExtensionService* service = GetExtensionService(); | |
| 37 if (!service) | |
| 38 return current_actions.Pass(); | |
| 39 | |
| 40 for (ExtensionSet::const_iterator it = service->extensions()->begin(); | |
| 41 it != service->extensions()->end(); ++it) { | |
| 42 const Extension* extension = *it; | |
| 43 if (extensions_executing_scripts_.count(extension->id())) | |
| 44 current_actions->push_back(extension->GetScriptBadge()); | |
| 45 } | |
| 46 return current_actions.Pass(); | |
| 47 } | 37 } |
| 48 | 38 |
| 49 LocationBarController::Action ScriptBadgeController::OnClicked( | 39 LocationBarController::Action ScriptBadgeController::OnClicked( |
| 50 const std::string& extension_id, int mouse_button) { | 40 const std::string& extension_id, int mouse_button) { |
| 51 ExtensionService* service = GetExtensionService(); | 41 ExtensionService* service = GetExtensionService(); |
| 52 if (!service) | 42 if (!service) |
| 53 return ACTION_NONE; | 43 return ACTION_NONE; |
| 54 | 44 |
| 55 const Extension* extension = service->extensions()->GetByID(extension_id); | 45 const Extension* extension = service->extensions()->GetByID(extension_id); |
| 56 CHECK(extension); | 46 CHECK(extension); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 this_callback); | 81 this_callback); |
| 92 } | 82 } |
| 93 | 83 |
| 94 void ScriptBadgeController::OnExecuteScriptFinished( | 84 void ScriptBadgeController::OnExecuteScriptFinished( |
| 95 const std::string& extension_id, | 85 const std::string& extension_id, |
| 96 const ExecuteScriptCallback& callback, | 86 const ExecuteScriptCallback& callback, |
| 97 bool success, | 87 bool success, |
| 98 int32 page_id, | 88 int32 page_id, |
| 99 const std::string& error) { | 89 const std::string& error) { |
| 100 if (success && page_id == GetPageID()) { | 90 if (success && page_id == GetPageID()) { |
| 101 extensions_executing_scripts_.insert(extension_id); | 91 if (InsertExtension(extension_id)) |
| 102 Notify(); | 92 Notify(); |
| 103 } | 93 } |
| 104 | 94 |
| 105 callback.Run(success, page_id, error); | 95 callback.Run(success, page_id, error); |
| 106 } | 96 } |
| 107 | 97 |
| 108 ExtensionService* ScriptBadgeController::GetExtensionService() { | 98 ExtensionService* ScriptBadgeController::GetExtensionService() { |
| 109 return ExtensionSystem::Get(tab_contents_->profile())->extension_service(); | 99 return ExtensionSystem::Get(tab_contents_->profile())->extension_service(); |
| 110 } | 100 } |
| 111 | 101 |
| 112 int32 ScriptBadgeController::GetPageID() { | 102 int32 ScriptBadgeController::GetPageID() { |
| 113 return tab_contents_->web_contents()->GetController().GetActiveEntry()-> | 103 return tab_contents_->web_contents()->GetController().GetActiveEntry()-> |
| 114 GetPageID(); | 104 GetPageID(); |
| 115 } | 105 } |
| 116 | 106 |
| 117 void ScriptBadgeController::Notify() { | 107 void ScriptBadgeController::Notify() { |
| 118 content::NotificationService::current()->Notify( | 108 content::NotificationService::current()->Notify( |
| 119 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | 109 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, |
| 120 content::Source<Profile>(tab_contents_->profile()), | 110 content::Source<Profile>(tab_contents_->profile()), |
| 121 content::Details<TabContents>(tab_contents_)); | 111 content::Details<TabContents>(tab_contents_)); |
| 122 } | 112 } |
| 123 | 113 |
| 124 void ScriptBadgeController::DidNavigateMainFrame( | 114 void ScriptBadgeController::DidNavigateMainFrame( |
| 125 const content::LoadCommittedDetails& details, | 115 const content::LoadCommittedDetails& details, |
| 126 const content::FrameNavigateParams& params) { | 116 const content::FrameNavigateParams& params) { |
| 127 extensions_executing_scripts_.clear(); | 117 extensions_executing_scripts_.clear(); |
| 118 current_actions_.clear(); |
| 119 } |
| 120 |
| 121 void ScriptBadgeController::Observe( |
| 122 int type, |
| 123 const content::NotificationSource& source, |
| 124 const content::NotificationDetails& details) { |
| 125 DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNLOADED); |
| 126 const Extension* extension = |
| 127 content::Details<UnloadedExtensionInfo>(details)->extension; |
| 128 if (EraseExtension(extension)) |
| 129 Notify(); |
| 128 } | 130 } |
| 129 | 131 |
| 130 bool ScriptBadgeController::OnMessageReceived(const IPC::Message& message) { | 132 bool ScriptBadgeController::OnMessageReceived(const IPC::Message& message) { |
| 131 bool handled = true; | 133 bool handled = true; |
| 132 IPC_BEGIN_MESSAGE_MAP(ScriptBadgeController, message) | 134 IPC_BEGIN_MESSAGE_MAP(ScriptBadgeController, message) |
| 133 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting, | 135 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting, |
| 134 OnContentScriptsExecuting) | 136 OnContentScriptsExecuting) |
| 135 IPC_MESSAGE_UNHANDLED(handled = false) | 137 IPC_MESSAGE_UNHANDLED(handled = false) |
| 136 IPC_END_MESSAGE_MAP() | 138 IPC_END_MESSAGE_MAP() |
| 137 return handled; | 139 return handled; |
| 138 } | 140 } |
| 139 | 141 |
| 140 void ScriptBadgeController::OnContentScriptsExecuting( | 142 void ScriptBadgeController::OnContentScriptsExecuting( |
| 141 const std::set<std::string>& extension_ids, int32 page_id) { | 143 const std::set<std::string>& extension_ids, int32 page_id) { |
| 142 if (page_id == GetPageID()) { | 144 if (page_id != GetPageID()) |
| 143 size_t original_size = extensions_executing_scripts_.size(); | 145 return; |
| 144 extensions_executing_scripts_.insert(extension_ids.begin(), | 146 |
| 145 extension_ids.end()); | 147 bool changed = false; |
| 146 if (extensions_executing_scripts_.size() > original_size) | 148 for (std::set<std::string>::const_iterator it = extension_ids.begin(); |
| 147 Notify(); | 149 it != extension_ids.end(); ++it) { |
| 150 changed |= InsertExtension(*it); |
| 148 } | 151 } |
| 152 if (changed) |
| 153 Notify(); |
| 154 } |
| 155 |
| 156 bool ScriptBadgeController::InsertExtension(const std::string& extension_id) { |
| 157 if (!extensions_executing_scripts_.insert(extension_id).second) |
| 158 return false; |
| 159 |
| 160 ExtensionService* service = GetExtensionService(); |
| 161 if (!service) |
| 162 return false; |
| 163 |
| 164 const Extension* extension = service->extensions()->GetByID(extension_id); |
| 165 if (!extension) |
| 166 return false; |
| 167 |
| 168 current_actions_.push_back(extension->GetScriptBadge()); |
| 169 return true; |
| 170 } |
| 171 |
| 172 |
| 173 bool ScriptBadgeController::EraseExtension(const Extension* extension) { |
| 174 if (extensions_executing_scripts_.erase(extension->id()) == 0) |
| 175 return false; |
| 176 |
| 177 size_t size_before = current_actions_.size(); |
| 178 |
| 179 for (std::vector<ExtensionAction*>::iterator it = current_actions_.begin(); |
| 180 it != current_actions_.end(); ++it) { |
| 181 // Safe to -> the extension action because we still have a handle to the |
| 182 // owner Extension. |
| 183 // |
| 184 // Also note that this means that when extensions are uninstalled their |
| 185 // script badges will disappear, even though they're still acting on the |
| 186 // page (since they would have already acted). |
| 187 if ((*it)->extension_id() == extension->id()) { |
| 188 current_actions_.erase(it); |
| 189 break; |
| 190 } |
| 191 } |
| 192 |
| 193 CHECK_EQ(size_before, current_actions_.size() + 1); |
| 194 return true; |
| 149 } | 195 } |
| 150 | 196 |
| 151 } // namespace extensions | 197 } // namespace extensions |
| OLD | NEW |