 Chromium Code Reviews
 Chromium Code Reviews Issue 10544185:
  Order the script badges in the location bar consistently  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master
    
  
    Issue 10544185:
  Order the script badges in the location bar consistently  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master| 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 scoped_ptr<std::vector<ExtensionAction*> > | 
| 32 ScriptBadgeController::GetCurrentActions() { | 36 ScriptBadgeController::GetCurrentActions() { | 
| 33 scoped_ptr<std::vector<ExtensionAction*> > current_actions( | 37 return make_scoped_ptr<std::vector<ExtensionAction*> >(current_actions_); | 
| 
Aaron Boodman
2012/06/17 14:44:31
Nice utility. Sorry for assuming it was jyasskin's
 | |
| 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 } | 38 } | 
| 48 | 39 | 
| 49 LocationBarController::Action ScriptBadgeController::OnClicked( | 40 LocationBarController::Action ScriptBadgeController::OnClicked( | 
| 50 const std::string& extension_id, int mouse_button) { | 41 const std::string& extension_id, int mouse_button) { | 
| 51 ExtensionService* service = GetExtensionService(); | 42 ExtensionService* service = GetExtensionService(); | 
| 52 if (!service) | 43 if (!service) | 
| 53 return ACTION_NONE; | 44 return ACTION_NONE; | 
| 54 | 45 | 
| 55 const Extension* extension = service->extensions()->GetByID(extension_id); | 46 const Extension* extension = service->extensions()->GetByID(extension_id); | 
| 56 CHECK(extension); | 47 CHECK(extension); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 this_callback); | 82 this_callback); | 
| 92 } | 83 } | 
| 93 | 84 | 
| 94 void ScriptBadgeController::OnExecuteScriptFinished( | 85 void ScriptBadgeController::OnExecuteScriptFinished( | 
| 95 const std::string& extension_id, | 86 const std::string& extension_id, | 
| 96 const ExecuteScriptCallback& callback, | 87 const ExecuteScriptCallback& callback, | 
| 97 bool success, | 88 bool success, | 
| 98 int32 page_id, | 89 int32 page_id, | 
| 99 const std::string& error) { | 90 const std::string& error) { | 
| 100 if (success && page_id == GetPageID()) { | 91 if (success && page_id == GetPageID()) { | 
| 101 extensions_executing_scripts_.insert(extension_id); | 92 if (InsertExtension(extension_id)) | 
| 102 Notify(); | 93 Notify(); | 
| 103 } | 94 } | 
| 104 | 95 | 
| 105 callback.Run(success, page_id, error); | 96 callback.Run(success, page_id, error); | 
| 106 } | 97 } | 
| 107 | 98 | 
| 108 ExtensionService* ScriptBadgeController::GetExtensionService() { | 99 ExtensionService* ScriptBadgeController::GetExtensionService() { | 
| 109 return ExtensionSystem::Get(tab_contents_->profile())->extension_service(); | 100 return ExtensionSystem::Get(tab_contents_->profile())->extension_service(); | 
| 110 } | 101 } | 
| 111 | 102 | 
| 112 int32 ScriptBadgeController::GetPageID() { | 103 int32 ScriptBadgeController::GetPageID() { | 
| 113 return tab_contents_->web_contents()->GetController().GetActiveEntry()-> | 104 return tab_contents_->web_contents()->GetController().GetActiveEntry()-> | 
| 114 GetPageID(); | 105 GetPageID(); | 
| 115 } | 106 } | 
| 116 | 107 | 
| 117 void ScriptBadgeController::Notify() { | 108 void ScriptBadgeController::Notify() { | 
| 118 content::NotificationService::current()->Notify( | 109 content::NotificationService::current()->Notify( | 
| 119 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | 110 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | 
| 120 content::Source<Profile>(tab_contents_->profile()), | 111 content::Source<Profile>(tab_contents_->profile()), | 
| 121 content::Details<TabContents>(tab_contents_)); | 112 content::Details<TabContents>(tab_contents_)); | 
| 122 } | 113 } | 
| 123 | 114 | 
| 124 void ScriptBadgeController::DidNavigateMainFrame( | 115 void ScriptBadgeController::DidNavigateMainFrame( | 
| 125 const content::LoadCommittedDetails& details, | 116 const content::LoadCommittedDetails& details, | 
| 126 const content::FrameNavigateParams& params) { | 117 const content::FrameNavigateParams& params) { | 
| 127 extensions_executing_scripts_.clear(); | 118 extensions_executing_scripts_.clear(); | 
| 119 current_actions_.clear(); | |
| 120 } | |
| 121 | |
| 122 void ScriptBadgeController::Observe( | |
| 123 int type, | |
| 124 const content::NotificationSource& source, | |
| 125 const content::NotificationDetails& details) { | |
| 126 DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNLOADED); | |
| 127 const Extension* extension = | |
| 128 content::Details<UnloadedExtensionInfo>(details)->extension; | |
| 129 if (EraseExtension(extension)) | |
| 130 Notify(); | |
| 128 } | 131 } | 
| 129 | 132 | 
| 130 bool ScriptBadgeController::OnMessageReceived(const IPC::Message& message) { | 133 bool ScriptBadgeController::OnMessageReceived(const IPC::Message& message) { | 
| 131 bool handled = true; | 134 bool handled = true; | 
| 132 IPC_BEGIN_MESSAGE_MAP(ScriptBadgeController, message) | 135 IPC_BEGIN_MESSAGE_MAP(ScriptBadgeController, message) | 
| 133 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting, | 136 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting, | 
| 134 OnContentScriptsExecuting) | 137 OnContentScriptsExecuting) | 
| 135 IPC_MESSAGE_UNHANDLED(handled = false) | 138 IPC_MESSAGE_UNHANDLED(handled = false) | 
| 136 IPC_END_MESSAGE_MAP() | 139 IPC_END_MESSAGE_MAP() | 
| 137 return handled; | 140 return handled; | 
| 138 } | 141 } | 
| 139 | 142 | 
| 140 void ScriptBadgeController::OnContentScriptsExecuting( | 143 void ScriptBadgeController::OnContentScriptsExecuting( | 
| 141 const std::set<std::string>& extension_ids, int32 page_id) { | 144 const std::set<std::string>& extension_ids, int32 page_id) { | 
| 142 if (page_id == GetPageID()) { | 145 if (page_id != GetPageID()) | 
| 143 size_t original_size = extensions_executing_scripts_.size(); | 146 return; | 
| 144 extensions_executing_scripts_.insert(extension_ids.begin(), | 147 | 
| 145 extension_ids.end()); | 148 bool changed = false; | 
| 146 if (extensions_executing_scripts_.size() > original_size) | 149 for (std::set<std::string>::const_iterator it = extension_ids.begin(); | 
| 147 Notify(); | 150 it != extension_ids.end(); ++it) { | 
| 151 changed |= InsertExtension(*it); | |
| 148 } | 152 } | 
| 153 if (changed) | |
| 154 Notify(); | |
| 155 } | |
| 156 | |
| 157 bool ScriptBadgeController::InsertExtension(const std::string& extension_id) { | |
| 158 if (!extensions_executing_scripts_.insert(extension_id).second) | |
| 159 return false; | |
| 160 | |
| 161 ExtensionService* service = GetExtensionService(); | |
| 162 if (!service) | |
| 163 return false; | |
| 164 | |
| 165 const Extension* extension = service->extensions()->GetByID(extension_id); | |
| 166 if (!extension) | |
| 167 return false; | |
| 168 | |
| 169 current_actions_.push_back(extension->GetScriptBadge()); | |
| 170 return true; | |
| 171 } | |
| 172 | |
| 173 | |
| 174 bool ScriptBadgeController::EraseExtension(const Extension* extension) { | |
| 175 if (extensions_executing_scripts_.erase(extension->id()) == 0) | |
| 176 return false; | |
| 177 | |
| 178 size_t size_before = current_actions_.size(); | |
| 179 | |
| 180 for (std::vector<ExtensionAction*>::iterator it = current_actions_.begin(); | |
| 181 it != current_actions_.end(); ++it) { | |
| 182 // Safe to -> the extension action because we still have a handle to the | |
| 183 // owner Extension. | |
| 184 // | |
| 185 // Also note that this means that when extensions are uninstalled their | |
| 
Aaron Boodman
2012/06/17 14:44:31
Yeah, tricky. Both keeping it alive and killing it
 | |
| 186 // script badges will disappear, even though they're still acting on the | |
| 187 // page (since they would have already acted). | |
| 188 if ((*it)->extension_id() == extension->id()) { | |
| 189 current_actions_.erase(it); | |
| 190 break; | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 CHECK_EQ(size_before, current_actions_.size() + 1); | |
| 195 return true; | |
| 149 } | 196 } | 
| 150 | 197 | 
| 151 } // namespace extensions | 198 } // namespace extensions | 
| OLD | NEW |