blob: 0042eb3a5e2c95a8200bbc58f39b26bf0cea00d2 [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_UI_WEBUI_SEARCHBOX_CONTEXTUAL_SEARCHBOX_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_SEARCHBOX_CONTEXTUAL_SEARCHBOX_HANDLER_H_
#include <memory>
#include <optional>
#include <string>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/unguessable_token.h"
#include "chrome/browser/ui/omnibox/omnibox_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/webui/searchbox/contextual_search_type_converters.h"
#include "chrome/browser/ui/webui/searchbox/searchbox_handler.h"
#include "chrome/browser/ui/webui/searchbox/searchbox_omnibox_client.h"
#include "components/contextual_search/contextual_search_context_controller.h"
#include "components/contextual_search/contextual_search_metrics_recorder.h"
#include "components/contextual_search/contextual_search_session_handle.h"
#include "components/contextual_search/contextual_search_types.h"
#include "components/lens/contextual_input.h"
#include "components/omnibox/browser/searchbox.mojom.h"
#include "components/omnibox/composebox/composebox_query.mojom.h"
#include "content/public/browser/web_contents.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "ui/webui/resources/cr_components/composebox/composebox.mojom.h"
class Profile;
class SkBitmap;
#if !BUILDFLAG(IS_ANDROID)
namespace contextual_tasks {
class ContextualTasksContextService;
} // namespace contextual_tasks
#endif
namespace lens {
struct ContextualInputData;
struct ImageEncodingOptions;
}
namespace tabs {
class TabInterface;
}
class ContextualOmniboxClient : public SearchboxOmniboxClient {
public:
ContextualOmniboxClient(Profile* profile, content::WebContents* web_contents);
~ContextualOmniboxClient() override;
private:
contextual_search::ContextualSearchContextController* GetQueryController()
const;
std::optional<lens::proto::LensOverlaySuggestInputs>
GetLensOverlaySuggestInputs() const override;
};
// Abstract class that extends the SearchboxHandler and implements all methods
// shared between the composebox and realbox to support contextual search.
class ContextualSearchboxHandler
: public contextual_search::ContextualSearchContextController::
FileUploadStatusObserver,
public SearchboxHandler,
public TabStripModelObserver {
public:
explicit ContextualSearchboxHandler(
mojo::PendingReceiver<searchbox::mojom::PageHandler>
pending_searchbox_handler,
Profile* profile,
content::WebContents* web_contents,
std::unique_ptr<OmniboxController> controller);
~ContextualSearchboxHandler() override;
// searchbox::mojom::PageHandler:
void NotifySessionStarted() override;
void NotifySessionAbandoned() override;
void AddFileContext(searchbox::mojom::SelectedFileInfoPtr file_info,
mojo_base::BigBuffer file_bytes,
AddFileContextCallback callback) override;
void AddTabContext(int32_t tab_id,
bool delay_upload,
AddTabContextCallback) override;
void DeleteContext(const base::UnguessableToken& file_token) override;
void ClearFiles() override;
void SubmitQuery(const std::string& query_text,
uint8_t mouse_button,
bool alt_key,
bool ctrl_key,
bool meta_key,
bool shift_key) override;
void GetRecentTabs(GetRecentTabsCallback callback) override;
void GetTabPreview(int32_t tab_id, GetTabPreviewCallback callback) override;
// contextual_search::FileUploadStatusObserver:
void OnFileUploadStatusChanged(
const base::UnguessableToken& file_token,
lens::MimeType mime_type,
contextual_search::FileUploadStatus file_upload_status,
const std::optional<contextual_search::FileUploadErrorType>& error_type)
override;
// SearchboxHandler:
std::string AutocompleteIconToResourceName(
const gfx::VectorIcon& icon) const override;
// TabStripModelObserver:
void OnTabStripModelChanged(
TabStripModel* tab_strip_model,
const TabStripModelChange& change,
const TabStripSelectionChange& selection) override;
std::optional<lens::ContextualInputData> context_input_data() {
return context_input_data_;
}
protected:
void ComputeAndOpenQueryUrl(
const std::string& query_text,
WindowOpenDisposition disposition,
std::map<std::string, std::string> additional_params);
FRIEND_TEST_ALL_PREFIXES(ContextualSearchboxHandlerBrowserTest,
CreateTabPreviewEncodingOptions_NotScaled);
FRIEND_TEST_ALL_PREFIXES(ContextualSearchboxHandlerBrowserTestDSF2,
CreateTabPreviewEncodingOptions_Scaled);
FRIEND_TEST_ALL_PREFIXES(ContextualSearchboxHandlerTest,
SubmitQuery_DelayUpload);
FRIEND_TEST_ALL_PREFIXES(ContextualSearchboxHandlerTestTabsTest,
AddTabContext_DelayUpload);
FRIEND_TEST_ALL_PREFIXES(ContextualSearchboxHandlerTestTabsTest,
DeleteContext_DelayUpload);
std::optional<lens::ImageEncodingOptions> CreateTabPreviewEncodingOptions(
content::WebContents* web_contents);
contextual_search::ContextualSearchMetricsRecorder* GetMetricsRecorder();
std::set<base::UnguessableToken> deleted_context_tokens() {
return deleted_context_tokens_;
}
private:
void OnGetTabPageContext(
bool delay_upload,
const base::UnguessableToken& context_token,
std::unique_ptr<lens::ContextualInputData> page_content_data);
// Helper function that handles the caching of the tab context. Once it's
// successfully cached, we notify the page that the file is uploaded.
void SnapshotTabContext(
const base::UnguessableToken& context_token,
std::unique_ptr<lens::ContextualInputData> page_content_data);
// Helper Function that does the actual uploading of the tab context.
void UploadTabContext(
const base::UnguessableToken& context_token,
std::unique_ptr<lens::ContextualInputData> page_content_data);
// Helper function that uploads the cached tab context if it exists.
void UploadSnapshotTabContextIfPresent();
void OpenUrl(GURL url, const WindowOpenDisposition disposition);
void OnPreviewReceived(GetTabPreviewCallback callback,
const SkBitmap& preview_bitmap);
void RecordTabClickedMetric(tabs::TabInterface* const tab);
std::set<base::UnguessableToken> deleted_context_tokens_;
raw_ptr<content::WebContents> web_contents_;
std::optional<std::pair<base::UnguessableToken,
std::unique_ptr<lens::ContextualInputData>>>
tab_context_snapshot_;
#if !BUILDFLAG(IS_ANDROID)
raw_ptr<contextual_tasks::ContextualTasksContextService>
contextual_tasks_context_service_;
#endif
base::ScopedObservation<contextual_search::ContextualSearchContextController,
contextual_search::ContextualSearchContextController::
FileUploadStatusObserver>
file_upload_status_observer_{this};
std::optional<lens::ContextualInputData> context_input_data_;
base::WeakPtrFactory<ContextualSearchboxHandler> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_WEBUI_SEARCHBOX_CONTEXTUAL_SEARCHBOX_HANDLER_H_