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

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: Convert MediaWebContentsObsever to be the client of WakeLock mojo interface. 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"
17 #include "ipc/ipc_message_macros.h" 16 #include "ipc/ipc_message_macros.h"
17 #include "mojo/public/cpp/bindings/interface_request.h"
18 18
19 namespace content { 19 namespace content {
20 20
21 namespace { 21 namespace {
22 22
23 AudibleMetrics* GetAudibleMetrics() { 23 AudibleMetrics* GetAudibleMetrics() {
24 static AudibleMetrics* metrics = new AudibleMetrics(); 24 static AudibleMetrics* metrics = new AudibleMetrics();
25 return metrics; 25 return metrics;
26 } 26 }
27 27
28 } // anonymous namespace 28 } // anonymous namespace
29 29
30 MediaWebContentsObserver::MediaWebContentsObserver(WebContents* web_contents) 30 MediaWebContentsObserver::MediaWebContentsObserver(WebContents* web_contents)
31 : WebContentsObserver(web_contents), 31 : WebContentsObserver(web_contents),
32 has_audio_wake_lock_for_testing_(false),
33 has_video_wake_lock_for_testing_(false),
32 session_controllers_manager_(this) {} 34 session_controllers_manager_(this) {}
33 35
34 MediaWebContentsObserver::~MediaWebContentsObserver() = default; 36 MediaWebContentsObserver::~MediaWebContentsObserver() = default;
35 37
36 void MediaWebContentsObserver::WebContentsDestroyed() { 38 void MediaWebContentsObserver::WebContentsDestroyed() {
37 GetAudibleMetrics()->UpdateAudibleWebContentsState(web_contents(), false); 39 GetAudibleMetrics()->UpdateAudibleWebContentsState(web_contents(), false);
38 } 40 }
39 41
40 void MediaWebContentsObserver::RenderFrameDeleted( 42 void MediaWebContentsObserver::RenderFrameDeleted(
41 RenderFrameHost* render_frame_host) { 43 RenderFrameHost* render_frame_host) {
42 ClearPowerSaveBlockers(render_frame_host); 44 ClearWakeLocks(render_frame_host);
43 session_controllers_manager_.RenderFrameDeleted(render_frame_host); 45 session_controllers_manager_.RenderFrameDeleted(render_frame_host);
44 46
45 if (fullscreen_player_ && fullscreen_player_->first == render_frame_host) 47 if (fullscreen_player_ && fullscreen_player_->first == render_frame_host)
46 fullscreen_player_.reset(); 48 fullscreen_player_.reset();
47 } 49 }
48 50
49 void MediaWebContentsObserver::MaybeUpdateAudibleState() { 51 void MediaWebContentsObserver::MaybeUpdateAudibleState() {
50 AudioStreamMonitor* audio_stream_monitor = 52 AudioStreamMonitor* audio_stream_monitor =
51 static_cast<WebContentsImpl*>(web_contents())->audio_stream_monitor(); 53 static_cast<WebContentsImpl*>(web_contents())->audio_stream_monitor();
52 54
53 if (audio_stream_monitor->WasRecentlyAudible()) { 55 if (audio_stream_monitor->WasRecentlyAudible()) {
DaleCurtis 2017/05/02 17:08:42 {} not necessary for single-line if.
ke.he 2017/05/04 11:58:23 Done.
54 if (!audio_power_save_blocker_) 56 LockAudio();
55 CreateAudioPowerSaveBlocker();
56 } else { 57 } else {
57 audio_power_save_blocker_.reset(); 58 CancelAudioLock();
58 } 59 }
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
(...skipping 20 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()) {
DaleCurtis 2017/05/02 17:08:42 Ditto
ke.he 2017/05/04 11:58:23 Done.
100 CreateVideoPowerSaveBlocker(); 101 LockVideo();
102 }
101 } 103 }
102 104
103 void MediaWebContentsObserver::WasHidden() { 105 void MediaWebContentsObserver::WasHidden() {
104 // If there are entities capturing screenshots or video (e.g., mirroring), 106 // If there are entities capturing screenshots or video (e.g., mirroring),
105 // don't release the power save blocker. 107 // don't release the wake lock.
106 if (!web_contents()->GetCapturerCount()) 108 if (!web_contents()->GetCapturerCount()) {
107 video_power_save_blocker_.reset(); 109 GetVideoWakeLock()->CancelWakeLock();
DaleCurtis 2017/05/02 17:08:42 Put in CancelVideoLock() function like the audio o
ke.he 2017/05/04 11:58:23 Done.
110 has_video_wake_lock_for_testing_ = false;
111 }
108 } 112 }
109 113
110 void MediaWebContentsObserver::RequestPersistentVideo(bool value) { 114 void MediaWebContentsObserver::RequestPersistentVideo(bool value) {
111 if (!fullscreen_player_) 115 if (!fullscreen_player_)
112 return; 116 return;
113 117
114 // The message is sent to the renderer even though the video is already the 118 // 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. 119 // fullscreen element itself. It will eventually be handled by Blink.
116 Send(new MediaPlayerDelegateMsg_BecamePersistentVideo( 120 Send(new MediaPlayerDelegateMsg_BecamePersistentVideo(
117 fullscreen_player_->first->GetRoutingID(), fullscreen_player_->second, 121 fullscreen_player_->first->GetRoutingID(), fullscreen_player_->second,
118 value)); 122 value));
119 } 123 }
120 124
121 void MediaWebContentsObserver::OnMediaDestroyed( 125 void MediaWebContentsObserver::OnMediaDestroyed(
122 RenderFrameHost* render_frame_host, 126 RenderFrameHost* render_frame_host,
123 int delegate_id) { 127 int delegate_id) {
124 OnMediaPaused(render_frame_host, delegate_id, true); 128 OnMediaPaused(render_frame_host, delegate_id, true);
125 } 129 }
126 130
127 void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host, 131 void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host,
128 int delegate_id, 132 int delegate_id,
129 bool reached_end_of_stream) { 133 bool reached_end_of_stream) {
130 const MediaPlayerId player_id(render_frame_host, delegate_id); 134 const MediaPlayerId player_id(render_frame_host, delegate_id);
131 const bool removed_audio = 135 const bool removed_audio =
132 RemoveMediaPlayerEntry(player_id, &active_audio_players_); 136 RemoveMediaPlayerEntry(player_id, &active_audio_players_);
133 const bool removed_video = 137 const bool removed_video =
134 RemoveMediaPlayerEntry(player_id, &active_video_players_); 138 RemoveMediaPlayerEntry(player_id, &active_video_players_);
135 MaybeReleasePowerSaveBlockers(); 139 MaybeCancelVideoLock();
136 140
137 if (removed_audio || removed_video) { 141 if (removed_audio || removed_video) {
138 // Notify observers the player has been "paused". 142 // Notify observers the player has been "paused".
139 static_cast<WebContentsImpl*>(web_contents()) 143 static_cast<WebContentsImpl*>(web_contents())
140 ->MediaStoppedPlaying( 144 ->MediaStoppedPlaying(
141 WebContentsObserver::MediaPlayerInfo(removed_video), player_id); 145 WebContentsObserver::MediaPlayerInfo(removed_video), player_id);
142 } 146 }
143 147
144 if (reached_end_of_stream) 148 if (reached_end_of_stream)
145 session_controllers_manager_.OnEnd(player_id); 149 session_controllers_manager_.OnEnd(player_id);
(...skipping 14 matching lines...) Expand all
160 if (is_remote) 164 if (is_remote)
161 return; 165 return;
162 166
163 const MediaPlayerId id(render_frame_host, delegate_id); 167 const MediaPlayerId id(render_frame_host, delegate_id);
164 if (has_audio) 168 if (has_audio)
165 AddMediaPlayerEntry(id, &active_audio_players_); 169 AddMediaPlayerEntry(id, &active_audio_players_);
166 170
167 if (has_video) { 171 if (has_video) {
168 AddMediaPlayerEntry(id, &active_video_players_); 172 AddMediaPlayerEntry(id, &active_video_players_);
169 173
170 // If we're not hidden and have just created a player, create a blocker. 174 // If we're not hidden and have just created a player, create a wakelock.
171 if (!video_power_save_blocker_ && 175 if (!static_cast<WebContentsImpl*>(web_contents())->IsHidden()) {
DaleCurtis 2017/05/02 17:08:42 no {} necessary.
ke.he 2017/05/04 11:58:23 Done.
172 !static_cast<WebContentsImpl*>(web_contents())->IsHidden()) { 176 LockVideo();
173 CreateVideoPowerSaveBlocker();
174 } 177 }
175 } 178 }
176 179
177 if (!session_controllers_manager_.RequestPlay( 180 if (!session_controllers_manager_.RequestPlay(
178 id, has_audio, is_remote, media_content_type)) { 181 id, has_audio, is_remote, media_content_type)) {
179 return; 182 return;
180 } 183 }
181 184
182 // Notify observers of the new player. 185 // Notify observers of the new player.
183 DCHECK(has_audio || has_video); 186 DCHECK(has_audio || has_video);
(...skipping 10 matching lines...) Expand all
194 197
195 if (!is_fullscreen) { 198 if (!is_fullscreen) {
196 if (fullscreen_player_ && *fullscreen_player_ == id) 199 if (fullscreen_player_ && *fullscreen_player_ == id)
197 fullscreen_player_.reset(); 200 fullscreen_player_.reset();
198 return; 201 return;
199 } 202 }
200 203
201 fullscreen_player_ = id; 204 fullscreen_player_ = id;
202 } 205 }
203 206
204 void MediaWebContentsObserver::ClearPowerSaveBlockers( 207 void MediaWebContentsObserver::ClearWakeLocks(
205 RenderFrameHost* render_frame_host) { 208 RenderFrameHost* render_frame_host) {
206 std::set<MediaPlayerId> removed_players; 209 std::set<MediaPlayerId> removed_players;
207 RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_, 210 RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_,
208 &removed_players); 211 &removed_players);
209 std::set<MediaPlayerId> video_players(removed_players); 212 std::set<MediaPlayerId> video_players(removed_players);
210 RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_, 213 RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_,
211 &removed_players); 214 &removed_players);
212 MaybeReleasePowerSaveBlockers(); 215 MaybeCancelVideoLock();
213 216
214 // Notify all observers the player has been "paused". 217 // Notify all observers the player has been "paused".
215 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents()); 218 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents());
216 for (const auto& id : removed_players) { 219 for (const auto& id : removed_players) {
217 auto it = video_players.find(id); 220 auto it = video_players.find(id);
218 bool was_video = (it != video_players.end()); 221 bool was_video = (it != video_players.end());
219 wci->MediaStoppedPlaying(WebContentsObserver::MediaPlayerInfo(was_video), 222 wci->MediaStoppedPlaying(WebContentsObserver::MediaPlayerInfo(was_video),
220 id); 223 id);
221 } 224 }
222 } 225 }
223 226
224 void MediaWebContentsObserver::CreateAudioPowerSaveBlocker() { 227 device::mojom::WakeLockServicePtr&
225 DCHECK(!audio_power_save_blocker_); 228 MediaWebContentsObserver::GetAudioWakeLock() {
226 audio_power_save_blocker_.reset(new device::PowerSaveBlocker( 229 // Here is a lazy binding, and will not reconnect after connection error.
227 device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 230 if (!audio_wake_lock_) {
DaleCurtis 2017/05/02 17:08:42 if (audio_wake_lock_) return audio_wake_lock_.get(
228 device::PowerSaveBlocker::kReasonAudioPlayback, "Playing audio", 231 device::mojom::WakeLockServiceRequest request =
229 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), 232 mojo::MakeRequest(&audio_wake_lock_);
DaleCurtis 2017/05/02 17:08:42 Inline into the call below?
ke.he 2017/05/04 11:58:23 See comments below:)
230 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE))); 233 device::mojom::WakeLockContext* wake_lock_context =
DaleCurtis 2017/05/02 17:08:42 could be written: if (auto* context = web_content
ke.he 2017/05/04 11:58:23 It is safe that context to be null. the "mojo::Mak
234 web_contents()->GetWakeLockContext();
235 if (wake_lock_context) {
236 wake_lock_context->GetWakeLock(
237 device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
238 device::PowerSaveBlocker::kReasonAudioPlayback, "Playing audio",
239 std::move(request));
240 }
241 }
242 return audio_wake_lock_;
DaleCurtis 2017/05/02 17:08:42 It's possible this will return nullptr if there's
ke.he 2017/05/04 11:58:23 The GetAudioWakeLock() never returns nullptr as co
231 } 243 }
232 244
233 void MediaWebContentsObserver::CreateVideoPowerSaveBlocker() { 245 device::mojom::WakeLockServicePtr&
234 DCHECK(!video_power_save_blocker_); 246 MediaWebContentsObserver::GetVideoWakeLock() {
235 DCHECK(!active_video_players_.empty()); 247 // Here is a lazy binding, and will not reconnect after connection error.
236 video_power_save_blocker_.reset(new device::PowerSaveBlocker( 248 if (!video_wake_lock_) {
237 device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, 249 device::mojom::WakeLockServiceRequest request =
238 device::PowerSaveBlocker::kReasonVideoPlayback, "Playing video", 250 mojo::MakeRequest(&video_wake_lock_);
239 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), 251 device::mojom::WakeLockContext* wake_lock_context =
240 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE))); 252 web_contents()->GetWakeLockContext();
241 #if defined(OS_ANDROID) 253 if (wake_lock_context) {
242 if (web_contents()->GetNativeView()) { 254 wake_lock_context->GetWakeLock(
243 video_power_save_blocker_.get()->InitDisplaySleepBlocker( 255 device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
244 web_contents()->GetNativeView()); 256 device::PowerSaveBlocker::kReasonVideoPlayback, "Playing video",
257 std::move(request));
258 }
245 } 259 }
246 #endif 260 return video_wake_lock_;
247 } 261 }
248 262
249 void MediaWebContentsObserver::MaybeReleasePowerSaveBlockers() { 263 void MediaWebContentsObserver::LockAudio() {
250 // If there are no more video players, clear the video power save blocker. 264 GetAudioWakeLock()->RequestWakeLock();
251 if (active_video_players_.empty()) 265 has_audio_wake_lock_for_testing_ = true;
252 video_power_save_blocker_.reset(); 266 }
267
268 void MediaWebContentsObserver::CancelAudioLock() {
269 GetAudioWakeLock()->CancelWakeLock();
270 has_audio_wake_lock_for_testing_ = false;
271 }
272
273 void MediaWebContentsObserver::LockVideo() {
274 DCHECK(!active_video_players_.empty());
275 GetVideoWakeLock()->RequestWakeLock();
276 has_video_wake_lock_for_testing_ = true;
277 }
278
279 void MediaWebContentsObserver::MaybeCancelVideoLock() {
280 // If there are no more video players, cancel the video wake lock.
281 if (active_video_players_.empty()) {
282 GetVideoWakeLock()->CancelWakeLock();
283 has_video_wake_lock_for_testing_ = false;
284 }
253 } 285 }
254 286
255 void MediaWebContentsObserver::AddMediaPlayerEntry( 287 void MediaWebContentsObserver::AddMediaPlayerEntry(
256 const MediaPlayerId& id, 288 const MediaPlayerId& id,
257 ActiveMediaPlayerMap* player_map) { 289 ActiveMediaPlayerMap* player_map) {
258 (*player_map)[id.first].insert(id.second); 290 (*player_map)[id.first].insert(id.second);
259 } 291 }
260 292
261 bool MediaWebContentsObserver::RemoveMediaPlayerEntry( 293 bool MediaWebContentsObserver::RemoveMediaPlayerEntry(
262 const MediaPlayerId& id, 294 const MediaPlayerId& id,
(...skipping 22 matching lines...) Expand all
285 if (it == player_map->end()) 317 if (it == player_map->end())
286 return; 318 return;
287 319
288 for (int delegate_id : it->second) 320 for (int delegate_id : it->second)
289 removed_players->insert(MediaPlayerId(render_frame_host, delegate_id)); 321 removed_players->insert(MediaPlayerId(render_frame_host, delegate_id));
290 322
291 player_map->erase(it); 323 player_map->erase(it);
292 } 324 }
293 325
294 } // namespace content 326 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698