// 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/extensions/extension_rlz_module.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;
}