diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-25 05:01:07 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-25 05:01:07 +0000 |
commit | 792556cf01f0d049e207b98dac8e1d5970f562af (patch) | |
tree | b11aa1bdb36d90d12f1fa901d9a93a2916f858b9 /chrome/browser/rlz | |
parent | 73d3a86c4ece60c7e703217f20bd1ea50f50356c (diff) | |
download | chromium_src-792556cf01f0d049e207b98dac8e1d5970f562af.zip chromium_src-792556cf01f0d049e207b98dac8e1d5970f562af.tar.gz chromium_src-792556cf01f0d049e207b98dac8e1d5970f562af.tar.bz2 |
Move RLZ extension api implementation to rlz directory.
We're moving all the extension api implementations out of
browser/extensions into the directory with the code they are
automating.
BUG=101244
Review URL: http://codereview.chromium.org/8374025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107064 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/rlz')
-rw-r--r-- | chrome/browser/rlz/rlz_extension_api.cc | 211 | ||||
-rw-r--r-- | chrome/browser/rlz/rlz_extension_api.h | 39 | ||||
-rw-r--r-- | chrome/browser/rlz/rlz_extension_apitest.cc | 99 |
3 files changed, 349 insertions, 0 deletions
diff --git a/chrome/browser/rlz/rlz_extension_api.cc b/chrome/browser/rlz/rlz_extension_api.cc new file mode 100644 index 0000000..02a4a18 --- /dev/null +++ b/chrome/browser/rlz/rlz_extension_api.cc @@ -0,0 +1,211 @@ +// Copyright (c) 2011 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/rlz/rlz_extension_api.h" + +#include "base/memory/scoped_ptr.h" +#include "base/threading/thread_restrictions.h" +#include "base/values.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; +} + +} // namespace + +bool RlzRecordProductEventFunction::RunImpl() { + // This can be slow if registry access goes to disk. Should preferably + // perform registry operations on the File thread. + // http://code.google.com/p/chromium/issues/detail?id=62098 + base::ThreadRestrictions::ScopedAllowIO allow_io; + + 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 rlz_lib::RecordProductEvent(product, access_point, event_id); +} + +bool RlzGetAccessPointRlzFunction::RunImpl() { + // This can be slow if registry access goes to disk. Should preferably + // perform registry operations on the File thread. + // http://code.google.com/p/chromium/issues/detail?id=62098 + base::ThreadRestrictions::ScopedAllowIO allow_io; + + 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 RlzSendFinancialPingFunction::RunImpl() { + // This can be slow if registry access goes to disk. Should preferably + // perform registry operations on the File thread. + // http://code.google.com/p/chromium/issues/detail?id=62098 + base::ThreadRestrictions::ScopedAllowIO allow_io; + + 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)); + + // rlz_lib::SendFinancialPing() will not send a ping more often than once in + // any 24-hour period. Calling it more often has no effect. If a ping is + // not sent false is returned, but this is not an error, so we should not + // use the return value of rlz_lib::SendFinancialPing() as the return value + // of this function. Callers interested in the return value can register + // an optional callback function. + bool sent = rlz_lib::SendFinancialPing(product, access_points.get(), + signature.c_str(), brand.c_str(), + id.c_str(), lang.c_str(), + exclude_machine_id); + result_.reset(Value::CreateBooleanValue(sent)); + return true; +} + +bool RlzClearProductStateFunction::RunImpl() { + // This can be slow if registry access goes to disk. Should preferably + // perform registry operations on the File thread. + // http://code.google.com/p/chromium/issues/detail?id=62098 + base::ThreadRestrictions::ScopedAllowIO allow_io; + + 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/rlz/rlz_extension_api.h b/chrome/browser/rlz/rlz_extension_api.h new file mode 100644 index 0000000..45c892e --- /dev/null +++ b/chrome/browser/rlz/rlz_extension_api.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 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_RLZ_RLZ_EXTENSION_API_H_ +#define CHROME_BROWSER_RLZ_RLZ_EXTENSION_API_H_ +#pragma once + +#include "build/build_config.h" + +#if defined(OS_WIN) + +#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 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") +}; + +#endif // defined(OS_WIN) + +#endif // CHROME_BROWSER_RLZ_RLZ_EXTENSION_API_H_ diff --git a/chrome/browser/rlz/rlz_extension_apitest.cc b/chrome/browser/rlz/rlz_extension_apitest.cc new file mode 100644 index 0000000..454efa1 --- /dev/null +++ b/chrome/browser/rlz/rlz_extension_apitest.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2011 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/win/registry.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/rlz/rlz_extension_api.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); + + // 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. + base::win::RegKey key(HKEY_CURRENT_USER, + L"Software\\Google\\Common\\Rlz\\Events\\N", + KEY_READ); + ASSERT_FALSE(key.Valid()); + + key.Open(HKEY_CURRENT_USER, L"Software\\Google\\Common\\Rlz\\Events\\D", + KEY_READ); + 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(3, 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", + KEY_READ); + ASSERT_TRUE(key.Valid()); + + DWORD value; + ASSERT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"D3I", &value)); + ASSERT_EQ(1, value); + ASSERT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"D3S", &value)); + ASSERT_EQ(1, value); + ASSERT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"D3F", &value)); + ASSERT_EQ(1, value); + + ASSERT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"D4I", &value)); + ASSERT_EQ(1, value); + + key.Open(HKEY_CURRENT_USER, L"Software\\Google\\Common\\Rlz\\Events\\D", + KEY_READ); + ASSERT_FALSE(key.Valid()); + + // Cleanup. + rlz_lib::ClearProductState(rlz_lib::PINYIN_IME, access_points); +} |