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