| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 // FieldTrial is a class for handling details of statistical experiments | 5 // FieldTrial is a class for handling details of statistical experiments | 
| 6 // performed by actual users in the field (i.e., in a shipped or beta product). | 6 // performed by actual users in the field (i.e., in a shipped or beta product). | 
| 7 // All code is called exclusively on the UI thread currently. | 7 // All code is called exclusively on the UI thread currently. | 
| 8 // | 8 // | 
| 9 // The simplest example is an experiment to see whether one of two options | 9 // The simplest example is an experiment to see whether one of two options | 
| 10 // produces "better" results across our user population.  In that scenario, UMA | 10 // produces "better" results across our user population.  In that scenario, UMA | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 66 #include "base/base_export.h" | 66 #include "base/base_export.h" | 
| 67 #include "base/command_line.h" | 67 #include "base/command_line.h" | 
| 68 #include "base/feature_list.h" | 68 #include "base/feature_list.h" | 
| 69 #include "base/files/file.h" | 69 #include "base/files/file.h" | 
| 70 #include "base/gtest_prod_util.h" | 70 #include "base/gtest_prod_util.h" | 
| 71 #include "base/macros.h" | 71 #include "base/macros.h" | 
| 72 #include "base/memory/ref_counted.h" | 72 #include "base/memory/ref_counted.h" | 
| 73 #include "base/memory/shared_memory.h" | 73 #include "base/memory/shared_memory.h" | 
| 74 #include "base/metrics/persistent_memory_allocator.h" | 74 #include "base/metrics/persistent_memory_allocator.h" | 
| 75 #include "base/observer_list_threadsafe.h" | 75 #include "base/observer_list_threadsafe.h" | 
|  | 76 #include "base/pickle.h" | 
| 76 #include "base/process/launch.h" | 77 #include "base/process/launch.h" | 
| 77 #include "base/strings/string_piece.h" | 78 #include "base/strings/string_piece.h" | 
| 78 #include "base/synchronization/lock.h" | 79 #include "base/synchronization/lock.h" | 
| 79 #include "base/time/time.h" | 80 #include "base/time/time.h" | 
| 80 | 81 | 
| 81 namespace base { | 82 namespace base { | 
| 82 | 83 | 
| 83 class FieldTrialList; | 84 class FieldTrialList; | 
| 84 | 85 | 
| 85 class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> { | 86 class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> { | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 126   struct BASE_EXPORT State { | 127   struct BASE_EXPORT State { | 
| 127     StringPiece trial_name; | 128     StringPiece trial_name; | 
| 128     StringPiece group_name; | 129     StringPiece group_name; | 
| 129     bool activated; | 130     bool activated; | 
| 130 | 131 | 
| 131     State(); | 132     State(); | 
| 132     State(const State& other); | 133     State(const State& other); | 
| 133     ~State(); | 134     ~State(); | 
| 134   }; | 135   }; | 
| 135 | 136 | 
|  | 137   // We create one FieldTrialEntry per field trial in shared memory, via | 
|  | 138   // AddToAllocatorWhileLocked. The FieldTrialEntry is followed by a | 
|  | 139   // base::Pickle object that we unpickle and read from. Any changes to this | 
|  | 140   // structure requires a bump in kFieldTrialType id defined in the .cc file. | 
|  | 141   struct BASE_EXPORT FieldTrialEntry { | 
|  | 142     // Expected size for 32/64-bit check. | 
|  | 143     static constexpr size_t kExpectedInstanceSize = 8; | 
|  | 144 | 
|  | 145     // Whether or not this field trial is activated. This is really just a | 
|  | 146     // boolean but marked as a uint32_t for portability reasons. | 
|  | 147     uint32_t activated; | 
|  | 148 | 
|  | 149     // Size of the pickled structure, NOT the total size of this entry. | 
|  | 150     uint32_t pickle_size; | 
|  | 151 | 
|  | 152     // Calling this is only valid when the entry is initialized. That is, it | 
|  | 153     // resides in shared memory and has a pickle containing the trial name and | 
|  | 154     // group name following it. | 
|  | 155     bool GetTrialAndGroupName(StringPiece* trial_name, | 
|  | 156                               StringPiece* group_name) const; | 
|  | 157 | 
|  | 158     // Calling this is only valid when the entry is initialized as well. Reads | 
|  | 159     // the parameters following the trial and group name and stores them as | 
|  | 160     // key-value mappings in |params|. | 
|  | 161     bool GetParams(std::map<std::string, std::string>* params) const; | 
|  | 162 | 
|  | 163    private: | 
|  | 164     // Returns an iterator over the data containing names and params. | 
|  | 165     PickleIterator GetPickleIterator() const; | 
|  | 166 | 
|  | 167     // Takes the iterator and writes out the first two items into |trial_name| | 
|  | 168     // and |group_name|. | 
|  | 169     bool ReadStringPair(PickleIterator* iter, | 
|  | 170                         StringPiece* trial_name, | 
|  | 171                         StringPiece* group_name) const; | 
|  | 172   }; | 
|  | 173 | 
| 136   typedef std::vector<ActiveGroup> ActiveGroups; | 174   typedef std::vector<ActiveGroup> ActiveGroups; | 
| 137 | 175 | 
| 138   // A return value to indicate that a given instance has not yet had a group | 176   // A return value to indicate that a given instance has not yet had a group | 
| 139   // assignment (and hence is not yet participating in the trial). | 177   // assignment (and hence is not yet participating in the trial). | 
| 140   static const int kNotFinalized; | 178   static const int kNotFinalized; | 
| 141 | 179 | 
| 142   // Disables this trial, meaning it always determines the default group | 180   // Disables this trial, meaning it always determines the default group | 
| 143   // has been selected. May be called immediately after construction, or | 181   // has been selected. May be called immediately after construction, or | 
| 144   // at any time after initialization (should not be interleaved with | 182   // at any time after initialization (should not be interleaved with | 
| 145   // AppendGroup calls). Once disabled, there is no way to re-enable a | 183   // AppendGroup calls). Once disabled, there is no way to re-enable a | 
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 570   // Gets the parameters for |field_trial| from shared memory and stores them in | 608   // Gets the parameters for |field_trial| from shared memory and stores them in | 
| 571   // |params|. This is only exposed for use by FieldTrialParamAssociator and | 609   // |params|. This is only exposed for use by FieldTrialParamAssociator and | 
| 572   // shouldn't be used by anything else. | 610   // shouldn't be used by anything else. | 
| 573   static bool GetParamsFromSharedMemory( | 611   static bool GetParamsFromSharedMemory( | 
| 574       FieldTrial* field_trial, | 612       FieldTrial* field_trial, | 
| 575       std::map<std::string, std::string>* params); | 613       std::map<std::string, std::string>* params); | 
| 576 | 614 | 
| 577   // Clears all the params in the allocator. | 615   // Clears all the params in the allocator. | 
| 578   static void ClearParamsFromSharedMemoryForTesting(); | 616   static void ClearParamsFromSharedMemoryForTesting(); | 
| 579 | 617 | 
|  | 618   // Dumps field trial state to an allocator so that it can be analyzed after a | 
|  | 619   // crash. | 
|  | 620   static void DumpAllFieldTrialsToPersistentAllocator( | 
|  | 621       PersistentMemoryAllocator* allocator); | 
|  | 622 | 
|  | 623   // Retrieves field trial state from an allocator so that it can be analyzed | 
|  | 624   // after a crash. The pointers in the returned vector are into the persistent | 
|  | 625   // memory segment and so are only valid as long as the allocator is valid. | 
|  | 626   static std::vector<const FieldTrial::FieldTrialEntry*> | 
|  | 627   GetAllFieldTrialsFromPersistentAllocator( | 
|  | 628       PersistentMemoryAllocator const& allocator); | 
|  | 629 | 
| 580  private: | 630  private: | 
| 581   // Allow tests to access our innards for testing purposes. | 631   // Allow tests to access our innards for testing purposes. | 
| 582   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, InstantiateAllocator); | 632   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, InstantiateAllocator); | 
| 583   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AddTrialsToAllocator); | 633   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AddTrialsToAllocator); | 
| 584   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, | 634   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, | 
| 585                            DoNotAddSimulatedFieldTrialsToAllocator); | 635                            DoNotAddSimulatedFieldTrialsToAllocator); | 
| 586   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AssociateFieldTrialParams); | 636   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AssociateFieldTrialParams); | 
| 587   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, ClearParamsFromSharedMemory); | 637   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, ClearParamsFromSharedMemory); | 
| 588 | 638 | 
| 589 #if defined(OS_WIN) | 639 #if defined(OS_WIN) | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 613   static bool CreateTrialsFromSharedMemory( | 663   static bool CreateTrialsFromSharedMemory( | 
| 614       std::unique_ptr<base::SharedMemory> shm); | 664       std::unique_ptr<base::SharedMemory> shm); | 
| 615 | 665 | 
| 616   // Instantiate the field trial allocator, add all existing field trials to it, | 666   // Instantiate the field trial allocator, add all existing field trials to it, | 
| 617   // and duplicates its handle to a read-only handle, which gets stored in | 667   // and duplicates its handle to a read-only handle, which gets stored in | 
| 618   // |readonly_allocator_handle|. | 668   // |readonly_allocator_handle|. | 
| 619   static void InstantiateFieldTrialAllocatorIfNeeded(); | 669   static void InstantiateFieldTrialAllocatorIfNeeded(); | 
| 620 | 670 | 
| 621   // Adds the field trial to the allocator. Caller must hold a lock before | 671   // Adds the field trial to the allocator. Caller must hold a lock before | 
| 622   // calling this. | 672   // calling this. | 
| 623   static void AddToAllocatorWhileLocked(FieldTrial* field_trial); | 673   static void AddToAllocatorWhileLocked(PersistentMemoryAllocator* allocator, | 
|  | 674                                         FieldTrial* field_trial); | 
| 624 | 675 | 
| 625   // Activate the corresponding field trial entry struct in shared memory. | 676   // Activate the corresponding field trial entry struct in shared memory. | 
| 626   static void ActivateFieldTrialEntryWhileLocked(FieldTrial* field_trial); | 677   static void ActivateFieldTrialEntryWhileLocked(FieldTrial* field_trial); | 
| 627 | 678 | 
| 628   // A map from FieldTrial names to the actual instances. | 679   // A map from FieldTrial names to the actual instances. | 
| 629   typedef std::map<std::string, FieldTrial*> RegistrationMap; | 680   typedef std::map<std::string, FieldTrial*> RegistrationMap; | 
| 630 | 681 | 
| 631   // If one-time randomization is enabled, returns a weak pointer to the | 682   // If one-time randomization is enabled, returns a weak pointer to the | 
| 632   // corresponding EntropyProvider. Otherwise, returns NULL. | 683   // corresponding EntropyProvider. Otherwise, returns NULL. | 
| 633   static const FieldTrial::EntropyProvider* | 684   static const FieldTrial::EntropyProvider* | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 675 | 726 | 
| 676   // Tracks whether CreateTrialsFromCommandLine() has been called. | 727   // Tracks whether CreateTrialsFromCommandLine() has been called. | 
| 677   bool create_trials_from_command_line_called_ = false; | 728   bool create_trials_from_command_line_called_ = false; | 
| 678 | 729 | 
| 679   DISALLOW_COPY_AND_ASSIGN(FieldTrialList); | 730   DISALLOW_COPY_AND_ASSIGN(FieldTrialList); | 
| 680 }; | 731 }; | 
| 681 | 732 | 
| 682 }  // namespace base | 733 }  // namespace base | 
| 683 | 734 | 
| 684 #endif  // BASE_METRICS_FIELD_TRIAL_H_ | 735 #endif  // BASE_METRICS_FIELD_TRIAL_H_ | 
| OLD | NEW | 
|---|