Commit 76ed6003 authored by Lily Chen's avatar Lily Chen Committed by Chromium LUCI CQ

Partially deduplicate PostMessage.Incoming.* UKM event recording

To decrease UKM volume, this maintains a list of the 20 most recently
recorded (source, target) UKM source ID pairs, such that duplicates can
be skipped.

Bug: 1112491
Change-Id: I4b6bfe26f55102078305bc7a5c3bc1a774ca62d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2622277Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarAaron Colwell <acolwell@chromium.org>
Commit-Queue: Lily Chen <chlily@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842718}
parent 9f3ae654
......@@ -9,8 +9,10 @@
#include <vector>
#include "base/callback.h"
#include "base/containers/circular_deque.h"
#include "base/hash/hash.h"
#include "base/lazy_instance.h"
#include "base/no_destructor.h"
#include "content/browser/bad_message.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/child_process_security_policy_impl.h"
......@@ -71,6 +73,35 @@ using TokenFrameMap = std::unordered_map<base::UnguessableToken,
base::LazyInstance<TokenFrameMap>::Leaky g_token_frame_proxy_map =
LAZY_INSTANCE_INITIALIZER;
// Maintains a list of the most recently recorded (source, target) pairs for the
// PostMessage.Incoming.Page UKM event, in order to partially deduplicate
// logged events. Its size is limited to 20. See RouteMessageEvent() where
// this UKM is logged.
// TODO(crbug.com/1112491): Remove when no longer needed.
bool ShouldRecordPostMessageIncomingPageUkmEvent(
ukm::SourceId source_page_ukm_source_id,
ukm::SourceId target_page_ukm_source_id) {
constexpr size_t kMaxPostMessageUkmAlreadyRecordedPairsSize = 20;
static base::NoDestructor<
base::circular_deque<std::pair<ukm::SourceId, ukm::SourceId>>>
s_post_message_ukm_already_recorded_pairs;
DCHECK_LE(s_post_message_ukm_already_recorded_pairs->size(),
kMaxPostMessageUkmAlreadyRecordedPairsSize);
std::pair<ukm::SourceId, ukm::SourceId> new_pair =
std::make_pair(source_page_ukm_source_id, target_page_ukm_source_id);
if (base::Contains(*s_post_message_ukm_already_recorded_pairs, new_pair))
return false;
if (s_post_message_ukm_already_recorded_pairs->size() ==
kMaxPostMessageUkmAlreadyRecordedPairsSize) {
s_post_message_ukm_already_recorded_pairs->pop_back();
}
s_post_message_ukm_already_recorded_pairs->push_front(new_pair);
return true;
}
} // namespace
// static
......@@ -595,11 +626,15 @@ void RenderFrameProxyHost::RouteMessageEvent(
}
// Record UKM metrics for the postMessage event.
ukm::builders::PostMessage_Incoming_Page ukm_builder(
target_rfh->GetPageUkmSourceId());
if (source_page_ukm_source_id != ukm::kInvalidSourceId)
ukm_builder.SetSourcePageSourceId(source_page_ukm_source_id);
ukm_builder.Record(ukm::UkmRecorder::Get());
ukm::SourceId target_page_ukm_source_id = target_rfh->GetPageUkmSourceId();
if (ShouldRecordPostMessageIncomingPageUkmEvent(source_page_ukm_source_id,
target_page_ukm_source_id)) {
ukm::builders::PostMessage_Incoming_Page ukm_builder(
target_page_ukm_source_id);
if (source_page_ukm_source_id != ukm::kInvalidSourceId)
ukm_builder.SetSourcePageSourceId(source_page_ukm_source_id);
ukm_builder.Record(ukm::UkmRecorder::Get());
}
target_rfh->PostMessageEvent(translated_source_token, source_origin,
target_origin, std::move(message));
......
......@@ -137,6 +137,31 @@
namespace blink {
namespace {
constexpr size_t kMaxPostMessageUkmRecordedSourceIdsSize = 20;
bool ShouldRecordPostMessageIncomingFrameUkmEvent(
ukm::SourceId source_frame_ukm_source_id,
Deque<ukm::SourceId>& already_recorded_source_frame_ids) {
DCHECK_LE(already_recorded_source_frame_ids.size(),
kMaxPostMessageUkmRecordedSourceIdsSize);
if (base::Contains(already_recorded_source_frame_ids,
source_frame_ukm_source_id)) {
return false;
}
if (already_recorded_source_frame_ids.size() ==
kMaxPostMessageUkmRecordedSourceIdsSize) {
already_recorded_source_frame_ids.pop_back();
}
already_recorded_source_frame_ids.push_front(source_frame_ukm_source_id);
return true;
}
} // namespace
LocalDOMWindow::LocalDOMWindow(LocalFrame& frame, WindowAgent* agent)
: DOMWindow(frame),
ExecutionContext(V8PerIsolateData::MainThreadIsolate(), agent),
......@@ -945,9 +970,13 @@ void LocalDOMWindow::SchedulePostMessage(
scoped_refptr<const SecurityOrigin> target,
LocalDOMWindow* source) {
// Record UKM metrics for postMessage event.
ukm::builders::PostMessage_Incoming_Frame(UkmSourceID())
.SetSourceFrameSourceId(source->UkmSourceID())
.Record(UkmRecorder());
ukm::SourceId source_frame_ukm_source_id = source->UkmSourceID();
if (ShouldRecordPostMessageIncomingFrameUkmEvent(
source_frame_ukm_source_id, post_message_ukm_recorded_source_ids_)) {
ukm::builders::PostMessage_Incoming_Frame(UkmSourceID())
.SetSourceFrameSourceId(source_frame_ukm_source_id)
.Record(UkmRecorder());
}
// Allowing unbounded amounts of messages to build up for a suspended context
// is problematic; consider imposing a limit or other restriction if this
......
......@@ -531,6 +531,13 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// this document, to avoid reporting duplicates. The value stored comes
// from |DocumentPolicyViolationReport::MatchId()|.
mutable HashSet<unsigned> document_policy_violation_reports_sent_;
// A list of the most recently recorded source frame UKM source IDs for the
// PostMessage.Incoming.Frame UKM event, in order to partially deduplicate
// logged events. Its size is limited to 20. See SchedulePostMessage() where
// this UKM is logged.
// TODO(crbug.com/1112491): Remove when no longer needed.
Deque<ukm::SourceId> post_message_ukm_recorded_source_ids_;
};
template <>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment