#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_io_data.h"
#include "components/custom_handlers/protocol_handler_registry.h"
#include "content/public/common/url_constants.h"
#include "url/url_util.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/web_applications/app_service/publisher_helper.h"
#include "chromeos/constants/chromeos_features.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/android/omnibox/jni_headers/ChromeAutocompleteSchemeClassifier_jni.h"
#endif
#if BUILDFLAG(IS_ANDROID)
static jlong
JNI_ChromeAutocompleteSchemeClassifier_CreateAutocompleteClassifier(
JNIEnv* env,
Profile* profile) {
DCHECK(profile);
return reinterpret_cast<intptr_t>(
new ChromeAutocompleteSchemeClassifier(profile));
}
static void JNI_ChromeAutocompleteSchemeClassifier_DeleteAutocompleteClassifier(
JNIEnv* env,
jlong chrome_autocomplete_scheme_classifier) {
delete reinterpret_cast<ChromeAutocompleteSchemeClassifier*>(
chrome_autocomplete_scheme_classifier);
}
#endif
#if BUILDFLAG(IS_CHROMEOS)
namespace {
bool IsCustomSchemeHandledByWebApp(Profile* profile,
const std::string& scheme) {
return chromeos::features::IsWebAppManifestProtocolHandlerSupportEnabled() &&
!web_app::GetWebAppIdsForProtocolUrl(
profile, GURL(scheme + url::kStandardSchemeSeparator))
.empty();
}
}
#endif
ChromeAutocompleteSchemeClassifier::ChromeAutocompleteSchemeClassifier(
Profile* profile)
: profile_(profile) {}
ChromeAutocompleteSchemeClassifier::~ChromeAutocompleteSchemeClassifier() =
default;
metrics::OmniboxInputType
ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme(
const std::string& scheme) const {
if (scheme.empty()) {
return metrics::OmniboxInputType::EMPTY;
}
if (base::IsStringASCII(scheme) &&
(ProfileIOData::IsHandledProtocol(scheme) ||
base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) ||
base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) ||
base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) {
return metrics::OmniboxInputType::URL;
}
custom_handlers::ProtocolHandlerRegistry* registry =
profile_ ? ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_)
: nullptr;
if (registry && registry->IsHandledProtocol(scheme))
return metrics::OmniboxInputType::URL;
const ExternalProtocolHandler::BlockState block_state =
ExternalProtocolHandler::GetBlockState(scheme, nullptr, profile_);
switch (block_state) {
case ExternalProtocolHandler::DONT_BLOCK:
return metrics::OmniboxInputType::URL;
case ExternalProtocolHandler::BLOCK:
return metrics::OmniboxInputType::QUERY;
case ExternalProtocolHandler::UNKNOWN: {
#if BUILDFLAG(IS_LINUX)
return metrics::OmniboxInputType::EMPTY;
#elif BUILDFLAG(IS_CHROMEOS)
return IsCustomSchemeHandledByWebApp(profile_, scheme)
? metrics::OmniboxInputType::URL
: metrics::OmniboxInputType::EMPTY;
#else
GURL url(scheme + "://");
std::u16string application_name =
shell_integration::GetApplicationNameForScheme(url);
return application_name.empty() ? metrics::OmniboxInputType::EMPTY
: metrics::OmniboxInputType::URL;
#endif
}
}
NOTREACHED();
}
#if BUILDFLAG(IS_ANDROID)
DEFINE_JNI(ChromeAutocompleteSchemeClassifier)
#endif