blob: c631c945397da4f04bc6321f82cddd4c893cdf28 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/caps_lock_notification_controller.h"
#include "ash/accessibility/accessibility_controller.h"
#include "ash/constants/notifier_catalogs.h"
#include "ash/public/cpp/notification_utils.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/input_device_settings/input_device_settings_controller_impl.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/unified/unified_system_tray.h"
#include "ash/system/unified/unified_system_tray_model.h"
#include "base/metrics/user_metrics.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/ash/mojom/modifier_key.mojom.h"
#include "ui/events/ash/pref_names.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/notification.h"
using message_center::MessageCenter;
using message_center::Notification;
using SystemTrayButtonSize = ash::UnifiedSystemTrayModel::SystemTrayButtonSize;
namespace ash {
namespace {
const char kCapsLockNotificationId[] = "capslock";
const char kNotifierCapsLock[] = "ash.caps-lock";
int GetMessageStringId() {
const ash::mojom::Keyboard* keyboard =
Shell::Get()
->input_device_settings_controller()
->GetGeneralizedKeyboard();
if (keyboard != nullptr) {
// If the keyboard has function key, return function key message id.
if (std::ranges::find(keyboard->modifier_keys,
ui::mojom::ModifierKey::kFunction) !=
keyboard->modifier_keys.end()) {
return IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_FN_QUICK_INSERT;
}
// If the search key is remapped to kCapsLock, return search key message id.
auto iter = keyboard->settings->modifier_remappings.find(
ui::mojom::ModifierKey::kMeta);
if (iter != keyboard->settings->modifier_remappings.end() &&
iter->second == ui::mojom::ModifierKey::kCapsLock) {
return IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_SEARCH;
}
}
// Otherwise return alt search key message id.
return IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_ALT_SEARCH;
}
std::unique_ptr<Notification> CreateNotification() {
const gfx::VectorIcon& capslock_icon =
features::IsModifierSplitEnabled()
? kModifierSplitNotificationCapslockIcon
: kNotificationCapslockIcon;
std::unique_ptr<Notification> notification = ash::CreateSystemNotificationPtr(
message_center::NOTIFICATION_TYPE_SIMPLE, kCapsLockNotificationId,
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAPS_LOCK_ENABLED),
l10n_util::GetStringUTF16(GetMessageStringId()),
std::u16string() /* display_source */, GURL(),
message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
kNotifierCapsLock,
NotificationCatalogName::kCapsLock),
message_center::RichNotificationData(), nullptr, capslock_icon,
message_center::SystemNotificationWarningLevel::NORMAL);
notification->set_pinned(true);
SystemTrayButtonSize primary_tray_button_size =
Shell::GetPrimaryRootWindowController()
->GetStatusAreaWidget()
->unified_system_tray()
->model()
->GetSystemTrayButtonSize();
// Set the priority to low to prevent the notification showing as a popup in
// medium or large size tray button because we already show an icon in tray
// for this in the feature.
if (primary_tray_button_size != SystemTrayButtonSize::kSmall) {
notification->set_priority(message_center::LOW_PRIORITY);
}
return notification;
}
} // namespace
CapsLockNotificationController::CapsLockNotificationController() {
Shell::Get()->ime_controller()->AddObserver(this);
}
CapsLockNotificationController::~CapsLockNotificationController() {
Shell::Get()->ime_controller()->RemoveObserver(this);
}
void CapsLockNotificationController::OnCapsLockChanged(bool enabled) {
// Send an a11y alert.
Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert(
enabled ? AccessibilityAlert::CAPS_ON : AccessibilityAlert::CAPS_OFF);
if (enabled) {
base::RecordAction(base::UserMetricsAction("StatusArea_CapsLock_Popup"));
MessageCenter::Get()->AddNotification(CreateNotification());
} else {
MessageCenter::Get()->RemoveNotification(kCapsLockNotificationId, false);
}
}
} // namespace ash