| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager
.h" |
| 6 |
| 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/time/time.h" |
| 9 #include "chrome/browser/chrome_notification_types.h" |
| 10 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" |
| 11 #include "chrome/browser/sessions/session_tab_helper.h" |
| 12 #include "chrome/browser/tab_contents/retargeting_details.h" |
| 13 #include "content/public/browser/navigation_details.h" |
| 14 #include "content/public/browser/notification_service.h" |
| 15 #include "content/public/browser/notification_types.h" |
| 16 #include "content/public/browser/render_frame_host.h" |
| 17 #include "content/public/browser/render_process_host.h" |
| 18 #include "content/public/browser/web_contents.h" |
| 19 |
| 20 using content::WebContents; |
| 21 namespace safe_browsing { |
| 22 |
| 23 static const double kUserGestureTTLInSecond = 0.5; |
| 24 |
| 25 // static |
| 26 bool SafeBrowsingNavigationObserverManager::IsUserGestureExpired( |
| 27 const base::Time& timestamp) { |
| 28 double now = base::Time::Now().ToDoubleT(); |
| 29 double timestamp_in_double = timestamp.ToDoubleT(); |
| 30 return now > timestamp_in_double |
| 31 ? now - timestamp_in_double > kUserGestureTTLInSecond |
| 32 : true; |
| 33 } |
| 34 |
| 35 // static |
| 36 GURL SafeBrowsingNavigationObserverManager::ClearURLRef(const GURL& url) { |
| 37 if (!url.has_ref()) |
| 38 return url; |
| 39 url::Replacements<char> replacements; |
| 40 replacements.ClearRef(); |
| 41 return url.ReplaceComponents(replacements); |
| 42 } |
| 43 |
| 44 SafeBrowsingNavigationObserverManager::SafeBrowsingNavigationObserverManager() { |
| 45 registrar_.Add(this, chrome::NOTIFICATION_RETARGETING, |
| 46 content::NotificationService::AllSources()); |
| 47 } |
| 48 |
| 49 void SafeBrowsingNavigationObserverManager::RecordNavigationEvent( |
| 50 const GURL& nav_event_key, |
| 51 NavigationEvent* nav_event) { |
| 52 auto insertion_result = navigation_map_.insert( |
| 53 std::make_pair(nav_event_key, std::vector<NavigationEvent>())); |
| 54 |
| 55 insertion_result.first->second.push_back(std::move(*nav_event)); |
| 56 } |
| 57 |
| 58 void SafeBrowsingNavigationObserverManager::RecordUserGestureForWebContents( |
| 59 content::WebContents* web_contents, |
| 60 const base::Time& timestamp) { |
| 61 auto insertion_result = |
| 62 user_gesture_map_.insert(std::make_pair(web_contents, timestamp)); |
| 63 if (!insertion_result.second) |
| 64 insertion_result.first->second = timestamp; |
| 65 } |
| 66 |
| 67 void SafeBrowsingNavigationObserverManager::OnUserGestureConsumed( |
| 68 content::WebContents* web_contents, |
| 69 const base::Time& timestamp) { |
| 70 auto it = user_gesture_map_.find(web_contents); |
| 71 if (it == user_gesture_map_.end()) |
| 72 return; |
| 73 if (timestamp >= it->second) |
| 74 user_gesture_map_.erase(web_contents); |
| 75 } |
| 76 |
| 77 void SafeBrowsingNavigationObserverManager::OnWebContentDestroyed( |
| 78 content::WebContents* web_contents) { |
| 79 user_gesture_map_.erase(web_contents); |
| 80 // TODO (jialiul): Will add other clean up tasks shortly. |
| 81 } |
| 82 |
| 83 SafeBrowsingNavigationObserverManager:: |
| 84 ~SafeBrowsingNavigationObserverManager() {} |
| 85 |
| 86 void SafeBrowsingNavigationObserverManager::Observe( |
| 87 int type, |
| 88 const content::NotificationSource& source, |
| 89 const content::NotificationDetails& details) { |
| 90 if (type == chrome::NOTIFICATION_RETARGETING) |
| 91 RecordRetargeting(details); |
| 92 } |
| 93 |
| 94 void SafeBrowsingNavigationObserverManager::RecordRetargeting( |
| 95 const content::NotificationDetails& details) { |
| 96 const RetargetingDetails* retargeting_detail = |
| 97 content::Details<const RetargetingDetails>(details).ptr(); |
| 98 DCHECK(retargeting_detail); |
| 99 content::WebContents* source_contents = |
| 100 retargeting_detail->source_web_contents; |
| 101 content::WebContents* target_contents = |
| 102 retargeting_detail->target_web_contents; |
| 103 DCHECK(source_contents); |
| 104 DCHECK(target_contents); |
| 105 |
| 106 // TODO(jialiul): This line would break with OOPIFs due to |
| 107 // https://crbug.com/649855. |
| 108 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( |
| 109 source_contents->GetRenderProcessHost()->GetID(), |
| 110 retargeting_detail->source_render_frame_id); |
| 111 const GURL& target_url = SafeBrowsingNavigationObserverManager::ClearURLRef( |
| 112 retargeting_detail->target_url); |
| 113 |
| 114 navigation_map_.insert( |
| 115 std::make_pair(target_url, std::vector<NavigationEvent>())); |
| 116 |
| 117 NavigationEvent nav_event; |
| 118 nav_event.source_url = |
| 119 rfh ? SafeBrowsingNavigationObserverManager::ClearURLRef( |
| 120 rfh->GetLastCommittedURL()) |
| 121 : GURL(); |
| 122 nav_event.source_tab_id = SessionTabHelper::IdForTab(source_contents); |
| 123 nav_event.target_url = target_url; |
| 124 nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents); |
| 125 nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1; |
| 126 nav_event.main_frame_url = SafeBrowsingNavigationObserverManager::ClearURLRef( |
| 127 source_contents->GetLastCommittedURL()); |
| 128 nav_event.timestamp = base::Time::Now(); |
| 129 auto it = user_gesture_map_.find(source_contents); |
| 130 if (it != user_gesture_map_.end() && |
| 131 !SafeBrowsingNavigationObserverManager::IsUserGestureExpired( |
| 132 it->second)) { |
| 133 nav_event.is_user_initiated = true; |
| 134 OnUserGestureConsumed(it->first, it->second); |
| 135 } else { |
| 136 nav_event.is_user_initiated = false; |
| 137 } |
| 138 |
| 139 navigation_map_[target_url].push_back(std::move(nav_event)); |
| 140 } |
| 141 |
| 142 } // namespace safe_browsing |
| OLD | NEW |