blob: 3e524b7621eed769f5d00914de327065e9400ea1 [file] [log] [blame]
// Copyright 2025 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_SAFE_BROWSING_NOTIFICATION_TELEMETRY_NOTIFICATION_TELEMETRY_SERVICE_H_
#define CHROME_BROWSER_SAFE_BROWSING_NOTIFICATION_TELEMETRY_NOTIFICATION_TELEMETRY_SERVICE_H_
#include <stdint.h>
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "chrome/browser/safe_browsing/notification_telemetry/notification_telemetry_store.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/safe_browsing/content/browser/ui_manager.h"
#include "components/safe_browsing/core/browser/db/database_manager.h"
#include "content/public/browser/service_worker_context_observer.h"
class Profile;
namespace content {
class ServiceWorkerContext;
struct ServiceWorkerRegistrationInformation;
} // namespace content
namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
} // namespace network
namespace safe_browsing {
struct ServiceWorkerTelemetryInfo {
ServiceWorkerTelemetryInfo() noexcept;
ServiceWorkerTelemetryInfo(const ServiceWorkerTelemetryInfo& other) noexcept;
~ServiceWorkerTelemetryInfo();
// The Registration ID assigned to the service worker
int64_t registration_id = 0;
// The scope url for the service worker
GURL scope;
// A vector of URLs that have been used to import service worker resources
std::vector<GURL> resources;
};
// This service tracks and reports telemetry regarding user notifications. It
// sends data directly to the Chrome Incident Reporting backend without using
// the normal incident reporting workflow.
class NotificationTelemetryService
: public content::ServiceWorkerContextObserver,
public KeyedService {
public:
// Convenience method to get the service for a profile.
static NotificationTelemetryService* Get(Profile* profile);
explicit NotificationTelemetryService(
Profile* profile,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
std::unique_ptr<NotificationTelemetryStoreInterface> telemetry_store,
scoped_refptr<SafeBrowsingUIManager> ui_manager);
explicit NotificationTelemetryService(const NotificationTelemetryService&) =
delete;
NotificationTelemetryService& operator=(const NotificationTelemetryService&) =
delete;
~NotificationTelemetryService() override;
// ServiceWorkerContextObserver:
void OnRegistrationStored(int64_t registration_id,
const GURL& scope,
const content::ServiceWorkerRegistrationInformation&
service_worker_registration_info) override;
void OnPushEventFinished(
const GURL& script_url,
const std::optional<std::vector<GURL>>& requested_urls) override;
void OnGetServiceWorkerBehaviors(
bool success,
std::unique_ptr<std::vector<CSBRR::ServiceWorkerBehavior>> entries);
static int ServiceWorkerInfoCacheSizeForTest();
NotificationTelemetryStoreInterface* GetTelemetryStoreForTest();
int GetEmptyDbFoundCountForTest();
private:
FRIEND_TEST_ALL_PREFIXES(NotificationTelemetryServiceTest,
OnGetServiceWorkerBehaviors);
FRIEND_TEST_ALL_PREFIXES(NotificationTelemetryServiceTest,
SendsTelemetryReport);
FRIEND_TEST_ALL_PREFIXES(NotificationTelemetryServiceTest,
EnforcesServiceWorkerInfoCacheSize);
FRIEND_TEST_ALL_PREFIXES(
NotificationTelemetryServiceTest,
ServiceWorkerSubscriptionRecordsServiceWorkerBehavior);
// TODO(crbug.com/433543634): Clean up post
// GlobalCacheListForGatingNotificationProtections launch.
FRIEND_TEST_ALL_PREFIXES(
NotificationTelemetryServiceFactoryTest,
CreatedWithoutDatabaseManagerWhenGlobalCacheListEnabled);
FRIEND_TEST_ALL_PREFIXES(
NotificationTelemetryServiceFactoryTest,
CreatedWithDatabaseManagerWhenGlobalCacheListDisabled);
// Callback used for checking the Safe Browsing allowlist.
void DatabaseCheckDone(
ServiceWorkerTelemetryInfo service_worker_info,
bool allowlisted,
std::optional<SafeBrowsingDatabaseManager::
HighConfidenceAllowlistCheckLoggingDetails>
logging_details);
// Store the service work info if the scope URL is not allowlisted.
void MaybeStoreServiceWorkerInfo(
ServiceWorkerTelemetryInfo service_worker_info,
bool allowlisted);
// Used for logging after an upload.
void UploadComplete(std::unique_ptr<std::string> response_body);
// Check if a notifications service worker ID matches any of the stored
// service worker origins.
void OnNewNotificationServiceWorkerSubscription(int64_t registration_id);
// Returns the URL to which telemetry reports are to be sent.
static GURL GetTelemetryReportUrl();
// Attempts to upload a CSBRR report.
void MaybeUploadReport();
// Called after the NotificationTelemetryStore has deleted all data because
// the user is no longer an ESB user.
void OnTelemetryStoreDeleted(bool success);
// Called after a new ServiceWorkerBehavior has been added to storage.
void OnAddServiceWorkerBehavior(bool success);
// Stored service worker info whose size is based on
// `kNotificationTelemetryServiceWorkerInfoMaxCount`
std::vector<ServiceWorkerTelemetryInfo> service_worker_infos_;
// Accessor for an URLLoaderFactory with which reports will be sent.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
// TODO(crbug.com/433543634): Remove `database_manager_` post
// GlobalCacheListForGatingNotificationProtections launch.
// Used to preform the Safe Browsing allowlist lookup.
scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
// Responsible for storing the ServiceWorkerBehaviors.
std::unique_ptr<NotificationTelemetryStoreInterface> telemetry_store_;
// Responsible for sending the CSBRRs.
scoped_refptr<SafeBrowsingUIManager> ui_manager_;
raw_ptr<Profile> profile_;
raw_ptr<content::ServiceWorkerContext> service_worker_context_ = nullptr;
// Tracks how many consecutive times an empty database was encountered.
int empty_db_found_count_ = 0;
// Used to periodically attempt to send a report to Safe Browsing.
base::RepeatingTimer timer_;
base::WeakPtrFactory<NotificationTelemetryService> weak_factory_{this};
};
} // namespace safe_browsing
#endif // CHROME_BROWSER_SAFE_BROWSING_NOTIFICATION_TELEMETRY_NOTIFICATION_TELEMETRY_SERVICE_H_