blob: 6a7450067e54af2d3835b03e254572c176b13db3 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_BROWSING_TOPICS_BROWSING_TOPICS_CALCULATOR_H_
#define COMPONENTS_BROWSING_TOPICS_BROWSING_TOPICS_CALCULATOR_H_
#include <map>
#include <set>
#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/browsing_topics/annotator.h"
#include "components/browsing_topics/common/common_types.h"
#include "components/browsing_topics/epoch_topics.h"
#include "components/history/core/browser/history_types.h"
namespace privacy_sandbox {
class PrivacySandboxSettings;
} // namespace privacy_sandbox
namespace history {
class HistoryService;
} // namespace history
namespace content {
class BrowsingTopicsSiteDataManager;
} // namespace content
namespace browsing_topics {
// Responsible for doing a one-off browsing topics calculation. It will:
// 1) Check the user settings for calculation permissions.
// 2) Query the `BrowsingTopicsSiteDataManager` for the contexts where the
// Topics API was called on.
// 3) Query the `HistoryService` for the hosts of the pages the API was called
// on.
// 4) Query the `Annotator` with a set of hosts, to get the corresponding
// topics.
// 5) Derive `EpochTopics` (i.e. the top topics and the their observed-by
// contexts), and return it as the final result.
class BrowsingTopicsCalculator {
public:
using CalculateCompletedCallback = base::OnceCallback<void(EpochTopics)>;
BrowsingTopicsCalculator(
privacy_sandbox::PrivacySandboxSettings* privacy_sandbox_settings,
history::HistoryService* history_service,
content::BrowsingTopicsSiteDataManager* site_data_manager,
Annotator* annotator,
const base::circular_deque<EpochTopics>& epochs,
bool is_manually_triggered,
int previous_timeout_count,
base::Time session_start_time,
CalculateCompletedCallback callback);
BrowsingTopicsCalculator(const BrowsingTopicsCalculator&) = delete;
BrowsingTopicsCalculator& operator=(const BrowsingTopicsCalculator&) = delete;
BrowsingTopicsCalculator(BrowsingTopicsCalculator&&) = delete;
BrowsingTopicsCalculator& operator=(BrowsingTopicsCalculator&&) = delete;
virtual ~BrowsingTopicsCalculator();
bool is_manually_triggered() const { return is_manually_triggered_; }
int previous_timeout_count() const { return previous_timeout_count_; }
protected:
// This method exists for the purposes of overriding in tests.
virtual uint64_t GenerateRandUint64();
virtual void CheckCanCalculate();
private:
enum class Progress {
kStarted,
kApiUsageRequested,
kHistoryRequested,
kModelRequested,
kAnnotationRequested,
kCompleted,
};
// Get the top `kBrowsingTopicsNumberOfTopTopicsPerEpoch` topics. If there
// aren't enough topics, pad with random ones. Return the result topics, and
// the starting index of the padded topics (or
// `kBrowsingTopicsNumberOfTopTopicsPerEpoch` if there's no padded topics),
// and the number of topics associated with `history_hosts_count`.
void DeriveTopTopics(
const std::map<HashedHost, size_t>& history_hosts_count,
const std::map<HashedHost, std::set<Topic>>& host_topics_map,
std::vector<Topic>& top_topics,
size_t& padded_top_topics_start_index,
size_t& history_topics_count);
void OnGetRecentBrowsingTopicsApiUsagesCompleted(
browsing_topics::ApiUsageContextQueryResult result);
void OnGetRecentlyVisitedURLsCompleted(history::QueryResults results);
void OnRequestModelCompleted(std::vector<std::string> raw_hosts);
void OnGetTopicsForHostsCompleted(const std::vector<Annotation>& results);
void OnCalculateCompleted(EpochTopics epoch_topics);
void OnCalculationHanging();
// Those pointers are safe to hold and use throughout the lifetime of
// `BrowsingTopicsService`, which owns this object.
raw_ptr<privacy_sandbox::PrivacySandboxSettings> privacy_sandbox_settings_;
raw_ptr<history::HistoryService> history_service_;
raw_ptr<content::BrowsingTopicsSiteDataManager> site_data_manager_;
raw_ptr<Annotator> annotator_;
CalculateCompletedCallback calculate_completed_callback_;
// The calculation start time.
base::Time calculation_time_;
base::Time history_data_start_time_;
base::Time api_usage_context_data_start_time_;
Progress progress_ = Progress::kStarted;
// The history hosts over
// `kBrowsingTopicsNumberOfEpochsOfObservationDataToUseForFiltering` epochs,
// and the calling context domains that used the Topics API in each main frame
// host.
std::map<HashedHost, std::vector<HashedDomain>> host_context_domains_map_;
// The hashed history hosts and their count over the last epoch.
std::map<HashedHost, size_t> history_hosts_count_;
// Used for the async tasks querying the HistoryService.
base::CancelableTaskTracker history_task_tracker_;
// Whether this calculator was generated via the topics-internals page rather
// than via a scheduled task.
bool is_manually_triggered_;
// The number of previous hanging calculations.
int previous_timeout_count_;
// The timeout timer for each async operation.
base::OneShotTimer timeout_timer_;
base::Time session_start_time_;
base::WeakPtrFactory<BrowsingTopicsCalculator> weak_ptr_factory_{this};
};
} // namespace browsing_topics
#endif // COMPONENTS_BROWSING_TOPICS_BROWSING_TOPICS_CALCULATOR_H_