blob: 2dd61126e09c475519350a7ea92fe16a987a692b [file] [log] [blame]
Jack Hsiehd06b1012022-12-13 18:20:141// Copyright 2022 The Chromium Authors
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/hid/hid_pinned_notification.h"
6
7#include "base/containers/contains.h"
8#include "base/strings/strcat.h"
9#include "build/build_config.h"
10#include "chrome/browser/hid/hid_connection_tracker.h"
11#include "chrome/browser/hid/hid_connection_tracker_factory.h"
12#include "chrome/browser/notifications/system_notification_helper.h"
13#include "chrome/browser/profiles/profile.h"
14#include "extensions/buildflags/buildflags.h"
15#include "ui/base/models/image_model.h"
16#include "ui/message_center/public/cpp/notification.h"
17#include "ui/message_center/public/cpp/notification_delegate.h"
18
19HidPinnedNotification::HidPinnedNotification() = default;
20
21HidPinnedNotification::~HidPinnedNotification() = default;
22
23// static
24std::string HidPinnedNotification::GetNotificationId(Profile* profile) {
25 return base::StrCat({"chrome://device_indicator/hid/", profile->UniqueId()});
26}
27
28std::unique_ptr<message_center::Notification>
29HidPinnedNotification::CreateNotification(Profile* profile) {
30 message_center::RichNotificationData data;
31 data.buttons.emplace_back(GetManageHidDeviceButtonLabel(profile));
32 auto delegate =
33 base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
34 base::BindRepeating(
35 [](Profile* profile, absl::optional<int> button_index) {
36 // HidConnectionTracker guarantees that RemoveProfile() is
37 // called on Profile destruction so it is impossible to interact
38 // with the notification after |profile| becomes a dangling
39 // pointer.
40 if (!button_index)
41 return;
42
43 DCHECK_EQ(*button_index, 0);
44 auto* hid_connection_tracker =
45 HidConnectionTrackerFactory::GetForProfile(
46 profile, /*create=*/false);
47 DCHECK(hid_connection_tracker);
48 hid_connection_tracker->ShowHidContentSettingsExceptions();
49 },
50 profile));
51 auto notification_id = GetNotificationId(profile);
52 auto* hid_connection_tracker =
53 HidConnectionTrackerFactory::GetForProfile(profile, /*create=*/false);
54 DCHECK(hid_connection_tracker);
55 auto notification = std::make_unique<message_center::Notification>(
56 message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
57 GetTooltipLabel(hid_connection_tracker->connection_count()),
58 /*message=*/std::u16string(), /*icon=*/ui::ImageModel(),
59 /*display_source=*/std::u16string(), /*origin_url=*/GURL(),
60#if BUILDFLAG(IS_CHROMEOS_ASH)
61 message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
62 notification_id,
63 ash::NotificationCatalogName::kWebHid),
64#else
65 message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
66 notification_id),
67#endif
68 data, std::move(delegate));
69 notification->set_small_image(gfx::Image(GetStatusTrayIcon()));
70 notification->set_pinned(true);
71 // Set to system priority so it will never timeout.
72 notification->SetSystemPriority();
73 return notification;
74}
75
76void HidPinnedNotification::DisplayNotification(
77 std::unique_ptr<message_center::Notification> notification) {
78 SystemNotificationHelper::GetInstance()->Display(*notification);
79}
80
81void HidPinnedNotification::AddProfile(Profile* profile) {
82 DCHECK(!base::Contains(profiles_, profile));
83 profiles_.emplace(profile);
84 DisplayNotification(CreateNotification(profile));
85}
86
87void HidPinnedNotification::RemoveProfile(Profile* profile) {
88 DCHECK(base::Contains(profiles_, profile));
89 profiles_.erase(profile);
90 SystemNotificationHelper::GetInstance()->Close(GetNotificationId(profile));
91}
92
93void HidPinnedNotification::NotifyConnectionCountUpdated(Profile* profile) {
94 DCHECK(base::Contains(profiles_, profile));
95 DisplayNotification(CreateNotification(profile));
96}