Home | History | Annotate | Download | only in rlz
      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 #ifndef CHROME_BROWSER_RLZ_RLZ_H_
      6 #define CHROME_BROWSER_RLZ_RLZ_H_
      7 
      8 #include "build/build_config.h"
      9 
     10 #if defined(ENABLE_RLZ)
     11 
     12 #include <map>
     13 #include <string>
     14 
     15 #include "base/basictypes.h"
     16 #include "base/memory/singleton.h"
     17 #include "base/strings/string16.h"
     18 #include "base/threading/sequenced_worker_pool.h"
     19 #include "base/time/time.h"
     20 #include "content/public/browser/notification_observer.h"
     21 #include "content/public/browser/notification_registrar.h"
     22 #include "rlz/lib/rlz_lib.h"
     23 
     24 class Profile;
     25 namespace net {
     26 class URLRequestContextGetter;
     27 }
     28 
     29 // RLZ is a library which is used to measure distribution scenarios.
     30 // Its job is to record certain lifetime events in the registry and to send
     31 // them encoded as a compact string at most twice. The sent data does
     32 // not contain information that can be used to identify a user or to infer
     33 // browsing habits. The API in this file is a wrapper around the open source
     34 // RLZ library which can be found at http://code.google.com/p/rlz.
     35 //
     36 // For partner or bundled installs, the RLZ might send more information
     37 // according to the terms disclosed in the EULA.
     38 
     39 class RLZTracker : public content::NotificationObserver {
     40  public:
     41   // Initializes the RLZ library services for use in chrome. Schedules a delayed
     42   // task that performs the ping and registers some events when 'first-run' is
     43   // true.
     44   //
     45   // When |send_ping_immediately| is true, a financial ping should be sent
     46   // immediately after a first search is recorded, without waiting for |delay|.
     47   // However, we only want this behaviour on first run.
     48   //
     49   // If the chrome brand is organic (no partners) then the pings don't occur.
     50   static bool InitRlzFromProfileDelayed(Profile* profile,
     51                                         bool first_run,
     52                                         bool send_ping_immediately,
     53                                         base::TimeDelta delay);
     54 
     55   // Records an RLZ event. Some events can be access point independent.
     56   // Returns false it the event could not be recorded. Requires write access
     57   // to the HKCU registry hive on windows.
     58   static bool RecordProductEvent(rlz_lib::Product product,
     59                                  rlz_lib::AccessPoint point,
     60                                  rlz_lib::Event event_id);
     61 
     62   // For the point parameter of RecordProductEvent.
     63   static const rlz_lib::AccessPoint CHROME_OMNIBOX;
     64   static const rlz_lib::AccessPoint CHROME_HOME_PAGE;
     65 
     66   // Gets the HTTP header value that can be added to requests from the
     67   // specific access point.  The string returned is of the form:
     68   //
     69   //    "X-Rlz-String: <access-point-rlz>\r\n"
     70   //
     71   static std::string GetAccessPointHttpHeader(rlz_lib::AccessPoint point);
     72 
     73   // Gets the RLZ value of the access point.
     74   // Returns false if the rlz string could not be obtained. In some cases
     75   // an empty string can be returned which is not an error.
     76   static bool GetAccessPointRlz(rlz_lib::AccessPoint point,
     77                                 base::string16* rlz);
     78 
     79   // Invoked during shutdown to clean up any state created by RLZTracker.
     80   static void CleanupRlz();
     81 
     82 #if defined(OS_CHROMEOS)
     83   // Clears all product state. Should be called when turning RLZ off. On other
     84   // platforms, this is done by product uninstaller.
     85   static void ClearRlzState();
     86 #endif
     87 
     88   // This method is public for use by the Singleton class.
     89   static RLZTracker* GetInstance();
     90 
     91   // Enables zero delay for InitRlzFromProfileDelayed. For testing only.
     92   static void EnableZeroDelayForTesting();
     93 
     94   // The following methods are made protected so that they can be used for
     95   // testing purposes. Production code should never need to call these.
     96  protected:
     97   RLZTracker();
     98   virtual ~RLZTracker();
     99 
    100   // Called by InitRlzFromProfileDelayed with values taken from |profile|.
    101   static bool InitRlzDelayed(bool first_run,
    102                              bool send_ping_immediately,
    103                              base::TimeDelta delay,
    104                              bool is_google_default_search,
    105                              bool is_google_homepage,
    106                              bool is_google_in_startpages);
    107 
    108   // Performs initialization of RLZ tracker that is purposefully delayed so
    109   // that it does not interfere with chrome startup time.
    110   virtual void DelayedInit();
    111 
    112   // content::NotificationObserver implementation:
    113   virtual void Observe(int type,
    114                        const content::NotificationSource& source,
    115                        const content::NotificationDetails& details) OVERRIDE;
    116 
    117   // Used by test code to override the default RLZTracker instance returned
    118   // by GetInstance().
    119   void set_tracker(RLZTracker* tracker) {
    120     tracker_ = tracker;
    121   }
    122 
    123   // Sends the financial ping to the RLZ servers and invalidates the RLZ string
    124   // cache since the response from the RLZ server may have changed then.
    125   // Protected so that its accessible from tests.
    126   void PingNowImpl();
    127 
    128  private:
    129   friend struct DefaultSingletonTraits<RLZTracker>;
    130   friend class base::RefCountedThreadSafe<RLZTracker>;
    131 
    132   // Implementation called from InitRlzDelayed() static method.
    133   bool Init(bool first_run,
    134             bool send_ping_immediately,
    135             base::TimeDelta delay,
    136             bool google_default_search,
    137             bool google_default_homepage,
    138             bool is_google_in_startpages);
    139 
    140   // Implementation called from RecordProductEvent() static method.
    141   bool RecordProductEventImpl(rlz_lib::Product product,
    142                               rlz_lib::AccessPoint point,
    143                               rlz_lib::Event event_id);
    144 
    145   // Records FIRST_SEARCH event. Called from Observe() on blocking task runner.
    146   void RecordFirstSearch(rlz_lib::AccessPoint point);
    147 
    148   // Implementation called from GetAccessPointRlz() static method.
    149   bool GetAccessPointRlzImpl(rlz_lib::AccessPoint point, base::string16* rlz);
    150 
    151   // Schedules the delayed initialization. This method is virtual to allow
    152   // tests to override how the scheduling is done.
    153   virtual void ScheduleDelayedInit(base::TimeDelta delay);
    154 
    155   // Schedules a call to rlz_lib::RecordProductEvent(). This method is virtual
    156   // to allow tests to override how the scheduling is done.
    157   virtual bool ScheduleRecordProductEvent(rlz_lib::Product product,
    158                                           rlz_lib::AccessPoint point,
    159                                           rlz_lib::Event event_id);
    160 
    161   // Schedules a call to rlz_lib::RecordFirstSearch(). This method is virtual
    162   // to allow tests to override how the scheduling is done.
    163   virtual bool ScheduleRecordFirstSearch(rlz_lib::AccessPoint point);
    164 
    165   // Schedules a call to rlz_lib::SendFinancialPing(). This method is virtual
    166   // to allow tests to override how the scheduling is done.
    167   virtual void ScheduleFinancialPing();
    168 
    169   // Schedules a call to GetAccessPointRlz() on the I/O thread if the current
    170   // thread is not already the I/O thread, otherwise does nothing. Returns
    171   // true if the call was scheduled, and false otherwise. This method is
    172   // virtual to allow tests to override how the scheduling is done.
    173   virtual bool ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point);
    174 
    175   // Sends the financial ping to the RLZ servers. This method is virtual to
    176   // allow tests to override.
    177   virtual bool SendFinancialPing(const std::string& brand,
    178                                  const base::string16& lang,
    179                                  const base::string16& referral);
    180 
    181 #if defined(OS_CHROMEOS)
    182   // Implementation called from ClearRlzState static method.
    183   void ClearRlzStateImpl();
    184 
    185   // Schedules a call to ClearRlzStateImpl(). This method is virtual
    186   // to allow tests to override how the scheduling is done.
    187   virtual bool ScheduleClearRlzState();
    188 #endif
    189 
    190   // Tracker used for testing purposes only. If this value is non-NULL, it
    191   // will be returned from GetInstance() instead of the regular singleton.
    192   static RLZTracker* tracker_;
    193 
    194   // Configuation data for RLZ tracker. Set by call to Init().
    195   bool first_run_;
    196   bool send_ping_immediately_;
    197   bool is_google_default_search_;
    198   bool is_google_homepage_;
    199   bool is_google_in_startpages_;
    200 
    201   // Unique sequence token so that tasks posted by RLZTracker are executed
    202   // sequentially in the blocking pool.
    203   base::SequencedWorkerPool::SequenceToken worker_pool_token_;
    204 
    205   // Keeps track if the RLZ tracker has already performed its delayed
    206   // initialization.
    207   bool already_ran_;
    208 
    209   // Keeps a cache of RLZ access point strings, since they rarely change.
    210   // The cache must be protected by a lock since it may be accessed from
    211   // the UI thread for reading and the IO thread for reading and/or writing.
    212   base::Lock cache_lock_;
    213   std::map<rlz_lib::AccessPoint, base::string16> rlz_cache_;
    214 
    215   // Keeps track of whether the omnibox or host page have been used.
    216   bool omnibox_used_;
    217   bool homepage_used_;
    218 
    219   // Main and (optionally) reactivation brand codes, assigned on UI thread.
    220   std::string brand_;
    221   std::string reactivation_brand_;
    222 
    223   content::NotificationRegistrar registrar_;
    224 
    225   // Minimum delay before sending financial ping after initialization.
    226   base::TimeDelta min_init_delay_;
    227 
    228   DISALLOW_COPY_AND_ASSIGN(RLZTracker);
    229 };
    230 
    231 #endif  // defined(ENABLE_RLZ)
    232 
    233 #endif  // CHROME_BROWSER_RLZ_RLZ_H_
    234