blob: 9ecd4ae14be08251b1a6f191f6cf97810170543c [file]
// 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));
}