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_split.h" | 9 #include "base/string_split.h" |
10 #include "base/string_util.h" | |
11 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "chrome/browser/instant/instant_service.h" | |
12 #include "chrome/browser/instant/instant_service_factory.h" | |
12 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/search_engines/template_url_service.h" | |
15 #include "chrome/browser/search_engines/template_url_service_factory.h" | |
13 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
14 #include "chrome/common/chrome_version_info.h" | 17 #include "chrome/common/url_constants.h" |
15 #include "content/public/browser/navigation_entry.h" | 18 #include "content/public/browser/navigation_entry.h" |
16 | 19 #include "content/public/browser/render_process_host.h" |
17 #if !defined(OS_ANDROID) | 20 #include "content/public/browser/web_contents.h" |
18 #include "chrome/browser/themes/theme_service.h" | |
19 #include "chrome/browser/themes/theme_service_factory.h" | |
20 #endif | |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Configuration options for Embedded Search. | 24 // Configuration options for Embedded Search. |
25 // InstantExtended field trials are named in such a way that we can parse out | 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 | 26 // the experiment configuration from the trial's group name in order to give |
27 // us maximum flexability in running experiments. | 27 // us maximum flexability in running experiments. |
28 // Field trials should be named things like "Group7 espv:2 themes:0". | 28 // Field trial groups should be named things like "Group7 espv:2 instant:1". |
29 // The first token is always GroupN for some integer N, followed by a | 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: | 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"; | 31 const char kEmbeddedPageVersionFlagName[] = "espv"; |
35 const int kEmbeddedPageVersionDefault = 1; | 32 const int kEmbeddedPageVersionDefault = 1; |
36 | 33 |
37 const char kInstantExtendedActivationName[] = "instant"; | 34 const char kInstantExtendedActivationName[] = "instant"; |
38 const chrome::search::InstantExtendedDefault kInstantExtendedActivationDefault = | 35 const chrome::search::InstantExtendedDefault kInstantExtendedActivationDefault = |
39 chrome::search::INSTANT_USE_EXISTING; | 36 chrome::search::INSTANT_USE_EXISTING; |
40 | 37 |
41 // Constants for the field trial name and group prefix. | 38 // Constants for the field trial name and group prefix. |
42 const char kInstantExtendedFieldTrialName[] = "InstantExtended"; | 39 const char kInstantExtendedFieldTrialName[] = "InstantExtended"; |
43 const char kGroupNumberPrefix[] = "Group"; | 40 const char kGroupNumberPrefix[] = "Group"; |
44 | 41 |
45 // If the field trial's group name ends with this string its configuration will | 42 // If the field trial's group name ends with this string its configuration will |
46 // be ignored and Instant Extended will not be enabled by default. | 43 // be ignored and Instant Extended will not be enabled by default. |
47 const char kDisablingSuffix[] = "DISABLED"; | 44 const char kDisablingSuffix[] = "DISABLED"; |
48 | 45 |
46 chrome::search::InstantExtendedDefault InstantExtendedDefaultFromInt64( | |
47 int64 default_value) { | |
48 switch (default_value) { | |
49 case 0: return chrome::search::INSTANT_DEFAULT_ON; | |
50 case 1: return chrome::search::INSTANT_USE_EXISTING; | |
51 case 2: return chrome::search::INSTANT_DEFAULT_OFF; | |
52 default: return chrome::search::INSTANT_USE_EXISTING; | |
53 } | |
54 } | |
55 | |
56 TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) { | |
57 TemplateURLService* template_url_service = | |
58 TemplateURLServiceFactory::GetForProfile(profile); | |
59 if (template_url_service) | |
60 return template_url_service->GetDefaultSearchProvider(); | |
61 return NULL; | |
62 } | |
63 | |
64 GURL TemplateURLRefToGURL(const TemplateURLRef& ref) { | |
65 return GURL( | |
66 ref.ReplaceSearchTerms(TemplateURLRef::SearchTermsArgs(string16()))); | |
67 } | |
68 | |
69 bool MatchesOriginAndPath(const GURL& my_url, const GURL& other_url) { | |
70 return my_url.host() == other_url.host() && | |
71 my_url.port() == other_url.port() && | |
72 my_url.path() == other_url.path() && | |
73 (my_url.scheme() == other_url.scheme() || | |
74 (my_url.SchemeIs(chrome::kHttpsScheme) && | |
75 other_url.SchemeIs(chrome::kHttpScheme))); | |
76 } | |
77 | |
78 bool IsCommandLineInstantURL(const GURL& url) { | |
79 const CommandLine* cl = CommandLine::ForCurrentProcess(); | |
80 GURL instant_url(cl->GetSwitchValueASCII(switches::kInstantURL)); | |
81 return instant_url.is_valid() && MatchesOriginAndPath(url, instant_url); | |
82 } | |
83 | |
84 // Coerces the commandline Instant URL to look like a template URL, so that we | |
85 // can extract search terms from it. | |
86 GURL CoerceCommandLineURLToTemplateURL(const GURL& instant_url, | |
87 const TemplateURLRef& ref) { | |
88 GURL search_url = TemplateURLRefToGURL(ref); | |
89 | |
90 GURL::Replacements replacements; | |
91 replacements.SetSchemeStr(chrome::kHttpsScheme); | |
92 replacements.SetHostStr(search_url.host()); | |
93 replacements.SetPortStr(search_url.port()); | |
94 replacements.SetPathStr(search_url.path()); | |
95 | |
96 return instant_url.ReplaceComponents(replacements); | |
97 } | |
98 | |
99 bool MatchesAnySearchURL(const GURL& url, TemplateURL* template_url) { | |
100 GURL search_url = TemplateURLRefToGURL(template_url->url_ref()); | |
101 if (search_url.is_valid() && MatchesOriginAndPath(url, search_url)) | |
102 return true; | |
103 | |
104 // "URLCount() - 1" because we already tested url_ref above. | |
105 for (size_t i = 0; i < template_url->URLCount() - 1; ++i) { | |
106 TemplateURLRef ref(template_url, i); | |
107 search_url = TemplateURLRefToGURL(ref); | |
108 if (search_url.is_valid() && MatchesOriginAndPath(url, search_url)) | |
109 return true; | |
110 } | |
111 | |
112 return false; | |
113 } | |
114 | |
49 } // namespace | 115 } // namespace |
50 | 116 |
51 namespace chrome { | 117 namespace chrome { |
52 namespace search { | 118 namespace search { |
53 | 119 |
54 // static | |
55 const char kInstantExtendedSearchTermsKey[] = "search_terms"; | 120 const char kInstantExtendedSearchTermsKey[] = "search_terms"; |
56 | 121 |
57 InstantExtendedDefault InstantExtendedDefaultFromInt64(int64 default_value) { | 122 const char kLocalOmniboxPopupURL[] = |
58 switch (default_value) { | 123 "chrome://local-omnibox-popup/local-omnibox-popup.html"; |
59 case 0: return INSTANT_FORCE_ON; | |
60 case 1: return INSTANT_USE_EXISTING; | |
61 case 2: return INSTANT_FORCE_OFF; | |
62 default: return INSTANT_USE_EXISTING; | |
63 } | |
64 } | |
65 | 124 |
66 InstantExtendedDefault GetInstantExtendedDefaultSetting() { | 125 InstantExtendedDefault GetInstantExtendedDefaultSetting() { |
67 InstantExtendedDefault default_setting = INSTANT_USE_EXISTING; | |
68 | |
69 FieldTrialFlags flags; | 126 FieldTrialFlags flags; |
70 if (GetFieldTrialInfo( | 127 if (GetFieldTrialInfo( |
71 base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName), | 128 base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName), |
72 &flags, NULL)) { | 129 &flags, NULL)) { |
73 uint64 trial_default = GetUInt64ValueForFlagWithDefault( | 130 uint64 trial_default = GetUInt64ValueForFlagWithDefault( |
74 kInstantExtendedActivationName, | 131 kInstantExtendedActivationName, |
75 kInstantExtendedActivationDefault, | 132 kInstantExtendedActivationDefault, |
76 flags); | 133 flags); |
77 default_setting = InstantExtendedDefaultFromInt64(trial_default); | 134 return InstantExtendedDefaultFromInt64(trial_default); |
78 } | 135 } |
79 | 136 |
80 return default_setting; | 137 return INSTANT_USE_EXISTING; |
81 } | 138 } |
82 | 139 |
83 // Check whether or not the Extended API should be used on the given profile. | 140 bool IsInstantExtendedAPIEnabled(const Profile* profile) { |
84 bool IsInstantExtendedAPIEnabled(Profile* profile) { | |
85 return EmbeddedSearchPageVersion(profile) != 0; | 141 return EmbeddedSearchPageVersion(profile) != 0; |
86 } | 142 } |
87 | 143 |
88 // Determine what embedded search page version to request from the user's | 144 // Determine what embedded search page version to request from the user's |
89 // default search provider. If 0, the embedded search UI should not be enabled. | 145 // default search provider. If 0, the embedded search UI should not be enabled. |
90 // Note that the profile object here isn't const because we need to determine | 146 uint64 EmbeddedSearchPageVersion(const Profile* profile) { |
91 // whether or not the user has a theme installed as part of this check, and | |
92 // that logic requires a non-const profile for whatever reason. | |
93 uint64 EmbeddedSearchPageVersion(Profile* profile) { | |
94 // Incognito windows do not currently use the embedded search API. | |
95 if (!profile || profile->IsOffTheRecord()) | 147 if (!profile || profile->IsOffTheRecord()) |
96 return 0; | 148 return 0; |
97 | 149 |
98 // Check Finch field trials. | |
99 FieldTrialFlags flags; | 150 FieldTrialFlags flags; |
100 if (GetFieldTrialInfo( | 151 if (GetFieldTrialInfo( |
101 base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName), | 152 base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName), |
102 &flags, NULL)) { | 153 &flags, NULL)) { |
103 uint64 espv = GetUInt64ValueForFlagWithDefault( | 154 return GetUInt64ValueForFlagWithDefault(kEmbeddedPageVersionFlagName, |
104 kEmbeddedPageVersionFlagName, | 155 kEmbeddedPageVersionDefault, |
105 kEmbeddedPageVersionDefault, | 156 flags); |
106 flags); | 157 } |
107 | 158 |
108 // Check for themes. | 159 const CommandLine* cl = CommandLine::ForCurrentProcess(); |
109 bool has_theme = false; | 160 if (cl->HasSwitch(switches::kEnableInstantExtendedAPI)) { |
110 #if !defined(OS_ANDROID) | |
111 has_theme = | |
112 !ThemeServiceFactory::GetForProfile(profile)->UsingDefaultTheme(); | |
113 #endif | |
114 | |
115 bool enable_for_themes = | |
116 GetBoolValueForFlagWithDefault(kEnableOnThemesFlagName, | |
117 kEnableOnThemesDefault, | |
118 flags); | |
119 if (!has_theme || enable_for_themes) | |
120 return espv; | |
121 } | |
122 | |
123 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
124 switches::kEnableInstantExtendedAPI)) { | |
125 // The user has manually flipped the about:flags switch - give the default | 161 // The user has manually flipped the about:flags switch - give the default |
126 // UI version. | 162 // UI version. |
127 return kEmbeddedPageVersionDefault; | 163 return kEmbeddedPageVersionDefault; |
128 } | 164 } |
165 | |
129 return 0; | 166 return 0; |
130 } | 167 } |
131 | 168 |
132 void EnableInstantExtendedAPIForTesting() { | 169 bool IsQueryExtractionEnabled(const Profile* profile) { |
133 CommandLine::ForCurrentProcess()->AppendSwitch( | |
134 switches::kEnableInstantExtendedAPI); | |
135 } | |
136 | |
137 bool IsQueryExtractionEnabled(Profile* profile) { | |
138 #if defined(OS_IOS) | 170 #if defined(OS_IOS) |
139 return CommandLine::ForCurrentProcess()->HasSwitch( | 171 const CommandLine* cl = CommandLine::ForCurrentProcess(); |
140 switches::kEnableQueryExtraction); | 172 return cl->HasSwitch(switches::kEnableQueryExtraction); |
141 #else | |
142 if (!profile || profile->IsOffTheRecord()) | |
143 return false; | |
144 | |
145 // On desktop, query extraction is controlled by the instant-extended-api | |
146 // flag. | |
147 bool enabled = IsInstantExtendedAPIEnabled(profile); | |
148 | |
149 // Running with --enable-query-extraction but not | |
150 // --enable-instant-extended-api is an error. | |
151 DCHECK(!(CommandLine::ForCurrentProcess()->HasSwitch( | |
152 switches::kEnableQueryExtraction) && | |
153 !enabled)); | |
154 return enabled; | |
155 #endif | |
156 } | |
157 | |
158 void EnableQueryExtractionForTesting() { | |
159 #if defined(OS_IOS) | |
160 CommandLine::ForCurrentProcess()->AppendSwitch( | |
161 switches::kEnableQueryExtraction); | |
162 #else | 173 #else |
163 // On desktop, query extraction is controlled by the instant-extended-api | 174 // On desktop, query extraction is controlled by the instant-extended-api |
164 // flag. | 175 // flag. |
165 CommandLine::ForCurrentProcess()->AppendSwitch( | 176 return IsInstantExtendedAPIEnabled(profile); |
166 switches::kEnableInstantExtendedAPI); | |
167 #endif | 177 #endif |
168 } | 178 } |
169 | 179 |
170 string16 GetSearchTermsFromNavigationEntry( | 180 string16 GetSearchTermsFromNavigationEntry( |
171 const content::NavigationEntry* entry) { | 181 const content::NavigationEntry* entry) { |
172 string16 search_terms; | 182 string16 search_terms; |
173 entry->GetExtraData(kInstantExtendedSearchTermsKey, &search_terms); | 183 if (entry) |
184 entry->GetExtraData(kInstantExtendedSearchTermsKey, &search_terms); | |
174 return search_terms; | 185 return search_terms; |
175 } | 186 } |
176 | 187 |
177 bool IsForcedInstantURL(const GURL& url) { | 188 string16 GetSearchTerms(const content::WebContents* contents) { |
178 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 189 string16 search_terms; |
179 if (!command_line->HasSwitch(switches::kInstantURL)) | 190 |
180 return false; | 191 if (!contents) |
181 | 192 return search_terms; |
dhollowa
2013/02/13 17:42:28
For these early returns, and anywhere you expect s
sreeram
2013/02/13 17:45:05
The reason why I kept it this way is to allow NRVO
| |
182 GURL instant_url(command_line->GetSwitchValueASCII(switches::kInstantURL)); | 193 |
183 return url.scheme() == instant_url.scheme() && | 194 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
184 url.host() == instant_url.host() && | 195 if (!IsQueryExtractionEnabled(profile)) |
185 url.port() == instant_url.port() && | 196 return search_terms; |
186 url.path() == instant_url.path(); | 197 |
198 // For security reasons, don't extract search terms if the page is not being | |
199 // rendered in the privileged Instant renderer process. This is to protect | |
200 // against a malicious page somehow scripting the search results page and | |
201 // faking search terms in the URL. Random pages can't get into the Instant | |
202 // renderer and scripting doesn't work cross-process, so if the page is in | |
203 // the Instant process, we know it isn't being exploited. | |
204 const content::RenderProcessHost* process_host = | |
205 contents->GetRenderProcessHost(); | |
206 if (!process_host) | |
207 return search_terms; | |
208 | |
209 const InstantService* instant_service = | |
210 InstantServiceFactory::GetForProfile(profile); | |
211 if (!instant_service) | |
212 return search_terms; | |
213 | |
214 if (!instant_service->IsInstantProcess(process_host->GetID())) | |
215 return search_terms; | |
216 | |
217 // Check to see if search terms have already been extracted. | |
218 const content::NavigationEntry* entry = | |
219 contents->GetController().GetVisibleEntry(); | |
220 if (!entry) | |
221 return search_terms; | |
222 | |
223 search_terms = GetSearchTermsFromNavigationEntry(entry); | |
224 if (!search_terms.empty()) | |
225 return search_terms; | |
226 | |
227 // Otherwise, extract from the URL. | |
228 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); | |
229 if (!template_url) | |
230 return search_terms; | |
231 | |
232 GURL url = entry->GetVirtualURL(); | |
233 | |
234 if (IsCommandLineInstantURL(url)) | |
235 url = CoerceCommandLineURLToTemplateURL(url, template_url->url_ref()); | |
236 | |
237 if (url.SchemeIsSecure() && template_url->HasSearchTermsReplacementKey(url)) | |
238 template_url->ExtractSearchTermsFromURL(url, &search_terms); | |
239 | |
240 return search_terms; | |
241 } | |
242 | |
243 bool ShouldAssignURLToInstantRenderer(const GURL& url, Profile* profile) { | |
244 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); | |
245 if (!template_url) | |
246 return false; | |
247 | |
248 GURL effective_url = url; | |
249 | |
250 if (IsCommandLineInstantURL(url)) { | |
251 const TemplateURLRef& instant_url_ref = template_url->instant_url_ref(); | |
252 effective_url = CoerceCommandLineURLToTemplateURL(url, instant_url_ref); | |
253 } | |
254 | |
255 return ShouldAssignURLToInstantRendererImpl( | |
256 effective_url, | |
257 IsInstantExtendedAPIEnabled(profile), | |
258 template_url); | |
259 } | |
260 | |
261 void EnableInstantExtendedAPIForTesting() { | |
262 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
263 cl->AppendSwitch(switches::kEnableInstantExtendedAPI); | |
264 } | |
265 | |
266 void EnableQueryExtractionForTesting() { | |
267 #if defined(OS_IOS) | |
268 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
269 cl->AppendSwitch(switches::kEnableQueryExtraction); | |
270 #else | |
271 EnableInstantExtendedAPIForTesting(); | |
272 #endif | |
273 } | |
274 | |
275 bool ShouldAssignURLToInstantRendererImpl(const GURL& url, | |
276 bool extended_api_enabled, | |
277 TemplateURL* template_url) { | |
278 if (!url.is_valid()) | |
279 return false; | |
280 | |
281 if (url.SchemeIs(chrome::kChromeSearchScheme)) | |
282 return true; | |
283 | |
284 if (extended_api_enabled && url == GURL(kLocalOmniboxPopupURL)) | |
285 return true; | |
286 | |
287 if (extended_api_enabled && !url.SchemeIsSecure()) | |
288 return false; | |
289 | |
290 if (extended_api_enabled && !template_url->HasSearchTermsReplacementKey(url)) | |
291 return false; | |
292 | |
293 GURL instant_url = TemplateURLRefToGURL(template_url->instant_url_ref()); | |
294 if (!instant_url.is_valid()) | |
295 return false; | |
296 | |
297 if (MatchesOriginAndPath(url, instant_url)) | |
298 return true; | |
299 | |
300 if (extended_api_enabled && MatchesAnySearchURL(url, template_url)) | |
301 return true; | |
302 | |
303 return false; | |
187 } | 304 } |
188 | 305 |
189 bool GetFieldTrialInfo(const std::string& group_name, | 306 bool GetFieldTrialInfo(const std::string& group_name, |
190 FieldTrialFlags* flags, | 307 FieldTrialFlags* flags, |
191 uint64* group_number) { | 308 uint64* group_number) { |
192 if (EndsWith(group_name, kDisablingSuffix, true) || | 309 if (EndsWith(group_name, kDisablingSuffix, true) || |
193 !StartsWithASCII(group_name, kGroupNumberPrefix, true)) { | 310 !StartsWithASCII(group_name, kGroupNumberPrefix, true)) |
194 return false; | 311 return false; |
195 } | |
196 | 312 |
197 // We have a valid trial that starts with "Group" and isn't disabled. | 313 // We have a valid trial that starts with "Group" and isn't disabled. |
198 // First extract the flags. | 314 // First extract the flags. |
199 std::string group_prefix(group_name); | 315 std::string group_prefix(group_name); |
200 | 316 |
201 size_t first_space = group_name.find(" "); | 317 size_t first_space = group_name.find(" "); |
202 if (first_space != std::string::npos) { | 318 if (first_space != std::string::npos) { |
203 // There is a flags section of the group name. Split that out and parse | 319 // There is a flags section of the group name. Split that out and parse it. |
204 // it. | |
205 group_prefix = group_name.substr(0, first_space); | 320 group_prefix = group_name.substr(0, first_space); |
206 if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space), | 321 if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space), |
207 ':', ' ', flags)) { | 322 ':', ' ', flags)) { |
208 // Failed to parse the flags section. Assume the whole group name is | 323 // Failed to parse the flags section. Assume the whole group name is |
209 // invalid. | 324 // invalid. |
210 return false; | 325 return false; |
211 } | 326 } |
212 } | 327 } |
213 | 328 |
214 // Now extract the group number, making sure we get a non-zero value. | 329 // Now extract the group number, making sure we get a non-zero value. |
215 uint64 temp_group_number = 0; | 330 uint64 temp_group_number = 0; |
216 if (!base::StringToUint64(group_prefix.substr(strlen(kGroupNumberPrefix)), | 331 std::string group_suffix = group_prefix.substr(strlen(kGroupNumberPrefix)); |
217 &temp_group_number) || | 332 if (!base::StringToUint64(group_suffix, &temp_group_number) || |
218 temp_group_number == 0) { | 333 temp_group_number == 0) |
219 return false; | 334 return false; |
220 } | |
221 | 335 |
222 if (group_number) | 336 if (group_number) |
223 *group_number = temp_group_number; | 337 *group_number = temp_group_number; |
224 | 338 |
225 return true; | 339 return true; |
226 } | 340 } |
227 | 341 |
228 // Given a FieldTrialFlags object, returns the string value of the provided | 342 // Given a FieldTrialFlags object, returns the string value of the provided |
229 // flag. | 343 // flag. |
230 std::string GetStringValueForFlagWithDefault( | 344 std::string GetStringValueForFlagWithDefault(const std::string& flag, |
231 const std::string& flag, | 345 const std::string& default_value, |
232 const std::string& default_value, | 346 const FieldTrialFlags& flags) { |
233 FieldTrialFlags& flags) { | |
234 FieldTrialFlags::const_iterator i; | 347 FieldTrialFlags::const_iterator i; |
235 for (i = flags.begin(); i != flags.end(); i++) { | 348 for (i = flags.begin(); i != flags.end(); i++) { |
236 if (i->first == flag) | 349 if (i->first == flag) |
237 return i->second; | 350 return i->second; |
238 } | 351 } |
239 return default_value; | 352 return default_value; |
240 } | 353 } |
241 | 354 |
242 // Given a FieldTrialFlags object, returns the uint64 value of the provided | 355 // Given a FieldTrialFlags object, returns the uint64 value of the provided |
243 // flag. | 356 // flag. |
244 uint64 GetUInt64ValueForFlagWithDefault( | 357 uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag, |
245 const std::string& flag, uint64 default_value, FieldTrialFlags& flags) { | 358 uint64 default_value, |
359 const FieldTrialFlags& flags) { | |
246 uint64 value; | 360 uint64 value; |
247 if (!base::StringToUint64(GetStringValueForFlagWithDefault(flag, "", flags), | 361 std::string str_value = GetStringValueForFlagWithDefault(flag, "", flags); |
248 &value)) | 362 if (base::StringToUint64(str_value, &value)) |
249 return default_value; | 363 return value; |
250 return value; | 364 return default_value; |
251 } | 365 } |
252 | 366 |
253 // Given a FieldTrialFlags object, returns the boolean value of the provided | 367 // Given a FieldTrialFlags object, returns the boolean value of the provided |
254 // flag. | 368 // flag. |
255 bool GetBoolValueForFlagWithDefault( | 369 bool GetBoolValueForFlagWithDefault(const std::string& flag, |
256 const std::string& flag, bool default_value, FieldTrialFlags& flags) { | 370 bool default_value, |
371 const FieldTrialFlags& flags) { | |
257 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); | 372 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); |
258 } | 373 } |
259 | 374 |
260 } // namespace search | 375 } // namespace search |
261 } // namespace chrome | 376 } // namespace chrome |
OLD | NEW |