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

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc

Issue 2601303002: Wireup SafeBrowsingNavigationObserverManager to help PPAPI download attribution (Closed)
Patch Set: nit Created 3 years, 11 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/safe_browsing/safe_browsing_navigation_observer_manager .h" 5 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager .h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 24 matching lines...) Expand all
35 // Note, if for some reason this event's timestamp is in the future, this 35 // Note, if for some reason this event's timestamp is in the future, this
36 // event's timestamp is invalid, hence we treat it as expired. 36 // event's timestamp is invalid, hence we treat it as expired.
37 bool IsEventExpired(const base::Time& event_time, double ttl_in_second) { 37 bool IsEventExpired(const base::Time& event_time, double ttl_in_second) {
38 double current_time_in_second = base::Time::Now().ToDoubleT(); 38 double current_time_in_second = base::Time::Now().ToDoubleT();
39 double event_time_in_second = event_time.ToDoubleT(); 39 double event_time_in_second = event_time.ToDoubleT();
40 if (current_time_in_second <= event_time_in_second) 40 if (current_time_in_second <= event_time_in_second)
41 return true; 41 return true;
42 return current_time_in_second - event_time_in_second > ttl_in_second; 42 return current_time_in_second - event_time_in_second > ttl_in_second;
43 } 43 }
44 44
45 // Helper function to determine if the URL type should be LANDING_REFERRER or
46 // LANDING_PAGE, and modify AttributionResult accordingly.
47 ReferrerChainEntry::URLType GetURLTypeAndAdjustAttributionResult(
48 int current_user_gesture_count,
Nathan Parker 2017/01/04 19:49:12 What is current_user_gesture_count? Is that how ma
Jialiu Lin 2017/01/04 21:53:35 Good suggestion. Thanks!
49 int user_gesture_count_limit,
50 SafeBrowsingNavigationObserverManager::AttributionResult* out_result) {
51 // Landing page of a download refers to the page user directly interacts
52 // with to trigger this download (e.g. clicking on download button). Landing
53 // referrer page is the one user interacts with right before navigating to
54 // the landing page.
55 // Since we are tracing navigations backwards, if we've reached
56 // |user_gesture_count_limit| number of user gesture before this navigation
57 // event, this is a navigation leading to the landing referrer page,
58 // otherwise it leads to landing page.
59 if (current_user_gesture_count == user_gesture_count_limit) {
60 *out_result =
61 SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER;
62 return ReferrerChainEntry::LANDING_REFERRER;
63 } else {
64 *out_result = SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE;
65 return ReferrerChainEntry::LANDING_PAGE;
66 }
67 }
68
45 } // namespace 69 } // namespace
46 70
47 // The expiration period of a user gesture. Any user gesture that happened 1.0 71 // The expiration period of a user gesture. Any user gesture that happened 1.0
48 // second ago is considered as expired and not relevant to upcoming navigation 72 // second ago is considered as expired and not relevant to upcoming navigation
49 // events. 73 // events.
50 static const double kUserGestureTTLInSecond = 1.0; 74 static const double kUserGestureTTLInSecond = 1.0;
51 // The expiration period of navigation events and resolved IP addresses. Any 75 // The expiration period of navigation events and resolved IP addresses. Any
52 // navigation related records that happened 2 minutes ago are considered as 76 // navigation related records that happened 2 minutes ago are considered as
53 // expired. So we clean up these navigation footprints every 2 minutes. 77 // expired. So we clean up these navigation footprints every 2 minutes.
54 static const double kNavigationFootprintTTLInSecond = 120.0; 78 static const double kNavigationFootprintTTLInSecond = 120.0;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 173
150 void SafeBrowsingNavigationObserverManager::CleanUpStaleNavigationFootprints() { 174 void SafeBrowsingNavigationObserverManager::CleanUpStaleNavigationFootprints() {
151 CleanUpNavigationEvents(); 175 CleanUpNavigationEvents();
152 CleanUpUserGestures(); 176 CleanUpUserGestures();
153 CleanUpIpAddresses(); 177 CleanUpIpAddresses();
154 ScheduleNextCleanUpAfterInterval( 178 ScheduleNextCleanUpAfterInterval(
155 base::TimeDelta::FromSecondsD(kNavigationFootprintTTLInSecond)); 179 base::TimeDelta::FromSecondsD(kNavigationFootprintTTLInSecond));
156 } 180 }
157 181
158 SafeBrowsingNavigationObserverManager::AttributionResult 182 SafeBrowsingNavigationObserverManager::AttributionResult
159 SafeBrowsingNavigationObserverManager::IdentifyReferrerChain( 183 SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForDownload(
160 const GURL& target_url, 184 const GURL& target_url,
161 int target_tab_id, 185 int target_tab_id,
162 int user_gesture_count_limit, 186 int user_gesture_count_limit,
163 std::vector<ReferrerChainEntry>* out_referrer_chain) { 187 std::vector<ReferrerChainEntry>* out_referrer_chain) {
164 if (!target_url.is_valid()) 188 if (!target_url.is_valid())
165 return INVALID_URL; 189 return INVALID_URL;
166 190
167 NavigationEvent* nav_event = FindNavigationEvent(target_url, target_tab_id); 191 NavigationEvent* nav_event = FindNavigationEvent(target_url, target_tab_id);
168 if (!nav_event) { 192 if (!nav_event) {
169 // We cannot find a single navigation event related to this download. 193 // We cannot find a single navigation event related to this download.
170 return NAVIGATION_EVENT_NOT_FOUND; 194 return NAVIGATION_EVENT_NOT_FOUND;
171 } 195 }
196 AttributionResult result = SUCCESS;
197 AddToReferrerChain(out_referrer_chain, nav_event,
198 ReferrerChainEntry::DOWNLOAD_URL);
199 int user_gesture_count = 0;
200 GetRemainingReferrerChain(
201 nav_event,
202 user_gesture_count,
203 user_gesture_count_limit,
204 out_referrer_chain,
205 &result);
206 return result;
207 }
208
209 SafeBrowsingNavigationObserverManager::AttributionResult
210 SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForPPAPIDownload(
211 const GURL& initiating_frame_url,
212 content::WebContents* web_contents,
213 int user_gesture_count_limit,
214 std::vector<ReferrerChainEntry>* out_referrer_chain) {
215 if (!initiating_frame_url.is_valid())
216 return INVALID_URL;
217
218 int tab_id = SessionTabHelper::IdForTab(web_contents);
219 UMA_HISTOGRAM_BOOLEAN(
220 "SafeBrowsing.ReferrerHasInvalidTabID.PPAPIDownloadAttribution",
221 tab_id == -1);
222
223 NavigationEvent* nav_event = FindNavigationEvent(initiating_frame_url,
224 tab_id);
225 if (!nav_event) {
226 // We cannot find a single navigation event related to this download.
227 return NAVIGATION_EVENT_NOT_FOUND;
228 }
172 229
173 AddToReferrerChain(out_referrer_chain, nav_event,
174 ReferrerChainEntry::DOWNLOAD_URL);
175 AttributionResult result = SUCCESS; 230 AttributionResult result = SUCCESS;
231 bool has_user_gesture = false;
232 auto it = user_gesture_map_.find(web_contents);
233 if (it != user_gesture_map_.end() &&
234 !IsEventExpired(it->second, kUserGestureTTLInSecond)) {
235 has_user_gesture = true;
236 user_gesture_map_.erase(it);
237 }
238
176 int user_gesture_count = 0; 239 int user_gesture_count = 0;
177 while (user_gesture_count < user_gesture_count_limit) { 240 // If this initiating_frame has user gesture, we consider this as the landing
178 // Back trace to the next nav_event that was initiated by the user. 241 // page of the PPAPI download.
179 while (!nav_event->is_user_initiated) { 242 if (has_user_gesture) {
180 nav_event = 243 user_gesture_count = 1;
181 FindNavigationEvent(nav_event->source_url, nav_event->source_tab_id); 244 AddToReferrerChain(out_referrer_chain, nav_event,
182 if (!nav_event) 245 GetURLTypeAndAdjustAttributionResult(
183 return result; 246 user_gesture_count,
184 AddToReferrerChain(out_referrer_chain, nav_event, 247 user_gesture_count_limit,
185 nav_event->has_server_redirect 248 &result));
186 ? ReferrerChainEntry::SERVER_REDIRECT 249 } else {
187 : ReferrerChainEntry::CLIENT_REDIRECT); 250 AddToReferrerChain(out_referrer_chain, nav_event,
188 } 251 nav_event->has_server_redirect
252 ? ReferrerChainEntry::SERVER_REDIRECT
253 : ReferrerChainEntry::CLIENT_REDIRECT);
254 }
189 255
190 user_gesture_count++; 256 GetRemainingReferrerChain(
191 257 nav_event,
192 // If the source_url and source_main_frame_url of current navigation event 258 user_gesture_count,
193 // are empty, and is_user_initiated is true, this is a browser initiated 259 user_gesture_count_limit,
194 // navigation (e.g. trigged by typing in address bar, clicking on bookmark, 260 out_referrer_chain,
195 // etc). We reached the end of the referrer chain. 261 &result);
196 if (nav_event->source_url.is_empty() &&
197 nav_event->source_main_frame_url.is_empty()) {
198 DCHECK(nav_event->is_user_initiated);
199 return result;
200 }
201
202 nav_event =
203 FindNavigationEvent(nav_event->source_url, nav_event->source_tab_id);
204 if (!nav_event)
205 return result;
206
207 // Landing page of a download refers to the page user directly interacts
208 // with to trigger this download (e.g. clicking on download button). Landing
209 // referrer page is the one user interacts with right before navigating to
210 // the landing page.
211 // Since we are tracing navigations backwards, if we've encountered 1 user
212 // gesture before this navigation event, this is a navigation leading to the
213 // landing page. If we've encountered 2 user gestures, it leads to landing
214 // referrer page.
215 if (user_gesture_count == 1) {
216 AddToReferrerChain(out_referrer_chain, nav_event,
217 ReferrerChainEntry::LANDING_PAGE);
218 result = SUCCESS_LANDING_PAGE;
219 } else if (user_gesture_count == 2) {
220 AddToReferrerChain(out_referrer_chain, nav_event,
221 ReferrerChainEntry::LANDING_REFERRER);
222 result = SUCCESS_LANDING_REFERRER;
223 } else {
224 NOTREACHED();
225 }
226 }
227 return result; 262 return result;
228 } 263 }
229 264
230 SafeBrowsingNavigationObserverManager:: 265 SafeBrowsingNavigationObserverManager::
231 ~SafeBrowsingNavigationObserverManager() {} 266 ~SafeBrowsingNavigationObserverManager() {}
232 267
233 void SafeBrowsingNavigationObserverManager::Observe( 268 void SafeBrowsingNavigationObserverManager::Observe(
234 int type, 269 int type,
235 const content::NotificationSource& source, 270 const content::NotificationSource& source,
236 const content::NotificationDetails& details) { 271 const content::NotificationDetails& details) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 referrer_chain_entry.set_referrer_main_frame_url( 425 referrer_chain_entry.set_referrer_main_frame_url(
391 nav_event->source_main_frame_url.spec()); 426 nav_event->source_main_frame_url.spec());
392 } 427 }
393 referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id != 428 referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id !=
394 nav_event->target_tab_id); 429 nav_event->target_tab_id);
395 referrer_chain_entry.set_navigation_time_msec( 430 referrer_chain_entry.set_navigation_time_msec(
396 nav_event->last_updated.ToJavaTime()); 431 nav_event->last_updated.ToJavaTime());
397 referrer_chain->push_back(std::move(referrer_chain_entry)); 432 referrer_chain->push_back(std::move(referrer_chain_entry));
398 } 433 }
399 434
435 void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain(
436 NavigationEvent* last_nav_event_traced,
437 int current_user_gesture_count,
438 int user_gesture_count_limit,
439 std::vector<ReferrerChainEntry>* out_referrer_chain,
440 SafeBrowsingNavigationObserverManager::AttributionResult* out_result) {
441
442 while (current_user_gesture_count < user_gesture_count_limit) {
443 // Back trace to the next nav_event that was initiated by the user.
444 while (!last_nav_event_traced->is_user_initiated) {
445 last_nav_event_traced =
446 FindNavigationEvent(last_nav_event_traced->source_url,
447 last_nav_event_traced->source_tab_id);
448 if (!last_nav_event_traced)
449 return;
450 AddToReferrerChain(out_referrer_chain, last_nav_event_traced,
451 last_nav_event_traced->has_server_redirect
452 ? ReferrerChainEntry::SERVER_REDIRECT
453 : ReferrerChainEntry::CLIENT_REDIRECT);
454 }
455
456 current_user_gesture_count++;
457
458
459 // If the source_url and source_main_frame_url of current navigation event
460 // are empty, and is_user_initiated is true, this is a browser initiated
461 // navigation (e.g. trigged by typing in address bar, clicking on bookmark,
462 // etc). We reached the end of the referrer chain.
463 if (last_nav_event_traced->source_url.is_empty() &&
Nathan Parker 2017/01/04 19:49:12 q: Up above in a few places is_valid() is used. I
Jialiu Lin 2017/01/04 21:53:35 invalid url could be empty or malformatted. Here I
464 last_nav_event_traced->source_main_frame_url.is_empty()) {
465 DCHECK(last_nav_event_traced->is_user_initiated);
466 return;
467 }
468
469 last_nav_event_traced =
470 FindNavigationEvent(last_nav_event_traced->source_url,
471 last_nav_event_traced->source_tab_id);
472 if (!last_nav_event_traced)
473 return;
474
475 AddToReferrerChain(out_referrer_chain, last_nav_event_traced,
476 GetURLTypeAndAdjustAttributionResult(
477 current_user_gesture_count,
478 user_gesture_count_limit,
479 out_result));
480 }
481 }
482
400 } // namespace safe_browsing 483 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698