| 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 | 
|---|