text: // Copyright 2021 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/ash/notifications/deprecation_notification_controller.h"
  
  #include <string>
  
  #include "ash/public/cpp/notification_utils.h"
  #include "ash/resources/vector_icons/vector_icons.h"
  #include "ash/session/session_controller_impl.h"
  #include "ash/shell.h"
  #include "ash/shell_delegate.h"
  #include "ash/strings/grit/ash_strings.h"
  #include "base/strings/string_number_conversions.h"
  #include "base/strings/utf_string_conversions.h"
  #include "ui/base/l10n/l10n_util.h"
  #include "ui/chromeos/events/keyboard_layout_util.h"
  #include "ui/message_center/message_center.h"
  #include "ui/message_center/public/cpp/notification.h"
  #include "ui/message_center/public/cpp/notification_types.h"
  
  namespace ash {
  
  namespace {
  
  const char kNotifierId[] = "event_rewriter_deprecation_controller";
  const char kNotificationIdPrefix[] = "alt_event_rewrite_deprecation.";
  
  }  // namespace
  
  DeprecationNotificationController::DeprecationNotificationController(
      message_center::MessageCenter* message_center)
      : message_center_(message_center) {
    DCHECK(message_center_);
  }
  
  DeprecationNotificationController::~DeprecationNotificationController() =
      default;
  
  bool DeprecationNotificationController::NotifyDeprecatedRightClickRewrite() {
    if (right_click_notification_shown_) {
      return false;
    }
  
    const std::string id = std::string(kNotificationIdPrefix) + "right_click";
    ShowNotificationFromIdWithLauncherKey(id,
                                          IDS_ASH_SHORTCUT_DEPRECATION_ALT_CLICK);
  
    // Don't show the notification again.
    right_click_notification_shown_ = true;
    return true;
  }
  
  bool DeprecationNotificationController::NotifyDeprecatedFKeyRewrite() {
    if (fkey_notification_shown_) {
      return false;
    }
  
    const std::string id = std::string(kNotificationIdPrefix) + "fkey";
    ShowNotificationFromIdWithLauncherKey(id, IDS_ASH_SHORTCUT_DEPRECATION_FKEY);
  
    // Don't show the notification again.
    fkey_notification_shown_ = true;
    return true;
  }
  
  bool DeprecationNotificationController::NotifyDeprecatedSixPackKeyRewrite(
      ui::KeyboardCode key_code) {
    if (!ShouldShowSixPackKeyDeprecationNotification(key_code)) {
      return false;
    }
  
    // The notification id is not user visible.
    const std::string id =
        std::string(kNotificationIdPrefix) + base::NumberToString(key_code);
    const int message_id = GetSixPackKeyDeprecationMessageId(key_code);
    ShowNotificationFromIdWithLauncherKey(id, message_id);
  
    // Keep track that the notification was shown to decide whether to show it
    // again in future.
    RecordSixPackKeyDeprecationNotificationShown(key_code);
    return true;
  }
  
  void DeprecationNotificationController::ResetStateForTesting() {
    shown_key_notifications_.clear();
    right_click_notification_shown_ = false;
    fkey_notification_shown_ = false;
  }
  
  void DeprecationNotificationController::ShowNotificationFromIdWithLauncherKey(
      const std::string& id,
      int message_id) {
    const int launcher_key_name_id = ui::DeviceUsesKeyboardLayout2()
                                         ? IDS_ASH_SHORTCUT_MODIFIER_LAUNCHER
                                         : IDS_ASH_SHORTCUT_MODIFIER_SEARCH;
    const std::u16string launcher_key_name =
        l10n_util::GetStringUTF16(launcher_key_name_id);
    const std::u16string message_body =
        l10n_util::GetStringFUTF16(message_id, launcher_key_name);
  
    ShowNotification(id, message_body);
  }
  
  void DeprecationNotificationController::ShowNotification(
      const std::string& id,
      const std::u16string& message_body) {
    auto on_click_handler =
        base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
            base::BindRepeating([]() {
              if (!Shell::Get()->session_controller()->IsUserSessionBlocked())
                Shell::Get()->shell_delegate()->OpenKeyboardShortcutHelpPage();
            }));
  
    auto notification = CreateSystemNotification(
        message_center::NOTIFICATION_TYPE_SIMPLE, id,
        l10n_util::GetStringUTF16(IDS_DEPRECATED_SHORTCUT_TITLE), message_body,
        std::u16string(), GURL(),
        message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
                                   kNotifierId),
        message_center::RichNotificationData(), std::move(on_click_handler),
        kNotificationKeyboardIcon,
        message_center::SystemNotificationWarningLevel::NORMAL);
    message_center_->AddNotification(std::move(notification));
  }
  
  bool DeprecationNotificationController::
      ShouldShowSixPackKeyDeprecationNotification(ui::KeyboardCode key_code) {
    return !shown_key_notifications_.contains(key_code);
  }
  
  void DeprecationNotificationController::
      RecordSixPackKeyDeprecationNotificationShown(ui::KeyboardCode key_code) {
    DCHECK(!shown_key_notifications_.contains(key_code));
    shown_key_notifications_.insert(key_code);
  }
  
  int DeprecationNotificationController::GetSixPackKeyDeprecationMessageId(
      ui::KeyboardCode key_code) {
    switch (key_code) {
      case ui::VKEY_DELETE:
        return IDS_ASH_SHORTCUT_DEPRECATION_ALT_BASED_DELETE;
      case ui::VKEY_INSERT:
        return IDS_ASH_SHORTCUT_DEPRECATION_SEARCH_PERIOD_INSERT;
      case ui::VKEY_HOME:
        return IDS_ASH_SHORTCUT_DEPRECATION_ALT_BASED_HOME;
      case ui::VKEY_END:
        return IDS_ASH_SHORTCUT_DEPRECATION_ALT_BASED_END;
      case ui::VKEY_PRIOR:
        return IDS_ASH_SHORTCUT_DEPRECATION_ALT_BASED_PAGE_UP;
      case ui::VKEY_NEXT:
        return IDS_ASH_SHORTCUT_DEPRECATION_ALT_BASED_PAGE_DOWN;
      default:
        NOTREACHED();
        return -1;
    }
  }
  
  }  // namespace ash
  