Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: chrome/browser/page_load_metrics/page_load_metrics_util.cc

Issue 2936543002: Move Google search related util methods to page_load_metrics_util (Closed)
Patch Set: incorporated falken's comment Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/page_load_metrics/page_load_metrics_util.h" 5 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "chrome/common/page_load_metrics/page_load_timing.h" 9 #include "chrome/common/page_load_metrics/page_load_timing.h"
10 10
(...skipping 23 matching lines...) Expand all
34 return ABORT_STOP; 34 return ABORT_STOP;
35 case END_CLOSE: 35 case END_CLOSE:
36 return ABORT_CLOSE; 36 return ABORT_CLOSE;
37 case END_OTHER: 37 case END_OTHER:
38 return ABORT_OTHER; 38 return ABORT_OTHER;
39 default: 39 default:
40 return ABORT_NONE; 40 return ABORT_NONE;
41 } 41 }
42 } 42 }
43 43
44 // Common helper for QueryContainsComponent and QueryContainsComponentPrefix.
45 bool QueryContainsComponentHelper(const base::StringPiece query,
46 const base::StringPiece component,
47 bool component_is_prefix) {
48 if (query.empty() || component.empty() ||
49 component.length() > query.length()) {
50 return false;
51 }
52
53 // Verify that the provided query string does not include the query or
54 // fragment start character, as the logic below depends on this character not
55 // being included.
56 DCHECK(query[0] != '?' && query[0] != '#');
57
58 // We shouldn't try to find matches beyond the point where there aren't enough
59 // characters left in query to fully match the component.
60 const size_t last_search_start = query.length() - component.length();
61
62 // We need to search for matches in a loop, rather than stopping at the first
63 // match, because we may initially match a substring that isn't a full query
64 // string component. Consider, for instance, the query string 'ab=cd&b=c'. If
65 // we search for component 'b=c', the first substring match will be characters
66 // 1-3 (zero-based) in the query string. However, this isn't a full component
67 // (the full component is ab=cd) so the match will fail. Thus, we must
68 // continue our search to find the second substring match, which in the
69 // example is at characters 6-8 (the end of the query string) and is a
70 // successful component match.
71 for (size_t start_offset = 0; start_offset <= last_search_start;
72 start_offset += component.length()) {
73 start_offset = query.find(component, start_offset);
74 if (start_offset == std::string::npos) {
75 // We searched to end of string and did not find a match.
76 return false;
77 }
78 // Verify that the character prior to the component is valid (either we're
79 // at the beginning of the query string, or are preceded by an ampersand).
80 if (start_offset != 0 && query[start_offset - 1] != '&') {
81 continue;
82 }
83 if (!component_is_prefix) {
84 // Verify that the character after the component substring is valid
85 // (either we're at the end of the query string, or are followed by an
86 // ampersand).
87 const size_t after_offset = start_offset + component.length();
88 if (after_offset < query.length() && query[after_offset] != '&') {
89 continue;
90 }
91 }
92 return true;
93 }
94 return false;
95 }
96
44 } // namespace 97 } // namespace
45 98
46 bool WasStartedInForegroundOptionalEventInForeground( 99 bool WasStartedInForegroundOptionalEventInForeground(
47 const base::Optional<base::TimeDelta>& event, 100 const base::Optional<base::TimeDelta>& event,
48 const PageLoadExtraInfo& info) { 101 const PageLoadExtraInfo& info) {
49 return info.started_in_foreground && event && 102 return info.started_in_foreground && event &&
50 (!info.first_background_time || 103 (!info.first_background_time ||
51 event.value() <= info.first_background_time.value()); 104 event.value() <= info.first_background_time.value());
52 } 105 }
53 106
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 bool DidObserveLoadingBehaviorInAnyFrame( 156 bool DidObserveLoadingBehaviorInAnyFrame(
104 const page_load_metrics::PageLoadExtraInfo& info, 157 const page_load_metrics::PageLoadExtraInfo& info,
105 blink::WebLoadingBehaviorFlag behavior) { 158 blink::WebLoadingBehaviorFlag behavior) {
106 const int all_frame_loading_behavior_flags = 159 const int all_frame_loading_behavior_flags =
107 info.main_frame_metadata.behavior_flags | 160 info.main_frame_metadata.behavior_flags |
108 info.subframe_metadata.behavior_flags; 161 info.subframe_metadata.behavior_flags;
109 162
110 return (all_frame_loading_behavior_flags & behavior) != 0; 163 return (all_frame_loading_behavior_flags & behavior) != 0;
111 } 164 }
112 165
166 bool IsGoogleSearchHostname(const GURL& url) {
167 base::Optional<std::string> result =
168 page_load_metrics::GetGoogleHostnamePrefix(url);
169 return result && result.value() == "www";
170 }
171
172 bool IsGoogleSearchResultUrl(const GURL& url) {
173 // NOTE: we do not require 'q=' in the query, as AJAXy search may instead
174 // store the query in the URL fragment.
175 if (!IsGoogleSearchHostname(url)) {
176 return false;
177 }
178
179 if (!QueryContainsComponentPrefix(url.query_piece(), "q=") &&
180 !QueryContainsComponentPrefix(url.ref_piece(), "q=")) {
181 return false;
182 }
183
184 const base::StringPiece path = url.path_piece();
185 return path == "/search" || path == "/webhp" || path == "/custom" ||
186 path == "/";
187 }
188
189 bool IsGoogleSearchRedirectorUrl(const GURL& url) {
190 if (!IsGoogleSearchHostname(url))
191 return false;
192
193 // The primary search redirector. Google search result redirects are
194 // differentiated from other general google redirects by 'source=web' in the
195 // query string.
196 if (url.path_piece() == "/url" && url.has_query() &&
197 QueryContainsComponent(url.query_piece(), "source=web")) {
198 return true;
199 }
200
201 // Intent-based navigations from search are redirected through a second
202 // redirector, which receives its redirect URL in the fragment/hash/ref
203 // portion of the URL (the portion after '#'). We don't check for the presence
204 // of certain params in the ref since this redirector is only used for
205 // redirects from search.
206 return url.path_piece() == "/searchurl/r.html" && url.has_ref();
207 }
208
209 bool QueryContainsComponent(const base::StringPiece query,
210 const base::StringPiece component) {
211 return QueryContainsComponentHelper(query, component, false);
212 }
213
214 bool QueryContainsComponentPrefix(const base::StringPiece query,
215 const base::StringPiece component) {
216 return QueryContainsComponentHelper(query, component, true);
217 }
218
113 } // namespace page_load_metrics 219 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698