| 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 | 
|  | 22 namespace safe_browsing { | 
|  | 23 | 
|  | 24 // The expiration period of a user gesture. Any user gesture that happened 1.0 | 
|  | 25 // second ago will be considered as expired and not relevant to upcoming | 
|  | 26 // navigation events. | 
|  | 27 static const double kUserGestureTTLInSecond = 1.0; | 
|  | 28 | 
|  | 29 // static | 
|  | 30 bool SafeBrowsingNavigationObserverManager::IsUserGestureExpired( | 
|  | 31     const base::Time& timestamp) { | 
|  | 32   double now = base::Time::Now().ToDoubleT(); | 
|  | 33   double timestamp_in_double = timestamp.ToDoubleT(); | 
|  | 34 | 
|  | 35   if (now <= timestamp_in_double) | 
|  | 36     return true; | 
|  | 37   return (now - timestamp_in_double) > kUserGestureTTLInSecond; | 
|  | 38 } | 
|  | 39 | 
|  | 40 // static | 
|  | 41 GURL SafeBrowsingNavigationObserverManager::ClearEmptyRef(const GURL& url) { | 
|  | 42   if (url.has_ref() && url.ref().empty()) { | 
|  | 43     url::Replacements<char> replacements; | 
|  | 44     replacements.ClearRef(); | 
|  | 45     return url.ReplaceComponents(replacements); | 
|  | 46   } | 
|  | 47   return url; | 
|  | 48 } | 
|  | 49 | 
|  | 50 SafeBrowsingNavigationObserverManager::SafeBrowsingNavigationObserverManager() { | 
|  | 51   registrar_.Add(this, chrome::NOTIFICATION_RETARGETING, | 
|  | 52                  content::NotificationService::AllSources()); | 
|  | 53 } | 
|  | 54 | 
|  | 55 void SafeBrowsingNavigationObserverManager::RecordNavigationEvent( | 
|  | 56     const GURL& nav_event_key, | 
|  | 57     NavigationEvent* nav_event) { | 
|  | 58   auto insertion_result = navigation_map_.insert( | 
|  | 59       std::make_pair(nav_event_key, std::vector<NavigationEvent>())); | 
|  | 60 | 
|  | 61   insertion_result.first->second.push_back(std::move(*nav_event)); | 
|  | 62 } | 
|  | 63 | 
|  | 64 void SafeBrowsingNavigationObserverManager::RecordUserGestureForWebContents( | 
|  | 65     content::WebContents* web_contents, | 
|  | 66     const base::Time& timestamp) { | 
|  | 67   auto insertion_result = | 
|  | 68       user_gesture_map_.insert(std::make_pair(web_contents, timestamp)); | 
|  | 69   // Update the timestamp if entry already exists. | 
|  | 70   if (!insertion_result.second) | 
|  | 71     insertion_result.first->second = timestamp; | 
|  | 72 } | 
|  | 73 | 
|  | 74 void SafeBrowsingNavigationObserverManager::OnUserGestureConsumed( | 
|  | 75     content::WebContents* web_contents, | 
|  | 76     const base::Time& timestamp) { | 
|  | 77   auto it = user_gesture_map_.find(web_contents); | 
|  | 78   // Remove entry from |user_gesture_map_| as a user_gesture is consumed by | 
|  | 79   // a navigation event. | 
|  | 80   if (it != user_gesture_map_.end() && timestamp >= it->second) | 
|  | 81     user_gesture_map_.erase(it); | 
|  | 82 } | 
|  | 83 | 
|  | 84 void SafeBrowsingNavigationObserverManager::RecordHostToIpMapping( | 
|  | 85     const std::string& host, | 
|  | 86     const std::string& ip) { | 
|  | 87   auto insert_result = host_to_ip_map_.insert( | 
|  | 88       std::make_pair(host, std::vector<ResolvedIPAddress>())); | 
|  | 89   if (!insert_result.second) { | 
|  | 90     // host_to_ip_map already contains this key. | 
|  | 91     // If this IP is already in the vector, we update its timestamp. | 
|  | 92     for (auto& vector_entry : insert_result.first->second) { | 
|  | 93       if (vector_entry.ip == host) { | 
|  | 94         vector_entry.timestamp = base::Time::Now(); | 
|  | 95         return; | 
|  | 96       } | 
|  | 97     } | 
|  | 98   } | 
|  | 99   // If this is a new IP of this host, and we added to the end of the vector. | 
|  | 100   insert_result.first->second.push_back( | 
|  | 101       ResolvedIPAddress(base::Time::Now(), ip)); | 
|  | 102 } | 
|  | 103 | 
|  | 104 void SafeBrowsingNavigationObserverManager::OnWebContentDestroyed( | 
|  | 105     content::WebContents* web_contents) { | 
|  | 106   user_gesture_map_.erase(web_contents); | 
|  | 107   // TODO (jialiul): Will add other clean up tasks shortly. | 
|  | 108 } | 
|  | 109 | 
|  | 110 SafeBrowsingNavigationObserverManager:: | 
|  | 111     ~SafeBrowsingNavigationObserverManager() {} | 
|  | 112 | 
|  | 113 void SafeBrowsingNavigationObserverManager::Observe( | 
|  | 114     int type, | 
|  | 115     const content::NotificationSource& source, | 
|  | 116     const content::NotificationDetails& details) { | 
|  | 117   if (type == chrome::NOTIFICATION_RETARGETING) | 
|  | 118     RecordRetargeting(details); | 
|  | 119 } | 
|  | 120 | 
|  | 121 void SafeBrowsingNavigationObserverManager::RecordRetargeting( | 
|  | 122     const content::NotificationDetails& details) { | 
|  | 123   const RetargetingDetails* retargeting_detail = | 
|  | 124       content::Details<const RetargetingDetails>(details).ptr(); | 
|  | 125   DCHECK(retargeting_detail); | 
|  | 126   content::WebContents* source_contents = | 
|  | 127       retargeting_detail->source_web_contents; | 
|  | 128   content::WebContents* target_contents = | 
|  | 129       retargeting_detail->target_web_contents; | 
|  | 130   DCHECK(source_contents); | 
|  | 131   DCHECK(target_contents); | 
|  | 132 | 
|  | 133   content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( | 
|  | 134       retargeting_detail->source_render_process_id, | 
|  | 135       retargeting_detail->source_render_frame_id); | 
|  | 136   // Remove the "#" at the end of URL, since it does not point to any actual | 
|  | 137   // page fragment ID. | 
|  | 138   GURL target_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef( | 
|  | 139       retargeting_detail->target_url); | 
|  | 140 | 
|  | 141   NavigationEvent nav_event; | 
|  | 142   if (rfh) { | 
|  | 143     nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef( | 
|  | 144         rfh->GetLastCommittedURL()); | 
|  | 145   } | 
|  | 146   nav_event.source_tab_id = SessionTabHelper::IdForTab(source_contents); | 
|  | 147   nav_event.source_main_frame_url = | 
|  | 148       SafeBrowsingNavigationObserverManager::ClearEmptyRef( | 
|  | 149           source_contents->GetLastCommittedURL()); | 
|  | 150   nav_event.original_request_url = target_url; | 
|  | 151   nav_event.destination_url = target_url; | 
|  | 152   nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents); | 
|  | 153   nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1; | 
|  | 154   auto it = user_gesture_map_.find(source_contents); | 
|  | 155   if (it != user_gesture_map_.end() && | 
|  | 156       !SafeBrowsingNavigationObserverManager::IsUserGestureExpired( | 
|  | 157           it->second)) { | 
|  | 158     nav_event.is_user_initiated = true; | 
|  | 159     OnUserGestureConsumed(it->first, it->second); | 
|  | 160   } else { | 
|  | 161     nav_event.is_user_initiated = false; | 
|  | 162   } | 
|  | 163 | 
|  | 164   auto insertion_result = navigation_map_.insert( | 
|  | 165       std::make_pair(target_url, std::vector<NavigationEvent>())); | 
|  | 166   insertion_result.first->second.push_back(std::move(nav_event)); | 
|  | 167 } | 
|  | 168 | 
|  | 169 }  // namespace safe_browsing | 
| OLD | NEW | 
|---|