OLD | NEW |
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 Loading... |
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 |
| 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 Loading... |
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 Loading... |
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 Loading... |
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( | |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |