| Index: content/browser/web_contents/web_contents_impl.cc
|
| diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
| index 501ae9aa0f4ed99da6be0385031b7cc5c55f39de..5c98256548fcedd504bd0a5c58d7cbd1573243e4 100644
|
| --- a/content/browser/web_contents/web_contents_impl.cc
|
| +++ b/content/browser/web_contents/web_contents_impl.cc
|
| @@ -111,6 +111,13 @@
|
| #include "base/mac/foundation_util.h"
|
| #endif
|
|
|
| +// Only do audio stream monitoring for platforms that use it for the tab media
|
| +// indicator UI or the OOM killer.
|
| +#if !defined(OS_ANDROID) && !defined(OS_IOS)
|
| +#define AUDIO_STREAM_MONITORING
|
| +#include "content/browser/media/audio_stream_monitor.h"
|
| +#endif
|
| +
|
| // Cross-Site Navigations
|
| //
|
| // If a WebContentsImpl is told to navigate to a different web site (as
|
| @@ -1042,6 +1049,10 @@ void WebContentsImpl::WasShown() {
|
| rvh->ResizeRectChanged(GetRootWindowResizerRect());
|
| }
|
|
|
| + // Restore power save blocker if there are active video players running.
|
| + if (!active_media_players_.empty())
|
| + CreatePowerSaveBlocker();
|
| +
|
| FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown());
|
|
|
| should_normally_be_visible_ = true;
|
| @@ -1066,6 +1077,9 @@ void WebContentsImpl::WasHidden() {
|
| }
|
| }
|
|
|
| + // Release any video power save blockers held as video is not visible.
|
| + power_save_blocker_.reset();
|
| +
|
| FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden());
|
|
|
| should_normally_be_visible_ = false;
|
| @@ -2388,6 +2402,15 @@ void WebContentsImpl::InsertCSS(const std::string& css) {
|
| GetMainFrame()->GetRoutingID(), css));
|
| }
|
|
|
| +bool WebContentsImpl::WasRecentlyAudible() {
|
| +#if !defined(AUDIO_STREAM_MONITORING)
|
| + return false;
|
| +#else
|
| + AudioStreamMonitor* const monitor = AudioStreamMonitor::FromWebContents(this);
|
| + return monitor ? monitor->WasRecentlyAudible() : false;
|
| +#endif
|
| +}
|
| +
|
| bool WebContentsImpl::FocusLocationBarByDefault() {
|
| NavigationEntry* entry = controller_.GetVisibleEntry();
|
| if (entry && entry->GetURL() == GURL(url::kAboutBlankURL))
|
| @@ -2999,42 +3022,61 @@ void WebContentsImpl::OnUpdateFaviconURL(
|
| DidUpdateFaviconURL(candidates));
|
| }
|
|
|
| +void WebContentsImpl::CreatePowerSaveBlocker() {
|
| + DCHECK(!power_save_blocker_);
|
| + DCHECK(!active_media_players_.empty());
|
| + power_save_blocker_ = PowerSaveBlocker::Create(
|
| + PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing Video");
|
| +#if defined(OS_ANDROID)
|
| + static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())
|
| + ->InitDisplaySleepBlocker(GetView()->GetNativeView());
|
| +#endif
|
| +}
|
| +
|
| void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
|
| bool has_video,
|
| bool has_audio) {
|
| #if !defined(OS_CHROMEOS)
|
| - scoped_ptr<PowerSaveBlocker> blocker;
|
| - if (has_video) {
|
| - blocker = PowerSaveBlocker::Create(
|
| - PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing video");
|
| -#if defined(OS_ANDROID)
|
| - static_cast<PowerSaveBlockerImpl*>(blocker.get())
|
| - ->InitDisplaySleepBlocker(GetView()->GetNativeView());
|
| +#if defined(AUDIO_STREAM_MONITORING)
|
| + // Don't handle audio if audio level analysis is available.
|
| + if (!has_video)
|
| + return;
|
| #endif
|
| - } else if (has_audio) {
|
| - blocker = PowerSaveBlocker::Create(
|
| - PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing audio");
|
| - }
|
|
|
| - if (blocker) {
|
| - uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_message_source_);
|
| - if (!power_save_blockers_.contains(key)) {
|
| - power_save_blockers_.add(key,
|
| - make_scoped_ptr(new PowerSaveBlockerMapEntry));
|
| - }
|
| - PowerSaveBlockerMapEntry* map_entry =
|
| - power_save_blockers_.get(key);
|
| - map_entry->set(player_cookie, blocker.Pass());
|
| - }
|
| + // Track current status to see if we need to create a new blocker.
|
| + const bool had_no_player = active_media_players_.empty();
|
| +
|
| + // Store tracking entries based on the RenderFrameHost.
|
| + const uintptr_t key =
|
| + reinterpret_cast<uintptr_t>(render_frame_message_source_);
|
| +
|
| + ActiveMediaPlayerMap::iterator it = active_media_players_.find(key);
|
| + if (it != active_media_players_.end())
|
| + it->second++;
|
| + else
|
| + active_media_players_[key] = 1;
|
| +
|
| + // If we're not hidden and just created a new video player, create a blocker.
|
| + if (had_no_player && !active_media_players_.empty() && !IsHidden())
|
| + CreatePowerSaveBlocker();
|
| #endif // !defined(OS_CHROMEOS)
|
| }
|
|
|
| void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
|
| #if !defined(OS_CHROMEOS)
|
| - uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_message_source_);
|
| - PowerSaveBlockerMapEntry* map_entry = power_save_blockers_.get(key);
|
| - if (map_entry)
|
| - map_entry->erase(player_cookie);
|
| + ActiveMediaPlayerMap::iterator it = active_media_players_.find(
|
| + reinterpret_cast<uintptr_t>(render_frame_message_source_));
|
| + if (it == active_media_players_.end())
|
| + return;
|
| + it->second--;
|
| + DCHECK_GE(it->second, 0);
|
| + // If there are no more active players in this RenderFrameHost, remove entry.
|
| + if (!it->second)
|
| + active_media_players_.erase(it);
|
| + // If there are no more active players at all, clear the power blocker.
|
| + if (active_media_players_.empty()) {
|
| + power_save_blocker_.reset();
|
| + }
|
| #endif // !defined(OS_CHROMEOS)
|
| }
|
|
|
| @@ -4203,17 +4245,22 @@ BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const {
|
| void WebContentsImpl::ClearPowerSaveBlockers(
|
| RenderFrameHost* render_frame_host) {
|
| #if !defined(OS_CHROMEOS)
|
| - uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
|
| - scoped_ptr<PowerSaveBlockerMapEntry> map_entry =
|
| - power_save_blockers_.take_and_erase(key);
|
| - if (map_entry)
|
| - map_entry->clear();
|
| + ActiveMediaPlayerMap::iterator it = active_media_players_.find(
|
| + reinterpret_cast<uintptr_t>(render_frame_message_source_));
|
| + if (it == active_media_players_.end())
|
| + return;
|
| + active_media_players_.erase(it);
|
| +
|
| + // If there are no more active players at all, clear the power blocker.
|
| + if (active_media_players_.empty())
|
| + power_save_blocker_.reset();
|
| #endif
|
| }
|
|
|
| void WebContentsImpl::ClearAllPowerSaveBlockers() {
|
| #if !defined(OS_CHROMEOS)
|
| - power_save_blockers_.clear();
|
| + active_media_players_.clear();
|
| + power_save_blocker_.reset();
|
| #endif
|
| }
|
|
|
|
|