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 #include "chrome/browser/ui/search/search.h" | 5 #include "chrome/browser/ui/search/search.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_split.h" |
10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
11 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
13 #include "chrome/common/chrome_version_info.h" | 14 #include "chrome/common/chrome_version_info.h" |
14 | 15 |
| 16 #if !defined(OS_ANDROID) |
| 17 #include "chrome/browser/themes/theme_service.h" |
| 18 #include "chrome/browser/themes/theme_service_factory.h" |
| 19 #endif |
| 20 |
15 namespace chrome { | 21 namespace chrome { |
16 namespace search { | 22 namespace search { |
17 | 23 |
18 bool IsInstantExtendedAPIEnabled(const Profile* profile) { | 24 // Configuration options for Embedded Search. |
| 25 // InstantExtended field trials are named in such a way that we can parse out |
| 26 // the experiment configuration from the trial's group name in order to give |
| 27 // us maximum flexability in running experiments. |
| 28 // Field trials should be named things like "Group7 espv:2 themes:0". |
| 29 // The first token is always GroupN for some integer N, followed by a |
| 30 // space-delimited list of key:value pairs which correspond to these flags: |
| 31 const char kEnableOnThemesFlagName[] = "themes"; |
| 32 const bool kEnableOnThemesDefault = false; |
| 33 |
| 34 const char kEmbeddedPageVersionFlagName[] = "espv"; |
| 35 const int kEmbeddedPageVersionDefault = 1; |
| 36 |
| 37 // Constants for the field trial name and group prefix. |
| 38 const char kInstantExtendedFieldTrialName[] = "InstantExtended"; |
| 39 const char kGroupNumberPrefix[] = "Group"; |
| 40 |
| 41 // If the field trial's group name ends with this string its configuration will |
| 42 // be ignored and Instant Extended will not be enabled by default. |
| 43 const char kDisablingSuffix[] = "DISABLED"; |
| 44 |
| 45 // Given a field trial group name in the above format, parses out the group |
| 46 // number and configuration flags. Will return a group number of 0 on error. |
| 47 void GetFieldTrialInfo(const std::string& group_name, |
| 48 FieldTrialFlags* flags, |
| 49 uint64* group_number) { |
| 50 if (!EndsWith(group_name, kDisablingSuffix, true) && |
| 51 StartsWithASCII(group_name, kGroupNumberPrefix, true)) { |
| 52 // We have a valid trial that starts with "Group" and isn't disabled. |
| 53 size_t first_space = group_name.find(" "); |
| 54 std::string group_prefix = group_name; |
| 55 if (first_space != std::string::npos) { |
| 56 // There is a flags section of the group name. Split that out and parse |
| 57 // it. |
| 58 group_prefix = group_name.substr(0, first_space); |
| 59 base::SplitStringIntoKeyValuePairs( |
| 60 group_name.substr(first_space), ':', ' ', flags); |
| 61 } |
| 62 if (!base::StringToUint64(group_prefix.substr(strlen(kGroupNumberPrefix)), |
| 63 group_number)) { |
| 64 // Could not parse group number. |
| 65 *group_number = 0; |
| 66 } |
| 67 } |
| 68 } |
| 69 |
| 70 // Given a FieldTrialFlags object, returns the string value of the provided |
| 71 // flag. |
| 72 std::string GetStringValueForFlagWithDefault( |
| 73 const std::string& flag, |
| 74 const std::string& default_value, |
| 75 FieldTrialFlags& flags) { |
| 76 FieldTrialFlags::const_iterator i; |
| 77 for (i = flags.begin(); i != flags.end(); i++) { |
| 78 if (i->first == flag) |
| 79 return i->second; |
| 80 } |
| 81 return default_value; |
| 82 } |
| 83 |
| 84 // Given a FieldTrialFlags object, returns the uint64 value of the provided |
| 85 // flag. |
| 86 uint64 GetUInt64ValueForFlagWithDefault( |
| 87 const std::string& flag, uint64 default_value, FieldTrialFlags& flags) { |
| 88 uint64 value; |
| 89 if (!base::StringToUint64(GetStringValueForFlagWithDefault(flag, "", flags), |
| 90 &value)) |
| 91 return default_value; |
| 92 return value; |
| 93 } |
| 94 |
| 95 // Given a FieldTrialFlags object, returns the boolean value of the provided |
| 96 // flag. |
| 97 bool GetBoolValueForFlagWithDefault( |
| 98 const std::string& flag, bool default_value, FieldTrialFlags& flags) { |
| 99 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); |
| 100 } |
| 101 |
| 102 // Check whether or not the Extended API should be used on the given profile. |
| 103 bool IsInstantExtendedAPIEnabled(Profile* profile) { |
19 return EmbeddedSearchPageVersion(profile) != 0; | 104 return EmbeddedSearchPageVersion(profile) != 0; |
20 } | 105 } |
21 | 106 |
22 uint64 EmbeddedSearchPageVersion(const Profile* profile) { | 107 // Determine what embedded search page version to request from the user's |
| 108 // default search provider. If 0, the embedded search UI should not be enabled. |
| 109 // Note that the profile object here isn't const because we need to determine |
| 110 // whether or not the user has a theme installed as part of this check, and |
| 111 // that logic requires a non-const profile for whatever reason. |
| 112 uint64 EmbeddedSearchPageVersion(Profile* profile) { |
23 // Incognito windows do not currently use the embedded search API. | 113 // Incognito windows do not currently use the embedded search API. |
24 if (!profile || profile->IsOffTheRecord()) | 114 if (!profile || profile->IsOffTheRecord()) |
25 return 0; | 115 return 0; |
26 | 116 |
27 // Check Finch field trials. | 117 // Check Finch field trials. |
28 base::FieldTrial* trial = base::FieldTrialList::Find("InstantExtended"); | 118 FieldTrialFlags flags; |
29 if (trial && StartsWithASCII(trial->group_name(), "Group", true)) { | 119 uint64 group_number = 0; |
30 uint64 group_number; | 120 base::FieldTrial* trial = |
31 if (base::StringToUint64(trial->group_name().substr(5), &group_number)) { | 121 base::FieldTrialList::Find(kInstantExtendedFieldTrialName); |
32 return group_number; | 122 if (trial) { |
33 } | 123 std::string group_name = trial->group_name(); |
| 124 GetFieldTrialInfo(group_name, &flags, &group_number); |
| 125 } |
| 126 |
| 127 if (group_number > 0) { |
| 128 uint64 espv = GetUInt64ValueForFlagWithDefault( |
| 129 kEmbeddedPageVersionFlagName, |
| 130 kEmbeddedPageVersionDefault, |
| 131 flags); |
| 132 |
| 133 // Check for themes. |
| 134 bool has_theme = false; |
| 135 #if !defined(OS_ANDROID) |
| 136 has_theme = |
| 137 !ThemeServiceFactory::GetForProfile(profile)->UsingDefaultTheme(); |
| 138 #endif |
| 139 |
| 140 bool enable_for_themes = |
| 141 GetBoolValueForFlagWithDefault(kEnableOnThemesFlagName, |
| 142 kEnableOnThemesDefault, |
| 143 flags); |
| 144 if (!has_theme || enable_for_themes) |
| 145 return espv; |
34 } | 146 } |
35 | 147 |
36 if (CommandLine::ForCurrentProcess()->HasSwitch( | 148 if (CommandLine::ForCurrentProcess()->HasSwitch( |
37 switches::kEnableInstantExtendedAPI)) { | 149 switches::kEnableInstantExtendedAPI)) { |
38 // The user has manually flipped the about:flags switch - give the default | 150 // The user has manually flipped the about:flags switch - give the default |
39 // UI version. | 151 // UI version. |
40 return 1; | 152 return kEmbeddedPageVersionDefault; |
41 } | 153 } |
42 return 0; | 154 return 0; |
43 } | 155 } |
44 | 156 |
45 void EnableInstantExtendedAPIForTesting() { | 157 void EnableInstantExtendedAPIForTesting() { |
46 CommandLine::ForCurrentProcess()->AppendSwitch( | 158 CommandLine::ForCurrentProcess()->AppendSwitch( |
47 switches::kEnableInstantExtendedAPI); | 159 switches::kEnableInstantExtendedAPI); |
48 } | 160 } |
49 | 161 |
50 bool IsQueryExtractionEnabled(const Profile* profile) { | 162 bool IsQueryExtractionEnabled(Profile* profile) { |
51 return IsInstantExtendedAPIEnabled(profile) || | 163 return IsInstantExtendedAPIEnabled(profile) || |
52 CommandLine::ForCurrentProcess()->HasSwitch( | 164 CommandLine::ForCurrentProcess()->HasSwitch( |
53 switches::kEnableInstantExtendedAPI); | 165 switches::kEnableInstantExtendedAPI); |
54 } | 166 } |
55 | 167 |
56 void EnableQueryExtractionForTesting() { | 168 void EnableQueryExtractionForTesting() { |
57 CommandLine::ForCurrentProcess()->AppendSwitch( | 169 CommandLine::ForCurrentProcess()->AppendSwitch( |
58 switches::kEnableInstantExtendedAPI); | 170 switches::kEnableInstantExtendedAPI); |
59 } | 171 } |
60 | 172 |
61 } // namespace search | 173 } // namespace search |
62 } // namespace chrome | 174 } // namespace chrome |
OLD | NEW |