#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include <stddef.h>
#include <utility>
#include "base/check_op.h"
#include "base/containers/fixed_flat_map.h"
#include "base/containers/fixed_flat_set.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/strings/escape.h"
#include "base/strings/string_util.h"
#include "base/types/optional_util.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/external_protocol/auto_launch_protocols_policy_handler.h"
#include "chrome/browser/external_protocol/constants.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/url_matcher/url_matcher.h"
#include "components/url_matcher/url_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/weak_document_ptr.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h"
#include "chrome/browser/sharing/click_to_call/click_to_call_utils.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "components/navigation_interception/intercept_navigation_delegate.h"
#else
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/url_formatter/elide_url.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#endif
namespace {
bool g_accept_requests = …;
ExternalProtocolHandler::Delegate* g_external_protocol_handler_delegate = …;
constexpr auto kDeniedSchemes = …;
void AddMessageToConsole(const content::WeakDocumentPtr& document,
blink::mojom::ConsoleMessageLevel level,
const std::string& message) { … }
#if !BUILDFLAG(IS_ANDROID)
scoped_refptr<shell_integration::DefaultSchemeClientWorker> CreateShellWorker(
const GURL& url,
ExternalProtocolHandler::Delegate* delegate) { … }
#endif
ExternalProtocolHandler::BlockState GetBlockStateWithDelegate(
const std::string& scheme,
const url::Origin* initiating_origin,
ExternalProtocolHandler::Delegate* delegate,
Profile* profile) { … }
#if !BUILDFLAG(IS_ANDROID)
void RunExternalProtocolDialogWithDelegate(
const GURL& url,
content::WebContents* web_contents,
ui::PageTransition page_transition,
bool has_user_gesture,
bool is_in_fenced_frame_tree,
const std::optional<url::Origin>& initiating_origin,
content::WeakDocumentPtr initiator_document,
const std::u16string& program_name,
ExternalProtocolHandler::Delegate* delegate) { … }
#endif
void LaunchUrlWithoutSecurityCheckWithDelegate(
const GURL& url,
content::WebContents* web_contents,
content::WeakDocumentPtr initiator_document,
ExternalProtocolHandler::Delegate* delegate) { … }
#if !BUILDFLAG(IS_ANDROID)
void OnDefaultSchemeClientWorkerFinished(
const GURL& escaped_url,
content::WebContents::Getter web_contents_getter,
bool prompt_user,
ui::PageTransition page_transition,
bool has_user_gesture,
bool is_in_fenced_frame_tree,
const std::optional<url::Origin>& initiating_origin,
content::WeakDocumentPtr initiator_document,
ExternalProtocolHandler::Delegate* delegate,
shell_integration::DefaultWebClientState state,
const std::u16string& program_name) { … }
#endif
bool IsSchemeOriginPairAllowedByPolicy(const std::string& scheme,
const url::Origin* initiating_origin,
PrefService* prefs) { … }
enum class LoggedScheme { … };
void LogRequestForScheme(const std::string& scheme) { … }
}
const char ExternalProtocolHandler::kBlockStateMetric[] = …;
const char ExternalProtocolHandler::kHandleStateMetric[] = …;
void ExternalProtocolHandler::SetDelegateForTesting(Delegate* delegate) { … }
bool ExternalProtocolHandler::MayRememberAllowDecisionsForThisOrigin(
const url::Origin* initiating_origin) { … }
ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState(
const std::string& scheme,
const url::Origin* initiating_origin,
Profile* profile) { … }
void ExternalProtocolHandler::SetBlockState(
const std::string& scheme,
const url::Origin& initiating_origin,
BlockState state,
Profile* profile) { … }
void ExternalProtocolHandler::LaunchUrl(
const GURL& url,
content::WebContents::Getter web_contents_getter,
ui::PageTransition page_transition,
bool has_user_gesture,
bool is_in_fenced_frame_tree,
const std::optional<url::Origin>& initiating_origin,
content::WeakDocumentPtr initiator_document
#if BUILDFLAG(IS_ANDROID)
,
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory
#endif
) { … }
void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(
const GURL& url,
content::WebContents* web_contents,
content::WeakDocumentPtr initiator_document) { … }
void ExternalProtocolHandler::PermitLaunchUrl() { … }
void ExternalProtocolHandler::RecordHandleStateMetrics(bool checkbox_selected,
BlockState block_state) { … }
void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { … }
void ExternalProtocolHandler::ClearData(Profile* profile) { … }