1 // Copyright 2013 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 #include "chrome/browser/history/most_visited_tiles_experiment.h" 6 7 #include "base/metrics/field_trial.h" 8 #include "base/metrics/histogram.h" 9 #include "base/strings/string_util.h" 10 #include "chrome/common/instant_types.h" 11 12 namespace history { 13 14 namespace { 15 16 // Constants for the most visited tile placement field trial. 17 // ex: 18 // "OneEightGroup_Flipped" --> Will cause tile 1 and 8 to be flipped. 19 // "OneEightGroup_NoChange" --> Will not flip anything. 20 // 21 // See field trial config (MostVisitedTilePlacement.json) for details. 22 const char kMostVisitedFieldTrialName[] = "MostVisitedTilePlacement"; 23 // Name of histogram tracking types of actions carried out by the field trial. 24 const char kMostVisitedExperimentHistogramName[] = 25 "NewTabPage.MostVisitedTilePlacementExperiment"; 26 const char kOneEightGroupPrefix[] = "OneEight"; 27 const char kOneFourGroupPrefix[] = "OneFour"; 28 const char kFlippedSuffix[] = "Flipped"; 29 const char kDontShowOpenURLsGroupName[] = "DontShowOpenTabs"; 30 // Minimum number of Most Visited suggestions required in order for the Most 31 // Visited Field Trial to remove a URL already open in the browser. 32 const size_t kMinUrlSuggestions = 8; 33 34 } // namespace 35 36 // static 37 void MostVisitedTilesExperiment::MaybeShuffle(MostVisitedURLList* data) { 38 const std::string group_name = 39 base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName); 40 41 // Depending on the study group of the client, we might flip the 1st and 4th 42 // tiles, or the 1st and 8th, or do nothing. 43 if (!EndsWith(group_name, kFlippedSuffix, true)) 44 return; 45 46 size_t index_to_flip = 0; 47 if (StartsWithASCII(group_name, kOneEightGroupPrefix, true)) { 48 if (data->size() < 8) { 49 LogInHistogram(NTP_TILE_EXPERIMENT_ACTION_TOO_FEW_URLS_TILES_1_8); 50 return; 51 } 52 index_to_flip = 7; 53 } else if (StartsWithASCII(group_name, kOneFourGroupPrefix, true)) { 54 if (data->size() < 4) { 55 LogInHistogram(NTP_TILE_EXPERIMENT_ACTION_TOO_FEW_URLS_TILES_1_4); 56 return; 57 } 58 index_to_flip = 3; 59 } 60 std::swap((*data)[0], (*data)[index_to_flip]); 61 } 62 63 // static 64 bool MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled() { 65 return base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName) == 66 kDontShowOpenURLsGroupName; 67 } 68 69 // static 70 void MostVisitedTilesExperiment::RemoveItemsMatchingOpenTabs( 71 const std::set<std::string>& open_urls, 72 std::vector<InstantMostVisitedItem>* items) { 73 for (size_t i = 0; i < items->size(); ) { 74 const std::string& url = (*items)[i].url.spec(); 75 if (ShouldRemoveURL(open_urls, url, items->size())) 76 items->erase(items->begin() + i); 77 else 78 ++i; 79 } 80 } 81 82 // static 83 void MostVisitedTilesExperiment::RemovePageValuesMatchingOpenTabs( 84 const std::set<std::string>& open_urls, 85 base::ListValue* pages_value) { 86 for (size_t i = 0; i < pages_value->GetSize(); ) { 87 base::DictionaryValue* page_value; 88 std::string url; 89 if (pages_value->GetDictionary(i, &page_value) && 90 page_value->GetString("url", &url) && 91 ShouldRemoveURL(open_urls, url, pages_value->GetSize())) { 92 pages_value->Remove(*page_value, &i); 93 } else { 94 ++i; 95 } 96 } 97 } 98 99 // static 100 void MostVisitedTilesExperiment::LogInHistogram( 101 NtpTileExperimentActions action) { 102 UMA_HISTOGRAM_ENUMERATION(kMostVisitedExperimentHistogramName, 103 action, 104 NUM_NTP_TILE_EXPERIMENT_ACTIONS); 105 } 106 107 // static 108 bool MostVisitedTilesExperiment::ShouldRemoveURL( 109 const std::set<std::string>& open_urls, 110 const std::string& url, 111 const size_t size) { 112 if (open_urls.count(url) == 0) 113 return false; 114 115 if (size <= kMinUrlSuggestions) { 116 LogInHistogram(NTP_TILE_EXPERIMENT_ACTION_DID_NOT_REMOVE_URL); 117 return false; 118 } 119 120 LogInHistogram(NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL); 121 return true; 122 } 123 124 } // namespace history 125