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