1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/rlz/rlz_extension_api.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/threading/sequenced_worker_pool.h"
10 #include "base/threading/thread_restrictions.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/common/extensions/extension.h"
14 #include "rlz/lib/lib_values.h"
15 #include "rlz/lib/rlz_lib.h"
19 bool GetProductFromName(const std::string
& product_name
,
20 rlz_lib::Product
* product
) {
22 switch (product_name
[0]) {
24 *product
= rlz_lib::FF_TOOLBAR
;
27 *product
= rlz_lib::CHROME
;
30 *product
= rlz_lib::DESKTOP
;
33 *product
= rlz_lib::QSB_WIN
;
36 *product
= rlz_lib::PINYIN_IME
;
39 *product
= rlz_lib::TOOLBAR_NOTIFIER
;
42 *product
= rlz_lib::IE_TOOLBAR
;
45 *product
= rlz_lib::PACK
;
48 *product
= rlz_lib::WEBAPPS
;
58 bool GetEventFromName(const std::string
& event_name
,
59 rlz_lib::Event
* event_id
) {
60 *event_id
= rlz_lib::INVALID_EVENT
;
62 if (event_name
== "install") {
63 *event_id
= rlz_lib::INSTALL
;
64 } else if (event_name
== "set-to-google") {
65 *event_id
= rlz_lib::SET_TO_GOOGLE
;
66 } else if (event_name
== "first-search") {
67 *event_id
= rlz_lib::FIRST_SEARCH
;
68 } else if (event_name
== "activate") {
69 *event_id
= rlz_lib::ACTIVATE
;
72 return *event_id
!= rlz_lib::INVALID_EVENT
;
77 bool RlzRecordProductEventFunction::RunImpl() {
78 // This can be slow if registry access goes to disk. Should preferably
79 // perform registry operations on the File thread.
80 // http://code.google.com/p/chromium/issues/detail?id=62098
81 base::ThreadRestrictions::ScopedAllowIO allow_io
;
83 std::string product_name
;
84 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(0, &product_name
));
85 rlz_lib::Product product
;
86 EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name
, &product
));
89 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(1, &ap_name
));
90 rlz_lib::AccessPoint access_point
;
91 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(ap_name
.c_str(),
94 std::string event_name
;
95 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(2, &event_name
));
96 rlz_lib::Event event_id
;
97 EXTENSION_FUNCTION_VALIDATE(GetEventFromName(event_name
, &event_id
));
99 return rlz_lib::RecordProductEvent(product
, access_point
, event_id
);
102 bool RlzGetAccessPointRlzFunction::RunImpl() {
103 // This can be slow if registry access goes to disk. Should preferably
104 // perform registry operations on the File thread.
105 // http://code.google.com/p/chromium/issues/detail?id=62098
106 base::ThreadRestrictions::ScopedAllowIO allow_io
;
109 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(0, &ap_name
));
110 rlz_lib::AccessPoint access_point
;
111 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(ap_name
.c_str(),
114 char rlz
[rlz_lib::kMaxRlzLength
+ 1];
115 rlz_lib::GetAccessPointRlz(access_point
, rlz
, rlz_lib::kMaxRlzLength
);
116 SetResult(Value::CreateStringValue(rlz
));
120 RlzSendFinancialPingFunction::RlzSendFinancialPingFunction()
121 : product_(rlz_lib::CHROME
),
122 exclude_machine_id_(true) {
125 RlzSendFinancialPingFunction::~RlzSendFinancialPingFunction() {
128 bool RlzSendFinancialPingFunction::RunImpl() {
129 std::string product_name
;
130 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(0, &product_name
));
131 EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name
, &product_
));
133 ListValue
* access_points_list
;
134 EXTENSION_FUNCTION_VALIDATE(args_
->GetList(1, &access_points_list
));
135 if (access_points_list
->GetSize() < 1) {
136 EXTENSION_FUNCTION_ERROR("Access point array should not be empty.");
139 // Allocate an access point array to pass to ClearProductState(). The array
140 // must be terminated with the value rlz_lib::NO_ACCESS_POINT, hence + 1
141 // when allocating the array.
142 access_points_
.reset(
143 new rlz_lib::AccessPoint
[access_points_list
->GetSize() + 1]);
146 for (i
= 0; i
< access_points_list
->GetSize(); ++i
) {
148 EXTENSION_FUNCTION_VALIDATE(access_points_list
->GetString(i
, &ap_name
));
149 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(
150 ap_name
.c_str(), &access_points_
[i
]));
152 access_points_
[i
] = rlz_lib::NO_ACCESS_POINT
;
154 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(2, &signature_
));
155 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(3, &brand_
));
156 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(4, &id_
));
157 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(5, &lang_
));
158 EXTENSION_FUNCTION_VALIDATE(args_
->GetBoolean(6, &exclude_machine_id_
));
160 // |system_request_context| needs to run on the UI thread.
161 rlz_lib::SetURLRequestContext(g_browser_process
->system_request_context());
163 content::BrowserThread::GetBlockingPool()->PostTask(
165 base::Bind(&RlzSendFinancialPingFunction::WorkOnWorkerThread
, this));
170 void RlzSendFinancialPingFunction::WorkOnWorkerThread() {
171 // rlz_lib::SendFinancialPing() will not send a ping more often than once in
172 // any 24-hour period. Calling it more often has no effect. If a ping is
173 // not sent false is returned, but this is not an error, so we should not
174 // use the return value of rlz_lib::SendFinancialPing() as the return value
175 // of this function. Callers interested in the return value can register
176 // an optional callback function.
177 bool sent
= rlz_lib::SendFinancialPing(product_
, access_points_
.get(),
178 signature_
.c_str(), brand_
.c_str(),
179 id_
.c_str(), lang_
.c_str(),
180 exclude_machine_id_
);
182 SetResult(Value::CreateBooleanValue(sent
));
184 bool post_task_result
= content::BrowserThread::PostTask(
185 content::BrowserThread::UI
, FROM_HERE
,
186 base::Bind(&RlzSendFinancialPingFunction::RespondOnUIThread
, this));
187 DCHECK(post_task_result
);
190 void RlzSendFinancialPingFunction::RespondOnUIThread() {
191 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
195 bool RlzClearProductStateFunction::RunImpl() {
196 // This can be slow if registry access goes to disk. Should preferably
197 // perform registry operations on the File thread.
198 // http://code.google.com/p/chromium/issues/detail?id=62098
199 base::ThreadRestrictions::ScopedAllowIO allow_io
;
201 std::string product_name
;
202 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(0, &product_name
));
203 rlz_lib::Product product
;
204 EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name
, &product
));
206 ListValue
* access_points_list
;
207 EXTENSION_FUNCTION_VALIDATE(args_
->GetList(1, &access_points_list
));
208 if (access_points_list
->GetSize() < 1) {
209 EXTENSION_FUNCTION_ERROR("Access point array should not be empty.");
212 // Allocate an access point array to pass to ClearProductState(). The array
213 // must be termindated with the value rlz_lib::NO_ACCESS_POINT, hence + 1
214 // when allocating the array.
215 scoped_ptr
<rlz_lib::AccessPoint
[]> access_points(
216 new rlz_lib::AccessPoint
[access_points_list
->GetSize() + 1]);
219 for (i
= 0; i
< access_points_list
->GetSize(); ++i
) {
221 EXTENSION_FUNCTION_VALIDATE(access_points_list
->GetString(i
, &ap_name
));
222 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(
223 ap_name
.c_str(), &access_points
[i
]));
225 access_points
[i
] = rlz_lib::NO_ACCESS_POINT
;
227 rlz_lib::ClearProductState(product
, access_points
.get());