diff options
author | rogerta@google.com <rogerta@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-17 03:11:21 +0000 |
---|---|---|
committer | rogerta@google.com <rogerta@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-17 03:11:21 +0000 |
commit | 3a612be14f1bd1aa730cedbd11bb3ec333cc078c (patch) | |
tree | 5b4db30938d55e8ac5e723e5bc1b7acf716640a1 | |
parent | 76c0613c3feb32332f67a1b6a273102d2c064801 (diff) | |
download | chromium_src-3a612be14f1bd1aa730cedbd11bb3ec333cc078c.zip chromium_src-3a612be14f1bd1aa730cedbd11bb3ec333cc078c.tar.gz chromium_src-3a612be14f1bd1aa730cedbd11bb3ec333cc078c.tar.bz2 |
When I specified the rlz chrome extension api, I explicitly did not include a
function to send pings to google for two reasons:
- I thought that chrome's own rlz pings would send all rlz information for all
other products installed on the machine
- I did not want to allow an extension to DoS google by sending too many rlz
pings
It turns out that the rlz library itself makes sure that a given product's
pings are never sent out more than once per day, as is required for rlz, so
there is no DoS danger by exposing a ping function. Also, I was wrong in
thinking that chrome's rlz pings would send out all rlz information about
other products installed on the machine: it sends out the other products rlz
strings, but it does not send out the other products rlz event information.
This makes sense since there are signatures and brand codes and other
information that cannot be determined by chrome for the extensions.
So adding a new rlz chrome extension function to expose sending pings.
BUG=None
TEST=See particular extension using this api
Review URL: http://codereview.chromium.org/3029001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52800 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 1 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_rlz_apitest.cc | 34 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_rlz_module.cc | 48 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_rlz_module.h | 7 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.json | 14 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/rlz/test.js | 35 |
6 files changed, 139 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 9015a68..4959310 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -204,6 +204,7 @@ void FactoryRegistry::ResetFunctions() { #if defined(OS_WIN) RegisterFunction<RlzRecordProductEventFunction>(); RegisterFunction<RlzGetAccessPointRlzFunction>(); + RegisterFunction<RlzSendFinancialPingFunction>(); RegisterFunction<RlzClearProductStateFunction>(); #endif diff --git a/chrome/browser/extensions/extension_rlz_apitest.cc b/chrome/browser/extensions/extension_rlz_apitest.cc index 04f5895..3d0ea9e 100644 --- a/chrome/browser/extensions/extension_rlz_apitest.cc +++ b/chrome/browser/extensions/extension_rlz_apitest.cc @@ -6,11 +6,37 @@ #include "base/registry.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/extension_function.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_rlz_module.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "rlz/win/lib/rlz_lib.h" +class MockRlzSendFinancialPingFunction : public RlzSendFinancialPingFunction { + virtual bool RunImpl(); + + static int expected_count_; + + public: + static int expected_count() { + return expected_count_; + } +}; + +int MockRlzSendFinancialPingFunction::expected_count_ = 0; + +bool MockRlzSendFinancialPingFunction::RunImpl() { + EXPECT_TRUE(RlzSendFinancialPingFunction::RunImpl()); + ++expected_count_; + return true; +} + +ExtensionFunction* MockRlzSendFinancialPingFunctionFactory() { + return new MockRlzSendFinancialPingFunction(); +} + IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Rlz) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableExperimentalExtensionApis); @@ -28,12 +54,20 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Rlz) { RegKey key(HKEY_CURRENT_USER, L"Software\\Google\\Common\\Rlz\\Events\\N"); ASSERT_FALSE(key.Valid()); + // Mock out experimental.rlz.sendFinancialPing(). + ASSERT_TRUE(ExtensionFunctionDispatcher::OverrideFunction( + "experimental.rlz.sendFinancialPing", + MockRlzSendFinancialPingFunctionFactory)); + // Set the access point that the test code is expecting. ASSERT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::GD_DESKBAND, "rlz_apitest")); // Now run all the tests. ASSERT_TRUE(RunExtensionTest("rlz")) << message_; + ASSERT_EQ(1, MockRlzSendFinancialPingFunction::expected_count()); + ExtensionFunctionDispatcher::ResetFunctions(); + // Now make sure we recorded what was expected. If the code in test.js // changes, need to make appropriate changes here. key.Open(HKEY_CURRENT_USER, L"Software\\Google\\Common\\Rlz\\Events\\N"); diff --git a/chrome/browser/extensions/extension_rlz_module.cc b/chrome/browser/extensions/extension_rlz_module.cc index 5410303..5519e2d 100644 --- a/chrome/browser/extensions/extension_rlz_module.cc +++ b/chrome/browser/extensions/extension_rlz_module.cc @@ -102,6 +102,54 @@ bool RlzGetAccessPointRlzFunction::RunImpl() { return true; } +bool RlzSendFinancialPingFunction::RunImpl() { + std::string product_name; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &product_name)); + rlz_lib::Product product; + EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name, &product)); + + ListValue* access_points_list; + EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &access_points_list)); + if (access_points_list->GetSize() < 1) { + EXTENSION_FUNCTION_ERROR("Access point array should not be empty."); + } + + // Allocate an access point array to pass to ClearProductState(). The array + // must be termindated with the value rlz_lib::NO_ACCESS_POINT, hence + 1 + // when allocating the array. + scoped_array<rlz_lib::AccessPoint> access_points( + new rlz_lib::AccessPoint[access_points_list->GetSize() + 1]); + + size_t i; + for (i = 0; i < access_points_list->GetSize(); ++i) { + std::string ap_name; + EXTENSION_FUNCTION_VALIDATE(access_points_list->GetString(i, &ap_name)); + EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName( + ap_name.c_str(), &access_points[i])); + } + access_points[i] = rlz_lib::NO_ACCESS_POINT; + + std::string signature; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &signature)); + + std::string brand; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &brand)); + + std::string id; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &id)); + + std::string lang; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(5, &lang)); + + bool exclude_machine_id; + EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(6, &exclude_machine_id)); + + return rlz_lib::SendFinancialPing(product, access_points.get(), + signature.c_str(), brand.c_str(), + id.c_str(), lang.c_str(), + exclude_machine_id); +} + bool RlzClearProductStateFunction::RunImpl() { std::string product_name; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &product_name)); diff --git a/chrome/browser/extensions/extension_rlz_module.h b/chrome/browser/extensions/extension_rlz_module.h index 88affd9..22364ac 100644 --- a/chrome/browser/extensions/extension_rlz_module.h +++ b/chrome/browser/extensions/extension_rlz_module.h @@ -23,6 +23,13 @@ class RlzGetAccessPointRlzFunction : public SyncExtensionFunction { DECLARE_EXTENSION_FUNCTION_NAME("experimental.rlz.getAccessPointRlz") }; +class RlzSendFinancialPingFunction : public SyncExtensionFunction { + DECLARE_EXTENSION_FUNCTION_NAME("experimental.rlz.sendFinancialPing") + // Making this function protected so that it can be overridden in tests. + protected: + virtual bool RunImpl(); +}; + class RlzClearProductStateFunction : public SyncExtensionFunction { virtual bool RunImpl(); DECLARE_EXTENSION_FUNCTION_NAME("experimental.rlz.clearProductState") diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index fcc1e61..698ec1d 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -2942,6 +2942,20 @@ ] }, { + "name": "sendFinancialPing", + "type": "function", + "description": "Sends Google promotional information about this extension.", + "parameters": [ + {"name": "product", "type": "string", "minLength": 1, "maxLength": 1}, + {"name": "accessPoints", "type": "array", "items": {"type": "string", "minLength": 1, "maxLength": 2}, "minItems": 1}, + {"name": "signature", "type": "string"}, + {"name": "brand", "type": "string"}, + {"name": "id", "type": "string"}, + {"name": "lang", "type": "string"}, + {"name": "exclude_machine_id", "type": "boolean"} + ] + }, + { "name": "clearProductState", "type": "function", "description": "Clears all product-specific RLZ state from the machine, as well as clearing all events for the specified access points.", diff --git a/chrome/test/data/extensions/api_test/rlz/test.js b/chrome/test/data/extensions/api_test/rlz/test.js index e79a7ae..6fb4239 100644 --- a/chrome/test/data/extensions/api_test/rlz/test.js +++ b/chrome/test/data/extensions/api_test/rlz/test.js @@ -106,5 +106,40 @@ chrome.test.runTests([ chrome.test.succeed(); }); }, + + function sendFinancialPing() { + // Bad product. + try { + chrome.experimental.rlz.sendFinancialPing('', ['D3'], 'sig', 'TEST', + 'id', 'en', false); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + // Bad access point list. + try { + chrome.experimental.rlz.sendFinancialPing('D', null, 'sig', 'TEST', + 'id', 'en', false); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + // Bad access point list. + try { + chrome.experimental.rlz.sendFinancialPing('D', [], 'sig', 'TEST', + 'id', 'en', false); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + // Valid call. + chrome.experimental.rlz.sendFinancialPing('D', ['D3'], 'sig', 'TEST', + 'id', 'en', false); + + chrome.test.succeed(); + } ]); |