blob: d7b87cb81e106847d7943284c96739a0df945539 [file] [log] [blame]
// Copyright 2019 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 "components/content_capture/renderer/content_capture_sender.h"
#include "base/metrics/histogram_macros.h"
#include "components/content_capture/common/content_capture_data.h"
#include "components/content_capture/common/content_capture_features.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/web/web_content_holder.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
namespace content_capture {
ContentCaptureSender::ContentCaptureSender(
content::RenderFrame* render_frame,
blink::AssociatedInterfaceRegistry* registry)
: content::RenderFrameObserver(render_frame), binding_(this) {
registry->AddInterface(base::BindRepeating(&ContentCaptureSender::BindRequest,
base::Unretained(this)));
}
ContentCaptureSender::~ContentCaptureSender() {}
void ContentCaptureSender::BindRequest(
mojom::ContentCaptureSenderAssociatedRequest request) {
binding_.Bind(std::move(request));
}
cc::NodeHolder::Type ContentCaptureSender::GetNodeHolderType() const {
if (content_capture::features::ShouldUseNodeID())
return cc::NodeHolder::Type::kID;
else
return cc::NodeHolder::Type::kTextHolder;
}
void ContentCaptureSender::GetTaskTimingParameters(
base::TimeDelta& short_delay,
base::TimeDelta& long_delay) const {
short_delay = base::TimeDelta::FromMilliseconds(
features::TaskShortDelayInMilliseconds());
long_delay = base::TimeDelta::FromMilliseconds(
features::TaskLongDelayInMilliseconds());
}
void ContentCaptureSender::DidCaptureContent(
const std::vector<scoped_refptr<blink::WebContentHolder>>& data,
bool first_data) {
ContentCaptureData frame_data;
FillContentCaptureData(data, &frame_data, first_data /* set_url */);
GetContentCaptureReceiver()->DidCaptureContent(frame_data, first_data);
}
void ContentCaptureSender::DidUpdateContent(
const std::vector<scoped_refptr<blink::WebContentHolder>>& data) {
ContentCaptureData frame_data;
FillContentCaptureData(data, &frame_data, false /* set_url */);
GetContentCaptureReceiver()->DidUpdateContent(frame_data);
}
void ContentCaptureSender::DidRemoveContent(const std::vector<int64_t>& data) {
GetContentCaptureReceiver()->DidRemoveContent(data);
}
void ContentCaptureSender::StartCapture() {
render_frame()->GetWebFrame()->SetContentCaptureClient(this);
}
void ContentCaptureSender::StopCapture() {
render_frame()->GetWebFrame()->SetContentCaptureClient(nullptr);
}
void ContentCaptureSender::OnDestruct() {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
void ContentCaptureSender::FillContentCaptureData(
const std::vector<scoped_refptr<blink::WebContentHolder>>& node_holders,
ContentCaptureData* data,
bool set_url) {
data->bounds = render_frame()->GetWebFrame()->VisibleContentRect();
if (set_url) {
data->value =
render_frame()->GetWebFrame()->GetDocument().Url().GetString().Utf16();
}
data->children.reserve(node_holders.size());
base::TimeTicks start = base::TimeTicks::Now();
for (auto holder : node_holders) {
ContentCaptureData child;
child.id = holder->GetId();
child.value = holder->GetValue().Utf16();
child.bounds = holder->GetBoundingBox();
data->children.push_back(child);
}
UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
"ContentCapture.GetBoundingBox", base::TimeTicks::Now() - start,
base::TimeDelta::FromMicroseconds(1),
base::TimeDelta::FromMilliseconds(10), 50);
}
const mojom::ContentCaptureReceiverAssociatedPtr&
ContentCaptureSender::GetContentCaptureReceiver() {
if (!content_capture_receiver_) {
render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
mojo::MakeRequest(&content_capture_receiver_));
}
return content_capture_receiver_;
}
} // namespace content_capture