Home | History | Annotate | Download | only in ntp
      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