Skip to content

Commit

Permalink
Autoplay: records metrics in UKM entries.
Browse files Browse the repository at this point in the history
This is using the UKM service to record the autoplay attempts and
the unmute results.

Bug: 744659
Change-Id: Ice9a259a4006beff1044e5ed62981619841895e5
Reviewed-on: https://chromium-review.googlesource.com/525692
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
Reviewed-by: Steven Holte <holte@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#509384}
  • Loading branch information
mounirlamouri authored and Commit Bot committed Oct 17, 2017
1 parent 51058e6 commit ad90070
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 7 deletions.
2 changes: 1 addition & 1 deletion content/public/app/mojo/content_renderer_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"requires": {
"*": [ "app" ],
"content_browser": [ "renderer" ],
"content_browser": [ "renderer", "url_keyed_metrics" ],
"device": [
"device:power_monitor",
"device:screen_orientation",
Expand Down
4 changes: 3 additions & 1 deletion services/metrics/public/cpp/mojo_ukm_recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ class METRICS_EXPORT MojoUkmRecorder : public UkmRecorder {
explicit MojoUkmRecorder(mojom::UkmRecorderInterfacePtr interface);
~MojoUkmRecorder() override;

private:
// UkmRecorder:
void UpdateSourceURL(SourceId source_id, const GURL& url) override;

private:
// UkmRecorder:
void AddEntry(mojom::UkmEntryPtr entry) override;

mojom::UkmRecorderInterfacePtr interface_;
Expand Down
5 changes: 5 additions & 0 deletions services/metrics/public/cpp/ukm_recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class SubresourceFilterMetricsObserver;
class UkmPageLoadMetricsObserver;
class LocalNetworkRequestsPageLoadMetricsObserver;

namespace blink {
class AutoplayUmaHelper;
}

namespace content {
class RenderWidgetHostLatencyTracker;
} // namespace content
Expand Down Expand Up @@ -76,6 +80,7 @@ class METRICS_EXPORT UkmRecorder {
virtual void UpdateSourceURL(SourceId source_id, const GURL& url) = 0;

private:
friend blink::AutoplayUmaHelper;
friend ContextualSearchRankerLoggerImpl;
friend PluginInfoMessageFilter;
friend UkmPageLoadMetricsObserver;
Expand Down
8 changes: 4 additions & 4 deletions third_party/WebKit/PRESUBMIT.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ def _CheckForPrintfDebugging(input_api, output_api):
return []


def _CheckForForbiddenNamespace(input_api, output_api):
"""Checks that Blink uses Chromium namespaces only in permitted code."""
def _CheckForForbiddenChromiumCode(input_api, output_api):
"""Checks that Blink uses Chromium classes and namespaces only in permitted code."""
# This list is not exhaustive, but covers likely ones.
chromium_namespaces = ["base", "cc", "content", "gfx", "net", "ui"]
chromium_forbidden_classes = []
chromium_forbidden_classes = ["GURL"]
chromium_allowed_classes = [
"base::make_span",
"base::span",
Expand Down Expand Up @@ -161,7 +161,7 @@ def CheckChangeOnUpload(input_api, output_api):
results.extend(_CommonChecks(input_api, output_api))
results.extend(_CheckStyle(input_api, output_api))
results.extend(_CheckForPrintfDebugging(input_api, output_api))
results.extend(_CheckForForbiddenNamespace(input_api, output_api))
results.extend(_CheckForForbiddenChromiumCode(input_api, output_api))
return results


Expand Down
1 change: 1 addition & 0 deletions third_party/WebKit/Source/core/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ include_rules = [
"+platform",
"+public/platform",
"+public/web",
"+services/metrics/public",
"+services/network/public/interfaces",
"+services/service_manager/public/interfaces/interface_provider.mojom-blink.h",
"+third_party/skia/include",
Expand Down
5 changes: 5 additions & 0 deletions third_party/WebKit/Source/core/dom/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,9 @@ blink_core_sources("dom") {
public_deps = [
"//third_party/WebKit/common:mojo_bindings_blink",
]

deps = [
"//services/metrics/public/cpp:metrics_cpp",
"//services/metrics/public/interfaces",
]
}
24 changes: 24 additions & 0 deletions third_party/WebKit/Source/core/dom/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,14 @@
#include "platform/wtf/text/CharacterNames.h"
#include "platform/wtf/text/StringBuffer.h"
#include "platform/wtf/text/TextEncodingRegistry.h"
#include "public/platform/InterfaceProvider.h"
#include "public/platform/Platform.h"
#include "public/platform/WebAddressSpace.h"
#include "public/platform/WebPrerenderingSupport.h"
#include "public/platform/modules/insecure_input/insecure_input_service.mojom-blink.h"
#include "public/platform/site_engagement.mojom-blink.h"
#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "services/metrics/public/interfaces/ukm_interface.mojom-shared.h"
#include "services/service_manager/public/cpp/interface_provider.h"

#ifndef NDEBUG
Expand Down Expand Up @@ -3696,6 +3699,9 @@ void Document::SetURL(const KURL& url) {
access_entry_from_url_ = nullptr;
UpdateBaseURL();
GetContextFeatures().UrlDidChange(this);

if (ukm_recorder_)
ukm_recorder_->UpdateSourceURL(ukm_source_id_, url_);
}

KURL Document::ValidBaseElementURL() const {
Expand Down Expand Up @@ -5960,6 +5966,24 @@ void Document::SetFeaturePolicy(const String& feature_policy_header) {
frame_->Client()->DidSetFeaturePolicyHeader(parsed_header);
}

ukm::UkmRecorder* Document::UkmRecorder() {
if (ukm_recorder_)
return ukm_recorder_.get();

ukm::mojom::UkmRecorderInterfacePtr interface;
Platform::Current()->GetInterfaceProvider()->GetInterface(
mojo::MakeRequest(&interface));
ukm_recorder_.reset(new ukm::MojoUkmRecorder(std::move(interface)));
ukm_source_id_ = ukm_recorder_->GetNewSourceID();
ukm_recorder_->UpdateSourceURL(ukm_source_id_, url_);
return ukm_recorder_.get();
}

int64_t Document::UkmSourceID() const {
DCHECK(ukm_recorder_);
return ukm_source_id_;
}

void Document::InitSecurityContext(const DocumentInit& initializer) {
DCHECK(!GetSecurityOrigin());

Expand Down
15 changes: 14 additions & 1 deletion third_party/WebKit/Source/core/dom/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,15 @@
#include "public/platform/WebFocusType.h"
#include "public/platform/WebInsecureRequestPolicy.h"

namespace ukm {
class UkmRecorder;
} // namespace ukm

namespace blink {

namespace mojom {
enum class EngagementLevel : int32_t;
}
} // namespace mojom

class AnimationClock;
class AXObjectCache;
Expand Down Expand Up @@ -1385,6 +1389,9 @@ class CORE_EXPORT Document : public ContainerNode,
void captureEvents() {}
void releaseEvents() {}

ukm::UkmRecorder* UkmRecorder();
int64_t UkmSourceID() const;

protected:
Document(const DocumentInit&, DocumentClassFlags = kDefaultDocumentClass);

Expand Down Expand Up @@ -1757,6 +1764,12 @@ class CORE_EXPORT Document : public ContainerNode,
bool has_high_media_engagement_;

std::unique_ptr<DocumentOutliveTimeReporter> document_outlive_time_reporter_;

// |mojo_ukm_recorder_| and |source_id_| will allow objects that are part of
// the |ukm_recorder_| and |source_id_| will allow objects that are part of
// the document to recorde UKM.
std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
int64_t ukm_source_id_;
};

extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>;
Expand Down
4 changes: 4 additions & 0 deletions third_party/WebKit/Source/core/html/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,10 @@ blink_core_sources("html") {
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
"//build/config/compiler:no_size_t_to_int_warning",
]

deps = [
"//services/metrics/public/cpp:metrics_cpp",
]
}

fuzzer_test("blink_html_tokenizer_fuzzer") {
Expand Down
58 changes: 58 additions & 0 deletions third_party/WebKit/Source/core/html/media/AutoplayUmaHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
#include "core/html/media/HTMLMediaElement.h"
#include "platform/Histogram.h"
#include "platform/wtf/CurrentTime.h"
#include "public/platform/InterfaceProvider.h"
#include "public/platform/Platform.h"
#include "services/metrics/public/cpp/ukm_entry_builder.h"
#include "services/metrics/public/cpp/ukm_recorder.h"

namespace blink {

Expand All @@ -24,6 +27,18 @@ const int32_t kOffscreenDurationUmaBucketCount = 50;
const int32_t kMaxWaitTimeUmaMS = 30 * 1000;
const int32_t kWaitTimeBucketCount = 50;

const char kAutoplayAttemptUkmEvent[] = "Media.Autoplay.Attempt";
const char kAutoplayAttemptUkmSourceMetric[] = "Source";
const char kAutoplayAttemptUkmAudioTrackMetric[] = "AudioTrack";
const char kAutoplayAttemptUkmVideoTrackMetric[] = "VideoTrack";
const char kAutoplayAttemptUkmUserGestureRequiredMetric[] =
"UserGestureRequired";
const char kAutoplayAttemptUkmMutedMetric[] = "Muted";

const char kAutoplayMutedUnmuteUkmEvent[] = "Media.Autoplay.Muted.UnmuteAction";
const char kAutoplayMutedUnmuteUkmSourceMetric[] = "Source";
const char kAutoplayMutedUnmuteUkmResultMetric[] = "Result";

} // namespace

AutoplayUmaHelper* AutoplayUmaHelper::Create(HTMLMediaElement* element) {
Expand Down Expand Up @@ -168,6 +183,22 @@ void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) {
}
}

// Record UKM autoplay event.
{
std::unique_ptr<ukm::UkmEntryBuilder> builder =
CreateUkmBuilder(kAutoplayAttemptUkmEvent);
builder->AddMetric(kAutoplayAttemptUkmSourceMetric,
source == AutoplaySource::kMethod);
builder->AddMetric(kAutoplayAttemptUkmAudioTrackMetric,
element_->HasAudio());
builder->AddMetric(kAutoplayAttemptUkmVideoTrackMetric,
element_->HasVideo());
builder->AddMetric(
kAutoplayAttemptUkmUserGestureRequiredMetric,
element_->GetAutoplayPolicy().IsGestureNeededForPlayback());
builder->AddMetric(kAutoplayAttemptUkmMutedMetric, element_->muted());
}

element_->addEventListener(EventTypeNames::playing, this, false);
}

Expand Down Expand Up @@ -257,6 +288,24 @@ void AutoplayUmaHelper::RecordAutoplayUnmuteStatus(
static_cast<int>(AutoplayUnmuteActionStatus::kNumberOfStatus)));

autoplay_unmute_histogram.Count(static_cast<int>(status));

// Record UKM event for unmute muted autoplay.
{
std::unique_ptr<ukm::UkmEntryBuilder> builder =
CreateUkmBuilder(kAutoplayMutedUnmuteUkmEvent);

int source = static_cast<int>(AutoplaySource::kAttribute);
if (sources_.size() ==
static_cast<size_t>(AutoplaySource::kNumberOfSources)) {
source = static_cast<int>(AutoplaySource::kDualSource);
} else if (sources_.count(AutoplaySource::kMethod)) {
source = static_cast<int>(AutoplaySource::kAttribute);
}

builder->AddMetric(kAutoplayMutedUnmuteUkmSourceMetric, source);
builder->AddMetric(kAutoplayMutedUnmuteUkmResultMetric,
status == AutoplayUnmuteActionStatus::kSuccess);
}
}

void AutoplayUmaHelper::VideoWillBeDrawnToCanvas() {
Expand Down Expand Up @@ -442,6 +491,15 @@ bool AutoplayUmaHelper::ShouldRecordUserPausedAutoplayingCrossOriginVideo()
CrossOriginAutoplayResult::kUserPaused);
}

std::unique_ptr<ukm::UkmEntryBuilder> AutoplayUmaHelper::CreateUkmBuilder(
const char* event) {
ukm::UkmRecorder* ukm_recorder = element_->GetDocument().UkmRecorder();
DCHECK(ukm_recorder);

return ukm_recorder->GetEntryBuilder(element_->GetDocument().UkmSourceID(),
event);
}

DEFINE_TRACE(AutoplayUmaHelper) {
EventListener::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
Expand Down
8 changes: 8 additions & 0 deletions third_party/WebKit/Source/core/html/media/AutoplayUmaHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

#include <set>

namespace ukm {
class UkmEntryBuilder;
} // namespace ukm

namespace blink {

// These values are used for histograms. Do not reorder.
Expand Down Expand Up @@ -114,6 +118,10 @@ class CORE_EXPORT AutoplayUmaHelper : public EventListener,
bool ShouldListenToContextDestroyed() const;
bool ShouldRecordUserPausedAutoplayingCrossOriginVideo() const;

// Returns a ukm::UkmEntryBuilder created from the UkmRecorder associated with
// the Document.
std::unique_ptr<ukm::UkmEntryBuilder> CreateUkmBuilder(const char*);

// The autoplay sources.
std::set<AutoplaySource> sources_;

Expand Down
5 changes: 5 additions & 0 deletions third_party/WebKit/Source/platform/weborigin/KURL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "platform/wtf/text/StringStatics.h"
#include "platform/wtf/text/StringUTF8Adaptor.h"
#include "platform/wtf/text/TextEncoding.h"
#include "url/gurl.h"
#include "url/url_util.h"
#ifndef NDEBUG
#include <stdio.h>
Expand Down Expand Up @@ -881,4 +882,8 @@ bool KURL::IsSafeToSendToAnotherThread() const {
(!inner_url_ || inner_url_->IsSafeToSendToAnotherThread());
}

KURL::operator GURL() const {
return GURL(string_.Utf8().data(), parsed_, is_valid_);
}

} // namespace blink
7 changes: 7 additions & 0 deletions third_party/WebKit/Source/platform/weborigin/KURL.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace WTF {
class TextEncoding;
}

class GURL;

namespace blink {

struct KURLHash;
Expand Down Expand Up @@ -212,6 +214,11 @@ class PLATFORM_EXPORT KURL {
return parsed_.potentially_dangling_markup;
}

// Returns a GURL with the same properties. This can be used in platform/ and
// web/. However, in core/ and modules/, this should only be used to pass
// a GURL to a layer that is expecting one instead of a KURL or a WebURL.
operator GURL() const;

private:
friend struct WTF::HashTraits<blink::KURL>;

Expand Down
Loading

0 comments on commit ad90070

Please sign in to comment.