| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/renderer/media/renderer_webmediaplayer_delegate.h" | 5 #include "content/renderer/media/renderer_webmediaplayer_delegate.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "content/common/media/media_player_delegate_messages.h" | 10 #include "content/common/media/media_player_delegate_messages.h" |
| 11 #include "content/public/renderer/render_frame.h" | 11 #include "content/public/renderer/render_frame.h" |
| 12 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" | 12 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" |
| 13 | 13 |
| 14 namespace media { | 14 namespace media { |
| 15 | 15 |
| 16 RendererWebMediaPlayerDelegate::RendererWebMediaPlayerDelegate( | 16 RendererWebMediaPlayerDelegate::RendererWebMediaPlayerDelegate( |
| 17 content::RenderFrame* render_frame) | 17 content::RenderFrame* render_frame) |
| 18 : RenderFrameObserver(render_frame), | 18 : RenderFrameObserver(render_frame), |
| 19 default_tick_clock_(new base::DefaultTickClock()), | 19 default_tick_clock_(new base::DefaultTickClock()), |
| 20 tick_clock_(default_tick_clock_.get()) { | 20 tick_clock_(default_tick_clock_.get()) { |
| 21 #if defined(OS_ANDROID) | |
| 22 // On Android the idle cleanup timer is enabled by default. | |
| 23 // TODO(dalecurtis): Eventually this should be enabled on all platforms. | |
| 24 idle_cleanup_enabled_ = true; | |
| 25 idle_cleanup_interval_ = base::TimeDelta::FromSeconds(5); | 21 idle_cleanup_interval_ = base::TimeDelta::FromSeconds(5); |
| 26 idle_timeout_ = base::TimeDelta::FromSeconds(15); | 22 idle_timeout_ = base::TimeDelta::FromSeconds(15); |
| 27 #endif | |
| 28 } | 23 } |
| 29 | 24 |
| 30 RendererWebMediaPlayerDelegate::~RendererWebMediaPlayerDelegate() {} | 25 RendererWebMediaPlayerDelegate::~RendererWebMediaPlayerDelegate() {} |
| 31 | 26 |
| 32 int RendererWebMediaPlayerDelegate::AddObserver(Observer* observer) { | 27 int RendererWebMediaPlayerDelegate::AddObserver(Observer* observer) { |
| 33 const int delegate_id = id_map_.Add(observer); | 28 const int delegate_id = id_map_.Add(observer); |
| 34 AddIdleDelegate(delegate_id); | 29 AddIdleDelegate(delegate_id); |
| 35 return delegate_id; | 30 return delegate_id; |
| 36 } | 31 } |
| 37 | 32 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 49 DCHECK(id_map_.Lookup(delegate_id)); | 44 DCHECK(id_map_.Lookup(delegate_id)); |
| 50 has_played_media_ = true; | 45 has_played_media_ = true; |
| 51 RemoveIdleDelegate(delegate_id); | 46 RemoveIdleDelegate(delegate_id); |
| 52 Send(new MediaPlayerDelegateHostMsg_OnMediaPlaying( | 47 Send(new MediaPlayerDelegateHostMsg_OnMediaPlaying( |
| 53 routing_id(), delegate_id, has_video, has_audio, is_remote, duration)); | 48 routing_id(), delegate_id, has_video, has_audio, is_remote, duration)); |
| 54 } | 49 } |
| 55 | 50 |
| 56 void RendererWebMediaPlayerDelegate::DidPause(int delegate_id, | 51 void RendererWebMediaPlayerDelegate::DidPause(int delegate_id, |
| 57 bool reached_end_of_stream) { | 52 bool reached_end_of_stream) { |
| 58 DCHECK(id_map_.Lookup(delegate_id)); | 53 DCHECK(id_map_.Lookup(delegate_id)); |
| 59 if (reached_end_of_stream) | 54 AddIdleDelegate(delegate_id); |
| 60 AddIdleDelegate(delegate_id); | |
| 61 Send(new MediaPlayerDelegateHostMsg_OnMediaPaused(routing_id(), delegate_id, | 55 Send(new MediaPlayerDelegateHostMsg_OnMediaPaused(routing_id(), delegate_id, |
| 62 reached_end_of_stream)); | 56 reached_end_of_stream)); |
| 63 } | 57 } |
| 64 | 58 |
| 65 void RendererWebMediaPlayerDelegate::PlayerGone(int delegate_id) { | 59 void RendererWebMediaPlayerDelegate::PlayerGone(int delegate_id) { |
| 66 DCHECK(id_map_.Lookup(delegate_id)); | 60 DCHECK(id_map_.Lookup(delegate_id)); |
| 67 RemoveIdleDelegate(delegate_id); | 61 RemoveIdleDelegate(delegate_id); |
| 68 Send(new MediaPlayerDelegateHostMsg_OnMediaDestroyed(routing_id(), | 62 Send(new MediaPlayerDelegateHostMsg_OnMediaDestroyed(routing_id(), |
| 69 delegate_id)); | 63 delegate_id)); |
| 70 } | 64 } |
| 71 | 65 |
| 72 bool RendererWebMediaPlayerDelegate::IsHidden() { | 66 bool RendererWebMediaPlayerDelegate::IsHidden() { |
| 73 return render_frame()->IsHidden(); | 67 return render_frame()->IsHidden(); |
| 74 } | 68 } |
| 75 | 69 |
| 76 void RendererWebMediaPlayerDelegate::WasHidden() { | 70 void RendererWebMediaPlayerDelegate::WasHidden() { |
| 77 for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) | 71 for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) |
| 78 it.GetCurrentValue()->OnHidden(false); | 72 it.GetCurrentValue()->OnHidden(); |
| 79 } | 73 } |
| 80 | 74 |
| 81 void RendererWebMediaPlayerDelegate::WasShown() { | 75 void RendererWebMediaPlayerDelegate::WasShown() { |
| 82 for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) | 76 for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) |
| 83 it.GetCurrentValue()->OnShown(); | 77 it.GetCurrentValue()->OnShown(); |
| 84 } | 78 } |
| 85 | 79 |
| 86 bool RendererWebMediaPlayerDelegate::OnMessageReceived( | 80 bool RendererWebMediaPlayerDelegate::OnMessageReceived( |
| 87 const IPC::Message& msg) { | 81 const IPC::Message& msg) { |
| 88 bool handled = true; | 82 bool handled = true; |
| 89 IPC_BEGIN_MESSAGE_MAP(RendererWebMediaPlayerDelegate, msg) | 83 IPC_BEGIN_MESSAGE_MAP(RendererWebMediaPlayerDelegate, msg) |
| 90 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Pause, OnMediaDelegatePause) | 84 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Pause, OnMediaDelegatePause) |
| 91 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Play, OnMediaDelegatePlay) | 85 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Play, OnMediaDelegatePlay) |
| 92 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SuspendAllMediaPlayers, | 86 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SuspendAllMediaPlayers, |
| 93 OnMediaDelegateSuspendAllMediaPlayers) | 87 OnMediaDelegateSuspendAllMediaPlayers) |
| 94 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_UpdateVolumeMultiplier, | 88 IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_UpdateVolumeMultiplier, |
| 95 OnMediaDelegateVolumeMultiplierUpdate) | 89 OnMediaDelegateVolumeMultiplierUpdate) |
| 96 IPC_MESSAGE_UNHANDLED(handled = false) | 90 IPC_MESSAGE_UNHANDLED(handled = false) |
| 97 IPC_END_MESSAGE_MAP() | 91 IPC_END_MESSAGE_MAP() |
| 98 return handled; | 92 return handled; |
| 99 } | 93 } |
| 100 | 94 |
| 101 void RendererWebMediaPlayerDelegate::EnableInstantIdleCleanupForTesting( | 95 void RendererWebMediaPlayerDelegate::SetIdleCleanupParamsForTesting( |
| 102 base::TimeDelta idle_timeout, | 96 base::TimeDelta idle_timeout, |
| 103 base::TickClock* tick_clock) { | 97 base::TickClock* tick_clock) { |
| 104 idle_cleanup_enabled_ = true; | |
| 105 idle_cleanup_interval_ = base::TimeDelta(); | 98 idle_cleanup_interval_ = base::TimeDelta(); |
| 106 idle_timeout_ = idle_timeout; | 99 idle_timeout_ = idle_timeout; |
| 107 tick_clock_ = tick_clock; | 100 tick_clock_ = tick_clock; |
| 108 } | 101 } |
| 109 | 102 |
| 110 void RendererWebMediaPlayerDelegate::OnMediaDelegatePause(int delegate_id) { | 103 void RendererWebMediaPlayerDelegate::OnMediaDelegatePause(int delegate_id) { |
| 111 Observer* observer = id_map_.Lookup(delegate_id); | 104 Observer* observer = id_map_.Lookup(delegate_id); |
| 112 if (observer) | 105 if (observer) |
| 113 observer->OnPause(); | 106 observer->OnPause(); |
| 114 } | 107 } |
| 115 | 108 |
| 116 void RendererWebMediaPlayerDelegate::OnMediaDelegatePlay(int delegate_id) { | 109 void RendererWebMediaPlayerDelegate::OnMediaDelegatePlay(int delegate_id) { |
| 117 Observer* observer = id_map_.Lookup(delegate_id); | 110 Observer* observer = id_map_.Lookup(delegate_id); |
| 118 if (observer) | 111 if (observer) |
| 119 observer->OnPlay(); | 112 observer->OnPlay(); |
| 120 } | 113 } |
| 121 | 114 |
| 122 void RendererWebMediaPlayerDelegate::OnMediaDelegateSuspendAllMediaPlayers() { | 115 void RendererWebMediaPlayerDelegate::OnMediaDelegateSuspendAllMediaPlayers() { |
| 123 for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) | 116 for (IDMap<Observer>::iterator it(&id_map_); !it.IsAtEnd(); it.Advance()) |
| 124 it.GetCurrentValue()->OnHidden(true); | 117 it.GetCurrentValue()->OnSuspendRequested(true); |
| 125 } | 118 } |
| 126 | 119 |
| 127 void RendererWebMediaPlayerDelegate::OnMediaDelegateVolumeMultiplierUpdate( | 120 void RendererWebMediaPlayerDelegate::OnMediaDelegateVolumeMultiplierUpdate( |
| 128 int delegate_id, | 121 int delegate_id, |
| 129 double multiplier) { | 122 double multiplier) { |
| 130 Observer* observer = id_map_.Lookup(delegate_id); | 123 Observer* observer = id_map_.Lookup(delegate_id); |
| 131 if (observer) | 124 if (observer) |
| 132 observer->OnVolumeMultiplierUpdate(multiplier); | 125 observer->OnVolumeMultiplierUpdate(multiplier); |
| 133 } | 126 } |
| 134 | 127 |
| 135 void RendererWebMediaPlayerDelegate::AddIdleDelegate(int delegate_id) { | 128 void RendererWebMediaPlayerDelegate::AddIdleDelegate(int delegate_id) { |
| 136 if (!idle_cleanup_enabled_) | |
| 137 return; | |
| 138 | |
| 139 idle_delegate_map_[delegate_id] = tick_clock_->NowTicks(); | 129 idle_delegate_map_[delegate_id] = tick_clock_->NowTicks(); |
| 140 if (!idle_cleanup_timer_.IsRunning()) { | 130 if (!idle_cleanup_timer_.IsRunning()) { |
| 141 idle_cleanup_timer_.Start( | 131 idle_cleanup_timer_.Start( |
| 142 FROM_HERE, idle_cleanup_interval_, this, | 132 FROM_HERE, idle_cleanup_interval_, this, |
| 143 &RendererWebMediaPlayerDelegate::CleanupIdleDelegates); | 133 &RendererWebMediaPlayerDelegate::CleanupIdleDelegates); |
| 144 } | 134 } |
| 145 } | 135 } |
| 146 | 136 |
| 147 void RendererWebMediaPlayerDelegate::RemoveIdleDelegate(int delegate_id) { | 137 void RendererWebMediaPlayerDelegate::RemoveIdleDelegate(int delegate_id) { |
| 148 if (!idle_cleanup_enabled_) | |
| 149 return; | |
| 150 | |
| 151 // To avoid invalidating the iterator, just mark the delegate for deletion | 138 // To avoid invalidating the iterator, just mark the delegate for deletion |
| 152 // using a sentinel value of an empty TimeTicks. | 139 // using a sentinel value of an empty TimeTicks. |
| 153 if (idle_cleanup_running_) { | 140 if (idle_cleanup_running_) { |
| 154 idle_delegate_map_[delegate_id] = base::TimeTicks(); | 141 idle_delegate_map_[delegate_id] = base::TimeTicks(); |
| 155 return; | 142 return; |
| 156 } | 143 } |
| 157 | 144 |
| 158 idle_delegate_map_.erase(delegate_id); | 145 idle_delegate_map_.erase(delegate_id); |
| 159 if (idle_delegate_map_.empty()) | 146 if (idle_delegate_map_.empty()) |
| 160 idle_cleanup_timer_.Stop(); | 147 idle_cleanup_timer_.Stop(); |
| 161 } | 148 } |
| 162 | 149 |
| 163 void RendererWebMediaPlayerDelegate::CleanupIdleDelegates() { | 150 void RendererWebMediaPlayerDelegate::CleanupIdleDelegates() { |
| 164 // Iterate over the delegates and suspend the idle ones. Note: The call to | 151 // Iterate over the delegates and suspend the idle ones. Note: The call to |
| 165 // OnHidden() can trigger calls into RemoveIdleDelegate(), so for iterator | 152 // OnHidden() can trigger calls into RemoveIdleDelegate(), so for iterator |
| 166 // validity we set |idle_cleanup_running_| to true and defer deletions. | 153 // validity we set |idle_cleanup_running_| to true and defer deletions. |
| 167 base::AutoReset<bool> scoper(&idle_cleanup_running_, true); | 154 base::AutoReset<bool> scoper(&idle_cleanup_running_, true); |
| 168 const base::TimeTicks now = tick_clock_->NowTicks(); | 155 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 169 for (const auto& kv : idle_delegate_map_) { | 156 for (auto& idle_delegate_entry : idle_delegate_map_) { |
| 170 if (now - kv.second > idle_timeout_) | 157 if (now - idle_delegate_entry.second > idle_timeout_) { |
| 171 id_map_.Lookup(kv.first)->OnHidden(true); | 158 id_map_.Lookup(idle_delegate_entry.first)->OnSuspendRequested(false); |
| 159 |
| 160 // Whether or not the player accepted the suspension, mark it for removal |
| 161 // from future polls to avoid running the timer forever. |
| 162 idle_delegate_entry.second = base::TimeTicks(); |
| 163 } |
| 172 } | 164 } |
| 173 | 165 |
| 174 // Take care of any removals that happened during the above iteration. | 166 // Take care of any removals that happened during the above iteration. |
| 175 for (auto it = idle_delegate_map_.begin(); it != idle_delegate_map_.end();) { | 167 for (auto it = idle_delegate_map_.begin(); it != idle_delegate_map_.end();) { |
| 176 if (it->second.is_null()) | 168 if (it->second.is_null()) |
| 177 it = idle_delegate_map_.erase(it); | 169 it = idle_delegate_map_.erase(it); |
| 178 else | 170 else |
| 179 ++it; | 171 ++it; |
| 180 } | 172 } |
| 181 | 173 |
| 182 // Shutdown the timer if no delegates are left. | 174 // Shutdown the timer if no delegates are left. |
| 183 if (idle_delegate_map_.empty()) | 175 if (idle_delegate_map_.empty()) |
| 184 idle_cleanup_timer_.Stop(); | 176 idle_cleanup_timer_.Stop(); |
| 185 } | 177 } |
| 186 | 178 |
| 187 } // namespace media | 179 } // namespace media |
| OLD | NEW |