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