blob: 287f6b66a0172d0fcf4ebe0b7be104ff1f461a59 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_SAFETY_HUB_MENU_NOTIFICATION_SERVICE_H_
#define CHROME_BROWSER_UI_SAFETY_HUB_MENU_NOTIFICATION_SERVICE_H_
#include <list>
#include <map>
#include <memory>
#include <optional>
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/ui/safety_hub/menu_notification.h"
#include "chrome/browser/ui/safety_hub/notification_permission_review_service.h"
#include "chrome/browser/ui/safety_hub/revoked_permissions_service.h"
#include "chrome/browser/ui/safety_hub/safety_hub_constants.h"
#include "chrome/browser/ui/safety_hub/safety_hub_result.h"
#include "components/keyed_service/core/keyed_service.h"
#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/extensions/cws_info_service.h"
#include "chrome/browser/ui/safety_hub/password_status_check_service.h"
#endif // BUILDFLAG(IS_ANDROID)
struct MenuNotificationEntry {
int command = 0;
std::u16string label;
safety_hub::SafetyHubModuleType module;
};
namespace {
enum MenuNotificationPriority {
LOW = 0,
MEDIUM,
HIGH,
};
struct SafetyHubModuleInfoElement {
SafetyHubModuleInfoElement();
~SafetyHubModuleInfoElement();
SafetyHubModuleInfoElement(
MenuNotificationPriority priority,
base::TimeDelta interval,
base::RepeatingCallback<std::optional<std::unique_ptr<SafetyHubResult>>()>
result_getter,
std::unique_ptr<SafetyHubMenuNotification> notification);
MenuNotificationPriority priority;
base::TimeDelta interval;
base::RepeatingCallback<std::optional<std::unique_ptr<SafetyHubResult>>()>
result_getter;
std::unique_ptr<SafetyHubMenuNotification> notification;
};
using ResultMap =
std::map<safety_hub::SafetyHubModuleType, std::unique_ptr<SafetyHubResult>>;
} // namespace
// This class manages the notifications that should be shown when a user opens
// the three-dot menu. It will collect the latest results from all the Safety
// Hub service and subsequently update the notifications. Based on priority and
// prior showing of notification, it will determine which notification that
// should be shown.
class SafetyHubMenuNotificationService : public KeyedService {
public:
explicit SafetyHubMenuNotificationService(
PrefService* pref_service,
RevokedPermissionsService* revoked_permissions_service,
NotificationPermissionsReviewService* notification_permissions_service,
#if !BUILDFLAG(IS_ANDROID)
PasswordStatusCheckService* password_check_service,
#endif // BUILDFLAG(IS_ANDROID)
Profile* profile);
SafetyHubMenuNotificationService(const SafetyHubMenuNotificationService&) =
delete;
SafetyHubMenuNotificationService& operator=(
const SafetyHubMenuNotificationService&) = delete;
~SafetyHubMenuNotificationService() override;
// Returns the CommandID and notification string that should be shown in the
// three-dot menu. When no notification should be shown, std::nullopt will be
// returned.
std::optional<MenuNotificationEntry> GetNotificationToShow();
// Dismisses all the active menu notifications.
void DismissActiveNotification();
// Dismisses the active menu notification of the specified module.
void DismissActiveNotificationOfModule(
safety_hub::SafetyHubModuleType module);
void UpdateResultGetterForTesting(
safety_hub::SafetyHubModuleType type,
base::RepeatingCallback<std::optional<std::unique_ptr<SafetyHubResult>>()>
result_getter);
private:
// Gets the latest result from each Safety Hub service. Will return
// std::nullopt when there is no result from one of the services.
std::optional<ResultMap> GetResultsFromAllModules();
// Stores the notifications (which should have their results updated) as a
// dict in the prefs.
void SaveNotificationsToPrefs() const;
// Creates a notification from the provided dictionary, for the specified
// Safety Hub service type.
std::unique_ptr<SafetyHubMenuNotification> GetNotificationFromDict(
const base::Value::Dict& dict,
safety_hub::SafetyHubModuleType& type) const;
// Sets the relevant, static meta information for the three-dot menu
// (priority, interval, and method to retrieve the relevant result) for a
// specific type of Safety Hub module provided the dictionary that stores the
// notifications.
void SetInfoElement(
safety_hub::SafetyHubModuleType type,
MenuNotificationPriority priority,
base::TimeDelta interval,
base::RepeatingCallback<std::optional<std::unique_ptr<SafetyHubResult>>()>
result_getter,
const base::Value::Dict& stored_notifications);
// Called when the pref for Safe Browsing has been updated.
void OnSafeBrowsingPrefUpdate();
// Returns if any safety hub notification has been shown in the menu so far.
bool HasAnyNotificationBeenShown() const;
// Holds the mapping from module type to pref name.
std::map<safety_hub::SafetyHubModuleType, const char*> pref_dict_key_map_;
// Preference service that persists the notifications.
raw_ptr<PrefService> pref_service_;
// A map that captures the meta information about menu notifications for each
// Safety Hub module.
std::map<safety_hub::SafetyHubModuleType,
std::unique_ptr<SafetyHubModuleInfoElement>>
module_info_map_;
// Registrar to record the pref changes to Safe Browsing.
PrefChangeRegistrar registrar_;
};
#endif // CHROME_BROWSER_UI_SAFETY_HUB_MENU_NOTIFICATION_SERVICE_H_