blob: 5b5c8b82ae8d83ab2794894d28ec97ee609d4ac5 [file] [log] [blame]
// Copyright 2018 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/renderer/render_frame_metadata_observer_impl.h"
#include "cc/trees/frame_token_allocator.h"
namespace content {
RenderFrameMetadataObserverImpl::RenderFrameMetadataObserverImpl(
mojom::RenderFrameMetadataObserverRequest request,
mojom::RenderFrameMetadataObserverClientPtrInfo client_info)
: request_(std::move(request)),
client_info_(std::move(client_info)),
render_frame_metadata_observer_binding_(this) {}
RenderFrameMetadataObserverImpl::~RenderFrameMetadataObserverImpl() {}
void RenderFrameMetadataObserverImpl::BindToCurrentThread(
cc::FrameTokenAllocator* frame_token_allocator) {
DCHECK(request_.is_pending());
frame_token_allocator_ = frame_token_allocator;
render_frame_metadata_observer_binding_.Bind(std::move(request_));
render_frame_metadata_observer_client_.Bind(std::move(client_info_));
}
void RenderFrameMetadataObserverImpl::OnRenderFrameSubmission(
cc::RenderFrameMetadata metadata) {
// By default only report metadata changes for fields which have a low
// frequency of change. However if there are changes in high frequency
// fields these can be reported while testing is enabled.
bool send_metadata = false;
if (render_frame_metadata_observer_client_) {
if (report_all_frame_submissions_for_testing_enabled_) {
last_frame_token_ = frame_token_allocator_->GetOrAllocateFrameToken();
render_frame_metadata_observer_client_->OnFrameSubmissionForTesting(
last_frame_token_);
send_metadata = !last_render_frame_metadata_ ||
*last_render_frame_metadata_ != metadata;
} else {
send_metadata = !last_render_frame_metadata_ ||
cc::RenderFrameMetadata::HasAlwaysUpdateMetadataChanged(
*last_render_frame_metadata_, metadata);
}
}
// Allways cache the full metadata, so that it can correctly be sent upon
// ReportAllFrameSubmissionsForTesting. This must only be done after we've
// compared the two for changes.
last_render_frame_metadata_ = metadata;
// If the metadata is different, updates all the observers; or the metadata is
// generated for first time and same as the default value, update the default
// value to all the observers.
if (send_metadata && render_frame_metadata_observer_client_) {
// Sending |root_scroll_offset| outside of tests would leave the browser
// process with out of date information. It is an optional parameter
// which we clear here.
if (!report_all_frame_submissions_for_testing_enabled_)
metadata.root_scroll_offset = base::nullopt;
last_frame_token_ = frame_token_allocator_->GetOrAllocateFrameToken();
render_frame_metadata_observer_client_->OnRenderFrameMetadataChanged(
last_frame_token_, metadata);
}
// Always cache the initial frame token, so that if a test connects later on
// it can be notified of the initial state.
if (!last_frame_token_)
last_frame_token_ = frame_token_allocator_->GetOrAllocateFrameToken();
}
void RenderFrameMetadataObserverImpl::ReportAllFrameSubmissionsForTesting(
bool enabled) {
report_all_frame_submissions_for_testing_enabled_ = enabled;
if (!enabled || !last_frame_token_)
return;
// When enabled for testing send the cached metadata.
DCHECK(render_frame_metadata_observer_client_);
DCHECK(last_render_frame_metadata_.has_value());
render_frame_metadata_observer_client_->OnRenderFrameMetadataChanged(
last_frame_token_, *last_render_frame_metadata_);
}
} // namespace content