Index: content/renderer/media/renderer_webmediaplayer_delegate.cc |
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc |
index 1eb7c8e7f2dc18ae1d3fcfdd39dff333f85a3593..ae2ab44da9ce68f410e11ce57ec250668baea795 100644 |
--- a/content/renderer/media/renderer_webmediaplayer_delegate.cc |
+++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc |
@@ -9,17 +9,31 @@ |
#include "base/auto_reset.h" |
#include "base/metrics/histogram_macros.h" |
#include "base/metrics/user_metrics_action.h" |
+#include "base/sys_info.h" |
#include "content/common/media/media_player_delegate_messages.h" |
#include "content/public/renderer/render_frame.h" |
#include "content/public/renderer/render_thread.h" |
#include "third_party/WebKit/public/platform/WebMediaPlayer.h" |
+#if defined(OS_ANDROID) |
+#include "base/android/build_info.h" |
+#endif |
+ |
namespace { |
void RecordAction(const base::UserMetricsAction& action) { |
content::RenderThread::Get()->RecordAction(action); |
} |
+bool IsLowEndDevice() { |
sandersd (OOO until July 31)
2016/09/13 23:02:42
Please comment that this check is specifically to
DaleCurtis
2016/09/15 23:03:55
Done.
|
+#if defined(OS_ANDROID) |
+ return base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || |
+ base::SysInfo::IsLowEndDevice(); |
+#else |
+ return base::SysInfo::IsLowEndDevice(); |
+#endif |
+} |
+ |
} // namespace |
namespace media { |
@@ -27,6 +41,7 @@ namespace media { |
RendererWebMediaPlayerDelegate::RendererWebMediaPlayerDelegate( |
content::RenderFrame* render_frame) |
: RenderFrameObserver(render_frame), |
+ idle_cleanup_timer_(true, true), |
default_tick_clock_(new base::DefaultTickClock()), |
tick_clock_(default_tick_clock_.get()) { |
idle_cleanup_interval_ = base::TimeDelta::FromSeconds(5); |
@@ -63,6 +78,11 @@ void RendererWebMediaPlayerDelegate::DidPlay( |
else |
playing_videos_.erase(delegate_id); |
RemoveIdleDelegate(delegate_id); |
+ |
+ // Upon receipt of a playback request, suspend everything that's not used. |
+ if (IsLowEndDevice()) |
+ CleanupIdleDelegates(base::TimeDelta()); |
+ |
Send(new MediaPlayerDelegateHostMsg_OnMediaPlaying( |
routing_id(), delegate_id, has_video, has_audio, is_remote, |
media_content_type)); |
@@ -80,7 +100,6 @@ void RendererWebMediaPlayerDelegate::DidPause(int delegate_id, |
void RendererWebMediaPlayerDelegate::PlayerGone(int delegate_id) { |
DCHECK(id_map_.Lookup(delegate_id)); |
- RemoveIdleDelegate(delegate_id); |
playing_videos_.erase(delegate_id); |
Send(new MediaPlayerDelegateHostMsg_OnMediaDestroyed(routing_id(), |
delegate_id)); |
@@ -171,9 +190,16 @@ void RendererWebMediaPlayerDelegate::AddIdleDelegate(int delegate_id) { |
idle_delegate_map_[delegate_id] = tick_clock_->NowTicks(); |
if (!idle_cleanup_timer_.IsRunning()) { |
idle_cleanup_timer_.Start( |
- FROM_HERE, idle_cleanup_interval_, this, |
- &RendererWebMediaPlayerDelegate::CleanupIdleDelegates); |
+ FROM_HERE, idle_cleanup_interval_, |
+ base::Bind(&RendererWebMediaPlayerDelegate::CleanupIdleDelegates, |
+ base::Unretained(this), idle_timeout_)); |
} |
+ |
+ // When we reach the maximum number of idle players, aggressively suspend idle |
+ // delegates to try and remain under the limit. |
+ static const size_t kMaxIdlePlayers = IsLowEndDevice() ? 2 : 8; |
+ if (idle_delegate_map_.size() > kMaxIdlePlayers) |
+ CleanupIdleDelegates(idle_timeout_ / 10); |
liberato (no reviews please)
2016/09/13 15:34:28
10?
DaleCurtis
2016/09/15 23:03:55
Just wanted something over 0, but now I don't see
|
} |
void RendererWebMediaPlayerDelegate::RemoveIdleDelegate(int delegate_id) { |
@@ -189,14 +215,15 @@ void RendererWebMediaPlayerDelegate::RemoveIdleDelegate(int delegate_id) { |
idle_cleanup_timer_.Stop(); |
} |
-void RendererWebMediaPlayerDelegate::CleanupIdleDelegates() { |
+void RendererWebMediaPlayerDelegate::CleanupIdleDelegates( |
+ base::TimeDelta idle_timeout) { |
liberato (no reviews please)
2016/09/13 15:34:28
|idle_timeout| and |idle_timeout_| are a little co
DaleCurtis
2016/09/15 23:03:55
Done.
|
// Iterate over the delegates and suspend the idle ones. Note: The call to |
// OnHidden() can trigger calls into RemoveIdleDelegate(), so for iterator |
// validity we set |idle_cleanup_running_| to true and defer deletions. |
base::AutoReset<bool> scoper(&idle_cleanup_running_, true); |
const base::TimeTicks now = tick_clock_->NowTicks(); |
for (auto& idle_delegate_entry : idle_delegate_map_) { |
- if (now - idle_delegate_entry.second > idle_timeout_) { |
+ if (now - idle_delegate_entry.second > idle_timeout) { |
id_map_.Lookup(idle_delegate_entry.first)->OnSuspendRequested(false); |
// Whether or not the player accepted the suspension, mark it for removal |