Chromium Code Reviews| Index: chrome/browser/safe_browsing/safe_browsing_navigation_observer.h |
| diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1ab41d13bbbf9671ffa114cd3bb26e3b1f2fe6b9 |
| --- /dev/null |
| +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h |
| @@ -0,0 +1,161 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_ |
| +#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_ |
| + |
| +#include "base/supports_user_data.h" |
| +#include "content/public/browser/navigation_handle.h" |
| +#include "content/public/browser/notification_observer.h" |
| +#include "content/public/browser/notification_registrar.h" |
| +#include "content/public/browser/web_contents_observer.h" |
| +#include "url/gurl.h" |
| + |
| +namespace content { |
| +class NavigationHandle; |
| +class NotificationRegistrar; |
|
Charlie Reis
2016/09/23 23:14:14
nit: You're including NavigationHandle and Notific
Jialiu Lin
2016/09/27 17:51:00
Done.
|
| +class RenderFrameHost; |
| +struct ResourceRedirectDetails; |
| +} |
| + |
| +namespace safe_browsing { |
| + |
| +// Struct to record the details of a navigation event for all frames. |
|
Charlie Reis
2016/09/23 23:14:14
nit: for any frame.
(A single struct won't record
Jialiu Lin
2016/09/27 17:51:00
Done.
|
| +// This information will be used to fill |url_chain| field in safe browsing |
| +// download pings. |
| +struct NavigationEvent { |
| + NavigationEvent(); |
| + NavigationEvent(NavigationEvent&& nav_event); |
| + NavigationEvent& operator=(NavigationEvent&& nav_event); |
| + ~NavigationEvent(); |
| + GURL source_url; |
|
Charlie Reis
2016/09/23 23:14:14
nit: Add blank line before, and add a comment sayi
Jialiu Lin
2016/09/27 17:51:00
Done.
|
| + int source_tab_id; // Tab ID of the source WebContents returned by |
| + // SessionTabHelper. It is immutable for a given tab |
| + // and unique across Chrome within the current session. |
| + |
| + GURL target_url; |
|
Charlie Reis
2016/09/23 23:14:14
Let's be clear about whether this is the original
Jialiu Lin
2016/09/27 17:50:59
This is the original request URL. But NavigationMa
|
| + int target_tab_id; |
| + |
| + int frame_id; // Frame tree node id. |
| + GURL main_frame_url; // Main frame url of the source. |
| + |
| + base::Time timestamp; // Timestamp of last time this object is updated. |
| + |
| + bool is_user_initiated; // browser_initiated || has_user_gesture. |
| + bool has_committed; |
| + bool is_server_redirect; |
| + GURL server_redirect_url; // Last server redirect url in redirect chain. |
|
Charlie Reis
2016/09/23 23:14:14
Please clarify in the comment whether this is alwa
Jialiu Lin
2016/09/27 17:51:00
Yes, in case no server redirect, this field will b
|
| +}; |
| + |
| +// Manager class for SafeBrowsingNavigationObserver. |
|
Charlie Reis
2016/09/23 23:14:14
Can you say more about what this class manages? T
Jialiu Lin
2016/09/27 17:51:00
Done.
|
| +// TODO(jialiul): Remove base class content::NotificationObserver when |
| +// WebContentsObserver::DidOpenRequestedURL() covers all retargeting cases. |
| +class SBNavigationObserverManager |
|
Charlie Reis
2016/09/23 23:14:14
Is declaring a top-level class in the same file ok
Jialiu Lin
2016/09/27 17:51:00
Moved this manager class into a separate file. Don
|
| + : public content::NotificationObserver, |
| + public base::RefCountedThreadSafe<SBNavigationObserverManager> { |
| + public: |
| + struct GurlHash { |
| + std::size_t operator()(const GURL& url) const { |
| + return std::hash<std::string>()(url.spec()); |
| + } |
| + }; |
| + typedef std::unordered_map<GURL, std::vector<NavigationEvent>, GurlHash> |
| + NavigationMap; |
| + SBNavigationObserverManager(); |
|
Charlie Reis
2016/09/23 23:14:14
nit: Blank line before (after typedefs).
Jialiu Lin
2016/09/27 17:51:00
Done.
|
| + void RecordNavigationEvent(const GURL& nav_event_key, |
| + NavigationEvent* nav_event); |
| + void RecordUserGestureForWebContents(content::WebContents* web_contents, |
| + const base::Time& timestamp); |
| + void OnUserGestureConsumed(content::WebContents* web_contents, |
| + const base::Time& timestamp); |
| + // Clean-ups need to be done when a WebContents gets destroyed. |
| + void OnWebContentDestroyed(content::WebContents* web_contents); |
| + |
| + // TODO(jialiul): more functions coming for managing navigation_map_. |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe<SBNavigationObserverManager>; |
| + friend class TestNavigationObserverManager; |
| + friend class SBNavigationObserverBrowserTest; |
| + friend class SBNavigationObserverTest; |
| + |
| + typedef std::unordered_map<content::WebContents*, base::Time> UserGestureMap; |
| + |
| + ~SBNavigationObserverManager() override; |
| + |
| + // content::NotificationObserver: |
| + void Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) override; |
| + |
| + void RecordRetargeting(const content::NotificationDetails& details); |
| + |
| + NavigationMap* navigation_map() { return &navigation_map_; } |
| + |
| + // navigation_map_ keeps track of all the observed navigations. This map is |
| + // keyed on target url. Since the same url can be requested multiple times |
|
Charlie Reis
2016/09/23 23:14:14
Is it correct to key this on the pre-redirect URL?
Jialiu Lin
2016/09/27 17:50:59
Fixed this comments. Map actually keyed on post-re
|
| + // across different tabs and frames, the value of this map is a vector of |
| + // NavigationEvent ordered by navigation finish time. Entries in |
| + // navigation_map_ will be removed if they are older than 2 minutes since |
| + // their corresponding navigations finish. |
|
Charlie Reis
2016/09/23 23:14:14
Is this timer implemented yet? I'm curious how it
Jialiu Lin
2016/09/27 17:50:59
Not yet. It will be in my next CL.
|
| + NavigationMap navigation_map_; |
| + |
| + // user_gesture_map_ keeps track of the timestamp of last user gesture in |
| + // in each WebContents. This is used to determin if any retargeting navigation |
|
Charlie Reis
2016/09/23 23:14:14
nit: determine
This seems like it won't be accura
Jialiu Lin
2016/09/27 17:51:00
Safe browsing backend will aggregate download ping
|
| + // is user_initiated. |
| + UserGestureMap user_gesture_map_; |
| + |
| + content::NotificationRegistrar registrar_; |
| + DISALLOW_COPY_AND_ASSIGN(SBNavigationObserverManager); |
| +}; |
| + |
| +// Observes the navigation events for a single WebContents (both main-frame |
| +// and sub-frame navigations) |
| +class SafeBrowsingNavigationObserver : public base::SupportsUserData::Data, |
| + public content::WebContentsObserver { |
| + public: |
| + static void MaybeCreateForWebContents(content::WebContents* web_contents); |
| + static SafeBrowsingNavigationObserver* FromWebContents( |
| + content::WebContents* web_contents); |
| + |
| + SafeBrowsingNavigationObserver( |
| + content::WebContents* contents, |
| + const scoped_refptr<SBNavigationObserverManager>& manager); |
| + |
| + ~SafeBrowsingNavigationObserver() override; |
| + |
| + private: |
| + static const char kWebContentsUserDataKey[]; |
|
Charlie Reis
2016/09/23 23:14:14
nit: Let's just declare this in an anonymous names
Jialiu Lin
2016/09/27 17:51:00
Done.
|
| + void RecordNavigationPendingEntry( |
|
Charlie Reis
2016/09/23 23:14:14
I don't see this implemented anywhere.
Jialiu Lin
2016/09/27 17:50:59
Oops, forgot to delete this one.
|
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details); |
| + |
| + // content::WebContentsObserver: |
| + void DidStartNavigation( |
| + content::NavigationHandle* navigation_handle) override; |
| + void DidRedirectNavigation( |
| + content::NavigationHandle* navigation_handle) override; |
| + void DidFinishNavigation( |
| + content::NavigationHandle* navigation_handle) override; |
| + void DidGetUserInteraction(const blink::WebInputEvent::Type type) override; |
| + void WebContentsDestroyed() override; |
| + |
| + // Map keyed on NavigationHandle* to keep track of all the ongoing navigation |
| + // events. NavigationHandle pointers are owned by RenderFrameHost. Since a |
| + // NavigationHandle object will be destructed after navigation is done, |
| + // corresponding entry in this map will be removed from navigation_handle_map_ |
| + // and added to navigation_map_ at the end of DidFinishNavigation(...). |
| + typedef std::unordered_map<content::NavigationHandle*, NavigationEvent> |
| + NavigationHandleMap; |
|
Charlie Reis
2016/09/23 23:14:14
nit: Typedefs should be declared at the beginning
Jialiu Lin
2016/09/27 17:50:59
Done
|
| + NavigationHandleMap navigation_handle_map_; |
| + scoped_refptr<SBNavigationObserverManager> manager_; |
| + // If current on-going navigation triggered by a user gesture. |
| + bool has_user_gesture_; |
|
Charlie Reis
2016/09/23 23:14:14
I don't think we can track this on a per-tab basis
Jialiu Lin
2016/09/27 17:51:00
Oh, sorry for the misleading comment.
This field
|
| + base::Time last_user_gesture_timestamp_; |
| + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingNavigationObserver); |
| +}; |
| + |
| +} // namespace safe_browsing |
| + |
| +#endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_ |