| Index: chrome/browser/rlz/rlz.cc
|
| ===================================================================
|
| --- chrome/browser/rlz/rlz.cc (revision 98701)
|
| +++ chrome/browser/rlz/rlz.cc (working copy)
|
| @@ -31,23 +31,78 @@
|
| #include "chrome/common/env_vars.h"
|
| #include "chrome/installer/util/google_update_settings.h"
|
| #include "content/browser/browser_thread.h"
|
| -#include "content/common/notification_registrar.h"
|
| +#include "content/browser/tab_contents/navigation_entry.h"
|
| #include "content/common/notification_service.h"
|
|
|
| namespace {
|
|
|
| -enum {
|
| - ACCESS_VALUES_STALE, // Possibly new values available.
|
| - ACCESS_VALUES_FRESH // The cached values are current.
|
| -};
|
| +// Organic brands all start with GG, such as GGCM.
|
| +static bool is_organic(const std::wstring& brand) {
|
| + return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG");
|
| +}
|
|
|
| -// Tracks if we have tried and succeeded sending the ping. This helps us
|
| -// decide if we need to refresh the cached RLZ string.
|
| -volatile int access_values_state = ACCESS_VALUES_STALE;
|
| -base::Lock rlz_lock;
|
| +void RecordProductEvents(bool first_run, bool google_default_search,
|
| + bool google_default_homepage, bool already_ran,
|
| + bool omnibox_used, bool homepage_used) {
|
| + // Record the installation of chrome. We call this all the time but the rlz
|
| + // lib should ingore all but the first one.
|
| + rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| + rlz_lib::CHROME_OMNIBOX,
|
| + rlz_lib::INSTALL);
|
| + rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| + rlz_lib::CHROME_HOME_PAGE,
|
| + rlz_lib::INSTALL);
|
|
|
| -bool SendFinancialPing(const std::wstring& brand, const std::wstring& lang,
|
| - const std::wstring& referral, bool exclude_id) {
|
| + if (!already_ran) {
|
| + // Do the initial event recording if is the first run or if we have an
|
| + // empty rlz which means we haven't got a chance to do it.
|
| + char omnibox_rlz[rlz_lib::kMaxRlzLength + 1];
|
| + if (!rlz_lib::GetAccessPointRlz(rlz_lib::CHROME_OMNIBOX, omnibox_rlz,
|
| + rlz_lib::kMaxRlzLength, NULL)) {
|
| + omnibox_rlz[0] = 0;
|
| + }
|
| +
|
| + // Record if google is the initial search provider and/or home page.
|
| + if ((first_run || omnibox_rlz[0] == 0) && google_default_search) {
|
| + rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| + rlz_lib::CHROME_OMNIBOX,
|
| + rlz_lib::SET_TO_GOOGLE);
|
| + }
|
| +
|
| + char homepage_rlz[rlz_lib::kMaxRlzLength + 1];
|
| + if (!rlz_lib::GetAccessPointRlz(rlz_lib::CHROME_HOME_PAGE, homepage_rlz,
|
| + rlz_lib::kMaxRlzLength, NULL)) {
|
| + homepage_rlz[0] = 0;
|
| + }
|
| +
|
| + if ((first_run || homepage_rlz[0] == 0) && google_default_homepage) {
|
| + rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| + rlz_lib::CHROME_HOME_PAGE,
|
| + rlz_lib::SET_TO_GOOGLE);
|
| + }
|
| + }
|
| +
|
| + // Record first user interaction with the omnibox. We call this all the
|
| + // time but the rlz lib should ingore all but the first one.
|
| + if (omnibox_used) {
|
| + rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| + rlz_lib::CHROME_OMNIBOX,
|
| + rlz_lib::FIRST_SEARCH);
|
| + }
|
| +
|
| + // Record first user interaction with the home page. We call this all the
|
| + // time but the rlz lib should ingore all but the first one.
|
| + if (homepage_used) {
|
| + rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| + rlz_lib::CHROME_HOME_PAGE,
|
| + rlz_lib::FIRST_SEARCH);
|
| + }
|
| +}
|
| +
|
| +bool SendFinancialPing(const std::wstring& brand,
|
| + const std::wstring& lang,
|
| + const std::wstring& referral,
|
| + bool exclude_id) {
|
| rlz_lib::AccessPoint points[] = {rlz_lib::CHROME_OMNIBOX,
|
| rlz_lib::CHROME_HOME_PAGE,
|
| rlz_lib::NO_ACCESS_POINT};
|
| @@ -57,7 +112,7 @@
|
|
|
| // If chrome has been reactivated, send a ping for this brand as well.
|
| // We ignore the return value of SendFinancialPing() since we'll try again
|
| - // later anyway. Callers of this function are only interested in whether
|
| + // later anyway. Callers of this function are only interested in whether
|
| // the ping for the main brand succeeded or not.
|
| std::wstring reactivation_brand;
|
| if (GoogleUpdateSettings::GetReactivationBrand(&reactivation_brand)) {
|
| @@ -74,248 +129,196 @@
|
| lang_ascii.c_str(), exclude_id, NULL, true);
|
| }
|
|
|
| -// This class leverages the AutocompleteEditModel notification to know when
|
| -// the user first interacted with the omnibox and set a global accordingly.
|
| -class OmniBoxUsageObserver : public NotificationObserver {
|
| - public:
|
| - OmniBoxUsageObserver(bool first_run, bool send_ping_immediately,
|
| - bool google_default_search)
|
| - : first_run_(first_run),
|
| - send_ping_immediately_(send_ping_immediately),
|
| - google_default_search_(google_default_search) {
|
| - registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
|
| - NotificationService::AllSources());
|
| - // If instant is enabled we'll start searching as soon as the user starts
|
| - // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED).
|
| - registrar_.Add(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
|
| - NotificationService::AllSources());
|
| - omnibox_used_ = false;
|
| - DCHECK(!instance_);
|
| - instance_ = this;
|
| - }
|
| +} // namespace
|
|
|
| - virtual void Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details);
|
| +RLZTracker* RLZTracker::tracker_ = NULL;
|
|
|
| - static bool used() {
|
| - return omnibox_used_;
|
| - }
|
| +// static
|
| +RLZTracker* RLZTracker::GetInstance() {
|
| + return tracker_ ? tracker_ : Singleton<RLZTracker>::get();
|
| +}
|
|
|
| - // Deletes the single instance of OmniBoxUsageObserver.
|
| - static void DeleteInstance() {
|
| - delete instance_;
|
| - }
|
| +RLZTracker::RLZTracker()
|
| + : first_run_(false),
|
| + send_ping_immediately_(false),
|
| + google_default_search_(false),
|
| + already_ran_(false),
|
| + omnibox_used_(false),
|
| + homepage_used_(false) {
|
| +}
|
|
|
| - private:
|
| - // Dtor is private so the object cannot be created on the stack.
|
| - ~OmniBoxUsageObserver() {
|
| - instance_ = NULL;
|
| - }
|
| +RLZTracker::~RLZTracker() {
|
| +}
|
|
|
| - static bool omnibox_used_;
|
| +bool RLZTracker::InitRlzDelayed(bool first_run, int delay,
|
| + bool google_default_search,
|
| + bool google_default_homepage) {
|
| + return GetInstance()->Init(first_run, delay, google_default_search,
|
| + google_default_homepage);
|
| +}
|
|
|
| - // There should only be one instance created at a time, and instance_ points
|
| - // to that instance.
|
| - // NOTE: this is only non-null for the amount of time it is needed. Once the
|
| - // instance_ is no longer needed (or Chrome is exiting), this is null.
|
| - static OmniBoxUsageObserver* instance_;
|
| +bool RLZTracker::Init(bool first_run, int delay, bool google_default_search,
|
| + bool google_default_homepage) {
|
| + first_run_ = first_run;
|
| + google_default_search_ = google_default_search;
|
| + google_default_homepage_ = google_default_homepage;
|
|
|
| - NotificationRegistrar registrar_;
|
| - bool first_run_;
|
| - bool send_ping_immediately_;
|
| - bool google_default_search_;
|
| -};
|
| -
|
| -bool OmniBoxUsageObserver::omnibox_used_ = false;
|
| -OmniBoxUsageObserver* OmniBoxUsageObserver::instance_ = NULL;
|
| -
|
| -// This task is run in the file thread, so to not block it for a long time
|
| -// we use a throwaway thread to do the blocking url request.
|
| -class DailyPingTask : public Task {
|
| - public:
|
| - virtual ~DailyPingTask() {
|
| + // A negative delay means that a financial ping should be sent immediately
|
| + // after a first search is recorded, without waiting for the next restart
|
| + // of chrome. However, we only want this behaviour on first run.
|
| + send_ping_immediately_ = false;
|
| + if (delay < 0) {
|
| + send_ping_immediately_ = true;
|
| + delay = -delay;
|
| }
|
| - virtual void Run() {
|
| - // We use a transient thread because we have no guarantees about
|
| - // how long the RLZ lib can block us.
|
| - _beginthread(PingNow, 0, NULL);
|
| - }
|
|
|
| - private:
|
| - // Causes a ping to the server using WinInet.
|
| - static void _cdecl PingNow(void*) {
|
| - // Needs to be evaluated. See http://crbug.com/62328.
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| + // Maximum and minimum delay we would allow to be set through master
|
| + // preferences. Somewhat arbitrary, may need to be adjusted in future.
|
| + const int kMaxDelay = 200 * 1000;
|
| + const int kMinDelay = 20 * 1000;
|
|
|
| - std::wstring lang;
|
| - GoogleUpdateSettings::GetLanguage(&lang);
|
| - if (lang.empty())
|
| - lang = L"en";
|
| - std::wstring brand;
|
| - GoogleUpdateSettings::GetBrand(&brand);
|
| - std::wstring referral;
|
| - GoogleUpdateSettings::GetReferral(&referral);
|
| - if (SendFinancialPing(brand, lang, referral, is_organic(brand))) {
|
| - base::AutoLock lock(rlz_lock);
|
| - access_values_state = ACCESS_VALUES_STALE;
|
| - GoogleUpdateSettings::ClearReferral();
|
| - }
|
| - }
|
| + delay *= 1000;
|
| + delay = (delay < kMinDelay) ? kMinDelay : delay;
|
| + delay = (delay > kMaxDelay) ? kMaxDelay : delay;
|
|
|
| - // Organic brands all start with GG, such as GGCM.
|
| - static bool is_organic(const std::wstring& brand) {
|
| - return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG");
|
| - }
|
| -};
|
| + // Register for notifications from the omnibox so that we can record when
|
| + // the user performs a first search.
|
| + registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
|
| + NotificationService::AllSources());
|
| + // If instant is enabled we'll start searching as soon as the user starts
|
| + // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED).
|
| + registrar_.Add(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
|
| + NotificationService::AllSources());
|
|
|
| -// Performs late RLZ initialization and RLZ event recording for chrome.
|
| -// This task needs to run on the UI thread.
|
| -class DelayedInitTask : public Task {
|
| - public:
|
| - DelayedInitTask(bool first_run, bool google_default_search)
|
| - : first_run_(first_run),
|
| - google_default_search_(google_default_search) {
|
| - }
|
| - virtual ~DelayedInitTask() {
|
| - }
|
| - virtual void Run() {
|
| - // For non-interactive tests we don't do the rest of the initialization
|
| - // because sometimes the very act of loading the dll causes QEMU to crash.
|
| - if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(),
|
| - NULL, 0)) {
|
| - return;
|
| - }
|
| - // For organic brandcodes do not use rlz at all. Empty brandcode usually
|
| - // means a chromium install. This is ok.
|
| - std::wstring brand;
|
| - if (!GoogleUpdateSettings::GetBrand(&brand) || brand.empty() ||
|
| - GoogleUpdateSettings::IsOrganic(brand))
|
| - return;
|
| + // Register for notifications from navigations, to see if the user has used
|
| + // the home page.
|
| + registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
|
| + NotificationService::AllSources());
|
|
|
| - RecordProductEvents(first_run_, google_default_search_, already_ran_);
|
| + ScheduleDelayedInit(delay);
|
| + return true;
|
| +}
|
|
|
| - // If chrome has been reactivated, record the events for this brand
|
| - // as well.
|
| - std::wstring reactivation_brand;
|
| - if (GoogleUpdateSettings::GetReactivationBrand(&reactivation_brand)) {
|
| - rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str());
|
| - RecordProductEvents(first_run_, google_default_search_, already_ran_);
|
| - }
|
| +void RLZTracker::ScheduleDelayedInit(int delay) {
|
| + BrowserThread::PostDelayedTask(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + NewRunnableMethod(this, &RLZTracker::DelayedInit),
|
| + delay);
|
| +}
|
|
|
| - already_ran_ = true;
|
| +void RLZTracker::DelayedInit() {
|
| + // For organic brandcodes do not use rlz at all. Empty brandcode usually
|
| + // means a chromium install. This is ok.
|
| + std::wstring brand;
|
| + if (!GoogleUpdateSettings::GetBrand(&brand) || brand.empty() ||
|
| + GoogleUpdateSettings::IsOrganic(brand))
|
| + return;
|
|
|
| - // Schedule the daily RLZ ping.
|
| - MessageLoop::current()->PostTask(FROM_HERE, new DailyPingTask());
|
| - }
|
| + RecordProductEvents(first_run_, google_default_search_,
|
| + google_default_homepage_, already_ran_,
|
| + omnibox_used_, homepage_used_);
|
|
|
| - private:
|
| - static void RecordProductEvents(bool first_run, bool google_default_search,
|
| - bool already_ran) {
|
| - // Record the installation of chrome. We call this all the time but the rlz
|
| - // lib should ingore all but the first one.
|
| - rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| - rlz_lib::CHROME_OMNIBOX,
|
| - rlz_lib::INSTALL);
|
| - rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| - rlz_lib::CHROME_HOME_PAGE,
|
| - rlz_lib::INSTALL);
|
| -
|
| - // Do the initial event recording if is the first run or if we have an
|
| - // empty rlz which means we haven't got a chance to do it.
|
| - char omnibox_rlz[rlz_lib::kMaxRlzLength + 1];
|
| - if (!rlz_lib::GetAccessPointRlz(rlz_lib::CHROME_OMNIBOX, omnibox_rlz,
|
| - rlz_lib::kMaxRlzLength, NULL)) {
|
| - omnibox_rlz[0] = 0;
|
| - }
|
| -
|
| - // Record if google is the initial search provider.
|
| - if ((first_run || omnibox_rlz[0] == 0) && google_default_search &&
|
| - !already_ran) {
|
| - rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| - rlz_lib::CHROME_OMNIBOX,
|
| - rlz_lib::SET_TO_GOOGLE);
|
| - }
|
| -
|
| - // Record first user interaction with the omnibox. We call this all the
|
| - // time but the rlz lib should ingore all but the first one.
|
| - if (OmniBoxUsageObserver::used()) {
|
| - rlz_lib::RecordProductEvent(rlz_lib::CHROME,
|
| - rlz_lib::CHROME_OMNIBOX,
|
| - rlz_lib::FIRST_SEARCH);
|
| - }
|
| + // If chrome has been reactivated, record the events for this brand
|
| + // as well.
|
| + std::wstring reactivation_brand;
|
| + if (GoogleUpdateSettings::GetReactivationBrand(&reactivation_brand)) {
|
| + rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str());
|
| + RecordProductEvents(first_run_, google_default_search_,
|
| + google_default_homepage_, already_ran_,
|
| + omnibox_used_, homepage_used_);
|
| }
|
|
|
| - // Flag that remembers if the delayed task already ran or not. This is
|
| - // needed only in the first_run case, since we don't want to record the
|
| - // set-to-google event more than once. We need to worry about this event
|
| - // (and not the others) because it is not a stateful RLZ event.
|
| - static bool already_ran_;
|
| + already_ran_ = true;
|
|
|
| - bool first_run_;
|
| + ScheduleFinancialPing();
|
| +}
|
|
|
| - // True if Google is the default search engine for the first profile starting
|
| - // in a browser during first run.
|
| - bool google_default_search_;
|
| +void RLZTracker::ScheduleFinancialPing() {
|
| + _beginthread(PingNow, 0, this);
|
| +}
|
|
|
| -};
|
| +// static
|
| +void _cdecl RLZTracker::PingNow(void* arg) {
|
| + RLZTracker* tracker = reinterpret_cast<RLZTracker*>(arg);
|
| + tracker->PingNowImpl();
|
| +}
|
|
|
| -bool DelayedInitTask::already_ran_ = false;
|
| -
|
| -void OmniBoxUsageObserver::Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| +void RLZTracker::PingNowImpl() {
|
| // Needs to be evaluated. See http://crbug.com/62328.
|
| base::ThreadRestrictions::ScopedAllowIO allow_io;
|
|
|
| - // Try to record event now, else set the flag to try later when we
|
| - // attempt the ping.
|
| - if (!RLZTracker::RecordProductEvent(rlz_lib::CHROME,
|
| - rlz_lib::CHROME_OMNIBOX,
|
| - rlz_lib::FIRST_SEARCH))
|
| - omnibox_used_ = true;
|
| - else if (send_ping_immediately_) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE, new DelayedInitTask(first_run_,
|
| - google_default_search_));
|
| + std::wstring lang;
|
| + GoogleUpdateSettings::GetLanguage(&lang);
|
| + if (lang.empty())
|
| + lang = L"en";
|
| + std::wstring brand;
|
| + GoogleUpdateSettings::GetBrand(&brand);
|
| + std::wstring referral;
|
| + GoogleUpdateSettings::GetReferral(&referral);
|
| + if (SendFinancialPing(brand, lang, referral, is_organic(brand))) {
|
| + GoogleUpdateSettings::ClearReferral();
|
| + base::AutoLock lock(cache_lock_);
|
| + rlz_cache_.clear();
|
| }
|
| +}
|
|
|
| - delete this;
|
| +bool RLZTracker::SendFinancialPing(const std::wstring& brand,
|
| + const std::wstring& lang,
|
| + const std::wstring& referral,
|
| + bool exclude_id) {
|
| + return ::SendFinancialPing(brand, lang, referral, exclude_id);
|
| }
|
|
|
| -} // namespace
|
| +void RLZTracker::Observe(int type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details) {
|
| + // Needs to be evaluated. See http://crbug.com/62328.
|
| + base::ThreadRestrictions::ScopedAllowIO allow_io;
|
|
|
| -bool RLZTracker::InitRlzDelayed(bool first_run, int delay,
|
| - bool google_default_search) {
|
| - // A negative delay means that a financial ping should be sent immediately
|
| - // after a first search is recorded, without waiting for the next restart
|
| - // of chrome. However, we only want this behaviour on first run.
|
| - bool send_ping_immediately = false;
|
| - if (delay < 0) {
|
| - send_ping_immediately = true;
|
| - delay = -delay;
|
| - }
|
| + rlz_lib::AccessPoint point;
|
| + bool* record_used = NULL;
|
| + bool call_record = false;
|
|
|
| - // Maximum and minimum delay we would allow to be set through master
|
| - // preferences. Somewhat arbitrary, may need to be adjusted in future.
|
| - const int kMaxDelay = 200 * 1000;
|
| - const int kMinDelay = 20 * 1000;
|
| + switch (type) {
|
| + case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
|
| + case chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED:
|
| + point = rlz_lib::CHROME_OMNIBOX;
|
| + record_used = &omnibox_used_;
|
| + call_record = true;
|
|
|
| - delay *= 1000;
|
| - delay = (delay < kMinDelay) ? kMinDelay : delay;
|
| - delay = (delay > kMaxDelay) ? kMaxDelay : delay;
|
| + registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
|
| + NotificationService::AllSources());
|
| + registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
|
| + NotificationService::AllSources());
|
| + break;
|
| + case content::NOTIFICATION_NAV_ENTRY_PENDING: {
|
| + const NavigationEntry* entry = Details<NavigationEntry>(details).ptr();
|
| + if (entry != NULL &&
|
| + ((entry->transition_type() & RLZ_PAGETRANSITION_HOME_PAGE) != 0)) {
|
| + point = rlz_lib::CHROME_HOME_PAGE;
|
| + record_used = &homepage_used_;
|
| + call_record = true;
|
|
|
| - if (!OmniBoxUsageObserver::used())
|
| - new OmniBoxUsageObserver(first_run, send_ping_immediately,
|
| - google_default_search);
|
| + registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
|
| + NotificationService::AllSources());
|
| + }
|
| + break;
|
| + }
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
|
|
| - // Schedule the delayed init items.
|
| - BrowserThread::PostDelayedTask(
|
| - BrowserThread::FILE,
|
| - FROM_HERE,
|
| - new DelayedInitTask(first_run, google_default_search),
|
| - delay);
|
| - return true;
|
| + if (call_record) {
|
| + // Try to record event now, else set the flag to try later when we
|
| + // attempt the ping.
|
| + if (!RecordProductEvent(rlz_lib::CHROME, point, rlz_lib::FIRST_SEARCH))
|
| + *record_used = true;
|
| + else if (send_ping_immediately_ && point == rlz_lib::CHROME_OMNIBOX) {
|
| + ScheduleDelayedInit(0);
|
| + }
|
| + }
|
| }
|
|
|
| bool RLZTracker::RecordProductEvent(rlz_lib::Product product,
|
| @@ -333,52 +336,59 @@
|
| return ret;
|
| }
|
|
|
| -// We implement caching of the answer of get_access_point() if the request
|
| -// is for CHROME_OMNIBOX. If we had a successful ping, then we update the
|
| -// cached value.
|
| -
|
| +// GetAccessPointRlz() caches RLZ strings for all access points. If we had
|
| +// a successful ping, then we update the cached value.
|
| bool RLZTracker::GetAccessPointRlz(rlz_lib::AccessPoint point,
|
| std::wstring* rlz) {
|
| - static std::wstring cached_ommibox_rlz;
|
| - if (rlz_lib::CHROME_OMNIBOX == point) {
|
| - base::AutoLock lock(rlz_lock);
|
| - if (access_values_state == ACCESS_VALUES_FRESH) {
|
| - *rlz = cached_ommibox_rlz;
|
| + return GetInstance()->GetAccessPointRlzImpl(point, rlz);
|
| +}
|
| +
|
| +// GetAccessPointRlz() caches RLZ strings for all access points. If we had
|
| +// a successful ping, then we update the cached value.
|
| +bool RLZTracker::GetAccessPointRlzImpl(rlz_lib::AccessPoint point,
|
| + std::wstring* rlz) {
|
| + // If the RLZ string for the specified access point is already cached,
|
| + // simply return its value.
|
| + {
|
| + base::AutoLock lock(cache_lock_);
|
| + if (rlz_cache_.find(point) != rlz_cache_.end()) {
|
| + if (rlz)
|
| + *rlz = rlz_cache_[point];
|
| return true;
|
| }
|
| }
|
|
|
| - // Make sure we don't access disk outside of the file context.
|
| + // Make sure we don't access disk outside of the I/O thread.
|
| // In such case we repost the task on the right thread and return error.
|
| - if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
|
| - // Caching of access points is now only implemented for the CHROME_OMNIBOX.
|
| - // Thus it is not possible to call this function on another thread for
|
| - // other access points until proper caching for these has been implemented
|
| - // and the code that calls this function can handle synchronous fetching
|
| - // of the access point.
|
| - DCHECK_EQ(rlz_lib::CHROME_OMNIBOX, point);
|
| + if (ScheduleGetAccessPointRlz(point))
|
| + return false;
|
|
|
| - BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - NewRunnableFunction(&RLZTracker::GetAccessPointRlz,
|
| - point, &cached_ommibox_rlz));
|
| - rlz->erase();
|
| - return false;
|
| - }
|
| -
|
| char str_rlz[rlz_lib::kMaxRlzLength + 1];
|
| if (!rlz_lib::GetAccessPointRlz(point, str_rlz, rlz_lib::kMaxRlzLength, NULL))
|
| return false;
|
| - *rlz = ASCIIToWide(std::string(str_rlz));
|
| - if (rlz_lib::CHROME_OMNIBOX == point) {
|
| - base::AutoLock lock(rlz_lock);
|
| - cached_ommibox_rlz.assign(*rlz);
|
| - access_values_state = ACCESS_VALUES_FRESH;
|
| - }
|
| +
|
| + std::wstring rlz_local(ASCIIToWide(std::string(str_rlz)));
|
| + if (rlz)
|
| + *rlz = rlz_local;
|
| +
|
| + base::AutoLock lock(cache_lock_);
|
| + rlz_cache_[point] = rlz_local;
|
| return true;
|
| }
|
|
|
| +bool RLZTracker::ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point) {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::FILE))
|
| + return false;
|
| +
|
| + std::wstring* not_used = NULL;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + NewRunnableFunction(&RLZTracker::GetAccessPointRlz, point, not_used));
|
| + return true;
|
| +}
|
| +
|
| // static
|
| void RLZTracker::CleanupRlz() {
|
| - OmniBoxUsageObserver::DeleteInstance();
|
| + GetInstance()->rlz_cache_.clear();
|
| + GetInstance()->registrar_.RemoveAll();
|
| }
|
|
|