diff options
Diffstat (limited to 'components/rlz/rlz_tracker.h')
| -rw-r--r-- | components/rlz/rlz_tracker.h | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/components/rlz/rlz_tracker.h b/components/rlz/rlz_tracker.h new file mode 100644 index 0000000..1236aa2 --- /dev/null +++ b/components/rlz/rlz_tracker.h @@ -0,0 +1,242 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_RLZ_RLZ_TRACKER_H_ +#define COMPONENTS_RLZ_RLZ_TRACKER_H_ + +#include <map> +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/singleton.h" +#include "base/strings/string16.h" +#include "base/threading/sequenced_worker_pool.h" +#include "base/time/time.h" +#include "rlz/lib/rlz_lib.h" + +namespace net { +class URLRequestContextGetter; +} + +namespace rlz { + +class RLZTrackerDelegate; + +// RLZ is a library which is used to measure distribution scenarios. +// Its job is to record certain lifetime events in the registry and to send +// them encoded as a compact string at most twice. The sent data does +// not contain information that can be used to identify a user or to infer +// browsing habits. The API in this file is a wrapper around the open source +// RLZ library which can be found at http://code.google.com/p/rlz. +// +// For partner or bundled installs, the RLZ might send more information +// according to the terms disclosed in the EULA. + +class RLZTracker { + public: + // Sets the RLZTrackerDelegate that should be used by the global RLZTracker + // instance. Must be called before calling any other method of RLZTracker. + static void SetRlzDelegate(scoped_ptr<RLZTrackerDelegate> delegate); + + // Initializes the RLZ library services for use in chrome. Schedules a delayed + // task that performs the ping and registers some events when 'first-run' is + // true. + // + // When |send_ping_immediately| is true, a financial ping should be sent + // immediately after a first search is recorded, without waiting for |delay|. + // However, we only want this behaviour on first run. + // + // If the chrome brand is organic (no partners) then the pings don't occur. + static bool InitRlzDelayed(bool first_run, + bool send_ping_immediately, + base::TimeDelta delay, + bool is_google_default_search, + bool is_google_homepage, + bool is_google_in_startpages); + + // Records an RLZ event. Some events can be access point independent. + // Returns false it the event could not be recorded. Requires write access + // to the HKCU registry hive on windows. + static bool RecordProductEvent(rlz_lib::Product product, + rlz_lib::AccessPoint point, + rlz_lib::Event event_id); + + // For the point parameter of RecordProductEvent. + static rlz_lib::AccessPoint ChromeOmnibox(); +#if !defined(OS_IOS) + static rlz_lib::AccessPoint ChromeHomePage(); + static rlz_lib::AccessPoint ChromeAppList(); +#endif + + // Gets the HTTP header value that can be added to requests from the + // specific access point. The string returned is of the form: + // + // "X-Rlz-String: <access-point-rlz>\r\n" + // + static std::string GetAccessPointHttpHeader(rlz_lib::AccessPoint point); + + // Gets the RLZ value of the access point. + // Returns false if the rlz string could not be obtained. In some cases + // an empty string can be returned which is not an error. + static bool GetAccessPointRlz(rlz_lib::AccessPoint point, + base::string16* rlz); + + // Invoked during shutdown to clean up any state created by RLZTracker. + static void CleanupRlz(); + +#if defined(OS_CHROMEOS) + // Clears all product state. Should be called when turning RLZ off. On other + // platforms, this is done by product uninstaller. + static void ClearRlzState(); +#endif + + // This method is public for use by the Singleton class. + static RLZTracker* GetInstance(); + + // Enables zero delay for InitRlzDelayed. For testing only. + static void EnableZeroDelayForTesting(); + +#if !defined(OS_IOS) + // Records that the app list search has been used. + static void RecordAppListSearch(); +#endif + + // The following methods are made protected so that they can be used for + // testing purposes. Production code should never need to call these. + protected: + RLZTracker(); + virtual ~RLZTracker(); + + // Performs initialization of RLZ tracker that is purposefully delayed so + // that it does not interfere with chrome startup time. + virtual void DelayedInit(); + + // Used by test code to override the default RLZTracker instance returned + // by GetInstance(). + void set_tracker(RLZTracker* tracker) { tracker_ = tracker; } + + // Sends the financial ping to the RLZ servers and invalidates the RLZ string + // cache since the response from the RLZ server may have changed then. + // Protected so that its accessible from tests. + void PingNowImpl(); + + private: + friend struct DefaultSingletonTraits<RLZTracker>; + friend class base::RefCountedThreadSafe<RLZTracker>; + + // Implementation called from SetRlzDelegate() static method. + void SetDelegate(scoped_ptr<RLZTrackerDelegate> delegate); + + // Implementation called from InitRlzDelayed() static method. + bool Init(bool first_run, + bool send_ping_immediately, + base::TimeDelta delay, + bool is_google_default_search, + bool is_google_homepage, + bool is_google_in_startpages); + + // Implementation called from CleanupRlz static method. + void Cleanup(); + + // Implementation called from RecordProductEvent() static method. + bool RecordProductEventImpl(rlz_lib::Product product, + rlz_lib::AccessPoint point, + rlz_lib::Event event_id); + + // Records FIRST_SEARCH event. Passed as bound callback to RLZTrackerDelegate. + void RecordFirstSearch(rlz_lib::AccessPoint point); + + // Implementation called from GetAccessPointRlz() static method. + bool GetAccessPointRlzImpl(rlz_lib::AccessPoint point, base::string16* rlz); + + // Schedules the delayed initialization. This method is virtual to allow + // tests to override how the scheduling is done. + virtual void ScheduleDelayedInit(base::TimeDelta delay); + + // Schedules a call to rlz_lib::RecordProductEvent(). This method is virtual + // to allow tests to override how the scheduling is done. + virtual bool ScheduleRecordProductEvent(rlz_lib::Product product, + rlz_lib::AccessPoint point, + rlz_lib::Event event_id); + + // Schedules a call to rlz_lib::RecordFirstSearch(). This method is virtual + // to allow tests to override how the scheduling is done. + virtual bool ScheduleRecordFirstSearch(rlz_lib::AccessPoint point); + + // Schedules a call to rlz_lib::SendFinancialPing(). This method is virtual + // to allow tests to override how the scheduling is done. + virtual void ScheduleFinancialPing(); + + // Schedules a call to GetAccessPointRlz() on the I/O thread if the current + // thread is not already the I/O thread, otherwise does nothing. Returns + // true if the call was scheduled, and false otherwise. This method is + // virtual to allow tests to override how the scheduling is done. + virtual bool ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point); + + // Sends the financial ping to the RLZ servers. This method is virtual to + // allow tests to override. + virtual bool SendFinancialPing(const std::string& brand, + const base::string16& lang, + const base::string16& referral); + +#if defined(OS_CHROMEOS) + // Implementation called from ClearRlzState static method. + void ClearRlzStateImpl(); + + // Schedules a call to ClearRlzStateImpl(). This method is virtual + // to allow tests to override how the scheduling is done. + virtual bool ScheduleClearRlzState(); +#endif + + // Returns a pointer to the bool corresponding to whether |point| has been + // used but not reported. + bool* GetAccessPointRecord(rlz_lib::AccessPoint point); + + // Tracker used for testing purposes only. If this value is non-NULL, it + // will be returned from GetInstance() instead of the regular singleton. + static RLZTracker* tracker_; + + // Delegate abstracting embedder specific knowledge. Must not be null. + scoped_ptr<RLZTrackerDelegate> delegate_; + + // Configuation data for RLZ tracker. Set by call to Init(). + bool first_run_; + bool send_ping_immediately_; + bool is_google_default_search_; + bool is_google_homepage_; + bool is_google_in_startpages_; + + // Unique sequence token so that tasks posted by RLZTracker are executed + // sequentially in the blocking pool. + base::SequencedWorkerPool::SequenceToken worker_pool_token_; + + // Keeps track if the RLZ tracker has already performed its delayed + // initialization. + bool already_ran_; + + // Keeps a cache of RLZ access point strings, since they rarely change. + // The cache must be protected by a lock since it may be accessed from + // the UI thread for reading and the IO thread for reading and/or writing. + base::Lock cache_lock_; + std::map<rlz_lib::AccessPoint, base::string16> rlz_cache_; + + // Keeps track of whether the omnibox, home page or app list have been used. + bool omnibox_used_; + bool homepage_used_; + bool app_list_used_; + + // Main and (optionally) reactivation brand codes, assigned on UI thread. + std::string brand_; + std::string reactivation_brand_; + + // Minimum delay before sending financial ping after initialization. + base::TimeDelta min_init_delay_; + + DISALLOW_COPY_AND_ASSIGN(RLZTracker); +}; + +} // namespace rlz + +#endif // COMPONENTS_RLZ_RLZ_TRACKER_H_ |
