Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 478543003: Use AudioStreamMonitor to control power save blocking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move it with style! Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/web_contents/web_contents_impl.h" 5 #include "content/browser/web_contents/web_contents_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 #include "content/browser/android/date_time_chooser_android.h" 104 #include "content/browser/android/date_time_chooser_android.h"
105 #include "content/browser/media/android/browser_media_player_manager.h" 105 #include "content/browser/media/android/browser_media_player_manager.h"
106 #include "content/browser/web_contents/web_contents_android.h" 106 #include "content/browser/web_contents/web_contents_android.h"
107 #include "content/public/browser/android/content_view_core.h" 107 #include "content/public/browser/android/content_view_core.h"
108 #endif 108 #endif
109 109
110 #if defined(OS_MACOSX) 110 #if defined(OS_MACOSX)
111 #include "base/mac/foundation_util.h" 111 #include "base/mac/foundation_util.h"
112 #endif 112 #endif
113 113
114 // Only do audio stream monitoring for platforms that use it for the tab media
115 // indicator UI or the OOM killer.
116 #if !defined(OS_ANDROID) && !defined(OS_IOS)
117 #define AUDIO_STREAM_MONITORING
jam 2014/09/02 19:50:33 nit: use a boolean member in this class that is in
DaleCurtis 2014/09/04 21:59:06 I instead plumbing a bit which is defined where th
118 #include "content/browser/media/audio_stream_monitor.h"
119 #endif
120
114 // Cross-Site Navigations 121 // Cross-Site Navigations
115 // 122 //
116 // If a WebContentsImpl is told to navigate to a different web site (as 123 // If a WebContentsImpl is told to navigate to a different web site (as
117 // determined by SiteInstance), it will replace its current RenderViewHost with 124 // determined by SiteInstance), it will replace its current RenderViewHost with
118 // a new RenderViewHost dedicated to the new SiteInstance. This works as 125 // a new RenderViewHost dedicated to the new SiteInstance. This works as
119 // follows: 126 // follows:
120 // 127 //
121 // - RVHM::Navigate determines whether the destination is cross-site, and if so, 128 // - RVHM::Navigate determines whether the destination is cross-site, and if so,
122 // it creates a pending_render_view_host_. 129 // it creates a pending_render_view_host_.
123 // - The pending RVH is "suspended," so that no navigation messages are sent to 130 // - The pending RVH is "suspended," so that no navigation messages are sent to
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 last_active_time_ = base::TimeTicks::Now(); 1042 last_active_time_ = base::TimeTicks::Now();
1036 1043
1037 // The resize rect might have changed while this was inactive -- send the new 1044 // The resize rect might have changed while this was inactive -- send the new
1038 // one to make sure it's up to date. 1045 // one to make sure it's up to date.
1039 RenderViewHostImpl* rvh = 1046 RenderViewHostImpl* rvh =
1040 static_cast<RenderViewHostImpl*>(GetRenderViewHost()); 1047 static_cast<RenderViewHostImpl*>(GetRenderViewHost());
1041 if (rvh) { 1048 if (rvh) {
1042 rvh->ResizeRectChanged(GetRootWindowResizerRect()); 1049 rvh->ResizeRectChanged(GetRootWindowResizerRect());
1043 } 1050 }
1044 1051
1052 // Restore power save blocker if there are active video players running.
1053 if (!active_media_players_.empty())
1054 CreatePowerSaveBlocker();
1055
1045 FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown()); 1056 FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown());
1046 1057
1047 should_normally_be_visible_ = true; 1058 should_normally_be_visible_ = true;
1048 } 1059 }
1049 1060
1050 void WebContentsImpl::WasHidden() { 1061 void WebContentsImpl::WasHidden() {
1051 // If there are entities capturing screenshots or video (e.g., mirroring), 1062 // If there are entities capturing screenshots or video (e.g., mirroring),
1052 // don't activate the "disable rendering" optimization. 1063 // don't activate the "disable rendering" optimization.
1053 if (capturer_count_ == 0) { 1064 if (capturer_count_ == 0) {
1054 // |GetRenderViewHost()| can be NULL if the user middle clicks a link to 1065 // |GetRenderViewHost()| can be NULL if the user middle clicks a link to
1055 // open a tab in the background, then closes the tab before selecting it. 1066 // open a tab in the background, then closes the tab before selecting it.
1056 // This is because closing the tab calls WebContentsImpl::Destroy(), which 1067 // This is because closing the tab calls WebContentsImpl::Destroy(), which
1057 // removes the |GetRenderViewHost()|; then when we actually destroy the 1068 // removes the |GetRenderViewHost()|; then when we actually destroy the
1058 // window, OnWindowPosChanged() notices and calls WasHidden() (which 1069 // window, OnWindowPosChanged() notices and calls WasHidden() (which
1059 // calls us). 1070 // calls us).
1060 std::set<RenderWidgetHostView*> widgets = GetRenderWidgetHostViewsInTree(); 1071 std::set<RenderWidgetHostView*> widgets = GetRenderWidgetHostViewsInTree();
1061 for (std::set<RenderWidgetHostView*>::iterator iter = widgets.begin(); 1072 for (std::set<RenderWidgetHostView*>::iterator iter = widgets.begin();
1062 iter != widgets.end(); 1073 iter != widgets.end();
1063 iter++) { 1074 iter++) {
1064 if (*iter) 1075 if (*iter)
1065 (*iter)->Hide(); 1076 (*iter)->Hide();
1066 } 1077 }
1067 } 1078 }
1068 1079
1080 // Release any video power save blockers held as video is not visible.
1081 power_save_blocker_.reset();
1082
1069 FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden()); 1083 FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden());
1070 1084
1071 should_normally_be_visible_ = false; 1085 should_normally_be_visible_ = false;
1072 } 1086 }
1073 1087
1074 bool WebContentsImpl::NeedToFireBeforeUnload() { 1088 bool WebContentsImpl::NeedToFireBeforeUnload() {
1075 // TODO(creis): Should we fire even for interstitial pages? 1089 // TODO(creis): Should we fire even for interstitial pages?
1076 return WillNotifyDisconnection() && 1090 return WillNotifyDisconnection() &&
1077 !ShowingInterstitialPage() && 1091 !ShowingInterstitialPage() &&
1078 !static_cast<RenderViewHostImpl*>( 1092 !static_cast<RenderViewHostImpl*>(
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 2395
2382 void WebContentsImpl::StopFinding(StopFindAction action) { 2396 void WebContentsImpl::StopFinding(StopFindAction action) {
2383 Send(new ViewMsg_StopFinding(GetRoutingID(), action)); 2397 Send(new ViewMsg_StopFinding(GetRoutingID(), action));
2384 } 2398 }
2385 2399
2386 void WebContentsImpl::InsertCSS(const std::string& css) { 2400 void WebContentsImpl::InsertCSS(const std::string& css) {
2387 GetMainFrame()->Send(new FrameMsg_CSSInsertRequest( 2401 GetMainFrame()->Send(new FrameMsg_CSSInsertRequest(
2388 GetMainFrame()->GetRoutingID(), css)); 2402 GetMainFrame()->GetRoutingID(), css));
2389 } 2403 }
2390 2404
2405 bool WebContentsImpl::WasRecentlyAudible() {
2406 #if !defined(AUDIO_STREAM_MONITORING)
2407 return false;
2408 #else
2409 AudioStreamMonitor* const monitor = AudioStreamMonitor::FromWebContents(this);
2410 return monitor ? monitor->WasRecentlyAudible() : false;
2411 #endif
2412 }
2413
2391 bool WebContentsImpl::FocusLocationBarByDefault() { 2414 bool WebContentsImpl::FocusLocationBarByDefault() {
2392 NavigationEntry* entry = controller_.GetVisibleEntry(); 2415 NavigationEntry* entry = controller_.GetVisibleEntry();
2393 if (entry && entry->GetURL() == GURL(url::kAboutBlankURL)) 2416 if (entry && entry->GetURL() == GURL(url::kAboutBlankURL))
2394 return true; 2417 return true;
2395 return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this); 2418 return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this);
2396 } 2419 }
2397 2420
2398 void WebContentsImpl::SetFocusToLocationBar(bool select_all) { 2421 void WebContentsImpl::SetFocusToLocationBar(bool select_all) {
2399 if (delegate_) 2422 if (delegate_)
2400 delegate_->SetFocusToLocationBar(select_all); 2423 delegate_->SetFocusToLocationBar(select_all);
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 } 3015 }
2993 image_download_map_.erase(id); 3016 image_download_map_.erase(id);
2994 } 3017 }
2995 3018
2996 void WebContentsImpl::OnUpdateFaviconURL( 3019 void WebContentsImpl::OnUpdateFaviconURL(
2997 const std::vector<FaviconURL>& candidates) { 3020 const std::vector<FaviconURL>& candidates) {
2998 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3021 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2999 DidUpdateFaviconURL(candidates)); 3022 DidUpdateFaviconURL(candidates));
3000 } 3023 }
3001 3024
3025 void WebContentsImpl::CreatePowerSaveBlocker() {
3026 DCHECK(!power_save_blocker_);
3027 DCHECK(!active_media_players_.empty());
3028 power_save_blocker_ = PowerSaveBlocker::Create(
3029 PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing Video");
3030 #if defined(OS_ANDROID)
3031 static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())
3032 ->InitDisplaySleepBlocker(GetView()->GetNativeView());
3033 #endif
3034 }
3035
3002 void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie, 3036 void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
3003 bool has_video, 3037 bool has_video,
3004 bool has_audio) { 3038 bool has_audio) {
3005 #if !defined(OS_CHROMEOS) 3039 #if !defined(OS_CHROMEOS)
3006 scoped_ptr<PowerSaveBlocker> blocker; 3040 #if defined(AUDIO_STREAM_MONITORING)
3007 if (has_video) { 3041 // Don't handle audio if audio level analysis is available.
3008 blocker = PowerSaveBlocker::Create( 3042 if (!has_video)
3009 PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing video"); 3043 return;
3010 #if defined(OS_ANDROID)
3011 static_cast<PowerSaveBlockerImpl*>(blocker.get())
3012 ->InitDisplaySleepBlocker(GetView()->GetNativeView());
3013 #endif 3044 #endif
3014 } else if (has_audio) {
3015 blocker = PowerSaveBlocker::Create(
miu 2014/09/02 21:04:39 I'm not sure the blocker is set up correctly for p
DaleCurtis 2014/09/03 18:48:55 It ends up being correct since Androids PowerSaveB
3016 PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing audio");
3017 }
3018 3045
3019 if (blocker) { 3046 // Track current status to see if we need to create a new blocker.
3020 uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_message_source_); 3047 const bool had_no_player = active_media_players_.empty();
3021 if (!power_save_blockers_.contains(key)) { 3048
3022 power_save_blockers_.add(key, 3049 // Store tracking entries based on the RenderFrameHost.
3023 make_scoped_ptr(new PowerSaveBlockerMapEntry)); 3050 const uintptr_t key =
3024 } 3051 reinterpret_cast<uintptr_t>(render_frame_message_source_);
3025 PowerSaveBlockerMapEntry* map_entry = 3052
3026 power_save_blockers_.get(key); 3053 ActiveMediaPlayerMap::iterator it = active_media_players_.find(key);
3027 map_entry->set(player_cookie, blocker.Pass()); 3054 if (it != active_media_players_.end())
3028 } 3055 it->second++;
3056 else
3057 active_media_players_[key] = 1;
3058
3059 // If we're not hidden and just created a new video player, create a blocker.
3060 if (had_no_player && !active_media_players_.empty() && !IsHidden())
3061 CreatePowerSaveBlocker();
3029 #endif // !defined(OS_CHROMEOS) 3062 #endif // !defined(OS_CHROMEOS)
3030 } 3063 }
3031 3064
3032 void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) { 3065 void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
3033 #if !defined(OS_CHROMEOS) 3066 #if !defined(OS_CHROMEOS)
3034 uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_message_source_); 3067 ActiveMediaPlayerMap::iterator it = active_media_players_.find(
3035 PowerSaveBlockerMapEntry* map_entry = power_save_blockers_.get(key); 3068 reinterpret_cast<uintptr_t>(render_frame_message_source_));
3036 if (map_entry) 3069 if (it == active_media_players_.end())
3037 map_entry->erase(player_cookie); 3070 return;
3071 it->second--;
3072 DCHECK_GE(it->second, 0);
3073 // If there are no more active players in this RenderFrameHost, remove entry.
3074 if (!it->second)
3075 active_media_players_.erase(it);
3076 // If there are no more active players at all, clear the power blocker.
3077 if (active_media_players_.empty()) {
3078 power_save_blocker_.reset();
3079 }
3038 #endif // !defined(OS_CHROMEOS) 3080 #endif // !defined(OS_CHROMEOS)
3039 } 3081 }
3040 3082
3041 void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() { 3083 void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() {
3042 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3084 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3043 DidFirstVisuallyNonEmptyPaint()); 3085 DidFirstVisuallyNonEmptyPaint());
3044 } 3086 }
3045 3087
3046 void WebContentsImpl::DidChangeVisibleSSLState() { 3088 void WebContentsImpl::DidChangeVisibleSSLState() {
3047 if (delegate_) 3089 if (delegate_)
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
4196 browser_plugin_guest_.reset(guest); 4238 browser_plugin_guest_.reset(guest);
4197 } 4239 }
4198 4240
4199 BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const { 4241 BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const {
4200 return browser_plugin_embedder_.get(); 4242 return browser_plugin_embedder_.get();
4201 } 4243 }
4202 4244
4203 void WebContentsImpl::ClearPowerSaveBlockers( 4245 void WebContentsImpl::ClearPowerSaveBlockers(
4204 RenderFrameHost* render_frame_host) { 4246 RenderFrameHost* render_frame_host) {
4205 #if !defined(OS_CHROMEOS) 4247 #if !defined(OS_CHROMEOS)
4206 uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host); 4248 ActiveMediaPlayerMap::iterator it = active_media_players_.find(
4207 scoped_ptr<PowerSaveBlockerMapEntry> map_entry = 4249 reinterpret_cast<uintptr_t>(render_frame_message_source_));
4208 power_save_blockers_.take_and_erase(key); 4250 if (it == active_media_players_.end())
4209 if (map_entry) 4251 return;
4210 map_entry->clear(); 4252 active_media_players_.erase(it);
4253
4254 // If there are no more active players at all, clear the power blocker.
4255 if (active_media_players_.empty())
4256 power_save_blocker_.reset();
4211 #endif 4257 #endif
4212 } 4258 }
4213 4259
4214 void WebContentsImpl::ClearAllPowerSaveBlockers() { 4260 void WebContentsImpl::ClearAllPowerSaveBlockers() {
4215 #if !defined(OS_CHROMEOS) 4261 #if !defined(OS_CHROMEOS)
4216 power_save_blockers_.clear(); 4262 active_media_players_.clear();
4263 power_save_blocker_.reset();
4217 #endif 4264 #endif
4218 } 4265 }
4219 4266
4220 gfx::Size WebContentsImpl::GetSizeForNewRenderView() { 4267 gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
4221 gfx::Size size; 4268 gfx::Size size;
4222 if (delegate_) 4269 if (delegate_)
4223 size = delegate_->GetSizeForNewRenderView(this); 4270 size = delegate_->GetSizeForNewRenderView(this);
4224 if (size.IsEmpty()) 4271 if (size.IsEmpty())
4225 size = GetContainerBounds().size(); 4272 size = GetContainerBounds().size();
4226 return size; 4273 return size;
(...skipping 17 matching lines...) Expand all
4244 node->render_manager()->ResumeResponseDeferredAtStart(); 4291 node->render_manager()->ResumeResponseDeferredAtStart();
4245 } 4292 }
4246 4293
4247 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { 4294 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
4248 force_disable_overscroll_content_ = force_disable; 4295 force_disable_overscroll_content_ = force_disable;
4249 if (view_) 4296 if (view_)
4250 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4297 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4251 } 4298 }
4252 4299
4253 } // namespace content 4300 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698