Chromium Code Reviews| 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 |