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 9dd0b0b8ef5afb5d5b29642615de9e1bdcd9adc6..90c1ecef0292ab59ade0a3a72739314438a0167a 100644 |
| --- a/chrome/browser/ui/toolbar/action_box_button_controller.cc |
| +++ b/chrome/browser/ui/toolbar/action_box_button_controller.cc |
| @@ -5,22 +5,43 @@ |
| #include "chrome/browser/ui/toolbar/action_box_button_controller.h" |
| #include "base/logging.h" |
| +#include "base/utf_string_conversions.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/browser_tabstrip.h" |
| #include "chrome/browser/ui/toolbar/action_box_menu_model.h" |
| #include "chrome/common/chrome_notification_types.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.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 { |
| -// Extensions get command IDs that are beyond the maximal valid command ID |
| +// 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. For more details see: chrome/app/chrome_command_ids.h |
| -const int kFirstExtensionCommandId = 0xE000; |
| +// 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 { |
| + kCWSFindShareIntentsCommandId = 0xE000, |
|
sky
2012/10/11 23:36:25
Enums use ALL_CAPS style.
skare_
2012/10/12 01:02:06
Done.
Switched to IDC_* names for command ids even
sky
2012/10/12 14:33:25
Don't do that, it's easy to misread when using IDC
skare_
2012/10/12 20:21:07
Done.
|
| + kFirstShareIntentCommandId, |
| + kLastShareIntentCommandId = |
| + kFirstShareIntentCommandId + kMaxShareItemsToShow - 1, |
| + kFirstExtensionCommandId |
| +}; |
| + |
| +const char kShareIntentAction[] = "http://webintents.org/share"; |
| +const char kShareIntentMimeType[] = "text/uri-list"; |
| } // namespace |
| @@ -28,7 +49,9 @@ ActionBoxButtonController::ActionBoxButtonController(Browser* browser, |
| Delegate* delegate) |
| : browser_(browser), |
| delegate_(delegate), |
| - next_extension_command_id_(kFirstExtensionCommandId) { |
| + next_share_intent_command_id_(kFirstShareIntentCommandId), |
| + next_extension_command_id_(kFirstExtensionCommandId), |
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| DCHECK(browser_); |
| DCHECK(delegate_); |
| registrar_.Add(this, |
| @@ -36,15 +59,46 @@ ActionBoxButtonController::ActionBoxButtonController(Browser* browser, |
| content::Source<Profile>(browser->profile())); |
| } |
| -ActionBoxButtonController::~ActionBoxButtonController() {} |
| +ActionBoxButtonController::~ActionBoxButtonController() { |
| + weak_ptr_factory_.InvalidateWeakPtrs(); |
|
sky
2012/10/11 23:36:25
Isn't this done for you by the destructor of WeakP
skare_
2012/10/12 01:02:06
Done.
|
| +} |
| void ActionBoxButtonController::OnButtonClicked() { |
| - // Creating the action box menu will populate it with the bookmark star etc, |
| - // but no extensions. |
| + // Request registered share intents; populate and show menu in the callback. |
| + WebIntentsRegistry* intents_registry = |
| + WebIntentsRegistryFactory::GetForProfile(browser_->profile()); |
| + intents_registry->GetIntentServices( |
| + ASCIIToUTF16(kShareIntentAction), |
| + ASCIIToUTF16(kShareIntentMimeType), |
| + base::Bind( |
| + &ActionBoxButtonController::OnWebIntentServicesAvailable, |
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +void ActionBoxButtonController::OnWebIntentServicesAvailable( |
| + const std::vector<webkit_glue::WebIntentServiceData>& services) { |
| scoped_ptr<ActionBoxMenuModel> menu_model( |
| new ActionBoxMenuModel(browser_, this)); |
| - // Add the extensions. |
| + // Add Share intent items. |
| + next_share_intent_command_id_ = kFirstShareIntentCommandId; |
| + share_intent_service_ids_.clear(); |
| + for (size_t i = 0; i < services.size(); ++i) { |
| + int command_id = next_share_intent_command_id_++; |
| + if (command_id > kLastShareIntentCommandId) { |
| + break; |
| + } |
| + share_intent_service_ids_[command_id] = services[i].service_url; |
| + menu_model->AddItem(command_id, services[i].title); |
| + } |
| + |
| + // Add link to the Web Store to find additional share intents. |
| + menu_model->AddItemWithStringId(kCWSFindShareIntentsCommandId, |
| + IDS_FIND_SHARE_INTENTS); |
| + |
| + // Add Extensions. |
| + next_extension_command_id_ = kFirstExtensionCommandId; |
| + extension_command_ids_.clear(); |
| ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(browser_->profile())-> |
| extension_service(); |
| @@ -55,6 +109,7 @@ void ActionBoxButtonController::OnButtonClicked() { |
| menu_model->AddExtension(**it, GetCommandIdForExtension(**it)); |
| } |
| + // And show the menu. |
|
sky
2012/10/11 23:36:25
How do you know how long it takes to get the servi
skare_
2012/10/12 01:02:06
is the pattern to watch for closed and then cancel
sky
2012/10/12 14:33:25
I don't know that there is anything you could look
skare_
2012/10/12 20:21:07
Resolved -- in the latest revision the population
|
| delegate_->ShowMenu(menu_model.Pass()); |
| } |
| @@ -73,7 +128,19 @@ bool ActionBoxButtonController::GetAcceleratorForCommandId( |
| } |
| void ActionBoxButtonController::ExecuteCommand(int command_id) { |
| - // It might be a command associated with an extension. |
| + // 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 == kCWSFindShareIntentsCommandId) { |
| + 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 = |
| @@ -86,6 +153,7 @@ void ActionBoxButtonController::ExecuteCommand(int command_id) { |
| return; |
| } |
| + // Otherwise, let the browser handle the command. |
| chrome::ExecuteCommand(browser_, command_id); |
| } |
| @@ -133,3 +201,32 @@ void ActionBoxButtonController::Observe( |
| // We may also want to listen to EXTENSION_LOADED to do the opposite. |
| extension_command_ids_.erase(extension->id()); |
| } |
| + |
| +void ActionBoxButtonController::NavigateToWebStoreShareIntentsList() { |
|
sky
2012/10/11 23:36:25
make order match header.
skare_
2012/10/12 01:02:06
Done.
|
| + Profile* profile = Profile::FromBrowserContext( |
|
sky
2012/10/11 23:36:25
browser_->profile()
skare_
2012/10/12 01:02:06
done and inlined below, thanks.
|
| + chrome::GetActiveWebContents(browser_)->GetBrowserContext()); |
| + if (!profile) |
|
sky
2012/10/11 23:36:25
Remove this.
skare_
2012/10/12 01:02:06
Done.
|
| + return; |
| + GURL query_url = extension_urls::GetWebstoreIntentQueryURL( |
| + "http://webintents.org/share", |
| + "text/uri-list"); |
| + |
| + chrome::NavigateParams params(profile, query_url, |
| + content::PAGE_TRANSITION_LINK); |
| + params.disposition = NEW_FOREGROUND_TAB; |
| + chrome::Navigate(¶ms); |
| +} |
| + |
| +void ActionBoxButtonController::TriggerExplicitShareIntent( |
| + const GURL& share_service_url) { |
| + const GURL& current_url = chrome::GetActiveWebContents(browser_)->GetURL(); |
| + webkit_glue::WebIntentData intent_data( |
| + ASCIIToUTF16(kShareIntentAction), |
| + ASCIIToUTF16(kShareIntentMimeType), |
| + UTF8ToUTF16(current_url.spec())); |
| + intent_data.service = share_service_url; |
| + scoped_ptr<content::WebIntentsDispatcher> dispatcher( |
| + content::WebIntentsDispatcher::Create(intent_data)); |
| + static_cast<content::WebContentsDelegate*>(browser_)-> |
| + WebIntentDispatch(NULL, dispatcher.release()); |
| +} |