Commit b0458416 authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[WebLayer] Defer media load if page isn't visible.

If the page is being invisible, we now defer media playback in the
background. I've moved this logic to a shared location so Chrome and
WebLayer can reuse it and stay in sync.

Bug: 1096088
Change-Id: I61465da4717d28ff8e9f6f83fd2a75fe79fc44ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2352819
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798072}
parent da289d32
......@@ -92,6 +92,7 @@
#include "components/prerender/common/prerender_url_loader_throttle.h"
#include "components/prerender/renderer/prerender_helper.h"
#include "components/prerender/renderer/prerender_render_frame_observer.h"
#include "components/prerender/renderer/prerender_utils.h"
#include "components/prerender/renderer/prerenderer_client.h"
#include "components/safe_browsing/buildflags.h"
#include "components/safe_browsing/content/renderer/threat_dom_details.h"
......@@ -300,31 +301,6 @@ bool IsStandaloneContentExtensionProcess() {
#endif
}
// Defers media player loading in background pages until they're visible.
class MediaLoadDeferrer : public content::RenderViewObserver {
public:
MediaLoadDeferrer(content::RenderView* render_view,
base::OnceClosure continue_loading_cb)
: content::RenderViewObserver(render_view),
continue_loading_cb_(std::move(continue_loading_cb)) {}
~MediaLoadDeferrer() override {}
// content::RenderFrameObserver implementation:
void OnDestruct() override { delete this; }
void OnPageVisibilityChanged(
content::PageVisibilityState visibility_state) override {
if (visibility_state != content::PageVisibilityState::kVisible)
return;
std::move(continue_loading_cb_).Run();
delete this;
}
private:
base::OnceClosure continue_loading_cb_;
DISALLOW_COPY_AND_ASSIGN(MediaLoadDeferrer);
};
std::unique_ptr<base::Unwinder> CreateV8Unwinder(v8::Isolate* isolate) {
return std::make_unique<V8Unwinder>(isolate);
}
......@@ -775,21 +751,8 @@ bool ChromeContentRendererClient::DeferMediaLoad(
content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure) {
// Don't allow autoplay/autoload of media resources in a page that is hidden
// and has never played any media before. We want to allow future loads even
// when hidden to allow playlist-like functionality.
//
// NOTE: This is also used to defer media loading for prerender.
if ((render_frame->GetRenderView()->GetWebView()->GetVisibilityState() !=
content::PageVisibilityState::kVisible &&
!has_played_media_before) ||
prerender::PrerenderHelper::IsPrerendering(render_frame)) {
new MediaLoadDeferrer(render_frame->GetRenderView(), std::move(closure));
return true;
}
std::move(closure).Run();
return false;
return prerender::DeferMediaLoad(render_frame, has_played_media_before,
std::move(closure));
}
#if BUILDFLAG(ENABLE_PLUGINS)
......
......@@ -11,6 +11,8 @@ static_library("renderer") {
"prerender_observer_list.h",
"prerender_render_frame_observer.cc",
"prerender_render_frame_observer.h",
"prerender_utils.cc",
"prerender_utils.h",
"prerenderer_client.cc",
"prerenderer_client.h",
]
......@@ -18,6 +20,7 @@ static_library("renderer") {
deps = [
"//components/prerender/common",
"//components/prerender/common:mojo_bindings",
"//content/public/common",
"//content/public/renderer",
"//third_party/blink/public:blink_headers",
]
......
include_rules = [
"+content/public/common",
"+content/public/renderer",
"+mojo/public/cpp/bindings",
"+third_party/blink/public",
......
// Copyright 2020 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/prerender/renderer/prerender_utils.h"
#include "components/prerender/renderer/prerender_helper.h"
#include "content/public/common/page_visibility_state.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_observer.h"
#include "third_party/blink/public/web/web_view.h"
namespace prerender {
namespace {
// Defers media player loading in background pages until they're visible.
class MediaLoadDeferrer : public content::RenderViewObserver {
public:
MediaLoadDeferrer(content::RenderView* render_view,
base::OnceClosure continue_loading_cb)
: content::RenderViewObserver(render_view),
continue_loading_cb_(std::move(continue_loading_cb)) {}
~MediaLoadDeferrer() override = default;
// content::RenderFrameObserver implementation:
void OnDestruct() override { delete this; }
void OnPageVisibilityChanged(
content::PageVisibilityState visibility_state) override {
if (visibility_state != content::PageVisibilityState::kVisible)
return;
std::move(continue_loading_cb_).Run();
delete this;
}
private:
base::OnceClosure continue_loading_cb_;
DISALLOW_COPY_AND_ASSIGN(MediaLoadDeferrer);
};
} // namespace
bool DeferMediaLoad(content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure) {
// Don't allow autoplay/autoload of media resources in a page that is hidden
// and has never played any media before. We want to allow future loads even
// when hidden to allow playlist-like functionality.
//
// NOTE: This is also used to defer media loading for prerender.
if ((render_frame->GetRenderView()->GetWebView()->GetVisibilityState() !=
content::PageVisibilityState::kVisible &&
!has_played_media_before) ||
prerender::PrerenderHelper::IsPrerendering(render_frame)) {
new MediaLoadDeferrer(render_frame->GetRenderView(), std::move(closure));
return true;
}
std::move(closure).Run();
return false;
}
} // namespace prerender
// Copyright 2020 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.
#ifndef COMPONENTS_PRERENDER_RENDERER_PRERENDER_UTILS_H_
#define COMPONENTS_PRERENDER_RENDERER_PRERENDER_UTILS_H_
#include "base/callback_forward.h"
namespace content {
class RenderFrame;
}
namespace prerender {
// Defers media load for |render_frame| if necessary, and returns true if that
// has been done. Runs |closure| at the end of the operation regardless of
// return value.
bool DeferMediaLoad(content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure);
} // namespace prerender
#endif // COMPONENTS_PRERENDER_RENDERER_PRERENDER_UTILS_H_
......@@ -17,6 +17,7 @@
#include "components/prerender/common/prerender_url_loader_throttle.h"
#include "components/prerender/renderer/prerender_helper.h"
#include "components/prerender/renderer/prerender_render_frame_observer.h"
#include "components/prerender/renderer/prerender_utils.h"
#include "components/prerender/renderer/prerenderer_client.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
......@@ -196,4 +197,12 @@ bool ContentRendererClientImpl::IsPrefetchOnly(
prerender::mojom::PrerenderMode::kPrefetchOnly;
}
bool ContentRendererClientImpl::DeferMediaLoad(
content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure) {
return prerender::DeferMediaLoad(render_frame, has_played_media_before,
std::move(closure));
}
} // namespace weblayer
......@@ -44,6 +44,9 @@ class ContentRendererClientImpl : public content::ContentRendererClient {
void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override;
bool IsPrefetchOnly(content::RenderFrame* render_frame,
const blink::WebURLRequest& request) override;
bool DeferMediaLoad(content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure) override;
private:
#if defined(OS_ANDROID)
......
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