| // 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. |
| |
| #include "chrome/browser/contextual_tasks/contextual_tasks_internals_page_handler.h" |
| |
| #include <optional> |
| #include <string> |
| #include <utility> |
| |
| #include "base/functional/bind.h" |
| #include "base/strings/strcat.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/autocomplete/aim_eligibility_service_factory.h" |
| #include "chrome/browser/contextual_tasks/contextual_tasks_context_service.h" |
| #include "chrome/browser/contextual_tasks/contextual_tasks_service_factory.h" |
| #include "chrome/browser/contextual_tasks/contextual_tasks_ui_service.h" |
| #include "chrome/browser/contextual_tasks/contextual_tasks_ui_service_factory.h" |
| #include "chrome/browser/contextual_tasks/entry_point_eligibility_manager.h" |
| #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search/search.h" |
| #include "components/contextual_search/contextual_search_service.h" |
| #include "components/contextual_tasks/public/contextual_tasks_service.h" |
| #include "components/contextual_tasks/public/features.h" |
| #include "components/omnibox/browser/aim_eligibility_service.h" |
| #include "content/public/browser/web_contents.h" |
| #include "mojo/public/cpp/bindings/pending_receiver.h" |
| #include "url/url_constants.h" |
| |
| ContextualTasksInternalsPageHandler::ContextualTasksInternalsPageHandler( |
| Profile* profile, |
| contextual_tasks::ContextualTasksContextService* context_service, |
| OptimizationGuideKeyedService* optimization_guide_keyed_service, |
| mojo::PendingReceiver< |
| contextual_tasks_internals::mojom::ContextualTasksInternalsPageHandler> |
| receiver, |
| mojo::PendingRemote< |
| contextual_tasks_internals::mojom::ContextualTasksInternalsPage> page) |
| : profile_(profile), |
| context_service_(context_service), |
| optimization_guide_logger_( |
| optimization_guide_keyed_service->GetOptimizationGuideLogger()), |
| receiver_(this, std::move(receiver)), |
| page_(std::move(page)) { |
| if (optimization_guide_logger_) { |
| optimization_guide_logger_->AddObserver(this); |
| } |
| } |
| |
| ContextualTasksInternalsPageHandler::~ContextualTasksInternalsPageHandler() { |
| if (optimization_guide_logger_) { |
| optimization_guide_logger_->RemoveObserver(this); |
| } |
| } |
| |
| void ContextualTasksInternalsPageHandler::GetRelevantContext( |
| contextual_tasks_internals::mojom::GetRelevantContextRequestPtr request, |
| GetRelevantContextCallback callback) { |
| if (!context_service_) { |
| std::move(callback).Run( |
| contextual_tasks_internals::mojom::GetRelevantContextResponse::New()); |
| return; |
| } |
| |
| contextual_tasks::TabSelectionOptions options; |
| options.tab_selection_mode = request->tab_selection_mode; |
| options.min_model_score = request->min_model_score; |
| context_service_->GetRelevantTabsForQuery( |
| options, request->query, |
| /*explicit_urls=*/{}, |
| base::BindOnce( |
| [](GetRelevantContextCallback callback, |
| std::vector<base::WeakPtr<content::WebContents>> relevant_tabs) { |
| auto result = contextual_tasks_internals::mojom:: |
| GetRelevantContextResponse::New(); |
| for (const auto& web_contents : relevant_tabs) { |
| if (web_contents) { |
| auto tab = contextual_tasks_internals::mojom::Tab::New(); |
| tab->title = base::UTF16ToUTF8(web_contents->GetTitle()); |
| tab->url = web_contents->GetLastCommittedURL(); |
| result->relevant_tabs.push_back(std::move(tab)); |
| } |
| } |
| std::move(callback).Run(std::move(result)); |
| }, |
| std::move(callback))); |
| } |
| |
| void ContextualTasksInternalsPageHandler::SetForcedEmbeddedPageHost( |
| const GURL& host) { |
| // Extract just the host portion, e.g. "test.google.com" from the URL. |
| // If the passed URL is empty/invalid, this clears the override. |
| contextual_tasks::SetForcedEmbeddedPageHostOverride(std::string(host.host())); |
| } |
| |
| void ContextualTasksInternalsPageHandler::GetForcedEmbeddedPageHost( |
| GetForcedEmbeddedPageHostCallback callback) { |
| std::string host = contextual_tasks::GetForcedEmbeddedPageHost(); |
| if (host.empty()) { |
| std::move(callback).Run(GURL()); |
| } else { |
| // Wrap the string host into a valid URL so it can be passed via Mojo. |
| std::move(callback).Run(GURL(base::StrCat( |
| {url::kHttpsScheme, url::kStandardSchemeSeparator, host}))); |
| } |
| } |
| |
| void ContextualTasksInternalsPageHandler::OnLogMessageAdded( |
| base::Time event_time, |
| optimization_guide_common::mojom::LogSource log_source, |
| const std::string& source_file, |
| int source_line, |
| const std::string& message) { |
| if (page_ && log_source == optimization_guide_common::mojom::LogSource:: |
| CONTEXTUAL_TASKS_CONTEXT) { |
| page_->OnLogMessageAdded(event_time, source_file, source_line, message); |
| } |
| } |
| |
| void ContextualTasksInternalsPageHandler::GetEligibilityState( |
| GetEligibilityStateCallback callback) { |
| auto state = contextual_tasks_internals::mojom::EligibilityState::New(); |
| |
| if (profile_) { |
| auto* aim_eligibility_service = |
| AimEligibilityServiceFactory::GetForProfile(profile_); |
| state->is_contextual_tasks_enabled = |
| base::FeatureList::IsEnabled(contextual_tasks::kContextualTasks); |
| |
| auto* ui_service = |
| contextual_tasks::ContextualTasksUiServiceFactory::GetForBrowserContext( |
| profile_); |
| if (ui_service) { |
| state->is_signed_in = |
| ui_service->IsSignedInToBrowserWithValidCredentials(); |
| state->primary_account_in_cookie_jar = |
| ui_service->CookieJarContainsPrimaryAccount(); |
| } |
| |
| state->is_aim_allowed_by_policy = |
| AimEligibilityService::IsAimAllowedByPolicy(profile_->GetPrefs()); |
| |
| if (aim_eligibility_service) { |
| state->is_aim_eligible = aim_eligibility_service->IsAimEligible(); |
| state->is_cobrowse_eligible = |
| aim_eligibility_service->IsCobrowseEligible(); |
| } |
| |
| state->is_context_sharing_enabled = |
| contextual_search::ContextualSearchService::IsContextSharingEnabled( |
| profile_->GetPrefs()); |
| |
| state->is_default_search_engine_google = |
| search::DefaultSearchProviderIsGoogle(profile_); |
| |
| state->is_eligible = |
| contextual_tasks::EntryPointEligibilityManager::IsEligible(profile_); |
| } |
| |
| std::move(callback).Run(std::move(state)); |
| } |