new_tab_page_handler.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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
25namespace {
26
27const char kDefaultPageTypeHistogram[] = "NewTabPage.DefaultPageType";
28
29enum PromoAction {
30  PROMO_VIEWED = 0,
31  PROMO_CLOSED,
32  PROMO_LINK_CLICKED,
33  PROMO_ACTION_MAX,
34};
35
36}  // namespace
37
38NewTabPageHandler::NewTabPageHandler() : page_switch_count_(0) {
39}
40
41NewTabPageHandler::~NewTabPageHandler() {
42  HISTOGRAM_COUNTS_100("NewTabPage.SingleSessionPageSwitches",
43                       page_switch_count_);
44}
45
46void 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
80void 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
87void 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
96void 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
103void 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
110void 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
117void 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
123void 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
147void 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
173void 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
183void 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
195void 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