1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
// 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_ZERO_STATE_SUGGESTIONS_PAGE_DATA_H_
#define CHROME_BROWSER_CONTEXTUAL_CUEING_ZERO_STATE_SUGGESTIONS_PAGE_DATA_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/time/time.h"
#include "chrome/browser/contextual_cueing/zero_state_suggestions_request.h"
#include "components/optimization_guide/content/browser/page_content_proto_provider.h"
#include "components/optimization_guide/core/hints/optimization_guide_decision.h"
#include "components/optimization_guide/core/hints/optimization_metadata.h"
#include "components/optimization_guide/core/optimization_guide_model_executor.h"
#include "content/public/browser/page_user_data.h"
class OptimizationGuideKeyedService;
namespace content_extraction {
struct InnerTextResult;
} // namespace content_extraction
namespace optimization_guide {
class PageContextEligibility;
namespace proto {
class ZeroStatePageContext;
} // namespace proto
} // namespace optimization_guide
namespace page_content_annotations {
class PageContentExtractionService;
} // namespace page_content_annotations
namespace contextual_cueing {
using PageContextCallbackList = base::OnceCallbackList<void(
std::optional<optimization_guide::proto::ZeroStatePageContext>)>;
using PageContextCallback = PageContextCallbackList::CallbackType;
// Processes necessary information about the page to generate zero state
// suggestions.
class ZeroStateSuggestionsPageData
: public content::PageUserData<ZeroStateSuggestionsPageData> {
public:
ZeroStateSuggestionsPageData(const ZeroStateSuggestionsPageData&) = delete;
ZeroStateSuggestionsPageData& operator=(const ZeroStateSuggestionsPageData&) =
delete;
~ZeroStateSuggestionsPageData() override;
// Initiates page content extraction.
void InitiatePageContentExtraction();
// Gets the page context for this page. Will return synchronously if page
// context is already ready.
void GetPageContext(PageContextCallback callback);
void set_cached_suggestions_for_focused_tab(
std::optional<std::vector<std::string>>
cached_suggestions_for_focused_tab) {
cached_suggestions_for_focused_tab_ = cached_suggestions_for_focused_tab;
}
std::optional<std::vector<std::string>> cached_suggestions_for_focused_tab()
const {
return cached_suggestions_for_focused_tab_;
}
void set_focused_tab_request(
std::unique_ptr<ZeroStateSuggestionsRequest> focused_tab_request) {
focused_tab_request_ = std::move(focused_tab_request);
}
ZeroStateSuggestionsRequest* focused_tab_request() {
return focused_tab_request_.get();
}
base::WeakPtr<ZeroStateSuggestionsPageData> AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void set_is_focused_tab(bool is_focused) { is_focused_ = is_focused; }
private:
friend class content::PageUserData<ZeroStateSuggestionsPageData>;
friend class ContextualCueingServiceTestZeroStateSuggestions;
friend class ZeroStateSuggestionsPageDataTest;
// Note that this constructor initiates extracting page content.
explicit ZeroStateSuggestionsPageData(content::Page& page);
// Returns the URL of the primary main frame associated with this page.
const GURL GetUrl() const;
// Called when inner text is extracted.
void OnReceivedInnerText(
std::unique_ptr<content_extraction::InnerTextResult> result);
// Called when annotated page content is received.
void OnReceivedAnnotatedPageContent(
std::optional<optimization_guide::proto::AnnotatedPageContent> content);
// Called when on-demand metadata is received.
void OnReceivedOptimizationMetadataOnDemand(
const GURL& url,
const base::flat_map<
optimization_guide::proto::OptimizationType,
optimization_guide::OptimizationGuideDecisionWithMetadata>&
decisions);
// Called when optimization metadata is received.
void OnReceivedOptimizationMetadata(
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata);
// Give up on extracting page content and signal no result.
void GiveUp();
// Notifies all page context callbacks that page context has been collected
// for the page.
void InvokePageContextCallbacksIfComplete();
// If `optimization_metadata_` contains everything necessary to determine a
// suggestions result, run `suggestions_callbacks_` to return those
// suggestions. This method itself also returns true if suggestions are sent
// via the callbacks as a result of execution.
bool ReturnSuggestionsFromOptimizationMetadataIfPossible();
bool work_done() const {
return inner_text_done_ && annotated_page_content_done_ &&
optimization_metadata_done_;
}
// Returns the page context collected for this page.
optimization_guide::proto::ZeroStatePageContext ConstructPageContextProto()
const;
void OnPageContextEligibilityAPILoaded(
optimization_guide::PageContextEligibility* page_context_eligibility);
// Tracks the status of page context needed to fetch suggestions:
// 1. inner text
// 2. annotated page content
// 3. optimization metadata
bool content_extraction_initiated_ = false;
base::TimeTicks page_context_begin_time_;
// Tracks if `this` has logged to page context extraction duration histogram.
bool page_context_duration_logged_ = false;
bool inner_text_done_ = false;
std::unique_ptr<content_extraction::InnerTextResult> inner_text_result_;
bool annotated_page_content_done_ = false;
std::optional<optimization_guide::proto::AnnotatedPageContent>
annotated_page_content_;
bool optimization_metadata_done_ = false;
optimization_guide::OptimizationGuideDecision optimization_decision_;
optimization_guide::OptimizationMetadata optimization_metadata_;
// The suggestions that were computed for this page when suggestions were
// requested for the focused tab.
std::optional<std::vector<std::string>> cached_suggestions_for_focused_tab_;
std::unique_ptr<ZeroStateSuggestionsRequest> focused_tab_request_;
// Tracks the state for a page context request.
PageContextCallbackList page_context_callbacks_;
bool timeout_scheduled_ = false;
bool is_focused_ = false;
// Not owned and guaranteed to outlive `this`.
raw_ptr<optimization_guide::PageContextEligibility> page_context_eligibility_;
raw_ptr<OptimizationGuideKeyedService> optimization_guide_keyed_service_ =
nullptr;
raw_ptr<page_content_annotations::PageContentExtractionService>
page_content_extraction_service_ = nullptr;
base::WeakPtrFactory<ZeroStateSuggestionsPageData> weak_ptr_factory_{this};
PAGE_USER_DATA_KEY_DECL();
};
} // namespace contextual_cueing
#endif // CHROME_BROWSER_CONTEXTUAL_CUEING_ZERO_STATE_SUGGESTIONS_PAGE_DATA_H_
|