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