Chromium Code Reviews| Index: chrome/browser/ui/toolbar/action_box_button_controller.cc |
| diff --git a/chrome/browser/ui/toolbar/action_box_button_controller.cc b/chrome/browser/ui/toolbar/action_box_button_controller.cc |
| index 51c8c8fad952ee630b3b3fdbade8020855bce98b..8e245270e4a7c32b094bf0cd225845df476c2599 100644 |
| --- a/chrome/browser/ui/toolbar/action_box_button_controller.cc |
| +++ b/chrome/browser/ui/toolbar/action_box_button_controller.cc |
| @@ -7,60 +7,37 @@ |
| #include "base/logging.h" |
| #include "base/metrics/histogram.h" |
| #include "base/utf_string_conversions.h" |
| +#include "chrome/app/chrome_command_ids.h" |
| +#include "chrome/browser/extensions/api/page_launcher/page_launcher_api.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_system.h" |
| -#include "chrome/browser/intents/web_intents_registry_factory.h" |
| -#include "chrome/browser/intents/web_intents_registry.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/toolbar/action_box_menu_model.h" |
| #include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/extensions/api/extension_action/action_info.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "chrome/common/extensions/extension_set.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/browser/user_metrics.h" |
| #include "content/public/browser/web_contents.h" |
| -#include "content/public/browser/web_intents_dispatcher.h" |
| -#include "grit/generated_resources.h" |
| -#include "webkit/glue/web_intent_data.h" |
| -#include "webkit/glue/webkit_glue.h" |
| - |
| -namespace { |
| - |
| -// This indicates we need to send UMA data about the number of |
| -// "Share with X" commands shown in the menu after user tried to |
| -// find share extensions from web store or the first use of action |
| -// box after browser starts. |
| -static bool send_uma_share_command_count = true; |
| - |
| -// Share intents get command IDs that are beyond the maximal valid command ID |
| -// (0xDFFF) so that they are not confused with actual commands that appear in |
| -// the menu. Extensions get a reserved block of commands after share handlers. |
| -// For more details see: chrome/app/chrome_command_ids.h |
| -const int kMaxShareItemsToShow = 20; // TODO(skare): Show extras in submenu. |
| -enum ActionBoxLocalCommandIds { |
| - CWS_FIND_SHARE_INTENTS_COMMAND = 0xE000, |
| - SHARE_COMMAND_FIRST, |
| - SHARE_COMMAND_LAST = |
| - SHARE_COMMAND_FIRST + kMaxShareItemsToShow - 1, |
| - EXTENSION_COMMAND_FIRST |
| -}; |
| - |
| -const char kShareIntentAction[] = "http://webintents.org/share"; |
| -const char kShareIntentMimeType[] = "text/uri-list"; |
| - |
| -} // namespace |
| using content::UserMetricsAction; |
| +using content::WebContents; |
| +using extensions::ActionInfo; |
| + |
| +void ActionBoxButtonController::Delegate::ShowMenu( |
| + scoped_ptr<ActionBoxMenuModel> menu_model) { |
| +} |
| ActionBoxButtonController::ActionBoxButtonController(Browser* browser, |
| Delegate* delegate) |
| : browser_(browser), |
| delegate_(delegate), |
| - next_extension_command_id_(EXTENSION_COMMAND_FIRST) { |
| + next_command_id_(0) { |
| DCHECK(browser_); |
| DCHECK(delegate_); |
| registrar_.Add(this, |
| @@ -75,60 +52,18 @@ void ActionBoxButtonController::OnButtonClicked() { |
| scoped_ptr<ActionBoxMenuModel> menu_model( |
| new ActionBoxMenuModel(browser_, this)); |
| - // Add share intent triggers and a link to the web store. |
| - // Web Intents are not currently supported in Incognito mode. |
| - ExtensionService* extension_service = |
| + const ExtensionSet* extensions = |
| extensions::ExtensionSystem::Get(browser_->profile())-> |
| - extension_service(); |
| - if (!browser_->profile()->IsOffTheRecord()) { |
| - int next_share_intent_command_id = SHARE_COMMAND_FIRST; |
| - share_intent_service_ids_.clear(); |
| - const ExtensionSet* extension_set = extension_service->extensions(); |
| - WebIntentsRegistry* intents_registry = |
| - WebIntentsRegistryFactory::GetForProfile(browser_->profile()); |
| - for (ExtensionSet::const_iterator it = extension_set->begin(); |
| - it != extension_set->end(); ++it) { |
| - const extensions::Extension* extension = *it; |
| - WebIntentsRegistry::IntentServiceList services; |
| - intents_registry->GetIntentServicesForExtensionFilter( |
| - ASCIIToUTF16(kShareIntentAction), |
| - ASCIIToUTF16(kShareIntentMimeType), |
| - extension->id(), |
| - &services); |
| - if (!services.empty()) { |
| - int command_id = next_share_intent_command_id++; |
| - if (command_id > SHARE_COMMAND_LAST) |
| - break; |
| - // TODO(skare): If an intent supports multiple services, be able to |
| - // disambiguate. Choosing the first matches the picker behavior; see |
| - // TODO in WebIntentPickerController::DispatchToInstalledExtension. |
| - share_intent_service_ids_[command_id] = services[0].service_url; |
| - menu_model->AddItem(command_id, services[0].title); |
| - } |
| + extension_service()->extensions(); |
| + for (ExtensionSet::const_iterator iter = extensions->begin(); |
|
not at google - send to devlin
2013/02/01 16:39:47
nit: this class uses "it" everywhere for iterator
Rune Fevang
2013/02/01 22:12:54
Done.
|
| + iter != extensions->end(); ++iter) { |
| + const extensions::Extension* extension = *iter; |
| + if (ActionInfo::GetPageLauncherInfo(extension)) { |
| + int command_id = GetCommandIdForExtension(*extension); |
| + menu_model->AddExtension(*extension, command_id); |
| } |
| - |
| - // Add link to the Web Store to find additional share intents. |
| - menu_model->AddItemWithStringId(CWS_FIND_SHARE_INTENTS_COMMAND, |
| - IDS_FIND_SHARE_INTENTS); |
| - |
| - content::RecordAction(UserMetricsAction("ActionBox.ClickButton")); |
| - if (send_uma_share_command_count) { |
| - UMA_HISTOGRAM_ENUMERATION("ActionBox.ShareCommandCount", |
| - next_share_intent_command_id - SHARE_COMMAND_FIRST, |
| - kMaxShareItemsToShow + 1); |
| - send_uma_share_command_count = false; |
| - } |
| - } |
| - |
| - // Add Extensions. |
| - next_extension_command_id_ = EXTENSION_COMMAND_FIRST; |
| - extension_command_ids_.clear(); |
| - const extensions::ExtensionList& extensions = |
| - extension_service->toolbar_model()->action_box_menu_items(); |
| - for (extensions::ExtensionList::const_iterator it = extensions.begin(); |
| - it != extensions.end(); ++it) { |
| - menu_model->AddExtension(**it, GetCommandIdForExtension(**it)); |
| } |
| + content::RecordAction(UserMetricsAction("ActionBox.ClickButton")); |
| // And show the menu. |
| delegate_->ShowMenu(menu_model.Pass()); |
| @@ -149,28 +84,21 @@ bool ActionBoxButtonController::GetAcceleratorForCommandId( |
| } |
| void ActionBoxButtonController::ExecuteCommand(int command_id) { |
| - // Handle explicit intent triggers for share intent commands. |
| - if (share_intent_service_ids_.count(command_id) > 0) { |
| - TriggerExplicitShareIntent(share_intent_service_ids_[command_id]); |
| - return; |
| - } |
| - |
| - // Handle link to the CWS web store. |
| - if (command_id == CWS_FIND_SHARE_INTENTS_COMMAND) { |
| - NavigateToWebStoreShareIntentsList(); |
| - return; |
| - } |
| - |
| - // Handle commands associated with extensions. |
| - // Note that the extension might have been uninstalled or disabled while the |
| - // menu was open (sync perhaps?) but that will just fall through safely. |
| - const extensions::Extension* extension = |
| - GetExtensionForCommandId(command_id); |
| - if (extension) { |
| - // TODO(kalman): do something with the result. |
| - extensions::ExtensionSystem::Get(browser_->profile())-> |
| - extension_service()->toolbar_model()->ExecuteBrowserAction( |
| - extension, browser_, NULL); |
| + // If the command id belongs to an extension, dispatch an onClicked event |
| + // to its pageLauncher. |
| + ExtensionIdCommandMap::const_iterator it = |
| + extension_command_ids_.find(command_id); |
| + if (it != extension_command_ids_.end()) { |
| + WebContents* web_contents = |
| + browser_->tab_strip_model()->GetActiveWebContents(); |
| + // TODO(rfevang): Send page title and selected text. |
| + extensions::PageLauncherAPI::DispatchOnClickedEvent( |
| + browser_->profile(), |
| + it->second, |
| + web_contents->GetURL().spec(), |
|
not at google - send to devlin
2013/02/01 16:39:47
send the url as a GURL?
Rune Fevang
2013/02/01 22:12:54
Done.
|
| + web_contents->GetContentsMimeType(), |
| + scoped_ptr<std::string>(), |
| + scoped_ptr<std::string>()); |
| return; |
| } |
| @@ -180,34 +108,33 @@ void ActionBoxButtonController::ExecuteCommand(int command_id) { |
| int ActionBoxButtonController::GetCommandIdForExtension( |
| const extensions::Extension& extension) { |
| - ExtensionIdCommandMap::iterator it = |
| - extension_command_ids_.find(extension.id()); |
| - if (it != extension_command_ids_.end()) |
| - return it->second; |
| - int command_id = next_extension_command_id_++; |
| - |
| - // Note that we deliberately don't clean up extension IDs here when |
| - // extensions are unloaded, so that if they're reloaded they get assigned the |
| - // old command ID. This situation could arise if an extension is updated |
| - // while the menu is open. On the other hand, we leak some memory... but |
| - // that's unlikely to matter. |
| - extension_command_ids_[extension.id()] = command_id; |
| + for (ExtensionIdCommandMap::const_iterator iter = |
|
not at google - send to devlin
2013/02/01 16:39:47
iter -> it rename is arbitrary, please revert (als
Rune Fevang
2013/02/01 22:12:54
Done.
|
| + extension_command_ids_.begin(); |
| + iter != extension_command_ids_.end(); ++iter) { |
| + if (iter->second == extension.id()) { |
| + return iter->first; |
| + } |
|
not at google - send to devlin
2013/02/01 16:39:47
single-line ifs omit {}
Rune Fevang
2013/02/01 22:12:54
Done.
|
| + } |
| + |
| + int command_id = GetNextCommandId(); |
| + extension_command_ids_[command_id] = extension.id(); |
| return command_id; |
| } |
| -const extensions::Extension* |
| - ActionBoxButtonController::GetExtensionForCommandId(int command_id) { |
| - for (ExtensionIdCommandMap::iterator it = extension_command_ids_.begin(); |
| - it != extension_command_ids_.end(); ++it) { |
| - if (it->second == command_id) { |
| - // Note: might be NULL anyway if the extension has been uninstalled. |
| - return extensions::ExtensionSystem::Get(browser_->profile())-> |
| - extension_service()->extensions()->GetByID(it->first); |
| - } |
| - } |
| +int ActionBoxButtonController::GetNextCommandId() { |
| + int command_id = next_command_id_; |
| + // Find an available command id to return next time the function is called. |
| + do { |
| + next_command_id_++; |
| + // Larger command ids are reserved for non-dynamic entries, so we start |
| + // reusing old ids at this point. |
| + if (next_command_id_ >= IDC_MinimumLabelValue) |
| + next_command_id_ = 0; |
| + } while (extension_command_ids_.find(next_command_id_) != |
| + extension_command_ids_.end()); |
| - return NULL; |
| + return command_id; |
| } |
| void ActionBoxButtonController::Observe( |
| @@ -218,33 +145,15 @@ void ActionBoxButtonController::Observe( |
| const extensions::Extension* extension = |
| content::Details<extensions::UnloadedExtensionInfo>(details)->extension; |
| + // Remove any entry point command ids associated with the extension. |
| + for (ExtensionIdCommandMap::iterator iter = extension_command_ids_.begin(); |
|
not at google - send to devlin
2013/02/01 16:39:47
ditto
Rune Fevang
2013/02/01 22:12:54
Done.
|
| + iter != extension_command_ids_.end();) { |
| + if (iter->second== extension->id()) { |
| + extension_command_ids_.erase(iter++); |
| + } else { |
| + ++iter; |
| + } |
|
not at google - send to devlin
2013/02/01 16:39:47
single-line ifs omit {}
Rune Fevang
2013/02/01 22:12:54
Done.
|
| + } |
| // TODO(kalman): if there's a menu open, remove it from that too. |
| // We may also want to listen to EXTENSION_LOADED to do the opposite. |
| - extension_command_ids_.erase(extension->id()); |
| -} |
| - |
| -void ActionBoxButtonController::TriggerExplicitShareIntent( |
| - const GURL& share_service_url) { |
| - const GURL& current_url = |
| - browser_->tab_strip_model()->GetActiveWebContents()->GetURL(); |
| - webkit_glue::WebIntentData intent_data( |
| - ASCIIToUTF16(kShareIntentAction), |
| - ASCIIToUTF16(kShareIntentMimeType), |
| - UTF8ToUTF16(current_url.spec())); |
| - intent_data.service = share_service_url; |
| - static_cast<content::WebContentsDelegate*>(browser_)->WebIntentDispatch( |
| - NULL, content::WebIntentsDispatcher::Create(intent_data)); |
| -} |
| - |
| -void ActionBoxButtonController::NavigateToWebStoreShareIntentsList() { |
| - const GURL& query_url = extension_urls::GetWebstoreIntentQueryURL( |
| - kShareIntentAction, |
| - kShareIntentMimeType); |
| - chrome::NavigateParams params(browser_->profile(), query_url, |
| - content::PAGE_TRANSITION_LINK); |
| - params.disposition = NEW_FOREGROUND_TAB; |
| - chrome::Navigate(¶ms); |
| - |
| - content::RecordAction(UserMetricsAction("ActionBox.FindShareHandlers")); |
| - send_uma_share_command_count = true; |
| } |