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

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

Issue 6028012: Fixed RLZTracker::GetAccessPointRlz to route IO calls to the FILE thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added thread safety to the RLZ code. Created 9 years, 11 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 | « no previous file | chrome/browser/search_engines/search_terms_data.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) 2011 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
11 #include <windows.h> 11 #include <windows.h>
12 #include <process.h> 12 #include <process.h>
13 13
14 #include <algorithm> 14 #include <algorithm>
15 15
16 #include "base/file_path.h" 16 #include "base/file_path.h"
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #include "base/path_service.h" 18 #include "base/path_service.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/task.h" 20 #include "base/task.h"
21 #include "base/threading/thread.h" 21 #include "base/threading/thread.h"
22 #include "base/threading/thread_restrictions.h" 22 #include "base/threading/thread_restrictions.h"
23 #include "base/synchronization/lock.h"
23 #include "base/utf_string_conversions.h" 24 #include "base/utf_string_conversions.h"
24 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/browser_thread.h"
25 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/profiles/profile_manager.h" 28 #include "chrome/browser/profiles/profile_manager.h"
27 #include "chrome/browser/search_engines/template_url.h" 29 #include "chrome/browser/search_engines/template_url.h"
28 #include "chrome/browser/search_engines/template_url_model.h" 30 #include "chrome/browser/search_engines/template_url_model.h"
29 #include "chrome/common/chrome_paths.h" 31 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/env_vars.h" 32 #include "chrome/common/env_vars.h"
31 #include "chrome/common/notification_registrar.h" 33 #include "chrome/common/notification_registrar.h"
32 #include "chrome/common/notification_service.h" 34 #include "chrome/common/notification_service.h"
33 #include "chrome/installer/util/google_update_settings.h" 35 #include "chrome/installer/util/google_update_settings.h"
34 36
35 namespace { 37 namespace {
36 38
37 // The maximum length of an access points RLZ in wide chars. 39 // The maximum length of an access points RLZ in wide chars.
38 const DWORD kMaxRlzLength = 64; 40 const DWORD kMaxRlzLength = 64;
39 41
40 enum { 42 enum {
41 ACCESS_VALUES_STALE, // Possibly new values available. 43 ACCESS_VALUES_STALE, // Possibly new values available.
42 ACCESS_VALUES_FRESH // The cached values are current. 44 ACCESS_VALUES_FRESH // The cached values are current.
43 }; 45 };
44 46
45 // Tracks if we have tried and succeeded sending the ping. This helps us 47 // Tracks if we have tried and succeeded sending the ping. This helps us
46 // decide if we need to refresh the some cached strings. 48 // decide if we need to refresh the some cached strings.
47 volatile int access_values_state = ACCESS_VALUES_STALE; 49 volatile int access_values_state = ACCESS_VALUES_STALE;
50 base::Lock rlz_lock;
48 51
49 bool SendFinancialPing(const std::wstring& brand, const std::wstring& lang, 52 bool SendFinancialPing(const std::wstring& brand, const std::wstring& lang,
50 const std::wstring& referral, bool exclude_id) { 53 const std::wstring& referral, bool exclude_id) {
51 rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX, 54 rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX,
52 rlz_lib::CHROME_HOME_PAGE, 55 rlz_lib::CHROME_HOME_PAGE,
53 rlz_lib::NO_ACCESS_POINT}; 56 rlz_lib::NO_ACCESS_POINT};
54 std::string brand_ascii(WideToASCII(brand)); 57 std::string brand_ascii(WideToASCII(brand));
55 std::string lang_ascii(WideToASCII(lang)); 58 std::string lang_ascii(WideToASCII(lang));
56 std::string referral_ascii(WideToASCII(referral)); 59 std::string referral_ascii(WideToASCII(referral));
57 60
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 143
141 std::wstring lang; 144 std::wstring lang;
142 GoogleUpdateSettings::GetLanguage(&lang); 145 GoogleUpdateSettings::GetLanguage(&lang);
143 if (lang.empty()) 146 if (lang.empty())
144 lang = L"en"; 147 lang = L"en";
145 std::wstring brand; 148 std::wstring brand;
146 GoogleUpdateSettings::GetBrand(&brand); 149 GoogleUpdateSettings::GetBrand(&brand);
147 std::wstring referral; 150 std::wstring referral;
148 GoogleUpdateSettings::GetReferral(&referral); 151 GoogleUpdateSettings::GetReferral(&referral);
149 if (SendFinancialPing(brand, lang, referral, is_organic(brand))) { 152 if (SendFinancialPing(brand, lang, referral, is_organic(brand))) {
153 base::AutoLock lock(rlz_lock);
150 access_values_state = ACCESS_VALUES_STALE; 154 access_values_state = ACCESS_VALUES_STALE;
151 GoogleUpdateSettings::ClearReferral(); 155 GoogleUpdateSettings::ClearReferral();
152 } 156 }
153 } 157 }
154 158
155 // Organic brands all start with GG, such as GGCM. 159 // Organic brands all start with GG, such as GGCM.
156 static bool is_organic(const std::wstring& brand) { 160 static bool is_organic(const std::wstring& brand) {
157 return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG"); 161 return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG");
158 } 162 }
159 }; 163 };
160 164
161 // Performs late RLZ initialization and RLZ event recording for chrome. 165 // Performs late RLZ initialization and RLZ event recording for chrome.
162 // This task needs to run on the UI thread. 166 // This task needs to run on the UI thread.
163 class DelayedInitTask : public Task { 167 class DelayedInitTask : public Task {
164 public: 168 public:
165 explicit DelayedInitTask(bool first_run) 169 explicit DelayedInitTask(bool first_run)
166 : first_run_(first_run) { 170 : first_run_(first_run) {
167 } 171 }
168 virtual ~DelayedInitTask() { 172 virtual ~DelayedInitTask() {
169 } 173 }
170 virtual void Run() { 174 virtual void Run() {
171 // Needs to be evaluated. See http://crbug.com/62328.
172 base::ThreadRestrictions::ScopedAllowIO allow_io;
173
174 // For non-interactive tests we don't do the rest of the initialization 175 // For non-interactive tests we don't do the rest of the initialization
175 // because sometimes the very act of loading the dll causes QEMU to crash. 176 // because sometimes the very act of loading the dll causes QEMU to crash.
176 if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(), 177 if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(),
177 NULL, 0)) { 178 NULL, 0)) {
178 return; 179 return;
179 } 180 }
180 // For organic brandcodes do not use rlz at all. Empty brandcode usually 181 // For organic brandcodes do not use rlz at all. Empty brandcode usually
181 // means a chromium install. This is ok. 182 // means a chromium install. This is ok.
182 std::wstring brand; 183 std::wstring brand;
183 if (!GoogleUpdateSettings::GetBrand(&brand) || brand.empty() || 184 if (!GoogleUpdateSettings::GetBrand(&brand) || brand.empty() ||
(...skipping 21 matching lines...) Expand all
205 } 206 }
206 } 207 }
207 // Record first user interaction with the omnibox. We call this all the 208 // Record first user interaction with the omnibox. We call this all the
208 // time but the rlz lib should ingore all but the first one. 209 // time but the rlz lib should ingore all but the first one.
209 if (OmniBoxUsageObserver::used()) { 210 if (OmniBoxUsageObserver::used()) {
210 RLZTracker::RecordProductEvent(rlz_lib::CHROME, 211 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
211 rlz_lib::CHROME_OMNIBOX, 212 rlz_lib::CHROME_OMNIBOX,
212 rlz_lib::FIRST_SEARCH); 213 rlz_lib::FIRST_SEARCH);
213 } 214 }
214 // Schedule the daily RLZ ping. 215 // Schedule the daily RLZ ping.
215 base::Thread* thread = g_browser_process->file_thread(); 216 MessageLoop::current()->PostTask(FROM_HERE, new DailyPingTask());
216 if (thread)
217 thread->message_loop()->PostTask(FROM_HERE, new DailyPingTask());
218 } 217 }
219 218
220 private: 219 private:
221 bool IsGoogleDefaultSearch() { 220 bool IsGoogleDefaultSearch() {
222 if (!g_browser_process) 221 if (!g_browser_process)
223 return false; 222 return false;
224 FilePath user_data_dir; 223 FilePath user_data_dir;
225 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) 224 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
226 return false; 225 return false;
227 ProfileManager* profile_manager = g_browser_process->profile_manager(); 226 ProfileManager* profile_manager = g_browser_process->profile_manager();
(...skipping 23 matching lines...) Expand all
251 const int kMinDelay = 20 * 1000; 250 const int kMinDelay = 20 * 1000;
252 251
253 delay *= 1000; 252 delay *= 1000;
254 delay = (delay < kMinDelay) ? kMinDelay : delay; 253 delay = (delay < kMinDelay) ? kMinDelay : delay;
255 delay = (delay > kMaxDelay) ? kMaxDelay : delay; 254 delay = (delay > kMaxDelay) ? kMaxDelay : delay;
256 255
257 if (!OmniBoxUsageObserver::used()) 256 if (!OmniBoxUsageObserver::used())
258 new OmniBoxUsageObserver(); 257 new OmniBoxUsageObserver();
259 258
260 // Schedule the delayed init items. 259 // Schedule the delayed init items.
261 MessageLoop::current()->PostDelayedTask(FROM_HERE, 260 BrowserThread::PostDelayedTask(
262 new DelayedInitTask(first_run), delay); 261 BrowserThread::FILE, FROM_HERE, new DelayedInitTask(first_run), delay);
263 return true; 262 return true;
264 } 263 }
265 264
266 bool RLZTracker::RecordProductEvent(rlz_lib::Product product, 265 bool RLZTracker::RecordProductEvent(rlz_lib::Product product,
267 rlz_lib::AccessPoint point, 266 rlz_lib::AccessPoint point,
268 rlz_lib::Event event_id) { 267 rlz_lib::Event event_id) {
269 return rlz_lib::RecordProductEvent(product, point, event_id); 268 return rlz_lib::RecordProductEvent(product, point, event_id);
270 } 269 }
271 270
272 bool RLZTracker::ClearAllProductEvents(rlz_lib::Product product) { 271 bool RLZTracker::ClearAllProductEvents(rlz_lib::Product product) {
273 return rlz_lib::ClearAllProductEvents(product); 272 return rlz_lib::ClearAllProductEvents(product);
274 } 273 }
275 274
276 // We implement caching of the answer of get_access_point() if the request 275 // We implement caching of the answer of get_access_point() if the request
277 // is for CHROME_OMNIBOX. If we had a successful ping, then we update the 276 // is for CHROME_OMNIBOX. If we had a successful ping, then we update the
278 // cached value. 277 // cached value.
279 278
280 bool RLZTracker::GetAccessPointRlz(rlz_lib::AccessPoint point, 279 bool RLZTracker::GetAccessPointRlz(rlz_lib::AccessPoint point,
281 std::wstring* rlz) { 280 std::wstring* rlz) {
282 static std::wstring cached_ommibox_rlz; 281 static std::wstring cached_ommibox_rlz;
283 if ((rlz_lib::CHROME_OMNIBOX == point) && 282 if (rlz_lib::CHROME_OMNIBOX == point) {
284 (access_values_state == ACCESS_VALUES_FRESH)) { 283 base::AutoLock lock(rlz_lock);
285 *rlz = cached_ommibox_rlz; 284 if (access_values_state == ACCESS_VALUES_FRESH) {
286 return true; 285 *rlz = cached_ommibox_rlz;
286 return true;
287 }
287 } 288 }
289
290 // Make sure we don't access disk outside of the file context.
291 // In such case we repost the task on the right thread and return error.
292 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
293 // Caching of access points is now only implemented for the CHROME_OMNIBOX.
294 // Thus it is not possible to call this function on another thread for
295 // other access points until proper caching for these has been implemented
296 // and the code that calls this function can handle synchronous fetching
297 // of the access point.
298 DCHECK_EQ(rlz_lib::CHROME_OMNIBOX, point);
299
300 BrowserThread::PostTask(
301 BrowserThread::FILE, FROM_HERE,
302 NewRunnableFunction(&RLZTracker::GetAccessPointRlz,
303 point, &cached_ommibox_rlz));
304 rlz->erase();
305 return false;
306 }
307
288 char str_rlz[kMaxRlzLength + 1]; 308 char str_rlz[kMaxRlzLength + 1];
289 if (!rlz_lib::GetAccessPointRlz(point, str_rlz, rlz_lib::kMaxRlzLength, NULL)) 309 if (!rlz_lib::GetAccessPointRlz(point, str_rlz, rlz_lib::kMaxRlzLength, NULL))
290 return false; 310 return false;
291 *rlz = ASCIIToWide(std::string(str_rlz)); 311 *rlz = ASCIIToWide(std::string(str_rlz));
292 if (rlz_lib::CHROME_OMNIBOX == point) { 312 if (rlz_lib::CHROME_OMNIBOX == point) {
313 base::AutoLock lock(rlz_lock);
314 cached_ommibox_rlz.assign(*rlz);
293 access_values_state = ACCESS_VALUES_FRESH; 315 access_values_state = ACCESS_VALUES_FRESH;
294 cached_ommibox_rlz.assign(*rlz);
295 } 316 }
296 return true; 317 return true;
297 } 318 }
298 319
299 // static 320 // static
300 void RLZTracker::CleanupRlz() { 321 void RLZTracker::CleanupRlz() {
301 OmniBoxUsageObserver::DeleteInstance(); 322 OmniBoxUsageObserver::DeleteInstance();
302 } 323 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/search_engines/search_terms_data.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698