Index: chrome/browser/extensions/api/extension_action/extension_action_api.cc |
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc |
index 98e73ee428297faf8f31e47801af00e6872994d5..cd27e5386d67ff4b08fac292d03afc0cb34dd0fe 100644 |
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc |
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc |
@@ -4,8 +4,6 @@ |
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
-#include <string> |
- |
#include "base/base64.h" |
#include "base/lazy_instance.h" |
#include "base/strings/string_number_conversions.h" |
@@ -17,6 +15,7 @@ |
#include "chrome/browser/extensions/extension_action.h" |
#include "chrome/browser/extensions/extension_action_manager.h" |
#include "chrome/browser/extensions/extension_function_registry.h" |
+#include "chrome/browser/extensions/extension_host.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/extension_system.h" |
#include "chrome/browser/extensions/extension_tab_util.h" |
@@ -59,6 +58,7 @@ const char kNoTabError[] = "No tab with id: *."; |
const char kNoPageActionError[] = |
"This extension has no page action specified."; |
const char kUrlNotActiveError[] = "This url is no longer active: *."; |
+const char kInternalError[] = "Internal error."; |
struct IconRepresentationInfo { |
// Size as a string that will be used to retrieve representation value from |
@@ -209,6 +209,7 @@ ExtensionActionAPI::ExtensionActionAPI(Profile* profile) { |
registry->RegisterFunction<BrowserActionGetPopupFunction>(); |
registry->RegisterFunction<BrowserActionEnableFunction>(); |
registry->RegisterFunction<BrowserActionDisableFunction>(); |
+ registry->RegisterFunction<BrowserActionOpenPopupFunction>(); |
// Page Actions |
registry->RegisterFunction<EnablePageActionsFunction>(); |
@@ -805,6 +806,60 @@ bool ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() { |
return true; |
} |
+BrowserActionOpenPopupFunction::BrowserActionOpenPopupFunction() |
+ : response_sent_(false) { |
+} |
+ |
+bool BrowserActionOpenPopupFunction::RunImpl() { |
+ ExtensionToolbarModel* model = extensions::ExtensionSystem::Get(profile_)-> |
+ extension_service()->toolbar_model(); |
+ if (!model) { |
+ error_ = kInternalError; |
+ return false; |
+ } |
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
+ content::Source<Profile>(profile_)); |
+ model->ShowBrowserActionPopup(extension_); |
+ |
+ // Set a timeout for waiting for the notification that the popup is loaded. |
+ // Waiting is required so that the popup view can be retrieved by the custom |
+ // bindings for the response callback. It's also needed to keep this function |
+ // instance around until a notification is observed. |
+ base::MessageLoopForUI::current()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&BrowserActionOpenPopupFunction::OpenPopupTimedOut, this), |
+ base::TimeDelta::FromSeconds(1)); |
+ return true; |
+} |
+ |
+void BrowserActionOpenPopupFunction::OpenPopupTimedOut() { |
+ if (response_sent_) |
+ return; |
+ |
+ DVLOG(1) << "chrome.browserAction.openPopup did not show a popup."; |
+ // Custom binding will still try to get the popup, but may fail. |
+ SendResponse(false); |
+ response_sent_ = true; |
+} |
+ |
+void BrowserActionOpenPopupFunction::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING); |
+ if (response_sent_) |
+ return; |
+ |
+ ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
+ if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || |
+ host->extension()->id() != extension_->id()) |
+ return; |
+ |
+ SendResponse(true); |
+ response_sent_ = true; |
+ registrar_.RemoveAll(); |
+} |
+ |
// |
// ScriptBadgeGetAttentionFunction |
// |