blob: 8736b9610d49ee631c7e8bc820f64f8960524cb3 [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 "android_webview/renderer/aw_render_frame_observer.h"
#include "android_webview/common/aw_features.h"
#include "base/android/orderfile/orderfile_buildflags.h"
#include "base/feature_list.h"
#include "base/time/time.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#if BUILDFLAG(ORDERFILE_INSTRUMENTATION)
#include "base/android/orderfile/orderfile_instrumentation.h" // nogncheck
#endif
namespace android_webview {
AwRenderFrameObserver::AwRenderFrameObserver(content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame) {}
AwRenderFrameObserver::~AwRenderFrameObserver() = default;
void AwRenderFrameObserver::DidStartNavigation(
const GURL& url,
std::optional<blink::WebNavigationType> navigation_type) {
#if BUILDFLAG(ORDERFILE_INSTRUMENTATION)
// Ensures that StartDelayedDump is called only once for the first navigation
// during the WebView Renderer process lifetime.
[[maybe_unused]] static bool call_once = [] {
base::android::orderfile::StartDelayedDump();
return true;
}();
#endif
}
void AwRenderFrameObserver::ReadyToCommitNavigation(
blink::WebDocumentLoader* document_loader) {
// ReadyToCommitNavigation is only called for navigations that have succeeded
// and will commit. It does not fire for same-document navigations.
if (base::FeatureList::IsEnabled(
features::kWebViewBoostRendererPriorityOnNavigation) &&
render_frame()->IsMainFrame() && !IsPrerendering() &&
!navigation_priority_lease_) {
// ThreadType::kAudioProcessing is currently not used for Android. We are
// using it as an intermediate solution to evaluate the impact of boosting
// the renderer main thread priority without introducing a new thread type.
navigation_priority_lease_.emplace(base::ThreadType::kAudioProcessing);
// Reset priority in 10 seconds in case DidDispatchDOMContentLoadedEvent
// does not fire.
reset_priority_timer_.Start(FROM_HERE, base::Seconds(10), this,
&AwRenderFrameObserver::ResetPriority);
}
}
void AwRenderFrameObserver::DidDispatchDOMContentLoadedEvent() {
if (base::FeatureList::IsEnabled(
features::kWebViewBoostRendererPriorityOnNavigation) &&
render_frame()->IsMainFrame()) {
ResetPriority();
}
}
void AwRenderFrameObserver::ResetPriority() {
reset_priority_timer_.Stop();
navigation_priority_lease_.reset();
}
bool AwRenderFrameObserver::IsPrerendering() const {
auto* frame = render_frame();
return frame && frame->GetWebFrame() &&
frame->GetWebFrame()->GetDocument().IsPrerendering();
}
void AwRenderFrameObserver::OnDestruct() {
delete this;
}
} // namespace android_webview