blob: a87bdf34cb4d045197cd8e81b7bc39827630374d [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/prerender/prerender_internals_handler_impl.h"
#include "content/browser/prerender/prerender_host_registry.h"
#include "content/browser/web_contents/web_contents_impl.h"
namespace content {
namespace {
const char* FinalStatusToString(PrerenderHost::FinalStatus final_status) {
switch (final_status) {
case PrerenderHost::FinalStatus::kActivated:
return "Activated";
case PrerenderHost::FinalStatus::kDestroyed:
return "Destroyed";
case PrerenderHost::FinalStatus::kLowEndDevice:
return "LowEndDevice";
case PrerenderHost::FinalStatus::kCrossOriginRedirect:
return "CrossOriginRedirect";
case PrerenderHost::FinalStatus::kCrossOriginNavigation:
return "CrossOriginNavigation";
case PrerenderHost::FinalStatus::kInvalidSchemeRedirect:
return "InvalidSchemeRedirect";
case PrerenderHost::FinalStatus::kInvalidSchemeNavigation:
return "InvalidSchemeNavigation";
case PrerenderHost::FinalStatus::kInProgressNavigation:
return "InProgressNavigation";
case PrerenderHost::FinalStatus::kNavigationRequestBlockedByCsp:
return "NavigationRequestBlockedByCsp";
case PrerenderHost::FinalStatus::kMainFrameNavigation:
return "MainFrameNavigation";
case PrerenderHost::FinalStatus::kMojoBinderPolicy:
return "MojoBinderPolicy";
case PrerenderHost::FinalStatus::kRendererProcessCrashed:
return "RendererProcessCrashed";
case PrerenderHost::FinalStatus::kRendererProcessKilled:
return "RendererProcessKilled";
case PrerenderHost::FinalStatus::kDownload:
return "Download";
case PrerenderHost::FinalStatus::kTriggerDestroyed:
return "TriggerDestroyed";
case PrerenderHost::FinalStatus::kNavigationNotCommitted:
return "NavigationNotCommitted";
case PrerenderHost::FinalStatus::kNavigationBadHttpStatus:
return "NavigationBadHttpStatus";
case PrerenderHost::FinalStatus::kClientCertRequested:
return "ClientCertRequested";
case PrerenderHost::FinalStatus::kNavigationRequestNetworkError:
return "NavigationRequestNetworkError";
case PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded:
return "MaxNumOfRunningPrerendersExceeded";
case PrerenderHost::FinalStatus::kCancelAllHostsForTesting:
return "CancelAllHostsForTesting";
case PrerenderHost::FinalStatus::kDidFailLoad:
return "DidFailLoad";
case PrerenderHost::FinalStatus::kStop:
return "Stop";
case PrerenderHost::FinalStatus::kSslCertificateError:
return "SslCertificateError";
case PrerenderHost::FinalStatus::kLoginAuthRequested:
return "LoginAuthRequested";
case PrerenderHost::FinalStatus::kUaChangeRequiresReload:
return "UaChangeRequiresReload";
case PrerenderHost::FinalStatus::kBlockedByClient:
return "BlockedByClient";
case PrerenderHost::FinalStatus::kAudioOutputDeviceRequested:
return "AudioOutputDeviceRequested";
case PrerenderHost::FinalStatus::kMixedContent:
return "MixedContent";
case PrerenderHost::FinalStatus::kTriggerBackgrounded:
return "TriggerBackgrounded";
case PrerenderHost::FinalStatus::kEmbedderTriggeredAndSameOriginRedirected:
return "EmbedderTriggeredAndSameOriginRedirected";
case PrerenderHost::FinalStatus::kEmbedderTriggeredAndCrossOriginRedirected:
return "EmbedderTriggeredAndCrossOriginRedirected";
}
NOTREACHED();
return "";
}
const char* GetFinalStatus(PrerenderHost& host) {
absl::optional<PrerenderHost::FinalStatus> final_status = host.final_status();
if (final_status) {
return FinalStatusToString(final_status.value());
} else {
return "FinalStatus is not set";
}
}
} // namespace
PrerenderInternalsHandlerImpl::PrerenderInternalsHandlerImpl(
mojo::PendingReceiver<mojom::PrerenderInternalsHandler> receiver)
: receiver_(this, std::move(receiver)) {}
PrerenderInternalsHandlerImpl::~PrerenderInternalsHandlerImpl() = default;
void PrerenderInternalsHandlerImpl::GetPrerenderInfo(
GetPrerenderInfoCallback callback) {
if (!blink::features::IsPrerender2Enabled()) {
std::move(callback).Run(std::vector<mojom::PrerenderInfoPtr>());
return;
}
std::vector<mojom::PrerenderInfoPtr> infos;
std::vector<WebContentsImpl*> all_contents =
WebContentsImpl::GetAllWebContents();
for (WebContentsImpl* web_contents : all_contents) {
mojom::PrerenderInfoPtr info = mojom::PrerenderInfo::New();
PrerenderHostRegistry* prerender_host_registry =
web_contents->GetPrerenderHostRegistry();
prerender_host_registry->ForEachPrerenderHost(base::BindRepeating(
[](mojom::PrerenderInfo* info, PrerenderHost& host) {
mojom::PrerenderedPageInfoPtr prerendered_page_info =
mojom::PrerenderedPageInfo::New();
RenderFrameHostImpl* render_frame_host =
host.GetPrerenderedMainFrameHost();
prerendered_page_info->url = render_frame_host->GetLastCommittedURL();
prerendered_page_info->trigger_page_url = host.initiator_url();
prerendered_page_info->final_status = GetFinalStatus(host);
info->prerendered_page_infos.push_back(
std::move(prerendered_page_info));
},
info.get()));
if (info->prerendered_page_infos.empty()) {
continue;
}
infos.push_back(std::move(info));
}
std::move(callback).Run(std::move(infos));
}
} // namespace content