| 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 |