| 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.h" | 
|  | 6 | 
|  | 7 #include "base/memory/ptr_util.h" | 
|  | 8 #include "base/time/time.h" | 
|  | 9 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager
     .h" | 
|  | 10 #include "chrome/browser/sessions/session_tab_helper.h" | 
|  | 11 #include "content/public/browser/navigation_handle.h" | 
|  | 12 #include "content/public/browser/render_frame_host.h" | 
|  | 13 #include "content/public/browser/resource_request_details.h" | 
|  | 14 #include "content/public/browser/web_contents.h" | 
|  | 15 #include "content/public/common/resource_type.h" | 
|  | 16 | 
|  | 17 using content::WebContents; | 
|  | 18 | 
|  | 19 namespace { | 
|  | 20 const char kWebContentsUserDataKey[] = | 
|  | 21     "web_contents_safe_browsing_navigation_observer"; | 
|  | 22 }  // namespace | 
|  | 23 | 
|  | 24 namespace safe_browsing { | 
|  | 25 | 
|  | 26 // SafeBrowsingNavigationObserver::NavigationEvent----------------------------- | 
|  | 27 NavigationEvent::NavigationEvent() | 
|  | 28     : source_url(), | 
|  | 29       source_tab_id(-1), | 
|  | 30       target_url(), | 
|  | 31       target_tab_id(-1), | 
|  | 32       frame_id(-1), | 
|  | 33       main_frame_url(), | 
|  | 34       timestamp(base::Time::Now()), | 
|  | 35       is_user_initiated(false), | 
|  | 36       has_committed(false), | 
|  | 37       has_server_redirect(false), | 
|  | 38       server_redirect_url() {} | 
|  | 39 | 
|  | 40 NavigationEvent::NavigationEvent(NavigationEvent&& nav_event) | 
|  | 41     : source_url(std::move(nav_event.source_url)), | 
|  | 42       source_tab_id(std::move(nav_event.source_tab_id)), | 
|  | 43       target_url(std::move(nav_event.target_url)), | 
|  | 44       target_tab_id(std::move(nav_event.target_tab_id)), | 
|  | 45       frame_id(nav_event.frame_id), | 
|  | 46       main_frame_url(std::move(nav_event.main_frame_url)), | 
|  | 47       timestamp(nav_event.timestamp), | 
|  | 48       is_user_initiated(nav_event.is_user_initiated), | 
|  | 49       has_committed(nav_event.has_committed), | 
|  | 50       has_server_redirect(nav_event.has_server_redirect), | 
|  | 51       server_redirect_url(std::move(nav_event.server_redirect_url)) {} | 
|  | 52 | 
|  | 53 NavigationEvent& NavigationEvent::operator=(NavigationEvent&& nav_event) { | 
|  | 54   source_url = std::move(nav_event.source_url); | 
|  | 55   source_tab_id = std::move(nav_event.source_tab_id); | 
|  | 56   target_url = std::move(nav_event.target_url); | 
|  | 57   target_tab_id = std::move(nav_event.target_tab_id); | 
|  | 58   frame_id = nav_event.frame_id; | 
|  | 59   main_frame_url = std::move(nav_event.main_frame_url); | 
|  | 60   timestamp = nav_event.timestamp; | 
|  | 61   is_user_initiated = nav_event.is_user_initiated; | 
|  | 62   has_committed = nav_event.has_committed; | 
|  | 63   has_server_redirect = nav_event.has_server_redirect; | 
|  | 64   server_redirect_url = std::move(nav_event.server_redirect_url); | 
|  | 65   return *this; | 
|  | 66 } | 
|  | 67 | 
|  | 68 NavigationEvent::~NavigationEvent() {} | 
|  | 69 | 
|  | 70 // SafeBrowsingNavigationObserver -------------------------------------------- | 
|  | 71 | 
|  | 72 // static | 
|  | 73 void SafeBrowsingNavigationObserver::MaybeCreateForWebContents( | 
|  | 74     content::WebContents* web_contents) { | 
|  | 75   if (FromWebContents(web_contents)) | 
|  | 76     return; | 
|  | 77   NOTIMPLEMENTED(); | 
|  | 78   // TODO(jialiul): This method will be called by TabHelpers::AttachTabHelpers. | 
|  | 79   // Complete this method when the entire class is ready. | 
|  | 80 } | 
|  | 81 | 
|  | 82 // static | 
|  | 83 SafeBrowsingNavigationObserver* SafeBrowsingNavigationObserver::FromWebContents( | 
|  | 84     content::WebContents* web_contents) { | 
|  | 85   return static_cast<SafeBrowsingNavigationObserver*>( | 
|  | 86       web_contents->GetUserData(kWebContentsUserDataKey)); | 
|  | 87 } | 
|  | 88 | 
|  | 89 SafeBrowsingNavigationObserver::SafeBrowsingNavigationObserver( | 
|  | 90     content::WebContents* contents, | 
|  | 91     const scoped_refptr<SafeBrowsingNavigationObserverManager>& manager) | 
|  | 92     : content::WebContentsObserver(contents), | 
|  | 93       manager_(manager), | 
|  | 94       has_user_gesture_(false), | 
|  | 95       last_user_gesture_timestamp_(base::Time::Now()) {} | 
|  | 96 | 
|  | 97 SafeBrowsingNavigationObserver::~SafeBrowsingNavigationObserver() {} | 
|  | 98 | 
|  | 99 // Called when a navigation started in the WebContents. |navigation_handle| in | 
|  | 100 // paramter is unique to this navigation, which will appear in the following | 
|  | 101 // DidRedirectNavigation, and DidFinishNavigation too. | 
|  | 102 void SafeBrowsingNavigationObserver::DidStartNavigation( | 
|  | 103     content::NavigationHandle* navigation_handle) { | 
|  | 104   // If we already seen this navigation_handle before, no need to do anything. | 
|  | 105   if (navigation_handle_map_.find(navigation_handle) != | 
|  | 106       navigation_handle_map_.end()) | 
|  | 107     return; | 
|  | 108 | 
|  | 109   // Construct a NavigationEvent based on available information in | 
|  | 110   // navigation_handle. | 
|  | 111   NavigationEvent nav_event; | 
|  | 112   content::RenderFrameHost* host = | 
|  | 113       navigation_handle->GetWebContents()->FindFrameByFrameTreeNodeId( | 
|  | 114           navigation_handle->GetFrameTreeNodeId()); | 
|  | 115 | 
|  | 116   // If there was URL previously committed in this render frame host, | 
|  | 117   // set it as the source url of this navigation. Otherwise, this is the | 
|  | 118   // first url going to commit in this frame. We set navigation_handle's URL as | 
|  | 119   // the source url. | 
|  | 120   if (host && host->GetLastCommittedURL().is_valid()) { | 
|  | 121     nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearURLRef( | 
|  | 122         host->GetLastCommittedURL()); | 
|  | 123   } else { | 
|  | 124     nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearURLRef( | 
|  | 125         navigation_handle->GetURL()); | 
|  | 126   } | 
|  | 127   nav_event.target_url = SafeBrowsingNavigationObserverManager::ClearURLRef( | 
|  | 128       navigation_handle->GetURL()); | 
|  | 129 | 
|  | 130   nav_event.source_tab_id = | 
|  | 131       SessionTabHelper::IdForTab(navigation_handle->GetWebContents()); | 
|  | 132   nav_event.timestamp = base::Time::Now(); | 
|  | 133   nav_event.frame_id = navigation_handle->GetFrameTreeNodeId(); | 
|  | 134 | 
|  | 135   if (navigation_handle->IsInMainFrame()) { | 
|  | 136     nav_event.main_frame_url = nav_event.source_url; | 
|  | 137   } else { | 
|  | 138     nav_event.main_frame_url = | 
|  | 139         SafeBrowsingNavigationObserverManager::ClearURLRef( | 
|  | 140             navigation_handle->GetWebContents()->GetLastCommittedURL()); | 
|  | 141   } | 
|  | 142   if (has_user_gesture_ && | 
|  | 143       !SafeBrowsingNavigationObserverManager::IsUserGestureExpired( | 
|  | 144           last_user_gesture_timestamp_)) { | 
|  | 145     nav_event.is_user_initiated = has_user_gesture_; | 
|  | 146     manager_->OnUserGestureConsumed(web_contents(), | 
|  | 147                                     last_user_gesture_timestamp_); | 
|  | 148   } | 
|  | 149   has_user_gesture_ = false; | 
|  | 150   navigation_handle_map_.insert( | 
|  | 151       std::make_pair(navigation_handle, std::move(nav_event))); | 
|  | 152 } | 
|  | 153 | 
|  | 154 void SafeBrowsingNavigationObserver::DidRedirectNavigation( | 
|  | 155     content::NavigationHandle* navigation_handle) { | 
|  | 156   // We should have already seen this navigation_handle in DidStartNavigation. | 
|  | 157   if (navigation_handle_map_.find(navigation_handle) == | 
|  | 158       navigation_handle_map_.end()) | 
|  | 159     return; | 
|  | 160 | 
|  | 161   NavigationEvent* nav_event = &navigation_handle_map_[navigation_handle]; | 
|  | 162   nav_event->has_server_redirect = true; | 
|  | 163   nav_event->server_redirect_url = | 
|  | 164       SafeBrowsingNavigationObserverManager::ClearURLRef( | 
|  | 165           navigation_handle->GetURL()); | 
|  | 166   nav_event->timestamp = base::Time::Now(); | 
|  | 167 } | 
|  | 168 | 
|  | 169 void SafeBrowsingNavigationObserver::DidFinishNavigation( | 
|  | 170     content::NavigationHandle* navigation_handle) { | 
|  | 171   if (navigation_handle_map_.find(navigation_handle) == | 
|  | 172       navigation_handle_map_.end()) | 
|  | 173     return; | 
|  | 174 | 
|  | 175   // If it is an error page, we ignore this navigation. | 
|  | 176   if (navigation_handle->IsErrorPage()) { | 
|  | 177     navigation_handle_map_.erase(navigation_handle); | 
|  | 178     return; | 
|  | 179   } | 
|  | 180   NavigationEvent* nav_event = &navigation_handle_map_[navigation_handle]; | 
|  | 181 | 
|  | 182   // Set is_user_initiated to has_user_gesture || browser_initiated. | 
|  | 183   nav_event->is_user_initiated = | 
|  | 184       nav_event->is_user_initiated || !navigation_handle->IsRendererInitiated(); | 
|  | 185   nav_event->has_committed = navigation_handle->HasCommitted(); | 
|  | 186   nav_event->target_tab_id = | 
|  | 187       SessionTabHelper::IdForTab(navigation_handle->GetWebContents()); | 
|  | 188   nav_event->timestamp = base::Time::Now(); | 
|  | 189 | 
|  | 190   GURL nav_event_key = | 
|  | 191       navigation_handle->HasCommitted() | 
|  | 192           ? SafeBrowsingNavigationObserverManager::ClearURLRef( | 
|  | 193                 navigation_handle->GetRenderFrameHost()->GetLastCommittedURL()) | 
|  | 194           : nav_event->has_server_redirect ? nav_event->server_redirect_url | 
|  | 195                                           : nav_event->target_url; | 
|  | 196   manager_->RecordNavigationEvent(nav_event_key, nav_event); | 
|  | 197   navigation_handle_map_.erase(navigation_handle); | 
|  | 198 } | 
|  | 199 | 
|  | 200 void SafeBrowsingNavigationObserver::DidGetUserInteraction( | 
|  | 201     const blink::WebInputEvent::Type type) { | 
|  | 202   last_user_gesture_timestamp_ = base::Time::Now(); | 
|  | 203   has_user_gesture_ = true; | 
|  | 204   // TODO (jialiul): Refine user gesture logic when DidOpenRequestedURL | 
|  | 205   // covers all retargetting cases. | 
|  | 206   manager_->RecordUserGestureForWebContents(web_contents(), | 
|  | 207                                             last_user_gesture_timestamp_); | 
|  | 208 } | 
|  | 209 | 
|  | 210 void SafeBrowsingNavigationObserver::WebContentsDestroyed() { | 
|  | 211   manager_->OnWebContentDestroyed(web_contents()); | 
|  | 212   web_contents()->RemoveUserData(kWebContentsUserDataKey); | 
|  | 213   // web_contents is null after this function. | 
|  | 214 } | 
|  | 215 | 
|  | 216 }  // namespace safe_browsing | 
| OLD | NEW | 
|---|