#ifndef CHROME_BROWSER_UI_CONTEXTUAL_SEARCH_TAB_CONTEXTUALIZATION_CONTROLLER_H_
#define CHROME_BROWSER_UI_CONTEXTUAL_SEARCH_TAB_CONTEXTUALIZATION_CONTROLLER_H_
#include <memory>
#include <optional>
#include "base/callback_list.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/task_runner.h"
#include "components/lens/contextual_input.h"
#include "components/lens/lens_bitmap_processing.h"
#include "components/optimization_guide/content/browser/page_content_proto_provider.h"
#include "components/tabs/public/tab_interface.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "pdf/buildflags.h"
#include "ui/base/unowned_user_data/scoped_unowned_user_data.h"
#if BUILDFLAG(ENABLE_PDF)
#include "components/pdf/browser/pdf_document_helper.h"
#include "pdf/mojom/pdf.mojom.h"
#endif
namespace viz {
struct CopyOutputBitmapWithMetadata;
}
namespace optimization_guide {
class PageContextEligibility;
}
namespace lens {
class TabContextualizationController : public content::WebContentsObserver {
public:
explicit TabContextualizationController(tabs::TabInterface* tab);
~TabContextualizationController() override;
DECLARE_USER_DATA(TabContextualizationController);
static TabContextualizationController* From(tabs::TabInterface* tab);
using GetPageContextCallback = base::OnceCallback<void(
std::unique_ptr<lens::ContextualInputData> page_content_data)>;
using GetApcResultCallback = base::OnceCallback<void(
bool page_context_eligible,
optimization_guide::AIPageContentResultOrError apc)>;
using GetAnnotatedPageContentCallback =
optimization_guide::OnAIPageContentDone;
using CaptureScreenshotCallback = base::OnceCallback<void(const SkBitmap&)>;
bool GetInitialPageContextEligibility();
bool GetCurrentPageContextEligibility();
virtual void GetPageContext(GetPageContextCallback callback);
void OnEligibilityChecked(bool is_page_context_eligible,
optimization_guide::AIPageContentResultOrError apc);
void UpdatePageContextEligibility(GetApcResultCallback callback);
virtual void CaptureScreenshot(
std::optional<lens::ImageEncodingOptions> image_options,
CaptureScreenshotCallback callback);
private:
void CreatePageContextEligibilityAPI();
void OnPageContextEligibilityAPILoaded(
optimization_guide::PageContextEligibility* page_context_eligibility);
void PrimaryPageChanged(content::Page& page) override;
void WillDiscardContents(tabs::TabInterface* tab,
content::WebContents* old_contents,
content::WebContents* new_contents);
void GetAnnotatedPageContent(GetAnnotatedPageContentCallback callback);
void OnAnnotatedPageContentReceived(
GetApcResultCallback callback,
optimization_guide::AIPageContentResultOrError result);
void OnApcAndEligibilityReceivedForGetPageContext(
GetPageContextCallback callback,
std::unique_ptr<lens::ContextualInputData> data,
bool page_context_eligible,
optimization_guide::AIPageContentResultOrError result);
#if BUILDFLAG(ENABLE_PDF)
void OnPdfBytesReceived(std::unique_ptr<lens::ContextualInputData> data,
GetPageContextCallback callback,
pdf::mojom::PdfListener::GetPdfBytesStatus status,
const std::vector<uint8_t>& bytes,
uint32_t page_count);
void OnPdfPageIndexReceived(std::unique_ptr<lens::ContextualInputData> data,
GetPageContextCallback callback,
std::optional<uint32_t> page_index);
#endif
void DownscaleScreenshotAndContinue(
base::ScopedClosureRunner decrement_capturer_count_runner,
std::optional<lens::ImageEncodingOptions> image_options,
CaptureScreenshotCallback callback,
const viz::CopyOutputBitmapWithMetadata& result);
void AddScreenshotToContextDataAndContinue(
GetPageContextCallback callback,
std::unique_ptr<lens::ContextualInputData> data,
const SkBitmap& screenshot);
raw_ptr<optimization_guide::PageContextEligibility>
page_context_eligibility_ = nullptr;
::ui::ScopedUnownedUserData<TabContextualizationController>
scoped_unowned_user_data_;
const raw_ptr<tabs::TabInterface> tab_;
base::CallbackListSubscription tab_subscription_;
scoped_refptr<base::TaskRunner> screenshot_task_runner_;
bool is_page_context_eligible_ = false;
base::WeakPtrFactory<TabContextualizationController> weak_ptr_factory_{this};
};
}
#endif