1 // Copyright (c) 2012 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/ui/webui/ntp/new_tab_page_handler.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/metrics/histogram.h" 11 #include "base/prefs/pref_service.h" 12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/sync/profile_sync_service.h" 14 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" 15 #include "chrome/browser/web_resource/notification_promo.h" 16 #include "chrome/common/pref_names.h" 17 #include "components/pref_registry/pref_registry_syncable.h" 18 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/web_ui.h" 20 21 namespace { 22 23 const char kDefaultPageTypeHistogram[] = "NewTabPage.DefaultPageType"; 24 25 enum PromoAction { 26 PROMO_VIEWED = 0, 27 PROMO_CLOSED, 28 PROMO_LINK_CLICKED, 29 PROMO_ACTION_MAX, 30 }; 31 32 } // namespace 33 34 NewTabPageHandler::NewTabPageHandler() : page_switch_count_(0) { 35 } 36 37 NewTabPageHandler::~NewTabPageHandler() { 38 LOCAL_HISTOGRAM_COUNTS_100("NewTabPage.SingleSessionPageSwitches", 39 page_switch_count_); 40 } 41 42 void NewTabPageHandler::RegisterMessages() { 43 // Record an open of the NTP with its default page type. 44 PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 45 int shown_page_type = prefs->GetInteger(prefs::kNtpShownPage) >> 46 kPageIdOffset; 47 UMA_HISTOGRAM_ENUMERATION(kDefaultPageTypeHistogram, 48 shown_page_type, kHistogramEnumerationMax); 49 50 web_ui()->RegisterMessageCallback("notificationPromoClosed", 51 base::Bind(&NewTabPageHandler::HandleNotificationPromoClosed, 52 base::Unretained(this))); 53 web_ui()->RegisterMessageCallback("notificationPromoViewed", 54 base::Bind(&NewTabPageHandler::HandleNotificationPromoViewed, 55 base::Unretained(this))); 56 web_ui()->RegisterMessageCallback("notificationPromoLinkClicked", 57 base::Bind(&NewTabPageHandler::HandleNotificationPromoLinkClicked, 58 base::Unretained(this))); 59 web_ui()->RegisterMessageCallback("bubblePromoClosed", 60 base::Bind(&NewTabPageHandler::HandleBubblePromoClosed, 61 base::Unretained(this))); 62 web_ui()->RegisterMessageCallback("bubblePromoViewed", 63 base::Bind(&NewTabPageHandler::HandleBubblePromoViewed, 64 base::Unretained(this))); 65 web_ui()->RegisterMessageCallback("bubblePromoLinkClicked", 66 base::Bind(&NewTabPageHandler::HandleBubblePromoLinkClicked, 67 base::Unretained(this))); 68 web_ui()->RegisterMessageCallback("pageSelected", 69 base::Bind(&NewTabPageHandler::HandlePageSelected, 70 base::Unretained(this))); 71 web_ui()->RegisterMessageCallback("logTimeToClick", 72 base::Bind(&NewTabPageHandler::HandleLogTimeToClick, 73 base::Unretained(this))); 74 } 75 76 void NewTabPageHandler::HandleNotificationPromoClosed( 77 const base::ListValue* args) { 78 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Notification", 79 PROMO_CLOSED, PROMO_ACTION_MAX); 80 NotificationPromo::HandleClosed(NotificationPromo::NTP_NOTIFICATION_PROMO); 81 Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED); 82 } 83 84 void NewTabPageHandler::HandleNotificationPromoViewed( 85 const base::ListValue* args) { 86 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Notification", 87 PROMO_VIEWED, PROMO_ACTION_MAX); 88 if (NotificationPromo::HandleViewed( 89 NotificationPromo::NTP_NOTIFICATION_PROMO)) { 90 Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED); 91 } 92 } 93 94 void NewTabPageHandler::HandleNotificationPromoLinkClicked( 95 const base::ListValue* args) { 96 DVLOG(1) << "HandleNotificationPromoLinkClicked"; 97 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Notification", 98 PROMO_LINK_CLICKED, PROMO_ACTION_MAX); 99 } 100 101 void NewTabPageHandler::HandleBubblePromoClosed(const base::ListValue* args) { 102 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Bubble", 103 PROMO_CLOSED, PROMO_ACTION_MAX); 104 NotificationPromo::HandleClosed(NotificationPromo::NTP_BUBBLE_PROMO); 105 Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED); 106 } 107 108 void NewTabPageHandler::HandleBubblePromoViewed(const base::ListValue* args) { 109 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Bubble", 110 PROMO_VIEWED, PROMO_ACTION_MAX); 111 if (NotificationPromo::HandleViewed(NotificationPromo::NTP_BUBBLE_PROMO)) 112 Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED); 113 } 114 115 void NewTabPageHandler::HandleBubblePromoLinkClicked( 116 const base::ListValue* args) { 117 DVLOG(1) << "HandleBubblePromoLinkClicked"; 118 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Bubble", 119 PROMO_LINK_CLICKED, PROMO_ACTION_MAX); 120 } 121 122 void NewTabPageHandler::HandlePageSelected(const base::ListValue* args) { 123 page_switch_count_++; 124 125 double page_id_double; 126 CHECK(args->GetDouble(0, &page_id_double)); 127 int page_id = static_cast<int>(page_id_double); 128 129 double index_double; 130 CHECK(args->GetDouble(1, &index_double)); 131 int index = static_cast<int>(index_double); 132 133 PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 134 int previous_shown_page = 135 prefs->GetInteger(prefs::kNtpShownPage) >> kPageIdOffset; 136 UMA_HISTOGRAM_ENUMERATION("NewTabPage.PreviousSelectedPageType", 137 previous_shown_page, kHistogramEnumerationMax); 138 139 prefs->SetInteger(prefs::kNtpShownPage, page_id | index); 140 141 int shown_page_type = page_id >> kPageIdOffset; 142 UMA_HISTOGRAM_ENUMERATION("NewTabPage.SelectedPageType", 143 shown_page_type, kHistogramEnumerationMax); 144 } 145 146 void NewTabPageHandler::HandleLogTimeToClick(const base::ListValue* args) { 147 std::string histogram_name; 148 double duration; 149 if (!args->GetString(0, &histogram_name) || !args->GetDouble(1, &duration)) { 150 NOTREACHED(); 151 return; 152 } 153 154 base::TimeDelta delta = base::TimeDelta::FromMilliseconds(duration); 155 156 if (histogram_name == "NewTabPage.TimeToClickMostVisited") { 157 UMA_HISTOGRAM_LONG_TIMES("NewTabPage.TimeToClickMostVisited", delta); 158 } else if (histogram_name == "NewTabPage.TimeToClickRecentlyClosed") { 159 UMA_HISTOGRAM_LONG_TIMES("NewTabPage.TimeToClickRecentlyClosed", delta); 160 } else if (histogram_name == "ExtendedNewTabPage.TimeToClickMostVisited") { 161 UMA_HISTOGRAM_LONG_TIMES( 162 "ExtendedNewTabPage.TimeToClickMostVisited", delta); 163 } else if (histogram_name == "ExtendedNewTabPage.TimeToClickRecentlyClosed") { 164 UMA_HISTOGRAM_LONG_TIMES( 165 "ExtendedNewTabPage.TimeToClickRecentlyClosed", delta); 166 } else { 167 NOTREACHED(); 168 } 169 } 170 171 // static 172 void NewTabPageHandler::RegisterProfilePrefs( 173 user_prefs::PrefRegistrySyncable* registry) { 174 // TODO(estade): should be syncable. 175 registry->RegisterIntegerPref( 176 prefs::kNtpShownPage, 177 APPS_PAGE_ID, 178 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 179 } 180 181 // static 182 void NewTabPageHandler::GetLocalizedValues(Profile* profile, 183 base::DictionaryValue* values) { 184 values->SetInteger("most_visited_page_id", MOST_VISITED_PAGE_ID); 185 values->SetInteger("apps_page_id", APPS_PAGE_ID); 186 values->SetInteger("suggestions_page_id", SUGGESTIONS_PAGE_ID); 187 188 PrefService* prefs = profile->GetPrefs(); 189 int shown_page = prefs->GetInteger(prefs::kNtpShownPage); 190 values->SetInteger("shown_page_type", shown_page & ~INDEX_MASK); 191 values->SetInteger("shown_page_index", shown_page & INDEX_MASK); 192 } 193 194 void NewTabPageHandler::Notify(chrome::NotificationType notification_type) { 195 content::NotificationService* service = 196 content::NotificationService::current(); 197 service->Notify(notification_type, 198 content::Source<NewTabPageHandler>(this), 199 content::NotificationService::NoDetails()); 200 } 201