OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/engagement/site_engagement_helper.h" | 5 #include "chrome/browser/engagement/site_engagement_helper.h" |
6 | 6 |
7 #include "base/time/time.h" | |
7 #include "chrome/browser/engagement/site_engagement_service.h" | 8 #include "chrome/browser/engagement/site_engagement_service.h" |
8 #include "chrome/browser/engagement/site_engagement_service_factory.h" | 9 #include "chrome/browser/engagement/site_engagement_service_factory.h" |
9 #include "chrome/browser/prerender/prerender_contents.h" | 10 #include "chrome/browser/prerender/prerender_contents.h" |
10 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
11 #include "content/public/browser/navigation_entry.h" | 12 #include "content/public/browser/navigation_entry.h" |
12 #include "content/public/browser/web_contents.h" | 13 #include "content/public/browser/web_contents.h" |
13 | 14 |
15 namespace { | |
16 | |
17 const int kSecondsBetweenUserInputCheck = 10; | |
calamity
2015/09/11 07:19:56
We're going to want some noise on top of this. Sho
| |
18 | |
19 } // anonymous namespace | |
20 | |
14 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SiteEngagementHelper); | 21 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SiteEngagementHelper); |
15 | 22 |
16 SiteEngagementHelper::~SiteEngagementHelper() { | 23 SiteEngagementHelper::~SiteEngagementHelper() { |
24 timer_.Stop(); | |
25 content::WebContents* contents = web_contents(); | |
26 if (contents) { | |
27 contents->GetRenderViewHost()->RemoveKeyPressEventCallback( | |
28 key_press_event_callback_); | |
29 contents->GetRenderViewHost()->RemoveMouseEventCallback( | |
30 mouse_event_callback_); | |
31 } | |
17 } | 32 } |
18 | 33 |
19 SiteEngagementHelper::SiteEngagementHelper(content::WebContents* web_contents) | 34 SiteEngagementHelper::SiteEngagementHelper(content::WebContents* web_contents) |
20 : content::WebContentsObserver(web_contents) { | 35 : content::WebContentsObserver(web_contents), |
36 user_input_recorded_(false), | |
37 callbacks_added_(true) { | |
38 key_press_event_callback_ = base::Bind( | |
39 &SiteEngagementHelper::HandleKeyPressEvent, base::Unretained(this)); | |
40 mouse_event_callback_ = base::Bind(&SiteEngagementHelper::HandleMouseEvent, | |
41 base::Unretained(this)); | |
calamity
2015/09/11 07:19:56
Probably want a WeakPtrFactory for this.
dominickn
2015/09/11 08:03:37
I can't use a WeakPtrFactory because weak pointers
calamity
2015/09/14 02:08:33
Lame. But this makes sense. The comment in bind_in
| |
42 web_contents->GetRenderViewHost()->AddKeyPressEventCallback( | |
43 key_press_event_callback_); | |
44 web_contents->GetRenderViewHost()->AddMouseEventCallback( | |
45 mouse_event_callback_); | |
21 } | 46 } |
22 | 47 |
23 void SiteEngagementHelper::DidStartNavigationToPendingEntry( | 48 // Record that there was some user input, and defer handling of the input event. |
24 const GURL& url, | 49 bool SiteEngagementHelper::HandleKeyPressEvent( |
25 content::NavigationController::ReloadType reload_type) { | 50 const content::NativeWebKeyboardEvent& event) { |
26 prerender::PrerenderContents* prerender_contents = | 51 user_input_recorded_ = true; |
27 prerender::PrerenderContents::FromWebContents(web_contents()); | 52 return false; |
53 } | |
28 | 54 |
29 // Ignore pre-render loads. | 55 bool SiteEngagementHelper::HandleMouseEvent(const blink::WebMouseEvent& event) { |
30 if (prerender_contents != NULL) | 56 user_input_recorded_ = true; |
31 return; | 57 return false; |
58 } | |
32 | 59 |
33 // Ignore all schemes except HTTP and HTTPS. | 60 void SiteEngagementHelper::TimerFired() { |
34 if (!url.SchemeIsHTTPOrHTTPS()) | 61 content::WebContents* contents = web_contents(); |
35 return; | 62 if (contents) { |
63 GURL url = contents->GetVisibleURL(); | |
64 if (user_input_recorded_) { | |
65 prerender::PrerenderContents* prerender_contents = | |
66 prerender::PrerenderContents::FromWebContents(contents); | |
36 | 67 |
37 Profile* profile = | 68 // Ignore pre-render loads. |
38 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); | 69 if (prerender_contents != NULL) |
39 SiteEngagementService* service = | 70 return; |
40 SiteEngagementServiceFactory::GetForProfile(profile); | |
41 // Service is null in incognito. | |
42 if (!service) | |
43 return; | |
44 | 71 |
45 service->HandleNavigation(url); | 72 // Ignore all schemes except HTTP and HTTPS. |
73 if (!url.SchemeIsHTTPOrHTTPS()) | |
74 return; | |
calamity
2015/09/11 07:19:56
These two checks feel like they should be done on
dominickn
2015/09/11 08:03:38
Done.
| |
75 | |
76 Profile* profile = | |
77 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); | |
78 SiteEngagementService* service = | |
79 SiteEngagementServiceFactory::GetForProfile(profile); | |
80 // Service is null in incognito. | |
81 if (service) | |
82 service->HandleUserInput(url); | |
83 } | |
84 } | |
85 user_input_recorded_ = false; | |
46 } | 86 } |
87 | |
88 void SiteEngagementHelper::StartTimer() { | |
89 timer_.Start(FROM_HERE, | |
90 base::TimeDelta::FromSeconds(kSecondsBetweenUserInputCheck), | |
91 this, &SiteEngagementHelper::TimerFired); | |
92 } | |
93 | |
94 void SiteEngagementHelper::RenderViewHostChanged( | |
95 content::RenderViewHost* old_host, | |
96 content::RenderViewHost* new_host) { | |
97 // On changing the render view host, we need to re-register the callbacks | |
98 // listening for user input. | |
99 if (old_host && callbacks_added_) { | |
100 old_host->RemoveKeyPressEventCallback(key_press_event_callback_); | |
101 old_host->RemoveMouseEventCallback(mouse_event_callback_); | |
102 } | |
103 new_host->AddKeyPressEventCallback(key_press_event_callback_); | |
104 new_host->AddMouseEventCallback(mouse_event_callback_); | |
105 callbacks_added_ = true; | |
calamity
2015/09/11 07:19:56
This only needs re-add the callbacks if they were
dominickn
2015/09/11 08:03:37
Done.
| |
106 } | |
107 | |
108 void SiteEngagementHelper::WasShown() { | |
109 // When we come back into view, ensure that the input listening callbacks are | |
110 // registered. | |
111 if (!callbacks_added_) { | |
112 content::WebContents* contents = web_contents(); | |
113 contents->GetRenderViewHost()->AddKeyPressEventCallback( | |
114 key_press_event_callback_); | |
115 contents->GetRenderViewHost()->AddMouseEventCallback(mouse_event_callback_); | |
116 callbacks_added_ = true; | |
117 } | |
118 StartTimer(); | |
119 } | |
120 | |
121 void SiteEngagementHelper::WasHidden() { | |
122 // Ensure that we are not recording user events for hidden web contents. | |
123 content::WebContents* contents = web_contents(); | |
124 if (contents) { | |
125 contents->GetRenderViewHost()->RemoveKeyPressEventCallback( | |
126 key_press_event_callback_); | |
127 contents->GetRenderViewHost()->RemoveMouseEventCallback( | |
128 mouse_event_callback_); | |
calamity
2015/09/11 07:19:56
It's probably worth making an Add/RemoveCallback(h
dominickn
2015/09/11 08:03:38
Done.
| |
129 callbacks_added_ = false; | |
calamity
2015/09/11 07:19:56
This should move outside the condition.
dominickn
2015/09/11 08:03:37
Done.
| |
130 } | |
131 timer_.Stop(); | |
132 } | |
OLD | NEW |