blob: e55c6efd2e7f6944c0860f28cd33745d40e628da [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_CONTEXTUAL_CUEING_CONTEXTUAL_CUEING_PAGE_DATA_H_
#define CHROME_BROWSER_CONTEXTUAL_CUEING_CONTEXTUAL_CUEING_PAGE_DATA_H_
#include "base/types/expected.h"
#include "chrome/browser/contextual_cueing/contextual_cueing_enums.h"
#include "components/optimization_guide/proto/contextual_cueing_metadata.pb.h"
#include "components/optimization_guide/proto/features/common_quality_data.pb.h"
#include "components/pdf/common/constants.h"
#include "content/public/browser/page_user_data.h"
#include "pdf/buildflags.h"
#include "pdf/mojom/pdf.mojom.h"
namespace contextual_cueing {
// Decider for contextual cueing that is scoped to `Page`.
class ContextualCueingPageData
: public content::PageUserData<ContextualCueingPageData> {
public:
using CueingDecisionCallback =
base::OnceCallback<void(base::expected<std::string, NudgeDecision>)>;
ContextualCueingPageData(const ContextualCueingPageData&) = delete;
ContextualCueingPageData& operator=(const ContextualCueingPageData&) = delete;
~ContextualCueingPageData() override;
void OnPageContentExtracted(
const optimization_guide::proto::AnnotatedPageContent& page_content);
private:
friend class content::PageUserData<ContextualCueingPageData>;
friend class ContextualCueingPageDataTest;
// Holds the cueing condition decision for one cueing configuration.
enum CueingConfigurationDecision {
kAllowed,
kDisallowed,
kNeedsPdfPageCount,
kNeedsPageContent,
};
// Holds the info related to word count client signal.
struct WordCountInfo {
// Maximum word count needed for the cueing conditions. This limits
// iterating through the page content more than needed.
size_t max_count_needed = 0;
// Count of words calculated from the page content. This is always less than
// or equal to `max_count_needed`. When the page count is more than the
// limit, the counting is stopped at the limit.
std::optional<size_t> page_contents_words;
};
ContextualCueingPageData(
content::Page& page,
optimization_guide::proto::GlicContextualCueingMetadata metadata,
CueingDecisionCallback cueing_decision_callback);
// Finds the matching config that passes all the conditions. Requests and
// waits for any client-signals when needed.
void FindMatchingConfig();
// Returns whether the `config` matches all the current cueing condition.
CueingConfigurationDecision DidMatchCueingConditions(
const optimization_guide::proto::GlicCueingConfiguration& config);
#if BUILDFLAG(ENABLE_PDF)
// Requests for page count if this is a PDF page.
void RequestPdfPageCount();
// Invoked when PDF document is loaded, so that the metadata can be queried.
void OnPdfDocumentLoadComplete();
// Invoked when page count is received.
void OnPdfPageCountReceived(pdf::mojom::PdfListener::GetPdfBytesStatus status,
const std::vector<uint8_t>& bytes,
uint32_t page_count);
#endif // BUILDFLAG(ENABLE_PDF)
const optimization_guide::proto::GlicContextualCueingMetadata metadata_;
// Holds the page count of PDF. Populated only when the mainframe of the page
// has a PDF renderer, and the page count has been successfully retrieved from
// it.
std::optional<size_t> pdf_page_count_;
// Holds the word count info. Populated only when word count signal is
// required for making the cueing decision.
std::optional<WordCountInfo> page_content_word_count_info_;
CueingDecisionCallback cueing_decision_callback_;
base::WeakPtrFactory<ContextualCueingPageData> weak_factory_{this};
PAGE_USER_DATA_KEY_DECL();
};
} // namespace contextual_cueing
#endif // CHROME_BROWSER_CONTEXTUAL_CUEING_CONTEXTUAL_CUEING_PAGE_DATA_H_