Home | History | Annotate | Download | only in variations
      1 // Copyright 2014 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 COMPONENTS_VARIATIONS_VARIATIONS_HTTP_HEADER_PROVIDER_H_
      6 #define COMPONENTS_VARIATIONS_VARIATIONS_HTTP_HEADER_PROVIDER_H_
      7 
      8 #include <set>
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/gtest_prod_util.h"
     13 #include "base/metrics/field_trial.h"
     14 #include "base/synchronization/lock.h"
     15 #include "components/variations/variations_associated_data.h"
     16 
     17 namespace content {
     18 class ResourceContext;
     19 }
     20 
     21 namespace net {
     22 class HttpRequestHeaders;
     23 }
     24 
     25 class GURL;
     26 
     27 template <typename T> struct DefaultSingletonTraits;
     28 
     29 namespace variations {
     30 
     31 // A helper class for maintaining client experiments and metrics state
     32 // transmitted in custom HTTP request headers.
     33 // This class is a thread-safe singleton.
     34 class VariationsHttpHeaderProvider : base::FieldTrialList::Observer {
     35  public:
     36   static VariationsHttpHeaderProvider* GetInstance();
     37 
     38   // Adds Chrome experiment and metrics state as custom headers to |headers|.
     39   // Some headers may not be set given the |incognito| mode or whether
     40   // the user has |uma_enabled|.  Also, we never transmit headers to non-Google
     41   // sites, which is checked based on the destination |url|.
     42   void AppendHeaders(const GURL& url,
     43                      bool incognito,
     44                      bool uma_enabled,
     45                      net::HttpRequestHeaders* headers);
     46 
     47   // Sets *additional* variation ids and trigger variation ids to be encoded in
     48   // the X-Client-Data request header.  This is intended for development use to
     49   // force a server side experiment id.  |variation_ids| should be a
     50   // comma-separated string of numeric experiment ids.  If an id is prefixed
     51   // with "t" it will be treated as a trigger experiment id.
     52   bool SetDefaultVariationIds(const std::string& variation_ids);
     53 
     54  private:
     55   friend struct DefaultSingletonTraits<VariationsHttpHeaderProvider>;
     56 
     57   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
     58                            ShouldAppendHeaders);
     59   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
     60                            SetDefaultVariationIds_Valid);
     61   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
     62                            SetDefaultVariationIds_Invalid);
     63   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
     64                            OnFieldTrialGroupFinalized);
     65 
     66   VariationsHttpHeaderProvider();
     67   virtual ~VariationsHttpHeaderProvider();
     68 
     69   // base::FieldTrialList::Observer implementation.
     70   // This will add the variation ID associated with |trial_name| and
     71   // |group_name| to the variation ID cache.
     72   virtual void OnFieldTrialGroupFinalized(
     73       const std::string& trial_name,
     74       const std::string& group_name) OVERRIDE;
     75 
     76   // Prepares the variation IDs cache with initial values if not already done.
     77   // This method also registers the caller with the FieldTrialList to receive
     78   // new variation IDs.
     79   void InitVariationIDsCacheIfNeeded();
     80 
     81   // Takes whatever is currently in |variation_ids_set_| and recreates
     82   // |variation_ids_header_| with it.  Assumes the the |lock_| is currently
     83   // held.
     84   void UpdateVariationIDsHeaderValue();
     85 
     86   // Checks whether variation headers should be appended to requests to the
     87   // specified |url|. Returns true for google.<TLD> and youtube.<TLD> URLs.
     88   static bool ShouldAppendHeaders(const GURL& url);
     89 
     90   // Guards |variation_ids_cache_initialized_|, |variation_ids_set_| and
     91   // |variation_ids_header_|.
     92   base::Lock lock_;
     93 
     94   // Whether or not we've initialized the cache.
     95   bool variation_ids_cache_initialized_;
     96 
     97   // Keep a cache of variation IDs that are transmitted in headers to Google.
     98   // This consists of a list of valid IDs, and the actual transmitted header.
     99   std::set<VariationID> variation_ids_set_;
    100   std::set<VariationID> variation_trigger_ids_set_;
    101 
    102   // Provides the google experiment ids forced from command line.
    103   std::set<VariationID> default_variation_ids_set_;
    104   std::set<VariationID> default_trigger_id_set_;
    105 
    106   std::string variation_ids_header_;
    107 
    108   DISALLOW_COPY_AND_ASSIGN(VariationsHttpHeaderProvider);
    109 };
    110 
    111 }  // namespace variations
    112 
    113 #endif  // COMPONENTS_VARIATIONS_VARIATIONS_HTTP_HEADER_PROVIDER_H_
    114