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

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

Issue 1212163011: Componentize chrome/browser/rlz (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 5 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
« no previous file with comments | « chrome/browser/rlz/rlz.h ('k') | chrome/browser/rlz/rlz_chromeos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4 //
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
7 // functions do nothing and just return false.
8
9 #include "chrome/browser/rlz/rlz.h"
10
11 #include <algorithm>
12
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/trace_event/trace_event.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/google/google_brand.h"
23 #include "chrome/browser/prefs/session_startup_pref.h"
24 #include "chrome/browser/search_engines/template_url_service_factory.h"
25 #include "chrome/browser/ui/startup/startup_browser_creator.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/pref_names.h"
28 #include "components/google/core/browser/google_util.h"
29 #include "components/omnibox/browser/omnibox_log.h"
30 #include "components/search_engines/template_url.h"
31 #include "components/search_engines/template_url_service.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/navigation_controller.h"
34 #include "content/public/browser/navigation_details.h"
35 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/browser/notification_service.h"
37 #include "net/http/http_util.h"
38
39 #if defined(OS_WIN)
40 #include "chrome/installer/util/google_update_settings.h"
41 #else
42 namespace GoogleUpdateSettings {
43 static bool GetLanguage(base::string16* language) {
44 // TODO(thakis): Implement.
45 NOTIMPLEMENTED();
46 return false;
47 }
48
49 // The referral program is defunct and not used. No need to implement these
50 // functions on non-Win platforms.
51 static bool GetReferral(base::string16* referral) {
52 return true;
53 }
54 static bool ClearReferral() {
55 return true;
56 }
57 } // namespace GoogleUpdateSettings
58 #endif
59
60 using content::BrowserThread;
61 using content::NavigationEntry;
62 using content::NavigationController;
63
64 namespace {
65
66 // Maximum and minimum delay for financial ping we would allow to be set through
67 // master preferences. Somewhat arbitrary, may need to be adjusted in future.
68 const base::TimeDelta kMaxInitDelay = base::TimeDelta::FromSeconds(200);
69 const base::TimeDelta kMinInitDelay = base::TimeDelta::FromSeconds(20);
70
71 bool IsBrandOrganic(const std::string& brand) {
72 return brand.empty() || google_brand::IsOrganic(brand);
73 }
74
75 void RecordProductEvents(bool first_run,
76 bool is_google_default_search,
77 bool is_google_homepage,
78 bool is_google_in_startpages,
79 bool already_ran,
80 bool omnibox_used,
81 bool homepage_used,
82 bool app_list_used) {
83 TRACE_EVENT0("RLZ", "RecordProductEvents");
84 // Record the installation of chrome. We call this all the time but the rlz
85 // lib should ignore all but the first one.
86 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
87 RLZTracker::ChromeOmnibox(),
88 rlz_lib::INSTALL);
89 #if !defined(OS_IOS)
90 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
91 RLZTracker::ChromeHomePage(),
92 rlz_lib::INSTALL);
93 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
94 RLZTracker::ChromeAppList(),
95 rlz_lib::INSTALL);
96 #endif // !defined(OS_IOS)
97
98 if (!already_ran) {
99 // Do the initial event recording if is the first run or if we have an
100 // empty rlz which means we haven't got a chance to do it.
101 char omnibox_rlz[rlz_lib::kMaxRlzLength + 1];
102 if (!rlz_lib::GetAccessPointRlz(RLZTracker::ChromeOmnibox(), omnibox_rlz,
103 rlz_lib::kMaxRlzLength)) {
104 omnibox_rlz[0] = 0;
105 }
106
107 // Record if google is the initial search provider and/or home page.
108 if ((first_run || omnibox_rlz[0] == 0) && is_google_default_search) {
109 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
110 RLZTracker::ChromeOmnibox(),
111 rlz_lib::SET_TO_GOOGLE);
112 }
113
114 #if !defined(OS_IOS)
115 char homepage_rlz[rlz_lib::kMaxRlzLength + 1];
116 if (!rlz_lib::GetAccessPointRlz(RLZTracker::ChromeHomePage(), homepage_rlz,
117 rlz_lib::kMaxRlzLength)) {
118 homepage_rlz[0] = 0;
119 }
120
121 if ((first_run || homepage_rlz[0] == 0) &&
122 (is_google_homepage || is_google_in_startpages)) {
123 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
124 RLZTracker::ChromeHomePage(),
125 rlz_lib::SET_TO_GOOGLE);
126 }
127
128 char app_list_rlz[rlz_lib::kMaxRlzLength + 1];
129 if (!rlz_lib::GetAccessPointRlz(RLZTracker::ChromeAppList(), app_list_rlz,
130 rlz_lib::kMaxRlzLength)) {
131 app_list_rlz[0] = 0;
132 }
133
134 // Record if google is the initial search provider and/or home page.
135 if ((first_run || app_list_rlz[0] == 0) && is_google_default_search) {
136 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
137 RLZTracker::ChromeAppList(),
138 rlz_lib::SET_TO_GOOGLE);
139 }
140 #endif // !defined(OS_IOS)
141 }
142
143 // Record first user interaction with the omnibox. We call this all the
144 // time but the rlz lib should ingore all but the first one.
145 if (omnibox_used) {
146 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
147 RLZTracker::ChromeOmnibox(),
148 rlz_lib::FIRST_SEARCH);
149 }
150
151 #if !defined(OS_IOS)
152 // Record first user interaction with the home page. We call this all the
153 // time but the rlz lib should ingore all but the first one.
154 if (homepage_used || is_google_in_startpages) {
155 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
156 RLZTracker::ChromeHomePage(),
157 rlz_lib::FIRST_SEARCH);
158 }
159
160 // Record first user interaction with the app list. We call this all the
161 // time but the rlz lib should ingore all but the first one.
162 if (app_list_used) {
163 rlz_lib::RecordProductEvent(rlz_lib::CHROME,
164 RLZTracker::ChromeAppList(),
165 rlz_lib::FIRST_SEARCH);
166 }
167 #endif // !defined(OS_IOS)
168 }
169
170 bool SendFinancialPing(const std::string& brand,
171 const base::string16& lang,
172 const base::string16& referral) {
173 rlz_lib::AccessPoint points[] = {RLZTracker::ChromeOmnibox(),
174 #if !defined(OS_IOS)
175 RLZTracker::ChromeHomePage(),
176 RLZTracker::ChromeAppList(),
177 #endif
178 rlz_lib::NO_ACCESS_POINT};
179 std::string lang_ascii(base::UTF16ToASCII(lang));
180 std::string referral_ascii(base::UTF16ToASCII(referral));
181 std::string product_signature;
182 #if defined(OS_CHROMEOS)
183 product_signature = "chromeos";
184 #else
185 product_signature = "chrome";
186 #endif
187 return rlz_lib::SendFinancialPing(rlz_lib::CHROME, points,
188 product_signature.c_str(),
189 brand.c_str(), referral_ascii.c_str(),
190 lang_ascii.c_str(), false, true);
191 }
192
193 } // namespace
194
195 RLZTracker* RLZTracker::tracker_ = NULL;
196
197 // static
198 RLZTracker* RLZTracker::GetInstance() {
199 return tracker_ ? tracker_ : Singleton<RLZTracker>::get();
200 }
201
202 RLZTracker::RLZTracker()
203 : first_run_(false),
204 send_ping_immediately_(false),
205 is_google_default_search_(false),
206 is_google_homepage_(false),
207 is_google_in_startpages_(false),
208 worker_pool_token_(BrowserThread::GetBlockingPool()->GetSequenceToken()),
209 already_ran_(false),
210 omnibox_used_(false),
211 homepage_used_(false),
212 app_list_used_(false),
213 min_init_delay_(kMinInitDelay) {
214 }
215
216 RLZTracker::~RLZTracker() {
217 }
218
219 // static
220 bool RLZTracker::InitRlzDelayed(bool first_run,
221 bool send_ping_immediately,
222 base::TimeDelta delay,
223 bool is_google_default_search,
224 bool is_google_homepage,
225 bool is_google_in_startpages) {
226 return GetInstance()->Init(first_run, send_ping_immediately, delay,
227 is_google_default_search, is_google_homepage,
228 is_google_in_startpages);
229 }
230
231 // static
232 bool RLZTracker::InitRlzFromProfileDelayed(Profile* profile,
233 bool first_run,
234 bool send_ping_immediately,
235 base::TimeDelta delay) {
236 bool is_google_default_search = false;
237 TemplateURLService* template_url_service =
238 TemplateURLServiceFactory::GetForProfile(profile);
239 if (template_url_service) {
240 const TemplateURL* url_template =
241 template_url_service->GetDefaultSearchProvider();
242 is_google_default_search =
243 url_template && url_template->url_ref().HasGoogleBaseURLs(
244 template_url_service->search_terms_data());
245 }
246
247 PrefService* pref_service = profile->GetPrefs();
248 bool is_google_homepage = google_util::IsGoogleHomePageUrl(
249 GURL(pref_service->GetString(prefs::kHomePage)));
250
251 bool is_google_in_startpages = false;
252 #if !defined(OS_IOS)
253 // iOS does not have a notion of startpages.
254 SessionStartupPref session_startup_prefs =
255 StartupBrowserCreator::GetSessionStartupPref(
256 *base::CommandLine::ForCurrentProcess(), profile);
257 if (session_startup_prefs.type == SessionStartupPref::URLS) {
258 is_google_in_startpages =
259 std::count_if(session_startup_prefs.urls.begin(),
260 session_startup_prefs.urls.end(),
261 google_util::IsGoogleHomePageUrl) > 0;
262 }
263 #endif
264
265 if (!InitRlzDelayed(first_run, send_ping_immediately, delay,
266 is_google_default_search, is_google_homepage,
267 is_google_in_startpages)) {
268 return false;
269 }
270
271 #if !defined(OS_IOS)
272 // Prime the RLZ cache for the home page access point so that its avaiable
273 // for the startup page if needed (i.e., when the startup page is set to
274 // the home page).
275 GetAccessPointRlz(ChromeHomePage(), NULL);
276 #endif // !defined(OS_IOS)
277
278 return true;
279 }
280
281 bool RLZTracker::Init(bool first_run,
282 bool send_ping_immediately,
283 base::TimeDelta delay,
284 bool is_google_default_search,
285 bool is_google_homepage,
286 bool is_google_in_startpages) {
287 first_run_ = first_run;
288 is_google_default_search_ = is_google_default_search;
289 is_google_homepage_ = is_google_homepage;
290 is_google_in_startpages_ = is_google_in_startpages;
291 send_ping_immediately_ = send_ping_immediately;
292
293 // Enable zero delays for testing.
294 if (base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType))
295 EnableZeroDelayForTesting();
296
297 delay = std::min(kMaxInitDelay, std::max(min_init_delay_, delay));
298
299 if (google_brand::GetBrand(&brand_) && !IsBrandOrganic(brand_)) {
300 // Register for notifications from the omnibox so that we can record when
301 // the user performs a first search.
302 registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
303 content::NotificationService::AllSources());
304
305 #if !defined(OS_IOS)
306 // Register for notifications from navigations, to see if the user has used
307 // the home page.
308 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
309 content::NotificationService::AllSources());
310 #endif // !defined(OS_IOS)
311 }
312 google_brand::GetReactivationBrand(&reactivation_brand_);
313
314 net::URLRequestContextGetter* context_getter =
315 g_browser_process->system_request_context();
316
317 // Could be NULL; don't run if so. RLZ will try again next restart.
318 if (context_getter) {
319 rlz_lib::SetURLRequestContext(context_getter);
320 ScheduleDelayedInit(delay);
321 }
322
323 return true;
324 }
325
326 void RLZTracker::ScheduleDelayedInit(base::TimeDelta delay) {
327 // The RLZTracker is a singleton object that outlives any runnable tasks
328 // that will be queued up.
329 BrowserThread::GetBlockingPool()->PostDelayedSequencedWorkerTask(
330 worker_pool_token_,
331 FROM_HERE,
332 base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)),
333 delay);
334 }
335
336 void RLZTracker::DelayedInit() {
337 bool schedule_ping = false;
338
339 // For organic brandcodes do not use rlz at all. Empty brandcode usually
340 // means a chromium install. This is ok.
341 if (!IsBrandOrganic(brand_)) {
342 RecordProductEvents(first_run_, is_google_default_search_,
343 is_google_homepage_, is_google_in_startpages_,
344 already_ran_, omnibox_used_, homepage_used_,
345 app_list_used_);
346 schedule_ping = true;
347 }
348
349 // If chrome has been reactivated, record the events for this brand
350 // as well.
351 if (!IsBrandOrganic(reactivation_brand_)) {
352 rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str());
353 RecordProductEvents(first_run_, is_google_default_search_,
354 is_google_homepage_, is_google_in_startpages_,
355 already_ran_, omnibox_used_, homepage_used_,
356 app_list_used_);
357 schedule_ping = true;
358 }
359
360 already_ran_ = true;
361
362 if (schedule_ping)
363 ScheduleFinancialPing();
364 }
365
366 void RLZTracker::ScheduleFinancialPing() {
367 BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior(
368 worker_pool_token_,
369 FROM_HERE,
370 base::Bind(&RLZTracker::PingNowImpl, base::Unretained(this)),
371 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
372 }
373
374 void RLZTracker::PingNowImpl() {
375 TRACE_EVENT0("RLZ", "RLZTracker::PingNowImpl");
376 base::string16 lang;
377 GoogleUpdateSettings::GetLanguage(&lang);
378 if (lang.empty())
379 lang = base::ASCIIToUTF16("en");
380 base::string16 referral;
381 GoogleUpdateSettings::GetReferral(&referral);
382
383 if (!IsBrandOrganic(brand_) && SendFinancialPing(brand_, lang, referral)) {
384 GoogleUpdateSettings::ClearReferral();
385
386 {
387 base::AutoLock lock(cache_lock_);
388 rlz_cache_.clear();
389 }
390
391 // Prime the RLZ cache for the access points we are interested in.
392 GetAccessPointRlz(RLZTracker::ChromeOmnibox(), NULL);
393 #if !defined(OS_IOS)
394 GetAccessPointRlz(RLZTracker::ChromeHomePage(), NULL);
395 GetAccessPointRlz(RLZTracker::ChromeAppList(), NULL);
396 #endif // !defined(OS_IOS)
397 }
398
399 if (!IsBrandOrganic(reactivation_brand_)) {
400 rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str());
401 SendFinancialPing(reactivation_brand_, lang, referral);
402 }
403 }
404
405 bool RLZTracker::SendFinancialPing(const std::string& brand,
406 const base::string16& lang,
407 const base::string16& referral) {
408 return ::SendFinancialPing(brand, lang, referral);
409 }
410
411 void RLZTracker::Observe(int type,
412 const content::NotificationSource& source,
413 const content::NotificationDetails& details) {
414 switch (type) {
415 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
416 // In M-36, we made NOTIFICATION_OMNIBOX_OPENED_URL fire more often than
417 // it did previously. The RLZ folks want RLZ's "first search" detection
418 // to remain as unaffected as possible by this change. This test is
419 // there to keep the old behavior.
420 if (!content::Details<OmniboxLog>(details).ptr()->is_popup_open)
421 break;
422 RecordFirstSearch(ChromeOmnibox());
423 registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
424 content::NotificationService::AllSources());
425 break;
426 #if !defined(OS_IOS)
427 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
428 // Firstly check if it is a Google search.
429 content::LoadCommittedDetails* load_details =
430 content::Details<content::LoadCommittedDetails>(details).ptr();
431 if (load_details == NULL)
432 break;
433
434 NavigationEntry* entry = load_details->entry;
435 if (entry == NULL)
436 break;
437
438 if (google_util::IsGoogleSearchUrl(entry->GetURL())) {
439 // If it is a Google search, check if it originates from HOMEPAGE by
440 // getting the previous NavigationEntry.
441 NavigationController* controller =
442 content::Source<NavigationController>(source).ptr();
443 if (controller == NULL)
444 break;
445
446 int entry_index = controller->GetLastCommittedEntryIndex();
447 if (entry_index < 1)
448 break;
449
450 const NavigationEntry* previous_entry = controller->GetEntryAtIndex(
451 entry_index - 1);
452
453 if (previous_entry == NULL)
454 break;
455
456 // Make sure it is a Google web page originated from HOMEPAGE.
457 if (google_util::IsGoogleHomePageUrl(previous_entry->GetURL()) &&
458 ((previous_entry->GetTransitionType() &
459 ui::PAGE_TRANSITION_HOME_PAGE) != 0)) {
460 RecordFirstSearch(ChromeHomePage());
461 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
462 content::NotificationService::AllSources());
463 }
464 }
465 break;
466 }
467 #endif // !defined(OS_IOS)
468 default:
469 NOTREACHED();
470 break;
471 }
472 }
473
474 // static
475 bool RLZTracker::RecordProductEvent(rlz_lib::Product product,
476 rlz_lib::AccessPoint point,
477 rlz_lib::Event event_id) {
478 return GetInstance()->RecordProductEventImpl(product, point, event_id);
479 }
480
481 bool RLZTracker::RecordProductEventImpl(rlz_lib::Product product,
482 rlz_lib::AccessPoint point,
483 rlz_lib::Event event_id) {
484 // Make sure we don't access disk outside of the I/O thread.
485 // In such case we repost the task on the right thread and return error.
486 if (ScheduleRecordProductEvent(product, point, event_id))
487 return true;
488
489 bool ret = rlz_lib::RecordProductEvent(product, point, event_id);
490
491 // If chrome has been reactivated, record the event for this brand as well.
492 if (!reactivation_brand_.empty()) {
493 rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str());
494 ret &= rlz_lib::RecordProductEvent(product, point, event_id);
495 }
496
497 return ret;
498 }
499
500 bool RLZTracker::ScheduleRecordProductEvent(rlz_lib::Product product,
501 rlz_lib::AccessPoint point,
502 rlz_lib::Event event_id) {
503 if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
504 return false;
505
506 BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior(
507 worker_pool_token_,
508 FROM_HERE,
509 base::Bind(base::IgnoreResult(&RLZTracker::RecordProductEvent),
510 product, point, event_id),
511 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
512
513 return true;
514 }
515
516 void RLZTracker::RecordFirstSearch(rlz_lib::AccessPoint point) {
517 // Make sure we don't access disk outside of the I/O thread.
518 // In such case we repost the task on the right thread and return error.
519 if (ScheduleRecordFirstSearch(point))
520 return;
521
522 bool* record_used = GetAccessPointRecord(point);
523
524 // Try to record event now, else set the flag to try later when we
525 // attempt the ping.
526 if (!RecordProductEvent(rlz_lib::CHROME, point, rlz_lib::FIRST_SEARCH))
527 *record_used = true;
528 else if (send_ping_immediately_ && point == ChromeOmnibox())
529 ScheduleDelayedInit(base::TimeDelta());
530 }
531
532 bool RLZTracker::ScheduleRecordFirstSearch(rlz_lib::AccessPoint point) {
533 if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
534 return false;
535 BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior(
536 worker_pool_token_,
537 FROM_HERE,
538 base::Bind(&RLZTracker::RecordFirstSearch,
539 base::Unretained(this), point),
540 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
541 return true;
542 }
543
544 bool* RLZTracker::GetAccessPointRecord(rlz_lib::AccessPoint point) {
545 if (point == ChromeOmnibox())
546 return &omnibox_used_;
547 #if !defined(OS_IOS)
548 if (point == ChromeHomePage())
549 return &homepage_used_;
550 if (point == ChromeAppList())
551 return &app_list_used_;
552 #endif // !defined(OS_IOS)
553 NOTREACHED();
554 return NULL;
555 }
556
557 // static
558 std::string RLZTracker::GetAccessPointHttpHeader(rlz_lib::AccessPoint point) {
559 TRACE_EVENT0("RLZ", "RLZTracker::GetAccessPointHttpHeader");
560 std::string extra_headers;
561 base::string16 rlz_string;
562 RLZTracker::GetAccessPointRlz(point, &rlz_string);
563 if (!rlz_string.empty()) {
564 net::HttpUtil::AppendHeaderIfMissing("X-Rlz-String",
565 base::UTF16ToUTF8(rlz_string),
566 &extra_headers);
567 }
568
569 return extra_headers;
570 }
571
572 // GetAccessPointRlz() caches RLZ strings for all access points. If we had
573 // a successful ping, then we update the cached value.
574 bool RLZTracker::GetAccessPointRlz(rlz_lib::AccessPoint point,
575 base::string16* rlz) {
576 TRACE_EVENT0("RLZ", "RLZTracker::GetAccessPointRlz");
577 return GetInstance()->GetAccessPointRlzImpl(point, rlz);
578 }
579
580 // GetAccessPointRlz() caches RLZ strings for all access points. If we had
581 // a successful ping, then we update the cached value.
582 bool RLZTracker::GetAccessPointRlzImpl(rlz_lib::AccessPoint point,
583 base::string16* rlz) {
584 // If the RLZ string for the specified access point is already cached,
585 // simply return its value.
586 {
587 base::AutoLock lock(cache_lock_);
588 if (rlz_cache_.find(point) != rlz_cache_.end()) {
589 if (rlz)
590 *rlz = rlz_cache_[point];
591 return true;
592 }
593 }
594
595 // Make sure we don't access disk outside of the I/O thread.
596 // In such case we repost the task on the right thread and return error.
597 if (ScheduleGetAccessPointRlz(point))
598 return false;
599
600 char str_rlz[rlz_lib::kMaxRlzLength + 1];
601 if (!rlz_lib::GetAccessPointRlz(point, str_rlz, rlz_lib::kMaxRlzLength))
602 return false;
603
604 base::string16 rlz_local(base::ASCIIToUTF16(str_rlz));
605 if (rlz)
606 *rlz = rlz_local;
607
608 base::AutoLock lock(cache_lock_);
609 rlz_cache_[point] = rlz_local;
610 return true;
611 }
612
613 bool RLZTracker::ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point) {
614 if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
615 return false;
616
617 base::string16* not_used = NULL;
618 BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior(
619 worker_pool_token_,
620 FROM_HERE,
621 base::Bind(base::IgnoreResult(&RLZTracker::GetAccessPointRlz), point,
622 not_used),
623 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
624 return true;
625 }
626
627 #if defined(OS_CHROMEOS)
628 // static
629 void RLZTracker::ClearRlzState() {
630 GetInstance()->ClearRlzStateImpl();
631 }
632
633 void RLZTracker::ClearRlzStateImpl() {
634 if (ScheduleClearRlzState())
635 return;
636 rlz_lib::ClearAllProductEvents(rlz_lib::CHROME);
637 }
638
639 bool RLZTracker::ScheduleClearRlzState() {
640 if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
641 return false;
642
643 BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior(
644 worker_pool_token_,
645 FROM_HERE,
646 base::Bind(&RLZTracker::ClearRlzStateImpl,
647 base::Unretained(this)),
648 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
649 return true;
650 }
651 #endif
652
653 // static
654 void RLZTracker::CleanupRlz() {
655 GetInstance()->rlz_cache_.clear();
656 GetInstance()->registrar_.RemoveAll();
657 rlz_lib::SetURLRequestContext(NULL);
658 }
659
660 // static
661 void RLZTracker::EnableZeroDelayForTesting() {
662 GetInstance()->min_init_delay_ = base::TimeDelta();
663 }
664
665 #if !defined(OS_IOS)
666 // static
667 void RLZTracker::RecordAppListSearch() {
668 GetInstance()->RecordFirstSearch(RLZTracker::ChromeAppList());
669 }
670 #endif
OLDNEW
« no previous file with comments | « chrome/browser/rlz/rlz.h ('k') | chrome/browser/rlz/rlz_chromeos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698