summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chrome_webusb_browser_client.cc
blob: aff680a2979bd377d12fa9cf86dbebd81880dacd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chrome_webusb_browser_client.h"

#include <utility>

#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/net/referrer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "content/public/common/origin_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/image/image.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_delegate.h"
#include "url/gurl.h"

namespace {

const char kWebUsbDetectorNotificationID[] = "webusb.detector";

// Reasons the notification may be closed. These are used in histograms so do
// not remove/reorder entries. Only add at the end just before
// WEBUSB_NOTIFICATION_CLOSED_MAX. Also remember to update the enum listing in
// tools/metrics/histograms/histograms.xml.
enum WebUsbNotificationClosed {
  // The notification was dismissed but not by the user (either automatically
  // or because the device was unplugged).
  WEBUSB_NOTIFICATION_CLOSED,
  // The user closed the notification.
  WEBUSB_NOTIFICATION_CLOSED_BY_USER,
  // The user clicked on the notification.
  WEBUSB_NOTIFICATION_CLOSED_CLICKED,
  // Maximum value for the enum.
  WEBUSB_NOTIFICATION_CLOSED_MAX
};

void RecordNotificationClosure(WebUsbNotificationClosed disposition) {
  UMA_HISTOGRAM_ENUMERATION("WebUsb.NotificationClosed", disposition,
                            WEBUSB_NOTIFICATION_CLOSED_MAX);
}

Browser* GetBrowser() {
  chrome::ScopedTabbedBrowserDisplayer browser_displayer(
      ProfileManager::GetActiveUserProfile(), chrome::GetActiveDesktop());
  DCHECK(browser_displayer.browser());
  return browser_displayer.browser();
}

void OpenURL(const GURL& url) {
  GetBrowser()->OpenURL(
      content::OpenURLParams(url, content::Referrer(), NEW_FOREGROUND_TAB,
                             ui::PAGE_TRANSITION_AUTO_TOPLEVEL, true));
}

// Delegate for webusb notification
class WebUsbNotificationDelegate : public message_center::NotificationDelegate {
 public:
  WebUsbNotificationDelegate(const GURL& landing_page,
                             const std::string& notification_id)
      : landing_page_(landing_page), notification_id_(notification_id) {}

  void Click() override {
    clicked_ = true;
    OpenURL(landing_page_);
    message_center::MessageCenter::Get()->RemoveNotification(
        notification_id_, false /* by_user */);
  }

  void Close(bool by_user) override {
    if (clicked_)
      RecordNotificationClosure(WEBUSB_NOTIFICATION_CLOSED_CLICKED);
    else if (by_user)
      RecordNotificationClosure(WEBUSB_NOTIFICATION_CLOSED_BY_USER);
    else
      RecordNotificationClosure(WEBUSB_NOTIFICATION_CLOSED);
  }

 private:
  ~WebUsbNotificationDelegate() override = default;

  GURL landing_page_;
  std::string notification_id_;
  bool clicked_ = false;

  DISALLOW_COPY_AND_ASSIGN(WebUsbNotificationDelegate);
};

}  // namespace

ChromeWebUsbBrowserClient::ChromeWebUsbBrowserClient() {}

ChromeWebUsbBrowserClient::~ChromeWebUsbBrowserClient() {}

void ChromeWebUsbBrowserClient::OnDeviceAdded(
    const base::string16& product_name,
    const GURL& landing_page,
    const std::string& notification_id) {
  if (!content::IsOriginSecure(landing_page)) {
    return;
  }

  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  message_center::RichNotificationData rich_notification_data;
  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
          l10n_util::GetStringFUTF16(
              IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION_TITLE, product_name),
          l10n_util::GetStringFUTF16(
              IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION,
              base::UTF8ToUTF16(landing_page.GetContent())),
          rb.GetNativeImageNamed(IDR_USB_NOTIFICATION_ICON),
          base::string16(), GURL(),
          message_center::NotifierId(
              message_center::NotifierId::SYSTEM_COMPONENT,
              kWebUsbDetectorNotificationID),
          rich_notification_data,
          new WebUsbNotificationDelegate(landing_page, notification_id)));

  notification->SetSystemPriority();
  message_center::MessageCenter::Get()->AddNotification(
      std::move(notification));
}

void ChromeWebUsbBrowserClient::OnDeviceRemoved(
    const std::string& notification_id) {
  message_center::MessageCenter* message_center =
      message_center::MessageCenter::Get();
  if (message_center->FindVisibleNotificationById(notification_id)) {
    message_center->RemoveNotification(notification_id, false /* by_user */);
  }
}