hid: Update HidPinnedNotification to show extension names
Update HidPinnedNotification to show extension names and revise icon
string literals to match go/usb-hid-extension-permission-ux
documentation.
Bug: 1353104
Change-Id: I2ca50ae52aaeec9b6ce77a96425fbc342c7fb232
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4452088
Reviewed-by: Reilly Grant <[email protected]>
Commit-Queue: Jack Hsieh <[email protected]>
Code-Coverage: Findit <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1135568}
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 0456210..60acc94 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -1009,11 +1009,17 @@
<if expr="not is_android">
<!-- WebHID system tray icon -->
- <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE" desc="Title for the WebHID system tray icon when one or more HID devices are being accessed.">
+ <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION" desc="Title for the WebHID system tray icon when one or more HID devices are being accessed by an extension.">
{NUM_DEVICES, plural,
- =0 {Chromium was accessing a HID device}
- =1 {Chromium is accessing a HID device}
- other {Chromium is accessing HID devices}}
+ =0 {A Chromium extension was accessing HID devices}
+ =1 {A Chromium extension is accessing 1 HID device}
+ other {A Chromium extension is accessing # HID devices}}
+ </message>
+ <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS" desc="Title for the WebHID system tray icon when HID devices are being accessed by multiple extensions.">
+ {NUM_DEVICES, plural,
+ =0 {Chromium extensions were accessing HID devices}
+ =1 {Chromium extensions are accessing HID devices}
+ other {Chromium extensions are accessing # HID devices}}
</message>
</if>
diff --git a/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE.png.sha1
deleted file mode 100644
index b830d56..0000000
--- a/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-590b07dbedaef63974c924244c3bf44de6bc280e
\ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS.png.sha1 b/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS.png.sha1
new file mode 100644
index 0000000..a444ee0c
--- /dev/null
+++ b/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS.png.sha1
@@ -0,0 +1 @@
+e1f083b41db133cc0e9d03ca73e00c8ddd8f0638
\ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION.png.sha1 b/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION.png.sha1
new file mode 100644
index 0000000..150f8c98
--- /dev/null
+++ b/chrome/app/chromium_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION.png.sha1
@@ -0,0 +1 @@
+3f3b3bab80f0635b73b43a91a7dcf7197dfa80ba
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 91f1e7d..c70bbe1 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -13005,25 +13005,31 @@
</message>
<if expr="not is_android">
- <!-- WebHID Notification -->
- <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE" desc="The text for WebHID system tray icon button for managing HID devices.">
- Manage HID devices
- </message>
- <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE_WITH_PROFILE_NAME" desc="The text with profile name for WebHID system tray icon button for managing HID devices.">
- Manage HID devices for <ph name="PROFILE_NAME">$1<ex>[email protected]</ex></ph>
- </message>
+ <!-- WebHID System Tray Icon -->
<message name="IDS_WEBHID_SYSTEM_TRAY_ICON_HID_SETTINGS" desc="Text for the WebHID system tray icon button that opens the HID settings page.">
HID settings
</message>
<message name="IDS_WEBHID_SYSTEM_TRAY_ICON_ABOUT_HID_DEVICE" desc="Text for the WebHID system tray icon button that opens the learn more page for the HID device.">
About HID devices
</message>
- <message name="IDS_DEVICE_CONNECTED_BY_EXTENSION" desc="Text for the WebHID system tray icon button that displays how many active connections for the extension and opens the extension's site setting page.">
- {NUM_CONNECTION, plural,
- =0 {Extension "<ph name="EXTENSION">{1}<ex>Google Translate</ex></ph>" was accessing devices}
- =1 {Extension "<ph name="EXTENSION">{1}<ex>Google Translate</ex></ph>" is accessing {0} device}
- other {Extension "<ph name="EXTENSION">{1}<ex>Google Translate</ex></ph>" is accessing {0} devices}}
- </message>
+ <if expr="is_chromeos">
+ <then>
+ <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST" desc="Text for the WebHID pinned notification message.">
+ {NUM_EXTENSION, plural,
+ =1 {<ph name="EXTENSION1">{1}<ex>Google Translate</ex></ph> is accessing HID devices}
+ =2 {Extensions accessing devices: <ph name="EXTENSION1">{1}<ex>Google Translate</ex></ph>, <ph name="EXTENSION2">{2}<ex>Secure Shell</ex></ph>}
+ other {Extensions accessing devices: <ph name="EXTENSION1">{1}<ex>Google Translate</ex></ph>, <ph name="EXTENSION2">{2}<ex>Secure Shell</ex></ph> +{3} more}}
+ </message>
+ </then>
+ <else>
+ <message name="IDS_DEVICE_CONNECTED_BY_EXTENSION" desc="Text for the WebHID system tray icon button that displays how many active connections for the extension and opens the extension's site setting page.">
+ {NUM_CONNECTION, plural,
+ =0 {Extension "<ph name="EXTENSION">{1}<ex>Google Translate</ex></ph>" was accessing devices}
+ =1 {Extension "<ph name="EXTENSION">{1}<ex>Google Translate</ex></ph>" is accessing {0} device}
+ other {Extension "<ph name="EXTENSION">{1}<ex>Google Translate</ex></ph>" is accessing {0} devices}}
+ </message>
+ </else>
+ </if>
</if>
<if expr="chromeos_ash">
diff --git a/chrome/app/generated_resources_grd/IDS_DEVICE_CONNECTED_BY_EXTENSION.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEVICE_CONNECTED_BY_EXTENSION.png.sha1
index 666d848..af43730 100644
--- a/chrome/app/generated_resources_grd/IDS_DEVICE_CONNECTED_BY_EXTENSION.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_DEVICE_CONNECTED_BY_EXTENSION.png.sha1
@@ -1 +1 @@
-475ad0e2633134f0d795024b21bd71696a035651
\ No newline at end of file
+a2b2d8eb0579ed3a99dad7ab91bdfc272ed0ee1f
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE.png.sha1
deleted file mode 100644
index 48de3fdd1..0000000
--- a/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-df167e129e49a5833e8ca321f7ebc6f7cdf4fe01
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE_WITH_PROFILE_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE_WITH_PROFILE_NAME.png.sha1
deleted file mode 100644
index 4a1bb4a..0000000
--- a/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE_WITH_PROFILE_NAME.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-891da6346817ba8cfbeb025930f923d41a2324ca
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST.png.sha1
new file mode 100644
index 0000000..a0c63ec
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST.png.sha1
@@ -0,0 +1 @@
+e192152c9bea3b1f8463eb54ddd8b776931e3510
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index fb3bd7b..79fa786 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -1070,11 +1070,17 @@
<if expr="not is_android">
<!-- WebHID system tray icon -->
- <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE" desc="Title for the WebHID system tray icon when one or more HID devices are being accessed.">
+ <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION" desc="Title for the WebHID system tray icon when one or more HID devices are being accessed by an extension.">
{NUM_DEVICES, plural,
- =0 {Google Chrome was accessing a HID device}
- =1 {Google Chrome is accessing a HID device}
- other {Google Chrome is accessing HID devices}}
+ =0 {A Google Chrome extension was accessing HID devices}
+ =1 {A Google Chrome extension is accessing 1 HID device}
+ other {A Google Chrome extension is accessing # HID devices}}
+ </message>
+ <message name="IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS" desc="Title for the WebHID system tray icon when HID devices are being accessed by multiple extensions.">
+ {NUM_DEVICES, plural,
+ =0 {Google Chrome extensions were accessing HID devices}
+ =1 {Google Chrome extensions are accessing HID devices}
+ other {Google Chrome extensions are accessing # HID devices}}
</message>
</if>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE.png.sha1
deleted file mode 100644
index b830d56..0000000
--- a/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-590b07dbedaef63974c924244c3bf44de6bc280e
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS.png.sha1
new file mode 100644
index 0000000..6a9c62c
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS.png.sha1
@@ -0,0 +1 @@
+2ae8ffc4166f134e98b5de1a6802ba677789a37f
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION.png.sha1
new file mode 100644
index 0000000..1fa6dbd
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION.png.sha1
@@ -0,0 +1 @@
+26aa7543e4596af969171e0a36e1149721ae9597
\ No newline at end of file
diff --git a/chrome/browser/hid/hid_pinned_notification.cc b/chrome/browser/hid/hid_pinned_notification.cc
index 3a847151..aa08dc47 100644
--- a/chrome/browser/hid/hid_pinned_notification.cc
+++ b/chrome/browser/hid/hid_pinned_notification.cc
@@ -3,19 +3,59 @@
// found in the LICENSE file.
#include "chrome/browser/hid/hid_pinned_notification.h"
+#include <string>
#include "base/containers/contains.h"
+#include "base/containers/flat_map.h"
+#include "base/i18n/message_formatter.h"
#include "base/strings/strcat.h"
+#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/hid/hid_connection_tracker.h"
#include "chrome/browser/hid/hid_connection_tracker_factory.h"
#include "chrome/browser/notifications/system_notification_helper.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/grit/generated_resources.h"
#include "extensions/buildflags/buildflags.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/image_model.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/constants.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
+namespace {
+
+std::u16string GetMessageLabel(HidConnectionTracker* connection_tracker) {
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ std::vector<std::u16string> extension_names;
+ for (const auto& [origin, state] : connection_tracker->origins()) {
+ CHECK_EQ(origin.scheme(), extensions::kExtensionScheme);
+ extension_names.push_back(base::UTF8ToUTF16(state.name));
+ }
+ CHECK(!extension_names.empty());
+ if (extension_names.size() == 1) {
+ return base::i18n::MessageFormatter::FormatWithNumberedArgs(
+ l10n_util::GetStringUTF16(IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST),
+ 1, extension_names[0]);
+ } else if (extension_names.size() == 2) {
+ return base::i18n::MessageFormatter::FormatWithNumberedArgs(
+ l10n_util::GetStringUTF16(IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST),
+ 2, extension_names[0], extension_names[1]);
+ }
+ return base::i18n::MessageFormatter::FormatWithNumberedArgs(
+ l10n_util::GetStringUTF16(IDS_WEBHID_SYSTEM_TRAY_ICON_EXTENSION_LIST),
+ static_cast<int>(extension_names.size()), extension_names[0],
+ extension_names[1], static_cast<int>(extension_names.size() - 2));
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+ NOTREACHED_NORETURN();
+}
+
+} // namespace
+
HidPinnedNotification::HidPinnedNotification() = default;
HidPinnedNotification::~HidPinnedNotification() = default;
@@ -28,7 +68,7 @@
std::unique_ptr<message_center::Notification>
HidPinnedNotification::CreateNotification(Profile* profile) {
message_center::RichNotificationData data;
- data.buttons.emplace_back(GetManageHidDeviceButtonLabel(profile));
+ data.buttons.emplace_back(GetContentSettingsLabel());
auto delegate =
base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
base::BindRepeating(
@@ -54,8 +94,9 @@
DCHECK(hid_connection_tracker);
auto notification = std::make_unique<message_center::Notification>(
message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
- GetTitleLabel(hid_connection_tracker->total_connection_count()),
- /*message=*/std::u16string(), /*icon=*/ui::ImageModel(),
+ GetTitleLabel(hid_connection_tracker->origins().size(),
+ hid_connection_tracker->total_connection_count()),
+ GetMessageLabel(hid_connection_tracker), /*icon=*/ui::ImageModel(),
/*display_source=*/std::u16string(), /*origin_url=*/GURL(),
#if BUILDFLAG(IS_CHROMEOS_ASH)
message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
@@ -68,8 +109,8 @@
data, std::move(delegate));
notification->set_small_image(gfx::Image(GetStatusTrayIcon()));
notification->set_pinned(true);
- // Set to system priority so it will never timeout.
- notification->SetSystemPriority();
+ // Set to low priority so it doesn't create a popup.
+ notification->set_priority(message_center::LOW_PRIORITY);
return notification;
}
diff --git a/chrome/browser/hid/hid_pinned_notification_unittest.cc b/chrome/browser/hid/hid_pinned_notification_unittest.cc
index 2be074f..45684bd4 100644
--- a/chrome/browser/hid/hid_pinned_notification_unittest.cc
+++ b/chrome/browser/hid/hid_pinned_notification_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "chrome/browser/hid/hid_pinned_notification.h"
+#include <string>
#include "chrome/browser/hid/hid_connection_tracker.h"
#include "chrome/browser/hid/hid_connection_tracker_factory.h"
@@ -10,9 +11,49 @@
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/notifications/system_notification_helper.h"
#include "chrome/test/base/testing_browser_process.h"
+#include "extensions/common/constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
+namespace {
+
+std::u16string GetExpectedMessage(
+ const std::vector<HidSystemTrayIconTestBase::OriginItem>& origin_items) {
+ auto sorted_origin_items = origin_items;
+ // Sort the |origin_items| by origin. This is necessary because the origin
+ // items for each profile in the pinned notification are created by iterating
+ // through a structure of flat_map<url::Origin, ...>.
+ base::ranges::sort(sorted_origin_items);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ std::vector<std::string> extension_names;
+ for (const auto& [origin, connection_count, name] : sorted_origin_items) {
+ CHECK(origin.scheme() == extensions::kExtensionScheme);
+ extension_names.push_back(name);
+ }
+ CHECK(!extension_names.empty());
+ if (extension_names.size() == 1) {
+ return base::UTF8ToUTF16(base::StringPrintf("%s is accessing HID devices",
+ extension_names[0].c_str()));
+ } else if (extension_names.size() == 2) {
+ return base::UTF8ToUTF16(base::StringPrintf(
+ "Extensions accessing devices: %s, %s", extension_names[0].c_str(),
+ extension_names[1].c_str()));
+ }
+ return base::UTF8ToUTF16(
+ base::StringPrintf("Extensions accessing devices: %s, %s +%zu more",
+ extension_names[0].c_str(), extension_names[1].c_str(),
+ extension_names.size() - 2));
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+ NOTREACHED_NORETURN();
+}
+
+} // namespace
+
class HidPinnedNotificationTest : public HidSystemTrayIconTestBase {
public:
void SetUp() override {
@@ -50,12 +91,14 @@
HidPinnedNotification::GetNotificationId(profile));
ASSERT_TRUE(maybe_notification);
EXPECT_EQ(maybe_notification->title(),
- GetExpectedTitle(total_connection_count));
-
+ GetExpectedTitle(origin_items.size(), total_connection_count));
+ EXPECT_EQ(maybe_notification->message(),
+ GetExpectedMessage(origin_items));
+ EXPECT_EQ(maybe_notification->priority(), message_center::LOW_PRIORITY);
EXPECT_EQ(maybe_notification->rich_notification_data().buttons.size(),
1u);
EXPECT_EQ(maybe_notification->rich_notification_data().buttons[0].title,
- GetExpectedButtonTitleForProfile(profile));
+ u"HID settings");
EXPECT_TRUE(maybe_notification->delegate());
EXPECT_CALL(*hid_connection_tracker, ShowContentSettingsExceptions());
@@ -110,4 +153,21 @@
TEST_F(HidPinnedNotificationTest, ExtensionRemoval) {
TestExtensionRemoval();
}
+
+// Test message in pinned notification for up to 5 extensions.
+TEST_F(HidPinnedNotificationTest, MultipleExtensionsNotificationMessage) {
+ Profile* profile = CreateTestingProfile("user");
+ HidConnectionTracker* hid_connection_tracker =
+ HidConnectionTrackerFactory::GetForProfile(profile, /*create=*/true);
+
+ std::vector<HidSystemTrayIconTestBase::OriginItem> origin_items;
+ for (size_t idx = 0; idx < 5; idx++) {
+ auto extension =
+ CreateExtensionWithName(base::StringPrintf("Test Extension %zu", idx));
+ AddExtensionToProfile(profile, extension.get());
+ hid_connection_tracker->IncrementConnectionCount(extension.get()->origin());
+ origin_items.emplace_back(extension->origin(), 1, extension->name());
+ CheckIcon({{profile, origin_items}});
+ }
+}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/hid/hid_status_icon.cc b/chrome/browser/hid/hid_status_icon.cc
index 188079a..d59e2268f 100644
--- a/chrome/browser/hid/hid_status_icon.cc
+++ b/chrome/browser/hid/hid_status_icon.cc
@@ -120,17 +120,6 @@
}
}
-size_t HidStatusIcon::GetTotalConnectionCount() {
- size_t total_connection_count = 0;
- for (const auto& [profile, staging] : profiles_) {
- auto* hid_connection_tracker =
- HidConnectionTrackerFactory::GetForProfile(profile, /*create=*/false);
- DCHECK(hid_connection_tracker);
- total_connection_count += hid_connection_tracker->total_connection_count();
- }
- return total_connection_count;
-}
-
void HidStatusIcon::RefreshIcon() {
command_id_callbacks_.clear();
auto* status_tray = g_browser_process->status_tray();
@@ -152,9 +141,11 @@
// |... |
// |---------------Separator----------------------|
// |ProfileN section |
- auto title_label = GetTitleLabel(GetTotalConnectionCount());
auto menu = std::make_unique<StatusIconMenuModel>(this);
- menu->AddTitle(title_label);
+ int total_connection_count = 0;
+ int total_origin_count = 0;
+ // Title will be updated after looping through profiles below.
+ menu->AddTitle(u"");
AddItem(menu.get(), GetAboutDeviceLabel(),
base::BindRepeating(&HidStatusIcon::ShowHelpCenterUrl));
for (const auto& [profile, staging] : profiles_) {
@@ -174,14 +165,20 @@
auto* connection_tracker =
HidConnectionTrackerFactory::GetForProfile(profile, /*create=*/false);
CHECK(connection_tracker);
+ total_origin_count += connection_tracker->origins().size();
for (const auto& [origin, state] : connection_tracker->origins()) {
AddItem(menu.get(),
GetOriginConnectionCountLabel(profile, origin, state.count,
state.name),
base::BindRepeating(&HidStatusIcon::ShowSiteSettings,
profile->GetWeakPtr(), origin));
+ // Only consider the count that will be shown to the system tray icon, so
+ // that connection count on title and extension buttons can match.
+ total_connection_count += state.count;
}
}
+ auto title_label = GetTitleLabel(total_origin_count, total_connection_count);
+ menu->SetLabel(0, title_label);
if (!status_icon_) {
status_icon_ = status_tray->CreateStatusIcon(
diff --git a/chrome/browser/hid/hid_status_icon.h b/chrome/browser/hid/hid_status_icon.h
index a09fbfa..6d1701b 100644
--- a/chrome/browser/hid/hid_status_icon.h
+++ b/chrome/browser/hid/hid_status_icon.h
@@ -29,9 +29,6 @@
void ProfileAdded(Profile* profile) override;
void ProfileRemoved(Profile* profile) override;
- // Get the total connection count from all the profiles being tracked.
- size_t GetTotalConnectionCount();
-
// StatusIconMenuModel::Delegate
void ExecuteCommand(int command_id, int event_flags) override;
diff --git a/chrome/browser/hid/hid_status_icon_unittest.cc b/chrome/browser/hid/hid_status_icon_unittest.cc
index 13cf695..b52b084 100644
--- a/chrome/browser/hid/hid_status_icon_unittest.cc
+++ b/chrome/browser/hid/hid_status_icon_unittest.cc
@@ -21,6 +21,7 @@
#include "chrome/test/base/testing_profile_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/browser/extension_registry.h"
@@ -135,6 +136,7 @@
auto sorted_profile_connection_counts = profile_connection_counts;
base::ranges::sort(sorted_profile_connection_counts);
size_t total_connection_count = 0;
+ size_t total_origin_count = 0;
auto* menu_item = status_icon->menu_item();
// The system tray icon title (i.e menu_idx == 0) will be checked at the end
// when |total_connection_count| is calculated.
@@ -144,6 +146,7 @@
expected_command_id++, /*click=*/false);
for (const auto& [profile, origin_items] :
sorted_profile_connection_counts) {
+ total_origin_count += origin_items.size();
auto sorted_origin_items = origin_items;
// Sort the |origin_items| by origin. This is necessary because the origin
// items for each profile in the menu are created by iterating through a
@@ -168,7 +171,11 @@
total_connection_count += connection_count;
}
}
- CheckMenuItemLabel(menu_item, 0, GetExpectedTitle(total_connection_count));
+ CheckMenuItemLabel(
+ menu_item, 0,
+ GetExpectedTitle(total_origin_count,
+ override_title_total_connection_count_.value_or(
+ total_connection_count)));
EXPECT_LE(expected_command_id, IDC_DEVICE_SYSTEM_TRAY_ICON_LAST + 1);
}
@@ -178,6 +185,13 @@
ASSERT_TRUE(status_tray);
EXPECT_TRUE(status_tray->GetStatusIconsForTest().empty());
}
+
+ protected:
+ // This is specifically used in the test case of
+ // NumCommandIdOverLimitExtensionOrigin, where the input parameter
+ // profile_connection_counts may not capture all of the origins because the
+ // limit is exceeded.
+ absl::optional<int> override_title_total_connection_count_;
};
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -248,6 +262,8 @@
{profile, {{extension->origin(), 1, extension->name()}}});
base::ranges::sort(profile_connection_counts);
profile_connection_counts.back().second.clear();
+ // The total connection count in the title still captures all of the origins
+ override_title_total_connection_count_ = 20;
CheckIcon(profile_connection_counts);
}
}
diff --git a/chrome/browser/hid/hid_system_tray_icon.cc b/chrome/browser/hid/hid_system_tray_icon.cc
index 8ff5945..7607cfc 100644
--- a/chrome/browser/hid/hid_system_tray_icon.cc
+++ b/chrome/browser/hid/hid_system_tray_icon.cc
@@ -9,11 +9,13 @@
#include "base/containers/cxx20_erase.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/vector_icons/vector_icons.h"
#include "content/public/browser/browser_thread.h"
+#include "extensions/buildflags/buildflags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h"
@@ -24,23 +26,19 @@
}
// static
-std::u16string HidSystemTrayIcon::GetManageHidDeviceButtonLabel(
- Profile* profile) {
- std::u16string profile_name =
- base::UTF8ToUTF16(profile->GetProfileUserName());
- if (profile_name.empty()) {
- return l10n_util::GetStringUTF16(
- IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE);
+std::u16string HidSystemTrayIcon::GetTitleLabel(size_t num_origins,
+ size_t num_connections) {
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (num_origins == 1) {
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION,
+ static_cast<int>(num_connections));
}
- return l10n_util::GetStringFUTF16(
- IDS_WEBHID_SYSTEM_TRAY_ICON_BUTTON_FOR_MANAGE_HID_DEVICE_WITH_PROFILE_NAME,
- profile_name);
-}
-
-// static
-std::u16string HidSystemTrayIcon::GetTitleLabel(size_t num_connections) {
- return l10n_util::GetPluralStringFUTF16(IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE,
- static_cast<int>(num_connections));
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS,
+ static_cast<int>(num_connections));
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+ NOTREACHED_NORETURN();
}
// static
diff --git a/chrome/browser/hid/hid_system_tray_icon.h b/chrome/browser/hid/hid_system_tray_icon.h
index 1662aae..cdae557f 100644
--- a/chrome/browser/hid/hid_system_tray_icon.h
+++ b/chrome/browser/hid/hid_system_tray_icon.h
@@ -51,12 +51,9 @@
// Get the image for the status tray icon.
static gfx::ImageSkia GetStatusTrayIcon();
- // Get the label of the button for managing HID device permission on the HID
- // system tray icon.
- static std::u16string GetManageHidDeviceButtonLabel(Profile* profile);
-
// Get the label of the title of the HID system tray icon.
- static std::u16string GetTitleLabel(size_t num_connections);
+ static std::u16string GetTitleLabel(size_t num_origins,
+ size_t num_connections);
// Returns a label for HID settings button.
static std::u16string GetContentSettingsLabel();
diff --git a/chrome/browser/hid/hid_system_tray_icon_unittest.cc b/chrome/browser/hid/hid_system_tray_icon_unittest.cc
index f256ba4..071e52b 100644
--- a/chrome/browser/hid/hid_system_tray_icon_unittest.cc
+++ b/chrome/browser/hid/hid_system_tray_icon_unittest.cc
@@ -83,12 +83,22 @@
}
std::u16string HidSystemTrayIconTestBase::GetExpectedTitle(
+ size_t num_origins,
size_t num_connections) {
- // It might be either ""Chromium is accessing a HID device" or "Google Chrome
- // is accessing a HID device" depending is_chrome_branded in the build config
- // file, hence using l10n_util to get the expected string.
- return l10n_util::GetPluralStringFUTF16(IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE,
- static_cast<int>(num_connections));
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ // The text might use "Google Chrome" or "Chromium" depending
+ // is_chrome_branded in the build config file, hence using l10n_util to get
+ // the expected string.
+ if (num_origins == 1) {
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_SINGLE_EXTENSION,
+ static_cast<int>(num_connections));
+ }
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_WEBHID_SYSTEM_TRAY_ICON_TITLE_MULTIPLE_EXTENSIONS,
+ static_cast<int>(num_connections));
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+ NOTREACHED_NORETURN();
}
BrowserContextKeyedServiceFactory::TestingFactory
diff --git a/chrome/browser/hid/hid_system_tray_icon_unittest.h b/chrome/browser/hid/hid_system_tray_icon_unittest.h
index 3cc3001b..c84f4f7 100644
--- a/chrome/browser/hid/hid_system_tray_icon_unittest.h
+++ b/chrome/browser/hid/hid_system_tray_icon_unittest.h
@@ -42,7 +42,7 @@
virtual void CheckIconHidden() = 0;
std::u16string GetExpectedButtonTitleForProfile(Profile* profile);
- std::u16string GetExpectedTitle(size_t num_connections);
+ std::u16string GetExpectedTitle(size_t num_origins, size_t num_connections);
// This is used to inject MockHidConnectionTracker.
BrowserContextKeyedServiceFactory::TestingFactory