blob: 3ad04eeda1eb82004794ca9afaf3b03cf39f73de [file] [log] [blame]
// 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/no_state_prefetch/renderer/prerender_utils.h"
#include "components/no_state_prefetch/renderer/no_state_prefetch_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 NoStatePrefetch.
if ((render_frame->GetRenderView()->GetWebView()->GetVisibilityState() !=
content::PageVisibilityState::kVisible &&
!has_played_media_before) ||
prerender::NoStatePrefetchHelper::IsPrefetching(render_frame)) {
new MediaLoadDeferrer(render_frame->GetRenderView(), std::move(closure));
return true;
}
std::move(closure).Run();
return false;
}
} // namespace prerender