summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/automation_extension_function.cc13
-rw-r--r--chrome/browser/automation/automation_extension_function.h12
-rw-r--r--chrome/browser/automation/automation_provider.cc5
-rw-r--r--chrome/browser/automation/automation_provider.h3
-rw-r--r--chrome/browser/extensions/extension_uitest.cc27
-rw-r--r--chrome/test/automation/automation_messages_internal.h7
-rw-r--r--chrome/test/automation/automation_proxy.cc5
-rw-r--r--chrome/test/automation/automation_proxy.h15
-rw-r--r--chrome_frame/chrome_frame_activex.cc13
-rw-r--r--chrome_frame/chrome_frame_automation.cc4
-rw-r--r--chrome_frame/chrome_frame_automation.h11
-rw-r--r--chrome_frame/chrome_frame_npapi.cc11
-rw-r--r--chrome_frame/chrome_frame_npapi_unittest.cc7
-rw-r--r--chrome_frame/chrome_frame_plugin.h9
-rw-r--r--chrome_frame/chrome_tab.idl5
-rw-r--r--chrome_frame/test/chrome_frame_unittests.cc3
16 files changed, 118 insertions, 32 deletions
diff --git a/chrome/browser/automation/automation_extension_function.cc b/chrome/browser/automation/automation_extension_function.cc
index 4bbc89f..70e886a 100644
--- a/chrome/browser/automation/automation_extension_function.cc
+++ b/chrome/browser/automation/automation_extension_function.cc
@@ -51,10 +51,15 @@ ExtensionFunction* AutomationExtensionFunction::Factory() {
return new AutomationExtensionFunction();
}
-void AutomationExtensionFunction::SetEnabled(bool enabled) {
- if (enabled) {
+void AutomationExtensionFunction::SetEnabled(
+ const std::vector<std::string>& functions_enabled) {
+ if (functions_enabled.size() > 0) {
std::vector<std::string> function_names;
- ExtensionFunctionDispatcher::GetAllFunctionNames(&function_names);
+ if (functions_enabled.size() == 1 && functions_enabled[0] == "*") {
+ ExtensionFunctionDispatcher::GetAllFunctionNames(&function_names);
+ } else {
+ function_names = functions_enabled;
+ }
for (std::vector<std::string>::iterator it = function_names.begin();
it != function_names.end(); it++) {
@@ -64,7 +69,7 @@ void AutomationExtensionFunction::SetEnabled(bool enabled) {
// current profile is not that.
bool result = ExtensionFunctionDispatcher::OverrideFunction(
*it, AutomationExtensionFunction::Factory);
- DCHECK(result);
+ LOG_IF(WARNING, !result) << "Failed to override API function: " << *it;
}
} else {
ExtensionFunctionDispatcher::ResetFunctions();
diff --git a/chrome/browser/automation/automation_extension_function.h b/chrome/browser/automation/automation_extension_function.h
index f48adff..d6fac7d 100644
--- a/chrome/browser/automation/automation_extension_function.h
+++ b/chrome/browser/automation/automation_extension_function.h
@@ -27,10 +27,14 @@ class AutomationExtensionFunction : public ExtensionFunction {
static ExtensionFunction* Factory();
- // If enabled, we set an instance of this function as the functor
- // for all function names in ExtensionFunctionFactoryRegistry.
- // If disabled, we restore the initial functions.
- static void SetEnabled(bool enabled);
+ // If the list of enabled functions is non-empty, we enable according to the
+ // list ("*" means enable all, otherwise we enable individual named
+ // functions). If empty, we restore the initial functions.
+ //
+ // Note that all calls to this function, except a call with the empty list,
+ // are additive. Functions previously enabled will remain enabled until
+ // you clear all function forwarding by specifying the empty list.
+ static void SetEnabled(const std::vector<std::string>& functions_enabled);
// Intercepts messages sent from the external host to check if they
// are actually responses to extension API calls. If they are, redirects
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 891b6b7..c28322f 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -1901,8 +1901,9 @@ void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
SavePackage::SetShouldPromptUser(should_prompt);
}
-void AutomationProvider::SetEnableExtensionAutomation(bool automation_enabled) {
- AutomationExtensionFunction::SetEnabled(automation_enabled);
+void AutomationProvider::SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled) {
+ AutomationExtensionFunction::SetEnabled(functions_enabled);
}
void AutomationProvider::GetWindowTitle(int handle, string16* text) {
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 1b5ee7d..44ee790 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -456,7 +456,8 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
void SavePackageShouldPromptUser(bool should_prompt);
// Enables extension automation (for e.g. UITests).
- void SetEnableExtensionAutomation(bool automation_enabled);
+ void SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled);
void GetWindowTitle(int handle, string16* text);
diff --git a/chrome/browser/extensions/extension_uitest.cc b/chrome/browser/extensions/extension_uitest.cc
index 5972f9e..4a16cc8 100644
--- a/chrome/browser/extensions/extension_uitest.cc
+++ b/chrome/browser/extensions/extension_uitest.cc
@@ -33,6 +33,10 @@ static const char kTestDirectoryBrowserEvent[] =
// extension API calls so that behavior can be tested deterministically
// through code, instead of having to contort the browser into a state
// suitable for testing.
+//
+// By default, makes Chrome forward all Chrome Extension API function calls
+// via the automation interface. To override this, call set_functions_enabled()
+// with a list of function names that should be forwarded,
template <class ParentTestType>
class ExtensionUITest : public ParentTestType {
public:
@@ -41,15 +45,21 @@ class ExtensionUITest : public ParentTestType {
filename = filename.AppendASCII(extension_path);
launch_arguments_.AppendSwitchWithValue(switches::kLoadExtension,
filename.value());
+ functions_enabled_.push_back("*");
+ }
+
+ void set_functions_enabled(
+ const std::vector<std::string>& functions_enabled) {
+ functions_enabled_ = functions_enabled;
}
void SetUp() {
ParentTestType::SetUp();
- automation()->SetEnableExtensionAutomation(true);
+ automation()->SetEnableExtensionAutomation(functions_enabled_);
}
void TearDown() {
- automation()->SetEnableExtensionAutomation(false);
+ automation()->SetEnableExtensionAutomation(std::vector<std::string>());
ParentTestType::TearDown();
}
@@ -84,6 +94,10 @@ class ExtensionUITest : public ParentTestType {
virtual void DoAdditionalPreNavigateSetup(TabProxy* tab) {
}
+ protected:
+ // Extension API functions that we want to take over. Defaults to all.
+ std::vector<std::string> functions_enabled_;
+
private:
DISALLOW_COPY_AND_ASSIGN(ExtensionUITest);
};
@@ -103,6 +117,15 @@ class SimpleApiCallExtensionTest : public SingleMessageExtensionUITest {
: SingleMessageExtensionUITest(kTestDirectorySimpleApiCall) {
}
+ void SetUp() {
+ // Set just this one function explicitly to be forwarded, as a test of
+ // the selective forwarding. The next test will leave the default to test
+ // universal forwarding.
+ functions_enabled_.clear();
+ functions_enabled_.push_back("tabs.remove");
+ SingleMessageExtensionUITest::SetUp();
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(SimpleApiCallExtensionTest);
};
diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h
index 174e1d0..69e9c51 100644
--- a/chrome/test/automation/automation_messages_internal.h
+++ b/chrome/test/automation/automation_messages_internal.h
@@ -906,7 +906,10 @@ IPC_BEGIN_MESSAGES(Automation)
// Used to put the browser into "extension automation mode" for the
// current profile, or turn off the mode.
IPC_MESSAGE_ROUTED1(AutomationMsg_SetEnableExtensionAutomation,
- bool /* true to enable extension automation */)
+ std::vector<std::string> /* empty to disable automation,
+ non-empty to enable automation
+ of the specified API
+ functions */)
// This message tells the browser to start using the new proxy configuration
// represented by the given JSON string. The parameters used in the JSON
@@ -1065,7 +1068,7 @@ IPC_BEGIN_MESSAGES(Automation)
AutomationMsg_GoForwardBlockUntilNavigationsComplete, int, int,
AutomationMsg_NavigationResponseValues)
- // This message is used by automaton clients to upload histogram data to the
+ // This message is used by automation clients to upload histogram data to the
// browser process.
IPC_MESSAGE_ROUTED1(AutomationMsg_RecordHistograms,
std::vector<std::string> /* histogram_list */)
diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc
index 28cfe37..4658bf3 100644
--- a/chrome/test/automation/automation_proxy.cc
+++ b/chrome/test/automation/automation_proxy.cc
@@ -220,9 +220,10 @@ bool AutomationProxy::SavePackageShouldPromptUser(bool should_prompt) {
return Send(new AutomationMsg_SavePackageShouldPromptUser(0, should_prompt));
}
-bool AutomationProxy::SetEnableExtensionAutomation(bool enable_automation) {
+bool AutomationProxy::SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled) {
return Send(
- new AutomationMsg_SetEnableExtensionAutomation(0, enable_automation));
+ new AutomationMsg_SetEnableExtensionAutomation(0, functions_enabled));
}
bool AutomationProxy::GetBrowserWindowCount(int* num_windows) {
diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h
index 1e02cff..cf40606 100644
--- a/chrome/test/automation/automation_proxy.h
+++ b/chrome/test/automation/automation_proxy.h
@@ -180,11 +180,22 @@ class AutomationProxy : public IPC::Channel::Listener,
// sent.
bool SavePackageShouldPromptUser(bool should_prompt);
- // Turn extension automation mode on and off. When extension automation
+ // Configure extension automation mode. When extension automation
// mode is turned on, the automation host can overtake extension API calls
// e.g. to make UI tests for extensions easier to write. Returns true if
// the message is successfully sent.
- bool SetEnableExtensionAutomation(bool enable_automation);
+ //
+ // The parameter can take the following types of values:
+ // a) An empty list to turn off extension automation.
+ // b) A list with one item, "*", to turn extension automation on for all
+ // functions.
+ // c) A list with one or more items which are the names of Chrome Extension
+ // API functions that should be forwarded over the automation interface.
+ // Other functions will continue to be fulfilled as normal. This lets you
+ // write tests where some functionality continues to function as normal,
+ // and other functionality is mocked out by the test.
+ bool SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled);
// Returns the ID of the automation IPC channel, so that it can be
// passed to the app as a launch parameter.
diff --git a/chrome_frame/chrome_frame_activex.cc b/chrome_frame/chrome_frame_activex.cc
index 78b09fa..16f5dda 100644
--- a/chrome_frame/chrome_frame_activex.cc
+++ b/chrome_frame/chrome_frame_activex.cc
@@ -337,6 +337,19 @@ HRESULT ChromeFrameActivex::IOleObject_SetClientSite(
chrome_extra_arguments.assign(extra_arguments_arg,
extra_arguments_arg.Length());
+ ScopedBstr automated_functions_arg;
+ service_hr = service->GetExtensionApisToAutomate(
+ automated_functions_arg.Receive());
+ if (S_OK == service_hr && automated_functions_arg) {
+ std::string automated_functions(
+ WideToASCII(static_cast<BSTR>(automated_functions_arg)));
+ functions_enabled_.clear();
+ // SplitString writes one empty entry for blank strings, so we need this
+ // to allow specifying zero automation of API functions.
+ if (!automated_functions.empty())
+ SplitString(automated_functions, ',', &functions_enabled_);
+ }
+
ScopedBstr profile_name_arg;
service_hr = service->GetChromeProfileName(profile_name_arg.Receive());
if (S_OK == service_hr && profile_name_arg)
diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc
index 17fb43d..2d22bbd 100644
--- a/chrome_frame/chrome_frame_automation.cc
+++ b/chrome_frame/chrome_frame_automation.cc
@@ -738,11 +738,11 @@ void ChromeFrameAutomationClient::CreateExternalTabComplete(HWND chrome_window,
}
void ChromeFrameAutomationClient::SetEnableExtensionAutomation(
- bool enable_automation) {
+ const std::vector<std::string>& functions_enabled) {
if (!is_initialized())
return;
- automation_server_->SetEnableExtensionAutomation(enable_automation);
+ automation_server_->SetEnableExtensionAutomation(functions_enabled);
}
// Invoked in launch background thread.
diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h
index e1a34d7..6eca88d 100644
--- a/chrome_frame/chrome_frame_automation.h
+++ b/chrome_frame/chrome_frame_automation.h
@@ -41,7 +41,8 @@ struct DECLSPEC_NOVTABLE ChromeFrameAutomationProxy {
virtual std::string server_version() = 0;
virtual void SendProxyConfig(const std::string&) = 0;
- virtual void SetEnableExtensionAutomation(bool enable) = 0;
+ virtual void SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled) = 0;
protected:
~ChromeFrameAutomationProxy() {}
};
@@ -72,8 +73,9 @@ class ChromeFrameAutomationProxyImpl : public ChromeFrameAutomationProxy,
AutomationProxy::SendProxyConfig(p);
}
- virtual void SetEnableExtensionAutomation(bool e) {
- AutomationProxy::SetEnableExtensionAutomation(e);
+ virtual void SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled) {
+ AutomationProxy::SetEnableExtensionAutomation(functions_enabled);
}
protected:
@@ -202,7 +204,8 @@ class ChromeFrameAutomationClient
const std::string& target);
bool SetProxySettings(const std::string& json_encoded_proxy_settings);
- virtual void SetEnableExtensionAutomation(bool enable_automation);
+ virtual void SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled);
void FindInPage(const std::wstring& search_string,
FindInPageDirection forward,
diff --git a/chrome_frame/chrome_frame_npapi.cc b/chrome_frame/chrome_frame_npapi.cc
index 6c9791f..ec324e0 100644
--- a/chrome_frame/chrome_frame_npapi.cc
+++ b/chrome_frame/chrome_frame_npapi.cc
@@ -102,6 +102,10 @@ static const char kPluginChromeExtraArguments[] = "chrome_extra_arguments";
// If privileged mode is enabled, the string value of this argument will
// be used as the profile name for our chrome.exe instance.
static const char kPluginChromeProfileName[] = "chrome_profile_name";
+// If privileged mode is enabled, this argument will be taken as a
+// comma-separated list of API function calls to automate.
+static const char kPluginChromeFunctionsAutomatedAttribute[] =
+ "chrome_functions_automated";
// If chrome network stack is to be used
static const char kPluginUseChromeNetwork[] = "usechromenetwork";
@@ -377,6 +381,13 @@ bool ChromeFrameNPAPI::Initialize(NPMIMEType mime_type, NPP instance,
chrome_extra_arguments_arg = argv[i];
} else if (LowerCaseEqualsASCII(argn[i], kPluginChromeProfileName)) {
chrome_profile_name_arg = argv[i];
+ } else if (LowerCaseEqualsASCII(argn[i],
+ kPluginChromeFunctionsAutomatedAttribute)) {
+ functions_enabled_.clear();
+ // SplitString writes one empty entry for blank strings, so we need this
+ // to allow specifying zero automation of API functions.
+ if (argv[i][0] != '\0')
+ SplitString(argv[i], ',', &functions_enabled_);
} else if (LowerCaseEqualsASCII(argn[i], kPluginUseChromeNetwork)) {
chrome_network_arg_set = true;
chrome_network_arg = atoi(argv[i]) ? true : false;
diff --git a/chrome_frame/chrome_frame_npapi_unittest.cc b/chrome_frame/chrome_frame_npapi_unittest.cc
index d2c9b4e..b30d5e8 100644
--- a/chrome_frame/chrome_frame_npapi_unittest.cc
+++ b/chrome_frame/chrome_frame_npapi_unittest.cc
@@ -83,7 +83,8 @@ class MockAutomationClient: public ChromeFrameAutomationClient {
MOCK_METHOD6(Initialize, bool(ChromeFrameDelegate*, int, bool,
const std::wstring&, const std::wstring&,
bool));
- MOCK_METHOD1(SetEnableExtensionAutomation, void(bool)); // NOLINT
+ MOCK_METHOD1(SetEnableExtensionAutomation,
+ void(const std::vector<std::string>&)); // NOLINT
};
class MockProxyService: public NpProxyService {
@@ -219,7 +220,7 @@ TEST_F(TestNPAPIPrivilegedApi, PrivilegedAllowsArgsAndProfile) {
L"-bar=far"); // Extra arguments expected
// With privileged mode we expect automation to be enabled.
- EXPECT_CALL(*mock_automation, SetEnableExtensionAutomation(true))
+ EXPECT_CALL(*mock_automation, SetEnableExtensionAutomation(_))
.Times(1);
char* argn[] = {
@@ -386,7 +387,7 @@ class TestNPAPIPrivilegedProperty: public TestNPAPIPrivilegedApi {
// And we should expect SetEnableExtensionAutomation to be called
// for privileged tests.
- EXPECT_CALL(*mock_automation, SetEnableExtensionAutomation(true))
+ EXPECT_CALL(*mock_automation, SetEnableExtensionAutomation(_))
.WillRepeatedly(Return());
// Initializes identifiers.
diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h
index b0814bb..fbc3f77 100644
--- a/chrome_frame/chrome_frame_plugin.h
+++ b/chrome_frame/chrome_frame_plugin.h
@@ -19,6 +19,7 @@ class ChromeFramePlugin : public ChromeFrameDelegateImpl {
ChromeFramePlugin()
: ignore_setfocus_(false),
is_privileged_(false) {
+ functions_enabled_.push_back("*");
}
~ChromeFramePlugin() {
Uninitialize();
@@ -78,7 +79,7 @@ END_MSG_MAP()
// Issue the extension automation request if we're privileged to
// allow this control to handle extension requests from Chrome.
if (is_privileged_)
- automation_client_->SetEnableExtensionAutomation(true);
+ automation_client_->SetEnableExtensionAutomation(functions_enabled_);
}
virtual bool IsValid() const {
@@ -170,7 +171,7 @@ END_MSG_MAP()
// modified as well (enable/disable commands, add/remove items).
// Override in most-derived class if needed.
bool PreProcessContextMenu(HMENU menu) {
- // Add an "About" item.
+ // Add an "About" item.
// TODO: The string should be localized and menu should
// be modified in ExternalTabContainer:: once we go public.
AppendMenu(menu, MF_STRING, IDC_ABOUT_CHROME_FRAME,
@@ -208,6 +209,10 @@ END_MSG_MAP()
//
// When privileged, additional interfaces are made available to the user.
bool is_privileged_;
+
+ // List of functions to enable for automation, or a single entry "*" to enable
+ // all functions for automation. Ignored unless is_privileged_ is true.
+ std::vector<std::string> functions_enabled_;
};
#endif // CHROME_FRAME_CHROME_FRAME_PLUGIN_H_
diff --git a/chrome_frame/chrome_tab.idl b/chrome_frame/chrome_tab.idl
index afb364e..c234c29 100644
--- a/chrome_frame/chrome_tab.idl
+++ b/chrome_frame/chrome_tab.idl
@@ -77,7 +77,7 @@ interface IChromeFrame : IDispatch {
[
object,
- uuid(679E292F-DBAB-46b8-8693-03084CEF61BE),
+ uuid(655A11E0-EF63-4fbe-9DF6-C182D2FCD6DC),
oleautomation,
nonextensible,
hidden,
@@ -91,6 +91,9 @@ interface IChromeFramePrivileged: IUnknown {
HRESULT GetChromeExtraArguments([out] BSTR *args);
// The profile name we want to use.
HRESULT GetChromeProfileName([out] BSTR *profile_name);
+ // The comma-separated list of extension API functions you wish to automate.
+ // Return S_FALSE to leave the default, which is to automate all functions.
+ HRESULT GetExtensionApisToAutomate([out] BSTR *extension_apis);
};
// Expose this service to the ChromeFrame control to trigger privileged
diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc
index 5bf33c1..37be881 100644
--- a/chrome_frame/test/chrome_frame_unittests.cc
+++ b/chrome_frame/test/chrome_frame_unittests.cc
@@ -790,7 +790,8 @@ class MockAutomationProxy : public ChromeFrameAutomationProxy {
MOCK_METHOD1(CreateTabProxy, scoped_refptr<TabProxy>(int handle));
MOCK_METHOD0(server_version, std::string(void));
MOCK_METHOD1(SendProxyConfig, void(const std::string&));
- MOCK_METHOD1(SetEnableExtensionAutomation, void(bool enable));
+ MOCK_METHOD1(SetEnableExtensionAutomation,
+ void(const std::vector<std::string>&));
~MockAutomationProxy() {}
};