new_tab_page_handler.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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  web_ui()->RegisterMessageCallback("getShouldShowApps",
79      base::Bind(&NewTabPageHandler::HandleGetShouldShowApps,
80                 base::Unretained(this)));
81}
82
83void NewTabPageHandler::HandleNotificationPromoClosed(const ListValue* args) {
84  UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Notification",
85                            PROMO_CLOSED, PROMO_ACTION_MAX);
86  NotificationPromo::HandleClosed(NotificationPromo::NTP_NOTIFICATION_PROMO);
87  Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED);
88}
89
90void NewTabPageHandler::HandleNotificationPromoViewed(const ListValue* args) {
91  UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Notification",
92                            PROMO_VIEWED, PROMO_ACTION_MAX);
93  if (NotificationPromo::HandleViewed(
94          NotificationPromo::NTP_NOTIFICATION_PROMO)) {
95    Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED);
96  }
97}
98
99void NewTabPageHandler::HandleNotificationPromoLinkClicked(
100    const ListValue* args) {
101  DVLOG(1) << "HandleNotificationPromoLinkClicked";
102  UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Notification",
103                            PROMO_LINK_CLICKED, PROMO_ACTION_MAX);
104}
105
106void NewTabPageHandler::HandleBubblePromoClosed(const ListValue* args) {
107  UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Bubble",
108                            PROMO_CLOSED, PROMO_ACTION_MAX);
109  NotificationPromo::HandleClosed(NotificationPromo::NTP_BUBBLE_PROMO);
110  Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED);
111}
112
113void NewTabPageHandler::HandleBubblePromoViewed(const ListValue* args) {
114  UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Bubble",
115                            PROMO_VIEWED, PROMO_ACTION_MAX);
116  if (NotificationPromo::HandleViewed(NotificationPromo::NTP_BUBBLE_PROMO))
117    Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED);
118}
119
120void NewTabPageHandler::HandleBubblePromoLinkClicked(const ListValue* args) {
121  DVLOG(1) << "HandleBubblePromoLinkClicked";
122  UMA_HISTOGRAM_ENUMERATION("NewTabPage.Promo.Bubble",
123                            PROMO_LINK_CLICKED, PROMO_ACTION_MAX);
124}
125
126void NewTabPageHandler::HandlePageSelected(const ListValue* args) {
127  page_switch_count_++;
128
129  double page_id_double;
130  CHECK(args->GetDouble(0, &page_id_double));
131  int page_id = static_cast<int>(page_id_double);
132
133  double index_double;
134  CHECK(args->GetDouble(1, &index_double));
135  int index = static_cast<int>(index_double);
136
137  PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
138  int previous_shown_page =
139      prefs->GetInteger(prefs::kNtpShownPage) >> kPageIdOffset;
140  UMA_HISTOGRAM_ENUMERATION("NewTabPage.PreviousSelectedPageType",
141                            previous_shown_page, kHistogramEnumerationMax);
142
143  prefs->SetInteger(prefs::kNtpShownPage, page_id | index);
144
145  int shown_page_type = page_id >> kPageIdOffset;
146  UMA_HISTOGRAM_ENUMERATION("NewTabPage.SelectedPageType",
147                            shown_page_type, kHistogramEnumerationMax);
148}
149
150void NewTabPageHandler::HandleLogTimeToClick(const ListValue* args) {
151  std::string histogram_name;
152  double duration;
153  if (!args->GetString(0, &histogram_name) || !args->GetDouble(1, &duration)) {
154    NOTREACHED();
155    return;
156  }
157
158  base::TimeDelta delta = base::TimeDelta::FromMilliseconds(duration);
159
160  if (histogram_name == "NewTabPage.TimeToClickMostVisited") {
161    UMA_HISTOGRAM_LONG_TIMES("NewTabPage.TimeToClickMostVisited", delta);
162  } else if (histogram_name == "NewTabPage.TimeToClickRecentlyClosed") {
163    UMA_HISTOGRAM_LONG_TIMES("NewTabPage.TimeToClickRecentlyClosed", delta);
164  } else if (histogram_name == "ExtendedNewTabPage.TimeToClickMostVisited") {
165    UMA_HISTOGRAM_LONG_TIMES(
166        "ExtendedNewTabPage.TimeToClickMostVisited", delta);
167  } else if (histogram_name == "ExtendedNewTabPage.TimeToClickRecentlyClosed") {
168    UMA_HISTOGRAM_LONG_TIMES(
169        "ExtendedNewTabPage.TimeToClickRecentlyClosed", delta);
170  } else {
171    NOTREACHED();
172  }
173}
174
175void NewTabPageHandler::HandleGetShouldShowApps(const ListValue* args) {
176  apps::GetIsAppLauncherEnabled(
177      base::Bind(&NewTabPageHandler::GotIsAppLauncherEnabled,
178                 AsWeakPtr()));
179}
180
181void NewTabPageHandler::GotIsAppLauncherEnabled(bool is_enabled) {
182  base::FundamentalValue should_show_apps(!is_enabled);
183  web_ui()->CallJavascriptFunction("ntp.gotShouldShowApps", should_show_apps);
184}
185
186// static
187void NewTabPageHandler::RegisterUserPrefs(PrefRegistrySyncable* registry) {
188  // TODO(estade): should be syncable.
189  registry->RegisterIntegerPref(prefs::kNtpShownPage, APPS_PAGE_ID,
190                                PrefRegistrySyncable::UNSYNCABLE_PREF);
191}
192
193// static
194void NewTabPageHandler::GetLocalizedValues(Profile* profile,
195                                           DictionaryValue* values) {
196  values->SetInteger("most_visited_page_id", MOST_VISITED_PAGE_ID);
197  values->SetInteger("apps_page_id", APPS_PAGE_ID);
198  values->SetInteger("suggestions_page_id", SUGGESTIONS_PAGE_ID);
199
200  PrefService* prefs = profile->GetPrefs();
201  int shown_page = prefs->GetInteger(prefs::kNtpShownPage);
202  values->SetInteger("shown_page_type", shown_page & ~INDEX_MASK);
203  values->SetInteger("shown_page_index", shown_page & INDEX_MASK);
204}
205
206void NewTabPageHandler::Notify(chrome::NotificationType notification_type) {
207  content::NotificationService* service =
208      content::NotificationService::current();
209  service->Notify(notification_type,
210                  content::Source<NewTabPageHandler>(this),
211                  content::NotificationService::NoDetails());
212}
213