Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Side by Side Diff: chrome/browser/rlz/rlz.cc

Issue 2755002: Link with RLZ library from open source repo.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/rlz/rlz.h ('k') | chrome/browser/rlz/rlz_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This code glues the RLZ library DLL with Chrome. It allows Chrome to work 5 // This code glues the RLZ library DLL with Chrome. It allows Chrome to work
6 // with or without the DLL being present. If the DLL is not present the 6 // with or without the DLL being present. If the DLL is not present the
7 // functions do nothing and just return false. 7 // functions do nothing and just return false.
8 8
9 #include "chrome/browser/rlz/rlz.h" 9 #include "chrome/browser/rlz/rlz.h"
10 10
(...skipping 16 matching lines...) Expand all
27 #include "chrome/common/env_vars.h" 27 #include "chrome/common/env_vars.h"
28 #include "chrome/common/notification_registrar.h" 28 #include "chrome/common/notification_registrar.h"
29 #include "chrome/common/notification_service.h" 29 #include "chrome/common/notification_service.h"
30 #include "chrome/installer/util/google_update_settings.h" 30 #include "chrome/installer/util/google_update_settings.h"
31 31
32 namespace { 32 namespace {
33 33
34 // The maximum length of an access points RLZ in wide chars. 34 // The maximum length of an access points RLZ in wide chars.
35 const DWORD kMaxRlzLength = 64; 35 const DWORD kMaxRlzLength = 64;
36 36
37 // The RLZ is a DLL that might not be present in the system. We load it
38 // as needed but never unload it.
39 volatile HMODULE rlz_dll = NULL;
40
41 enum { 37 enum {
42 ACCESS_VALUES_STALE, // Possibly new values available. 38 ACCESS_VALUES_STALE, // Possibly new values available.
43 ACCESS_VALUES_FRESH // The cached values are current. 39 ACCESS_VALUES_FRESH // The cached values are current.
44 }; 40 };
45 41
46 // Tracks if we have tried and succeeded sending the ping. This helps us 42 // Tracks if we have tried and succeeded sending the ping. This helps us
47 // decide if we need to refresh the some cached strings. 43 // decide if we need to refresh the some cached strings.
48 volatile int access_values_state = ACCESS_VALUES_STALE; 44 volatile int access_values_state = ACCESS_VALUES_STALE;
49 45
50 extern "C" { 46 bool SendFinancialPing(const std::wstring& brand, const std::wstring& lang,
51 typedef bool (*RecordProductEventFn)(RLZTracker::Product product, 47 const std::wstring& referral, bool exclude_id) {
52 RLZTracker::AccessPoint point, 48 rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX,
53 RLZTracker::Event event_id, 49 rlz_lib::CHROME_HOME_PAGE,
54 void* reserved); 50 rlz_lib::NO_ACCESS_POINT};
51 std::string brand_ascii(WideToASCII(brand));
52 std::string lang_ascii(WideToASCII(lang));
53 std::string referral_ascii(WideToASCII(referral));
55 54
56 typedef bool (*GetAccessPointRlzFn)(RLZTracker::AccessPoint point, 55 return rlz_lib::SendFinancialPing(rlz_lib::CHROME, points, "chrome",
57 wchar_t* rlz, 56 brand_ascii.c_str(), referral_ascii.c_str(),
58 DWORD rlz_size, 57 lang_ascii.c_str(), exclude_id, NULL, true);
59 void* reserved);
60
61 typedef bool (*ClearAllProductEventsFn)(RLZTracker::Product product,
62 void* reserved);
63
64 typedef bool (*SendFinancialPingNoDelayFn)(RLZTracker::Product product,
65 RLZTracker::AccessPoint* access_point s,
66 const WCHAR* product_signature,
67 const WCHAR* product_brand,
68 const WCHAR* product_id,
69 const WCHAR* product_lang,
70 bool exclude_id,
71 void* reserved);
72 } // extern "C".
73
74 RecordProductEventFn record_event = NULL;
75 GetAccessPointRlzFn get_access_point = NULL;
76 ClearAllProductEventsFn clear_all_events = NULL;
77 SendFinancialPingNoDelayFn send_ping_no_delay = NULL;
78
79 template <typename FuncT>
80 FuncT WireExport(HMODULE module, const char* export_name) {
81 if (!module)
82 return NULL;
83 void* entry_point = ::GetProcAddress(module, export_name);
84 return reinterpret_cast<FuncT>(entry_point);
85 }
86
87 HMODULE LoadRLZLibraryInternal(int directory_key) {
88 FilePath rlz_path;
89 if (!PathService::Get(directory_key, &rlz_path))
90 return NULL;
91 rlz_path = rlz_path.AppendASCII("rlz.dll");
92 return ::LoadLibraryW(rlz_path.value().c_str());
93 }
94
95 bool LoadRLZLibrary(int directory_key) {
96 rlz_dll = LoadRLZLibraryInternal(directory_key);
97 if (!rlz_dll) {
98 // As a last resort we can try the EXE directory.
99 if (directory_key != base::DIR_EXE)
100 rlz_dll = LoadRLZLibraryInternal(base::DIR_EXE);
101 }
102 if (rlz_dll) {
103 record_event =
104 WireExport<RecordProductEventFn>(rlz_dll, "RecordProductEvent");
105 get_access_point =
106 WireExport<GetAccessPointRlzFn>(rlz_dll, "GetAccessPointRlz");
107 clear_all_events =
108 WireExport<ClearAllProductEventsFn>(rlz_dll, "ClearAllProductEvents");
109 send_ping_no_delay =
110 WireExport<SendFinancialPingNoDelayFn>(rlz_dll,
111 "SendFinancialPingNoDelay");
112 return (record_event && get_access_point && clear_all_events &&
113 send_ping_no_delay);
114 }
115 return false;
116 }
117
118 bool SendFinancialPing(const wchar_t* brand, const wchar_t* lang,
119 const wchar_t* referral, bool exclude_id) {
120 RLZTracker::AccessPoint points[] = {RLZTracker::CHROME_OMNIBOX,
121 RLZTracker::CHROME_HOME_PAGE,
122 RLZTracker::NO_ACCESS_POINT};
123 if (!send_ping_no_delay)
124 return false;
125 return send_ping_no_delay(RLZTracker::CHROME, points, L"chrome", brand,
126 referral, lang, exclude_id, NULL);
127 } 58 }
128 59
129 // This class leverages the AutocompleteEditModel notification to know when 60 // This class leverages the AutocompleteEditModel notification to know when
130 // the user first interacted with the omnibox and set a global accordingly. 61 // the user first interacted with the omnibox and set a global accordingly.
131 class OmniBoxUsageObserver : public NotificationObserver { 62 class OmniBoxUsageObserver : public NotificationObserver {
132 public: 63 public:
133 OmniBoxUsageObserver() { 64 OmniBoxUsageObserver() {
134 registrar_.Add(this, NotificationType::OMNIBOX_OPENED_URL, 65 registrar_.Add(this, NotificationType::OMNIBOX_OPENED_URL,
135 NotificationService::AllSources()); 66 NotificationService::AllSources());
136 omnibox_used_ = false; 67 omnibox_used_ = false;
137 DCHECK(!instance_); 68 DCHECK(!instance_);
138 instance_ = this; 69 instance_ = this;
139 } 70 }
140 71
141 virtual void Observe(NotificationType type, 72 virtual void Observe(NotificationType type,
142 const NotificationSource& source, 73 const NotificationSource& source,
143 const NotificationDetails& details) { 74 const NotificationDetails& details) {
144 // Try to record event now, else set the flag to try later when we 75 // Try to record event now, else set the flag to try later when we
145 // attempt the ping. 76 // attempt the ping.
146 if (!RLZTracker::RecordProductEvent(RLZTracker::CHROME, 77 if (!RLZTracker::RecordProductEvent(rlz_lib::CHROME,
147 RLZTracker::CHROME_OMNIBOX, 78 rlz_lib::CHROME_OMNIBOX,
148 RLZTracker::FIRST_SEARCH)) 79 rlz_lib::FIRST_SEARCH))
149 omnibox_used_ = true; 80 omnibox_used_ = true;
150 delete this; 81 delete this;
151 } 82 }
152 83
153 static bool used() { 84 static bool used() {
154 return omnibox_used_; 85 return omnibox_used_;
155 } 86 }
156 87
157 // Deletes the single instance of OmniBoxUsageObserver. 88 // Deletes the single instance of OmniBoxUsageObserver.
158 static void DeleteInstance() { 89 static void DeleteInstance() {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 // Causes a ping to the server using WinInet. 126 // Causes a ping to the server using WinInet.
196 static void _cdecl PingNow(void*) { 127 static void _cdecl PingNow(void*) {
197 std::wstring lang; 128 std::wstring lang;
198 GoogleUpdateSettings::GetLanguage(&lang); 129 GoogleUpdateSettings::GetLanguage(&lang);
199 if (lang.empty()) 130 if (lang.empty())
200 lang = L"en"; 131 lang = L"en";
201 std::wstring brand; 132 std::wstring brand;
202 GoogleUpdateSettings::GetBrand(&brand); 133 GoogleUpdateSettings::GetBrand(&brand);
203 std::wstring referral; 134 std::wstring referral;
204 GoogleUpdateSettings::GetReferral(&referral); 135 GoogleUpdateSettings::GetReferral(&referral);
205 if (SendFinancialPing(brand.c_str(), lang.c_str(), referral.c_str(), 136 if (SendFinancialPing(brand, lang, referral, is_organic(brand))) {
206 is_organic(brand))) {
207 access_values_state = ACCESS_VALUES_STALE; 137 access_values_state = ACCESS_VALUES_STALE;
208 GoogleUpdateSettings::ClearReferral(); 138 GoogleUpdateSettings::ClearReferral();
209 } 139 }
210 } 140 }
211 141
212 // Organic brands all start with GG, such as GGCM. 142 // Organic brands all start with GG, such as GGCM.
213 static bool is_organic(const std::wstring& brand) { 143 static bool is_organic(const std::wstring& brand) {
214 return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG"); 144 return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG");
215 } 145 }
216 }; 146 };
217 147
218 // Performs late RLZ initialization and RLZ event recording for chrome. 148 // Performs late RLZ initialization and RLZ event recording for chrome.
219 // This task needs to run on the UI thread. 149 // This task needs to run on the UI thread.
220 class DelayedInitTask : public Task { 150 class DelayedInitTask : public Task {
221 public: 151 public:
222 explicit DelayedInitTask(int directory_key, bool first_run) 152 explicit DelayedInitTask(bool first_run)
223 : directory_key_(directory_key), first_run_(first_run) { 153 : first_run_(first_run) {
224 } 154 }
225 virtual ~DelayedInitTask() { 155 virtual ~DelayedInitTask() {
226 } 156 }
227 virtual void Run() { 157 virtual void Run() {
228 // For non-interactive tests we don't do the rest of the initialization 158 // For non-interactive tests we don't do the rest of the initialization
229 // because sometimes the very act of loading the dll causes QEMU to crash. 159 // because sometimes the very act of loading the dll causes QEMU to crash.
230 if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(), 160 if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(),
231 NULL, 0)) { 161 NULL, 0)) {
232 return; 162 return;
233 } 163 }
234 // For organic brandcodes do not use rlz at all. Empty brandcode usually 164 // For organic brandcodes do not use rlz at all. Empty brandcode usually
235 // means a chromium install. This is ok. 165 // means a chromium install. This is ok.
236 std::wstring brand; 166 std::wstring brand;
237 GoogleUpdateSettings::GetBrand(&brand); 167 GoogleUpdateSettings::GetBrand(&brand);
238 if (is_strict_organic(brand)) 168 if (is_strict_organic(brand))
239 return; 169 return;
240 170
241 if (!LoadRLZLibrary(directory_key_))
242 return;
243 // Do the initial event recording if is the first run or if we have an 171 // Do the initial event recording if is the first run or if we have an
244 // empty rlz which means we haven't got a chance to do it. 172 // empty rlz which means we haven't got a chance to do it.
245 std::wstring omnibox_rlz; 173 std::wstring omnibox_rlz;
246 RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &omnibox_rlz); 174 RLZTracker::GetAccessPointRlz(rlz_lib::CHROME_OMNIBOX, &omnibox_rlz);
247 175
248 if (first_run_ || omnibox_rlz.empty()) { 176 if (first_run_ || omnibox_rlz.empty()) {
249 // Record the installation of chrome. 177 // Record the installation of chrome.
250 RLZTracker::RecordProductEvent(RLZTracker::CHROME, 178 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
251 RLZTracker::CHROME_OMNIBOX, 179 rlz_lib::CHROME_OMNIBOX,
252 RLZTracker::INSTALL); 180 rlz_lib::INSTALL);
253 RLZTracker::RecordProductEvent(RLZTracker::CHROME, 181 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
254 RLZTracker::CHROME_HOME_PAGE, 182 rlz_lib::CHROME_HOME_PAGE,
255 RLZTracker::INSTALL); 183 rlz_lib::INSTALL);
256 // Record if google is the initial search provider. 184 // Record if google is the initial search provider.
257 if (IsGoogleDefaultSearch()) { 185 if (IsGoogleDefaultSearch()) {
258 RLZTracker::RecordProductEvent(RLZTracker::CHROME, 186 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
259 RLZTracker::CHROME_OMNIBOX, 187 rlz_lib::CHROME_OMNIBOX,
260 RLZTracker::SET_TO_GOOGLE); 188 rlz_lib::SET_TO_GOOGLE);
261 } 189 }
262 } 190 }
263 // Record first user interaction with the omnibox. We call this all the 191 // Record first user interaction with the omnibox. We call this all the
264 // time but the rlz lib should ingore all but the first one. 192 // time but the rlz lib should ingore all but the first one.
265 if (OmniBoxUsageObserver::used()) { 193 if (OmniBoxUsageObserver::used()) {
266 RLZTracker::RecordProductEvent(RLZTracker::CHROME, 194 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
267 RLZTracker::CHROME_OMNIBOX, 195 rlz_lib::CHROME_OMNIBOX,
268 RLZTracker::FIRST_SEARCH); 196 rlz_lib::FIRST_SEARCH);
269 } 197 }
270 // Schedule the daily RLZ ping. 198 // Schedule the daily RLZ ping.
271 base::Thread* thread = g_browser_process->file_thread(); 199 base::Thread* thread = g_browser_process->file_thread();
272 if (thread) 200 if (thread)
273 thread->message_loop()->PostTask(FROM_HERE, new DailyPingTask()); 201 thread->message_loop()->PostTask(FROM_HERE, new DailyPingTask());
274 } 202 }
275 203
276 private: 204 private:
277 bool IsGoogleDefaultSearch() { 205 bool IsGoogleDefaultSearch() {
278 if (!g_browser_process) 206 if (!g_browser_process)
(...skipping 26 matching lines...) Expand all
305 const wchar_t** end = &kBrands[arraysize(kBrands)]; 233 const wchar_t** end = &kBrands[arraysize(kBrands)];
306 const wchar_t** found = std::find(&kBrands[0], end, brand); 234 const wchar_t** found = std::find(&kBrands[0], end, brand);
307 if (found != end) 235 if (found != end)
308 return true; 236 return true;
309 if (StartsWith(brand, L"EUB", true) || StartsWith(brand, L"EUC", true) || 237 if (StartsWith(brand, L"EUB", true) || StartsWith(brand, L"EUC", true) ||
310 StartsWith(brand, L"GGR", true)) 238 StartsWith(brand, L"GGR", true))
311 return true; 239 return true;
312 return false; 240 return false;
313 } 241 }
314 242
315 int directory_key_;
316 bool first_run_; 243 bool first_run_;
317 DISALLOW_IMPLICIT_CONSTRUCTORS(DelayedInitTask); 244 DISALLOW_IMPLICIT_CONSTRUCTORS(DelayedInitTask);
318 }; 245 };
319 246
320 } // namespace 247 } // namespace
321 248
322 bool RLZTracker::InitRlz(int directory_key) { 249 bool RLZTracker::InitRlzDelayed(bool first_run, int delay) {
323 return LoadRLZLibrary(directory_key);
324 }
325
326 bool RLZTracker::InitRlzDelayed(int directory_key, bool first_run, int delay) {
327 // Maximum and minimum delay we would allow to be set through master 250 // Maximum and minimum delay we would allow to be set through master
328 // preferences. Somewhat arbitrary, may need to be adjusted in future. 251 // preferences. Somewhat arbitrary, may need to be adjusted in future.
329 const int kMaxDelay = 200 * 1000; 252 const int kMaxDelay = 200 * 1000;
330 const int kMinDelay = 20 * 1000; 253 const int kMinDelay = 20 * 1000;
331 254
332 delay *= 1000; 255 delay *= 1000;
333 delay = (delay < kMinDelay) ? kMinDelay : delay; 256 delay = (delay < kMinDelay) ? kMinDelay : delay;
334 delay = (delay > kMaxDelay) ? kMaxDelay : delay; 257 delay = (delay > kMaxDelay) ? kMaxDelay : delay;
335 258
336 if (!OmniBoxUsageObserver::used()) 259 if (!OmniBoxUsageObserver::used())
337 new OmniBoxUsageObserver(); 260 new OmniBoxUsageObserver();
338 261
339 // Schedule the delayed init items. 262 // Schedule the delayed init items.
340 MessageLoop::current()->PostDelayedTask(FROM_HERE, 263 MessageLoop::current()->PostDelayedTask(FROM_HERE,
341 new DelayedInitTask(directory_key, first_run), delay); 264 new DelayedInitTask(first_run), delay);
342 return true; 265 return true;
343 } 266 }
344 267
345 bool RLZTracker::RecordProductEvent(Product product, AccessPoint point, 268 bool RLZTracker::RecordProductEvent(rlz_lib::Product product,
346 Event event) { 269 rlz_lib::AccessPoint point,
347 return (record_event) ? record_event(product, point, event, NULL) : false; 270 rlz_lib::Event event_id) {
271 return rlz_lib::RecordProductEvent(product, point, event_id);
348 } 272 }
349 273
350 bool RLZTracker::ClearAllProductEvents(Product product) { 274 bool RLZTracker::ClearAllProductEvents(rlz_lib::Product product) {
351 return (clear_all_events) ? clear_all_events(product, NULL) : false; 275 return rlz_lib::ClearAllProductEvents(product);
352 } 276 }
353 277
354 // We implement caching of the answer of get_access_point() if the request 278 // We implement caching of the answer of get_access_point() if the request
355 // is for CHROME_OMNIBOX. If we had a successful ping, then we update the 279 // is for CHROME_OMNIBOX. If we had a successful ping, then we update the
356 // cached value. 280 // cached value.
357 281
358 bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) { 282 bool RLZTracker::GetAccessPointRlz(rlz_lib::AccessPoint point,
283 std::wstring* rlz) {
359 static std::wstring cached_ommibox_rlz; 284 static std::wstring cached_ommibox_rlz;
360 if (!get_access_point) 285 if ((rlz_lib::CHROME_OMNIBOX == point) &&
361 return false;
362 if ((CHROME_OMNIBOX == point) &&
363 (access_values_state == ACCESS_VALUES_FRESH)) { 286 (access_values_state == ACCESS_VALUES_FRESH)) {
364 *rlz = cached_ommibox_rlz; 287 *rlz = cached_ommibox_rlz;
365 return true; 288 return true;
366 } 289 }
367 wchar_t str_rlz[kMaxRlzLength]; 290 char str_rlz[kMaxRlzLength + 1];
368 if (!get_access_point(point, str_rlz, kMaxRlzLength, NULL)) 291 if (!rlz_lib::GetAccessPointRlz(point, str_rlz, rlz_lib::kMaxRlzLength, NULL))
369 return false; 292 return false;
370 if (CHROME_OMNIBOX == point) { 293 *rlz = ASCIIToWide(std::string(str_rlz));
294 if (rlz_lib::CHROME_OMNIBOX == point) {
371 access_values_state = ACCESS_VALUES_FRESH; 295 access_values_state = ACCESS_VALUES_FRESH;
372 cached_ommibox_rlz.assign(str_rlz); 296 cached_ommibox_rlz.assign(*rlz);
373 } 297 }
374 *rlz = str_rlz;
375 return true; 298 return true;
376 } 299 }
377 300
378 // static 301 // static
379 void RLZTracker::CleanupRlz() { 302 void RLZTracker::CleanupRlz() {
380 OmniBoxUsageObserver::DeleteInstance(); 303 OmniBoxUsageObserver::DeleteInstance();
381 } 304 }
OLDNEW
« no previous file with comments | « chrome/browser/rlz/rlz.h ('k') | chrome/browser/rlz/rlz_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698