summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrogerta@google.com <rogerta@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-28 15:21:50 +0000
committerrogerta@google.com <rogerta@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-28 15:21:50 +0000
commit549c4e3cbf7da1c6d65b865855d055c4dc02e979 (patch)
tree7c66144efc1e53891245507701830f3b88e24e37 /chrome
parent8cc9dd62ea7a7d60ce5486fbd62baf9266fa0f15 (diff)
downloadchromium_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.cc10
-rw-r--r--chrome/browser/extensions/extension_rlz_apitest.cc58
-rw-r--r--chrome/browser/extensions/extension_rlz_module.cc134
-rw-r--r--chrome/browser/extensions/extension_rlz_module.h33
-rw-r--r--chrome/chrome_browser.gypi3
-rw-r--r--chrome/chrome_tests.gypi7
-rw-r--r--chrome/common/extensions/api/extension_api.json36
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js1
-rw-r--r--chrome/test/data/extensions/api_test/rlz/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/rlz/test.html1
-rw-r--r--chrome/test/data/extensions/api_test/rlz/test.js110
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();
+ });
+ },
+]);
+