diff options
author | rogerta@google.com <rogerta@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-28 15:21:50 +0000 |
---|---|---|
committer | rogerta@google.com <rogerta@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-28 15:21:50 +0000 |
commit | 549c4e3cbf7da1c6d65b865855d055c4dc02e979 (patch) | |
tree | 7c66144efc1e53891245507701830f3b88e24e37 /chrome | |
parent | 8cc9dd62ea7a7d60ce5486fbd62baf9266fa0f15 (diff) | |
download | chromium_src-549c4e3cbf7da1c6d65b865855d055c4dc02e979.zip chromium_src-549c4e3cbf7da1c6d65b865855d055c4dc02e979.tar.gz chromium_src-549c4e3cbf7da1c6d65b865855d055c4dc02e979.tar.bz2 |
Add support for RLZ chrome extension api.
BUG=NONE
TEST=See unit tests as part of this CL.
Review URL: http://codereview.chromium.org/2804010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50977 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 10 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_rlz_apitest.cc | 58 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_rlz_module.cc | 134 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_rlz_module.h | 33 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 3 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 7 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.json | 36 | ||||
-rw-r--r-- | chrome/renderer/resources/renderer_extension_bindings.js | 1 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/rlz/manifest.json | 7 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/rlz/test.html | 1 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/rlz/test.js | 110 |
11 files changed, 399 insertions, 1 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 31d6984..9015a68 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -8,7 +8,7 @@ #include "base/singleton.h" #include "base/ref_counted.h" #include "base/values.h" -#include "chrome/browser/browser.h" +#include "build/build_config.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" @@ -36,6 +36,7 @@ #include "chrome/browser/extensions/extension_popup_api.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_processes_api.h" +#include "chrome/browser/extensions/extension_rlz_module.h" #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/browser/extensions/extension_test_api.h" @@ -199,6 +200,13 @@ void FactoryRegistry::ResetFunctions() { RegisterFunction<MetricsRecordMediumTimeFunction>(); RegisterFunction<MetricsRecordLongTimeFunction>(); + // RLZ. +#if defined(OS_WIN) + RegisterFunction<RlzRecordProductEventFunction>(); + RegisterFunction<RlzGetAccessPointRlzFunction>(); + RegisterFunction<RlzClearProductStateFunction>(); +#endif + // Cookies. RegisterFunction<GetCookieFunction>(); RegisterFunction<GetAllCookiesFunction>(); diff --git a/chrome/browser/extensions/extension_rlz_apitest.cc b/chrome/browser/extensions/extension_rlz_apitest.cc new file mode 100644 index 0000000..b6fc697 --- /dev/null +++ b/chrome/browser/extensions/extension_rlz_apitest.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <map> + +#include "base/registry.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/extension.h" +#include "rlz/win/lib/rlz_lib.h" + +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Rlz) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalExtensionApis); + + // Before running the tests, clear the state of the RLZ products used. + rlz_lib::AccessPoint access_points[] = { + rlz_lib::GD_WEB_SERVER, + rlz_lib::GD_OUTLOOK, + rlz_lib::NO_ACCESS_POINT + }; + rlz_lib::ClearProductState(rlz_lib::PINYIN_IME, access_points); + rlz_lib::ClearProductState(rlz_lib::DESKTOP, access_points); + + // Check that the state has really been cleared. + RegKey key(HKEY_CURRENT_USER, L"Software\\Google\\Common\\Rlz\\Events\\N"); + ASSERT_FALSE(key.Valid()); + + // 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_; + + // 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"); + ASSERT_TRUE(key.Valid()); + + DWORD value; + ASSERT_TRUE(key.ReadValueDW(L"D3I", &value)); + ASSERT_EQ(1, value); + ASSERT_TRUE(key.ReadValueDW(L"D3S", &value)); + ASSERT_EQ(1, value); + ASSERT_TRUE(key.ReadValueDW(L"D3F", &value)); + ASSERT_EQ(1, value); + + ASSERT_TRUE(key.ReadValueDW(L"D4I", &value)); + ASSERT_EQ(1, value); + + key.Open(HKEY_CURRENT_USER, L"Software\\Google\\Common\\Rlz\\Events\\D"); + ASSERT_FALSE(key.Valid()); + + // Cleanup. + rlz_lib::ClearProductState(rlz_lib::PINYIN_IME, access_points); +} diff --git a/chrome/browser/extensions/extension_rlz_module.cc b/chrome/browser/extensions/extension_rlz_module.cc new file mode 100644 index 0000000..31b76f8 --- /dev/null +++ b/chrome/browser/extensions/extension_rlz_module.cc @@ -0,0 +1,134 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_rlz_module.h" + +#include "base/scoped_ptr.h" +#include "chrome/browser/rlz/rlz.h" +#include "chrome/common/extensions/extension.h" +#include "rlz/win/lib/lib_values.h" + +namespace { + +bool GetProductFromName(const std::string& product_name, + rlz_lib::Product* product) { + bool success = true; + switch (product_name[0]) { + case 'B': + *product = rlz_lib::FF_TOOLBAR; + break; + case 'C': + *product = rlz_lib::CHROME; + break; + case 'D': + *product = rlz_lib::DESKTOP; + break; + case 'K': + *product = rlz_lib::QSB_WIN; + break; + case 'N': + *product = rlz_lib::PINYIN_IME; + break; + case 'P': + *product = rlz_lib::TOOLBAR_NOTIFIER; + break; + case 'T': + *product = rlz_lib::IE_TOOLBAR; + break; + case 'U': + *product = rlz_lib::PACK; + break; + case 'W': + *product = rlz_lib::WEBAPPS; + break; + default: + success = false; + break; + } + + return success; +} + +bool GetEventFromName(const std::string& event_name, + rlz_lib::Event* event_id) { + *event_id = rlz_lib::INVALID_EVENT; + + if (event_name == "install") { + *event_id = rlz_lib::INSTALL; + } else if (event_name == "set-to-google") { + *event_id = rlz_lib::SET_TO_GOOGLE; + } else if (event_name == "first-search") { + *event_id = rlz_lib::FIRST_SEARCH; + } else if (event_name == "activate") { + *event_id = rlz_lib::ACTIVATE; + } + + return *event_id != rlz_lib::INVALID_EVENT; +} + +} // anonymous namespace + +bool RlzRecordProductEventFunction::RunImpl() { + std::string product_name; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &product_name)); + rlz_lib::Product product; + EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name, &product)); + + std::string ap_name; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &ap_name)); + rlz_lib::AccessPoint access_point; + EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(ap_name.c_str(), + &access_point)); + + std::string event_name; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &event_name)); + rlz_lib::Event event_id; + EXTENSION_FUNCTION_VALIDATE(GetEventFromName(event_name, &event_id)); + + return RLZTracker::RecordProductEvent(product, access_point, event_id); +} + +bool RlzGetAccessPointRlzFunction::RunImpl() { + std::string ap_name; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &ap_name)); + rlz_lib::AccessPoint access_point; + EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(ap_name.c_str(), + &access_point)); + + char rlz[rlz_lib::kMaxRlzLength + 1]; + rlz_lib::GetAccessPointRlz(access_point, rlz, rlz_lib::kMaxRlzLength); + result_.reset(Value::CreateStringValue(rlz)); + return true; +} + +bool RlzClearProductStateFunction::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; + + rlz_lib::ClearProductState(product, access_points.get()); + return true; +} diff --git a/chrome/browser/extensions/extension_rlz_module.h b/chrome/browser/extensions/extension_rlz_module.h new file mode 100644 index 0000000..88affd9 --- /dev/null +++ b/chrome/browser/extensions/extension_rlz_module.h @@ -0,0 +1,33 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_RLZ_MODULE_H__ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_RLZ_MODULE_H__ + +#include "build/build_config.h" + +#if defined(OS_WIN) + +#include <string> + +#include "chrome/browser/extensions/extension_function.h" + +class RlzRecordProductEventFunction : public SyncExtensionFunction { + virtual bool RunImpl(); + DECLARE_EXTENSION_FUNCTION_NAME("experimental.rlz.recordProductEvent") +}; + +class RlzGetAccessPointRlzFunction : public SyncExtensionFunction { + virtual bool RunImpl(); + DECLARE_EXTENSION_FUNCTION_NAME("experimental.rlz.getAccessPointRlz") +}; + +class RlzClearProductStateFunction : public SyncExtensionFunction { + virtual bool RunImpl(); + DECLARE_EXTENSION_FUNCTION_NAME("experimental.rlz.clearProductState") +}; + +#endif // defined(OS_WIN) + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_RLZ_MODULE_H__ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a7eedfd..475de92 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1178,6 +1178,8 @@ 'browser/extensions/extension_processes_api_constants.h', 'browser/extensions/extension_protocols.cc', 'browser/extensions/extension_protocols.h', + 'browser/extensions/extension_rlz_module.cc', + 'browser/extensions/extension_rlz_module.h', 'browser/extensions/extension_shelf_model.cc', 'browser/extensions/extension_shelf_model.h', 'browser/extensions/extension_tabs_module.cc', @@ -3019,6 +3021,7 @@ # Exclude all of rlz. ['exclude', '^browser/rlz/'], + ['exclude', '^browser/extensions/extension_rlz_module'], # Exclude all of views. ['exclude', '^browser/views/'], diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 10c8633..cb47678 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1402,6 +1402,7 @@ 'browser/extensions/extension_omnibox_apitest.cc', 'browser/extensions/extension_override_apitest.cc', 'browser/extensions/extension_processes_apitest.cc', + 'browser/extensions/extension_rlz_apitest.cc', 'browser/extensions/extension_startup_browsertest.cc', 'browser/extensions/extension_storage_apitest.cc', 'browser/extensions/extension_tabs_apitest.cc', @@ -1480,6 +1481,9 @@ } }], ['OS=="linux"', { + 'sources/': [ + ['exclude', '^browser/extensions/extension_rlz_apitest.cc'], + ], 'dependencies': [ '../build/linux/system.gyp:gtk', '../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck', @@ -1534,6 +1538,9 @@ 'sources': [ 'browser/extensions/browser_action_test_util_mac.mm', ], + 'sources/': [ + ['exclude', '^browser/extensions/extension_rlz_apitest.cc'], + ], 'include_dirs': [ '../third_party/GTM', ], diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index 2741f2c..9edd8cb 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -2926,6 +2926,42 @@ ] }, { + "namespace": "experimental.rlz", + "nodoc": true, + "types": [], + "functions": [ + { + "name": "recordProductEvent", + "type": "function", + "description": "Records an RLZ event for a given product's access point.", + "parameters": [ + {"name": "product", "type": "string", "minLength": 1, "maxLength": 1}, + {"name": "accessPoint", "type": "string", "minLength": 1, "maxLength": 2}, + {"name": "event", "type": "string", "enum": ["install", "set-to-google", "first-search", "activate"]} + ] + }, + { + "name": "getAccessPointRlz", + "type": "function", + "description": "Gets the RLZ string to be used when accessing a Google property through the given access point.", + "parameters": [ + {"name": "accessPoint", "type": "string", "minLength": 1, "maxLength": 2}, + {"name": "callback", "type": "function", "parameters": [{"name": "rlz", "type": "string"}]} + ] + }, + { + "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.", + "parameters": [ + {"name": "product", "type": "string", "minLength": 1, "maxLength": 1}, + {"name": "accessPoints", "type": "array", "items": {"type": "string", "minLength": 1, "maxLength": 2}, "minItems": 1} + ] + } + ], + "events": [] + }, + { "namespace": "test", "nodoc": true, "types": [], diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js index 1f3220c..f274be7 100644 --- a/chrome/renderer/resources/renderer_extension_bindings.js +++ b/chrome/renderer/resources/renderer_extension_bindings.js @@ -256,6 +256,7 @@ var chrome = chrome || {}; "experimental.omnibox", "experimental.popup", "experimental.processes", + "experimental.rlz", "history", "pageAction", "pageActions", diff --git a/chrome/test/data/extensions/api_test/rlz/manifest.json b/chrome/test/data/extensions/api_test/rlz/manifest.json new file mode 100644 index 0000000..949fd81 --- /dev/null +++ b/chrome/test/data/extensions/api_test/rlz/manifest.json @@ -0,0 +1,7 @@ +{ + "name": "chrome.rlz", + "version": "0.1", + "description": "end-to-end browser test for chrome.rlz API", + "background_page": "test.html", + "permissions": ["experimental"] +} diff --git a/chrome/test/data/extensions/api_test/rlz/test.html b/chrome/test/data/extensions/api_test/rlz/test.html new file mode 100644 index 0000000..46f4d74 --- /dev/null +++ b/chrome/test/data/extensions/api_test/rlz/test.html @@ -0,0 +1 @@ +<script src="test.js"></script> diff --git a/chrome/test/data/extensions/api_test/rlz/test.js b/chrome/test/data/extensions/api_test/rlz/test.js new file mode 100644 index 0000000..e79a7ae --- /dev/null +++ b/chrome/test/data/extensions/api_test/rlz/test.js @@ -0,0 +1,110 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// RLZ api test +// browser_tests.exe --gtest_filter=ExtensionApiTest.Rlz + +// If this code changes, then the corresponding code in extension_rlz_apitest.cc +// also needs to change. + +chrome.test.runTests([ + function recordProductNEvent() { + chrome.experimental.rlz.recordProductEvent('N', 'D3', 'install'); + chrome.experimental.rlz.recordProductEvent('N', 'D3', 'set-to-google'); + chrome.experimental.rlz.recordProductEvent('N', 'D3', 'first-search'); + + chrome.experimental.rlz.recordProductEvent('N', 'D4', 'install'); + chrome.test.succeed(); + }, + + function badProductName() { + try { + chrome.experimental.rlz.recordProductEvent('NN', 'D3', 'install'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + try { + chrome.experimental.rlz.recordProductEvent('', 'D3', 'install'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + try { + chrome.experimental.rlz.recordProductEvent(null, 'D3', 'install'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + chrome.test.succeed(); + }, + + function badAccessPointName() { + try { + chrome.experimental.rlz.recordProductEvent('N', 'D3A', 'install'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + try { + chrome.experimental.rlz.recordProductEvent('N', '', 'install'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + try { + chrome.experimental.rlz.recordProductEvent('N', null, 'install'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + chrome.test.succeed(); + }, + + function badEventName() { + try { + chrome.experimental.rlz.recordProductEvent('N', 'D3', 'foo'); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + try { + chrome.experimental.rlz.recordProductEvent('N', 'D3', null); + // Should not reach this line since the above call throws. + chrome.test.fail(); + } catch(ex) { + } + + chrome.test.succeed(); + }, + + function recordProductDEvent() { + chrome.experimental.rlz.recordProductEvent('D', 'D3', 'install'); + chrome.experimental.rlz.recordProductEvent('D', 'D4', 'install'); + chrome.test.succeed(); + }, + + function clearProductState() { + chrome.experimental.rlz.clearProductState('D', ['D3', 'D4']); + chrome.test.succeed(); + }, + + function getAccessPointRlz() { + // Using an access point different then those used above so that if the + // clearProductState() test runs before this one it does not clear the + // rlz string tested for here. + chrome.experimental.rlz.getAccessPointRlz('D1', function(rlzString) { + chrome.test.assertEq('rlz_apitest', rlzString); + chrome.test.succeed(); + }); + }, +]); + |