network_portal_notification_controller.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/net/network_portal_notification_controller.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/shell.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/system_notifier.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/basictypes.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/command_line.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/compiler_specific.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h"
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/metrics/histogram.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/string16.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/singleton_tabs.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/chromeos_switches.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/network/network_state.h"
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/captive_portal/captive_portal_detector.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "grit/generated_resources.h"
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "grit/theme_resources.h"
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/message_center/message_center.h"
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/message_center/notification.h"
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/message_center/notification_types.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/message_center/notifier_settings.h"
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using message_center::Notification;
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace chromeos {
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool IsPortalNotificationEnabled() {
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !CommandLine::ForCurrentProcess()->HasSwitch(
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      switches::kDisableNetworkPortalNotification);
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CloseNotification() {
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_center::MessageCenter::Get()->RemoveNotification(
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NetworkPortalNotificationController::kNotificationId, false);
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class NetworkPortalNotificationControllerDelegate
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : public message_center::NotificationDelegate {
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NetworkPortalNotificationControllerDelegate(): clicked_(false) {}
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Overridden from message_center::NotificationDelegate:
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void Display() OVERRIDE;
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void Error() OVERRIDE;
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void Close(bool by_user) OVERRIDE;
5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void Click() OVERRIDE;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~NetworkPortalNotificationControllerDelegate() {}
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool clicked_;
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkPortalNotificationControllerDelegate);
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid NetworkPortalNotificationControllerDelegate::Display() {
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UMA_HISTOGRAM_ENUMERATION(
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::kNotificationMetric,
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::NOTIFICATION_METRIC_DISPLAYED,
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::NOTIFICATION_METRIC_COUNT);
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid NetworkPortalNotificationControllerDelegate::Error() {
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UMA_HISTOGRAM_ENUMERATION(
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::kNotificationMetric,
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::NOTIFICATION_METRIC_ERROR,
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::NOTIFICATION_METRIC_COUNT);
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid NetworkPortalNotificationControllerDelegate::Close(bool by_user) {
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (clicked_)
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NetworkPortalNotificationController::UserActionMetric metric =
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      by_user
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ? NetworkPortalNotificationController::USER_ACTION_METRIC_CLOSED
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      : NetworkPortalNotificationController::USER_ACTION_METRIC_IGNORED;
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UMA_HISTOGRAM_ENUMERATION(
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::kUserActionMetric,
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      metric,
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::USER_ACTION_METRIC_COUNT);
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void NetworkPortalNotificationControllerDelegate::Click() {
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  clicked_ = true;
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UMA_HISTOGRAM_ENUMERATION(
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::kUserActionMetric,
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::USER_ACTION_METRIC_CLICKED,
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NetworkPortalNotificationController::USER_ACTION_METRIC_COUNT);
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Profile* profile = ProfileManager::GetActiveUserProfile();
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!profile)
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  chrome::ScopedTabbedBrowserDisplayer displayer(profile,
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                 chrome::HOST_DESKTOP_TYPE_ASH);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GURL url(captive_portal::CaptivePortalDetector::kDefaultURL);
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  chrome::ShowSingletonTab(displayer.browser(), url);
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CloseNotification();
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char NetworkPortalNotificationController::kNotificationId[] =
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "chrome://net/network_portal_detector";
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char NetworkPortalNotificationController::kNotificationMetric[] =
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    "CaptivePortal.Notification.Status";
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char NetworkPortalNotificationController::kUserActionMetric[] =
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    "CaptivePortal.Notification.UserAction";
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NetworkPortalNotificationController::NetworkPortalNotificationController() {}
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)NetworkPortalNotificationController::~NetworkPortalNotificationController() {}
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetworkPortalNotificationController::OnPortalDetectionCompleted(
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const NetworkState* network,
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const NetworkPortalDetector::CaptivePortalState& state) {
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!IsPortalNotificationEnabled())
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!network ||
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.status != NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL) {
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    last_network_path_.clear();
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CloseNotification();
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Don't do anything if notification for |network| already was
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // displayed.
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (network->path() == last_network_path_)
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  last_network_path_ = network->path();
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Image& icon = bundle.GetImageNamed(IDR_PORTAL_DETECTION_ALERT);
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_center::NotifierId notifier_id(
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      message_center::NotifierId::SYSTEM_COMPONENT,
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::system_notifier::kNotifierNetworkPortalDetector);
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<Notification> notification(new Notification(
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      message_center::NOTIFICATION_TYPE_SIMPLE,
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kNotificationId,
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_PORTAL_DETECTION_NOTIFICATION_TITLE),
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      l10n_util::GetStringFUTF16(IDS_PORTAL_DETECTION_NOTIFICATION_MESSAGE,
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 base::UTF8ToUTF16(network->name())),
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      icon,
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::string16() /* display_source */,
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      notifier_id,
16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      message_center::RichNotificationData(),
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new NetworkPortalNotificationControllerDelegate()));
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notification->SetSystemPriority();
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (ash::Shell::HasInstance()) {
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ash::Shell::GetInstance()
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ->system_tray_notifier()
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ->NotifyOnCaptivePortalDetected(network->path());
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_center::MessageCenter::Get()->AddNotification(notification.Pass());
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace chromeos
180