1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/extensions/extension_rlz_module.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/threading/thread_restrictions.h"
9 #include "base/values.h"
10 #include "chrome/common/extensions/extension.h"
11 #include "rlz/win/lib/lib_values.h"
12
13 namespace {
14
GetProductFromName(const std::string & product_name,rlz_lib::Product * product)15 bool GetProductFromName(const std::string& product_name,
16 rlz_lib::Product* product) {
17 bool success = true;
18 switch (product_name[0]) {
19 case 'B':
20 *product = rlz_lib::FF_TOOLBAR;
21 break;
22 case 'C':
23 *product = rlz_lib::CHROME;
24 break;
25 case 'D':
26 *product = rlz_lib::DESKTOP;
27 break;
28 case 'K':
29 *product = rlz_lib::QSB_WIN;
30 break;
31 case 'N':
32 *product = rlz_lib::PINYIN_IME;
33 break;
34 case 'P':
35 *product = rlz_lib::TOOLBAR_NOTIFIER;
36 break;
37 case 'T':
38 *product = rlz_lib::IE_TOOLBAR;
39 break;
40 case 'U':
41 *product = rlz_lib::PACK;
42 break;
43 case 'W':
44 *product = rlz_lib::WEBAPPS;
45 break;
46 default:
47 success = false;
48 break;
49 }
50
51 return success;
52 }
53
GetEventFromName(const std::string & event_name,rlz_lib::Event * event_id)54 bool GetEventFromName(const std::string& event_name,
55 rlz_lib::Event* event_id) {
56 *event_id = rlz_lib::INVALID_EVENT;
57
58 if (event_name == "install") {
59 *event_id = rlz_lib::INSTALL;
60 } else if (event_name == "set-to-google") {
61 *event_id = rlz_lib::SET_TO_GOOGLE;
62 } else if (event_name == "first-search") {
63 *event_id = rlz_lib::FIRST_SEARCH;
64 } else if (event_name == "activate") {
65 *event_id = rlz_lib::ACTIVATE;
66 }
67
68 return *event_id != rlz_lib::INVALID_EVENT;
69 }
70
71 } // namespace
72
RunImpl()73 bool RlzRecordProductEventFunction::RunImpl() {
74 // This can be slow if registry access goes to disk. Should preferably
75 // perform registry operations on the File thread.
76 // http://code.google.com/p/chromium/issues/detail?id=62098
77 base::ThreadRestrictions::ScopedAllowIO allow_io;
78
79 std::string product_name;
80 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &product_name));
81 rlz_lib::Product product;
82 EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name, &product));
83
84 std::string ap_name;
85 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &ap_name));
86 rlz_lib::AccessPoint access_point;
87 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(ap_name.c_str(),
88 &access_point));
89
90 std::string event_name;
91 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &event_name));
92 rlz_lib::Event event_id;
93 EXTENSION_FUNCTION_VALIDATE(GetEventFromName(event_name, &event_id));
94
95 return rlz_lib::RecordProductEvent(product, access_point, event_id);
96 }
97
RunImpl()98 bool RlzGetAccessPointRlzFunction::RunImpl() {
99 // This can be slow if registry access goes to disk. Should preferably
100 // perform registry operations on the File thread.
101 // http://code.google.com/p/chromium/issues/detail?id=62098
102 base::ThreadRestrictions::ScopedAllowIO allow_io;
103
104 std::string ap_name;
105 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &ap_name));
106 rlz_lib::AccessPoint access_point;
107 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(ap_name.c_str(),
108 &access_point));
109
110 char rlz[rlz_lib::kMaxRlzLength + 1];
111 rlz_lib::GetAccessPointRlz(access_point, rlz, rlz_lib::kMaxRlzLength);
112 result_.reset(Value::CreateStringValue(rlz));
113 return true;
114 }
115
RunImpl()116 bool RlzSendFinancialPingFunction::RunImpl() {
117 // This can be slow if registry access goes to disk. Should preferably
118 // perform registry operations on the File thread.
119 // http://code.google.com/p/chromium/issues/detail?id=62098
120 base::ThreadRestrictions::ScopedAllowIO allow_io;
121
122 std::string product_name;
123 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &product_name));
124 rlz_lib::Product product;
125 EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name, &product));
126
127 ListValue* access_points_list;
128 EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &access_points_list));
129 if (access_points_list->GetSize() < 1) {
130 EXTENSION_FUNCTION_ERROR("Access point array should not be empty.");
131 }
132
133 // Allocate an access point array to pass to ClearProductState(). The array
134 // must be termindated with the value rlz_lib::NO_ACCESS_POINT, hence + 1
135 // when allocating the array.
136 scoped_array<rlz_lib::AccessPoint> access_points(
137 new rlz_lib::AccessPoint[access_points_list->GetSize() + 1]);
138
139 size_t i;
140 for (i = 0; i < access_points_list->GetSize(); ++i) {
141 std::string ap_name;
142 EXTENSION_FUNCTION_VALIDATE(access_points_list->GetString(i, &ap_name));
143 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(
144 ap_name.c_str(), &access_points[i]));
145 }
146 access_points[i] = rlz_lib::NO_ACCESS_POINT;
147
148 std::string signature;
149 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &signature));
150
151 std::string brand;
152 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &brand));
153
154 std::string id;
155 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &id));
156
157 std::string lang;
158 EXTENSION_FUNCTION_VALIDATE(args_->GetString(5, &lang));
159
160 bool exclude_machine_id;
161 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(6, &exclude_machine_id));
162
163 // rlz_lib::SendFinancialPing() will not send a ping more often than once in
164 // any 24-hour period. Calling it more often has no effect. If a ping is
165 // not sent false is returned, but this is not an error, so we should not
166 // use the return value of rlz_lib::SendFinancialPing() as the return value
167 // of this function. Callers interested in the return value can register
168 // an optional callback function.
169 bool sent = rlz_lib::SendFinancialPing(product, access_points.get(),
170 signature.c_str(), brand.c_str(),
171 id.c_str(), lang.c_str(),
172 exclude_machine_id);
173 result_.reset(Value::CreateBooleanValue(sent));
174 return true;
175 }
176
RunImpl()177 bool RlzClearProductStateFunction::RunImpl() {
178 // This can be slow if registry access goes to disk. Should preferably
179 // perform registry operations on the File thread.
180 // http://code.google.com/p/chromium/issues/detail?id=62098
181 base::ThreadRestrictions::ScopedAllowIO allow_io;
182
183 std::string product_name;
184 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &product_name));
185 rlz_lib::Product product;
186 EXTENSION_FUNCTION_VALIDATE(GetProductFromName(product_name, &product));
187
188 ListValue* access_points_list;
189 EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &access_points_list));
190 if (access_points_list->GetSize() < 1) {
191 EXTENSION_FUNCTION_ERROR("Access point array should not be empty.");
192 }
193
194 // Allocate an access point array to pass to ClearProductState(). The array
195 // must be termindated with the value rlz_lib::NO_ACCESS_POINT, hence + 1
196 // when allocating the array.
197 scoped_array<rlz_lib::AccessPoint> access_points(
198 new rlz_lib::AccessPoint[access_points_list->GetSize() + 1]);
199
200 size_t i;
201 for (i = 0; i < access_points_list->GetSize(); ++i) {
202 std::string ap_name;
203 EXTENSION_FUNCTION_VALIDATE(access_points_list->GetString(i, &ap_name));
204 EXTENSION_FUNCTION_VALIDATE(rlz_lib::GetAccessPointFromName(
205 ap_name.c_str(), &access_points[i]));
206 }
207 access_points[i] = rlz_lib::NO_ACCESS_POINT;
208
209 rlz_lib::ClearProductState(product, access_points.get());
210 return true;
211 }
212