普通文本  |  212行  |  7.36 KB

// 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;
}