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

Side by Side Diff: content/browser/media/media_web_contents_observer.cc

Issue 2846813002: Convert MediaWebContentsObsever to be the client of WakeLock mojo interface. (Closed)
Patch Set: remove dependency, code rebase Created 3 years, 7 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/media/media_web_contents_observer.h" 5 #include "content/browser/media/media_web_contents_observer.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "content/browser/media/audible_metrics.h" 10 #include "content/browser/media/audible_metrics.h"
11 #include "content/browser/media/audio_stream_monitor.h" 11 #include "content/browser/media/audio_stream_monitor.h"
12 #include "content/browser/web_contents/web_contents_impl.h" 12 #include "content/browser/web_contents/web_contents_impl.h"
13 #include "content/common/media/media_player_delegate_messages.h" 13 #include "content/common/media/media_player_delegate_messages.h"
14 #include "content/public/browser/render_frame_host.h" 14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "device/power_save_blocker/power_save_blocker.h" 16 #include "device/wake_lock/public/interfaces/wake_lock_context.mojom.h"
17 #include "ipc/ipc_message_macros.h" 17 #include "ipc/ipc_message_macros.h"
18 #include "mojo/public/cpp/bindings/interface_request.h"
18 19
19 namespace content { 20 namespace content {
20 21
21 namespace { 22 namespace {
22 23
23 AudibleMetrics* GetAudibleMetrics() { 24 AudibleMetrics* GetAudibleMetrics() {
24 static AudibleMetrics* metrics = new AudibleMetrics(); 25 static AudibleMetrics* metrics = new AudibleMetrics();
25 return metrics; 26 return metrics;
26 } 27 }
27 28
28 } // anonymous namespace 29 } // anonymous namespace
29 30
30 MediaWebContentsObserver::MediaWebContentsObserver(WebContents* web_contents) 31 MediaWebContentsObserver::MediaWebContentsObserver(WebContents* web_contents)
31 : WebContentsObserver(web_contents), 32 : WebContentsObserver(web_contents),
33 has_audio_wake_lock_for_testing_(false),
34 has_video_wake_lock_for_testing_(false),
32 session_controllers_manager_(this) {} 35 session_controllers_manager_(this) {}
33 36
34 MediaWebContentsObserver::~MediaWebContentsObserver() = default; 37 MediaWebContentsObserver::~MediaWebContentsObserver() = default;
35 38
36 void MediaWebContentsObserver::WebContentsDestroyed() { 39 void MediaWebContentsObserver::WebContentsDestroyed() {
37 GetAudibleMetrics()->UpdateAudibleWebContentsState(web_contents(), false); 40 GetAudibleMetrics()->UpdateAudibleWebContentsState(web_contents(), false);
38 } 41 }
39 42
40 void MediaWebContentsObserver::RenderFrameDeleted( 43 void MediaWebContentsObserver::RenderFrameDeleted(
41 RenderFrameHost* render_frame_host) { 44 RenderFrameHost* render_frame_host) {
42 ClearPowerSaveBlockers(render_frame_host); 45 ClearWakeLocks(render_frame_host);
43 session_controllers_manager_.RenderFrameDeleted(render_frame_host); 46 session_controllers_manager_.RenderFrameDeleted(render_frame_host);
44 47
45 if (fullscreen_player_ && fullscreen_player_->first == render_frame_host) 48 if (fullscreen_player_ && fullscreen_player_->first == render_frame_host)
46 fullscreen_player_.reset(); 49 fullscreen_player_.reset();
47 } 50 }
48 51
49 void MediaWebContentsObserver::MaybeUpdateAudibleState() { 52 void MediaWebContentsObserver::MaybeUpdateAudibleState() {
50 AudioStreamMonitor* audio_stream_monitor = 53 AudioStreamMonitor* audio_stream_monitor =
51 static_cast<WebContentsImpl*>(web_contents())->audio_stream_monitor(); 54 static_cast<WebContentsImpl*>(web_contents())->audio_stream_monitor();
52 55
53 if (audio_stream_monitor->WasRecentlyAudible()) { 56 if (audio_stream_monitor->WasRecentlyAudible())
54 if (!audio_power_save_blocker_) 57 LockAudio();
55 CreateAudioPowerSaveBlocker(); 58 else
56 } else { 59 CancelAudioLock();
57 audio_power_save_blocker_.reset();
58 }
59 60
60 GetAudibleMetrics()->UpdateAudibleWebContentsState( 61 GetAudibleMetrics()->UpdateAudibleWebContentsState(
61 web_contents(), audio_stream_monitor->IsCurrentlyAudible()); 62 web_contents(), audio_stream_monitor->IsCurrentlyAudible());
62 } 63 }
63 64
64 bool MediaWebContentsObserver::HasActiveEffectivelyFullscreenVideo() const { 65 bool MediaWebContentsObserver::HasActiveEffectivelyFullscreenVideo() const {
65 if (!web_contents()->IsFullscreen() || !fullscreen_player_) 66 if (!web_contents()->IsFullscreen() || !fullscreen_player_)
66 return false; 67 return false;
67 68
68 // Check that the player is active. 69 // Check that the player is active.
(...skipping 19 matching lines...) Expand all
88 OnMediaPlaying) 89 OnMediaPlaying)
89 IPC_MESSAGE_HANDLER( 90 IPC_MESSAGE_HANDLER(
90 MediaPlayerDelegateHostMsg_OnMediaEffectivelyFullscreenChange, 91 MediaPlayerDelegateHostMsg_OnMediaEffectivelyFullscreenChange,
91 OnMediaEffectivelyFullscreenChange) 92 OnMediaEffectivelyFullscreenChange)
92 IPC_MESSAGE_UNHANDLED(handled = false) 93 IPC_MESSAGE_UNHANDLED(handled = false)
93 IPC_END_MESSAGE_MAP() 94 IPC_END_MESSAGE_MAP()
94 return handled; 95 return handled;
95 } 96 }
96 97
97 void MediaWebContentsObserver::WasShown() { 98 void MediaWebContentsObserver::WasShown() {
98 // Restore power save blocker if there are active video players running. 99 // Restore wake lock if there are active video players running.
99 if (!active_video_players_.empty() && !video_power_save_blocker_) 100 if (!active_video_players_.empty())
100 CreateVideoPowerSaveBlocker(); 101 LockVideo();
101 } 102 }
102 103
103 void MediaWebContentsObserver::WasHidden() { 104 void MediaWebContentsObserver::WasHidden() {
104 // If there are entities capturing screenshots or video (e.g., mirroring), 105 // If there are entities capturing screenshots or video (e.g., mirroring),
105 // don't release the power save blocker. 106 // don't release the wake lock.
106 if (!web_contents()->GetCapturerCount()) 107 if (!web_contents()->GetCapturerCount()) {
107 video_power_save_blocker_.reset(); 108 GetVideoWakeLock()->CancelWakeLock();
109 has_video_wake_lock_for_testing_ = false;
110 }
108 } 111 }
109 112
110 void MediaWebContentsObserver::RequestPersistentVideo(bool value) { 113 void MediaWebContentsObserver::RequestPersistentVideo(bool value) {
111 if (!fullscreen_player_) 114 if (!fullscreen_player_)
112 return; 115 return;
113 116
114 // The message is sent to the renderer even though the video is already the 117 // The message is sent to the renderer even though the video is already the
115 // fullscreen element itself. It will eventually be handled by Blink. 118 // fullscreen element itself. It will eventually be handled by Blink.
116 Send(new MediaPlayerDelegateMsg_BecamePersistentVideo( 119 Send(new MediaPlayerDelegateMsg_BecamePersistentVideo(
117 fullscreen_player_->first->GetRoutingID(), fullscreen_player_->second, 120 fullscreen_player_->first->GetRoutingID(), fullscreen_player_->second,
118 value)); 121 value));
119 } 122 }
120 123
121 void MediaWebContentsObserver::OnMediaDestroyed( 124 void MediaWebContentsObserver::OnMediaDestroyed(
122 RenderFrameHost* render_frame_host, 125 RenderFrameHost* render_frame_host,
123 int delegate_id) { 126 int delegate_id) {
124 OnMediaPaused(render_frame_host, delegate_id, true); 127 OnMediaPaused(render_frame_host, delegate_id, true);
125 } 128 }
126 129
127 void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host, 130 void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host,
128 int delegate_id, 131 int delegate_id,
129 bool reached_end_of_stream) { 132 bool reached_end_of_stream) {
130 const MediaPlayerId player_id(render_frame_host, delegate_id); 133 const MediaPlayerId player_id(render_frame_host, delegate_id);
131 const bool removed_audio = 134 const bool removed_audio =
132 RemoveMediaPlayerEntry(player_id, &active_audio_players_); 135 RemoveMediaPlayerEntry(player_id, &active_audio_players_);
133 const bool removed_video = 136 const bool removed_video =
134 RemoveMediaPlayerEntry(player_id, &active_video_players_); 137 RemoveMediaPlayerEntry(player_id, &active_video_players_);
135 MaybeReleasePowerSaveBlockers(); 138 MaybeCancelVideoLock();
136 139
137 if (removed_audio || removed_video) { 140 if (removed_audio || removed_video) {
138 // Notify observers the player has been "paused". 141 // Notify observers the player has been "paused".
139 static_cast<WebContentsImpl*>(web_contents()) 142 static_cast<WebContentsImpl*>(web_contents())
140 ->MediaStoppedPlaying( 143 ->MediaStoppedPlaying(
141 WebContentsObserver::MediaPlayerInfo(removed_video), player_id); 144 WebContentsObserver::MediaPlayerInfo(removed_video), player_id);
142 } 145 }
143 146
144 if (reached_end_of_stream) 147 if (reached_end_of_stream)
145 session_controllers_manager_.OnEnd(player_id); 148 session_controllers_manager_.OnEnd(player_id);
(...skipping 14 matching lines...) Expand all
160 if (is_remote) 163 if (is_remote)
161 return; 164 return;
162 165
163 const MediaPlayerId id(render_frame_host, delegate_id); 166 const MediaPlayerId id(render_frame_host, delegate_id);
164 if (has_audio) 167 if (has_audio)
165 AddMediaPlayerEntry(id, &active_audio_players_); 168 AddMediaPlayerEntry(id, &active_audio_players_);
166 169
167 if (has_video) { 170 if (has_video) {
168 AddMediaPlayerEntry(id, &active_video_players_); 171 AddMediaPlayerEntry(id, &active_video_players_);
169 172
170 // If we're not hidden and have just created a player, create a blocker. 173 // If we're not hidden and have just created a player, create a wakelock.
171 if (!video_power_save_blocker_ && 174 if (!static_cast<WebContentsImpl*>(web_contents())->IsHidden())
172 !static_cast<WebContentsImpl*>(web_contents())->IsHidden()) { 175 LockVideo();
173 CreateVideoPowerSaveBlocker();
174 }
175 } 176 }
176 177
177 if (!session_controllers_manager_.RequestPlay( 178 if (!session_controllers_manager_.RequestPlay(
178 id, has_audio, is_remote, media_content_type)) { 179 id, has_audio, is_remote, media_content_type)) {
179 return; 180 return;
180 } 181 }
181 182
182 // Notify observers of the new player. 183 // Notify observers of the new player.
183 DCHECK(has_audio || has_video); 184 DCHECK(has_audio || has_video);
184 static_cast<WebContentsImpl*>(web_contents()) 185 static_cast<WebContentsImpl*>(web_contents())
185 ->MediaStartedPlaying(WebContentsObserver::MediaPlayerInfo(has_video), 186 ->MediaStartedPlaying(WebContentsObserver::MediaPlayerInfo(has_video),
186 id); 187 id);
187 } 188 }
188 189
189 void MediaWebContentsObserver::OnMediaEffectivelyFullscreenChange( 190 void MediaWebContentsObserver::OnMediaEffectivelyFullscreenChange(
190 RenderFrameHost* render_frame_host, 191 RenderFrameHost* render_frame_host,
191 int delegate_id, 192 int delegate_id,
192 bool is_fullscreen) { 193 bool is_fullscreen) {
193 const MediaPlayerId id(render_frame_host, delegate_id); 194 const MediaPlayerId id(render_frame_host, delegate_id);
194 195
195 if (!is_fullscreen) { 196 if (!is_fullscreen) {
196 if (fullscreen_player_ && *fullscreen_player_ == id) 197 if (fullscreen_player_ && *fullscreen_player_ == id)
197 fullscreen_player_.reset(); 198 fullscreen_player_.reset();
198 return; 199 return;
199 } 200 }
200 201
201 fullscreen_player_ = id; 202 fullscreen_player_ = id;
202 } 203 }
203 204
204 void MediaWebContentsObserver::ClearPowerSaveBlockers( 205 void MediaWebContentsObserver::ClearWakeLocks(
205 RenderFrameHost* render_frame_host) { 206 RenderFrameHost* render_frame_host) {
206 std::set<MediaPlayerId> removed_players; 207 std::set<MediaPlayerId> removed_players;
207 RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_, 208 RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_,
208 &removed_players); 209 &removed_players);
209 std::set<MediaPlayerId> video_players(removed_players); 210 std::set<MediaPlayerId> video_players(removed_players);
210 RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_, 211 RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_,
211 &removed_players); 212 &removed_players);
212 MaybeReleasePowerSaveBlockers(); 213 MaybeCancelVideoLock();
213 214
214 // Notify all observers the player has been "paused". 215 // Notify all observers the player has been "paused".
215 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents()); 216 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents());
216 for (const auto& id : removed_players) { 217 for (const auto& id : removed_players) {
217 auto it = video_players.find(id); 218 auto it = video_players.find(id);
218 bool was_video = (it != video_players.end()); 219 bool was_video = (it != video_players.end());
219 wci->MediaStoppedPlaying(WebContentsObserver::MediaPlayerInfo(was_video), 220 wci->MediaStoppedPlaying(WebContentsObserver::MediaPlayerInfo(was_video),
220 id); 221 id);
221 } 222 }
222 } 223 }
223 224
224 void MediaWebContentsObserver::CreateAudioPowerSaveBlocker() { 225 device::mojom::WakeLockService* MediaWebContentsObserver::GetAudioWakeLock() {
225 DCHECK(!audio_power_save_blocker_); 226 // Here is a lazy binding, and will not reconnect after connection error.
226 audio_power_save_blocker_.reset(new device::PowerSaveBlocker( 227 if (!audio_wake_lock_) {
227 device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 228 device::mojom::WakeLockServiceRequest request =
228 device::PowerSaveBlocker::kReasonAudioPlayback, "Playing audio", 229 mojo::MakeRequest(&audio_wake_lock_);
229 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), 230 device::mojom::WakeLockContext* wake_lock_context =
230 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE))); 231 web_contents()->GetWakeLockContext();
232 if (wake_lock_context) {
233 wake_lock_context->GetWakeLock(
234 device::mojom::WakeLockType::PreventAppSuspension,
235 device::mojom::WakeLockReason::ReasonAudioPlayback, "Playing audio",
236 std::move(request));
237 }
238 }
239 return audio_wake_lock_.get();
231 } 240 }
232 241
233 void MediaWebContentsObserver::CreateVideoPowerSaveBlocker() { 242 device::mojom::WakeLockService* MediaWebContentsObserver::GetVideoWakeLock() {
234 DCHECK(!video_power_save_blocker_); 243 // Here is a lazy binding, and will not reconnect after connection error.
235 DCHECK(!active_video_players_.empty()); 244 if (!video_wake_lock_) {
236 video_power_save_blocker_.reset(new device::PowerSaveBlocker( 245 device::mojom::WakeLockServiceRequest request =
237 device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, 246 mojo::MakeRequest(&video_wake_lock_);
238 device::PowerSaveBlocker::kReasonVideoPlayback, "Playing video", 247 device::mojom::WakeLockContext* wake_lock_context =
239 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), 248 web_contents()->GetWakeLockContext();
240 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE))); 249 if (wake_lock_context) {
241 #if defined(OS_ANDROID) 250 wake_lock_context->GetWakeLock(
242 if (web_contents()->GetNativeView()) { 251 device::mojom::WakeLockType::PreventDisplaySleep,
243 video_power_save_blocker_.get()->InitDisplaySleepBlocker( 252 device::mojom::WakeLockReason::ReasonVideoPlayback, "Playing video",
244 web_contents()->GetNativeView()); 253 std::move(request));
254 }
245 } 255 }
246 #endif 256 return video_wake_lock_.get();
247 } 257 }
248 258
249 void MediaWebContentsObserver::MaybeReleasePowerSaveBlockers() { 259 void MediaWebContentsObserver::LockAudio() {
250 // If there are no more video players, clear the video power save blocker. 260 GetAudioWakeLock()->RequestWakeLock();
261 has_audio_wake_lock_for_testing_ = true;
262 }
263
264 void MediaWebContentsObserver::CancelAudioLock() {
265 GetAudioWakeLock()->CancelWakeLock();
266 has_audio_wake_lock_for_testing_ = false;
267 }
268
269 void MediaWebContentsObserver::LockVideo() {
270 DCHECK(!active_video_players_.empty());
271 GetVideoWakeLock()->RequestWakeLock();
272 has_video_wake_lock_for_testing_ = true;
273 }
274
275 void MediaWebContentsObserver::CancelVideoLock() {
276 GetVideoWakeLock()->CancelWakeLock();
277 has_video_wake_lock_for_testing_ = false;
278 }
279
280 void MediaWebContentsObserver::MaybeCancelVideoLock() {
281 // If there are no more video players, cancel the video wake lock.
251 if (active_video_players_.empty()) 282 if (active_video_players_.empty())
252 video_power_save_blocker_.reset(); 283 CancelVideoLock();
253 } 284 }
254 285
255 void MediaWebContentsObserver::AddMediaPlayerEntry( 286 void MediaWebContentsObserver::AddMediaPlayerEntry(
256 const MediaPlayerId& id, 287 const MediaPlayerId& id,
257 ActiveMediaPlayerMap* player_map) { 288 ActiveMediaPlayerMap* player_map) {
258 (*player_map)[id.first].insert(id.second); 289 (*player_map)[id.first].insert(id.second);
259 } 290 }
260 291
261 bool MediaWebContentsObserver::RemoveMediaPlayerEntry( 292 bool MediaWebContentsObserver::RemoveMediaPlayerEntry(
262 const MediaPlayerId& id, 293 const MediaPlayerId& id,
(...skipping 22 matching lines...) Expand all
285 if (it == player_map->end()) 316 if (it == player_map->end())
286 return; 317 return;
287 318
288 for (int delegate_id : it->second) 319 for (int delegate_id : it->second)
289 removed_players->insert(MediaPlayerId(render_frame_host, delegate_id)); 320 removed_players->insert(MediaPlayerId(render_frame_host, delegate_id));
290 321
291 player_map->erase(it); 322 player_map->erase(it);
292 } 323 }
293 324
294 } // namespace content 325 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/media_web_contents_observer.h ('k') | content/browser/web_contents/web_contents_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698