Merge lp:~justinmcp/oxide/media-arbitration into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Justin McPherson
Status: Needs review
Proposed branch: lp:~justinmcp/oxide/media-arbitration
Merge into: lp:~oxide-developers/oxide/oxide.trunk
Diff against target: 866 lines (+645/-4)
18 files modified
CMakeLists.txt (+5/-0)
shared/browser/media/mediahub_player_shim.cc (+48/-0)
shared/browser/media/mediahub_player_shim.h (+9/-0)
shared/browser/media/oxide_browser_media_arbitrator.cc (+204/-0)
shared/browser/media/oxide_browser_media_arbitrator.h (+89/-0)
shared/browser/media/oxide_media_web_contents_observer.cc (+2/-2)
shared/browser/oxide_browser_process_main.cc (+4/-0)
shared/browser/oxide_content_browser_client.cc (+2/-1)
shared/browser/oxide_web_view.cc (+7/-0)
shared/common/oxide_constants.cc (+1/-0)
shared/common/oxide_constants.h (+1/-0)
shared/common/oxide_messages.h (+29/-0)
shared/renderer/media/oxide_renderer_media_arbitrator.cc (+148/-0)
shared/renderer/media/oxide_renderer_media_arbitrator.h (+61/-0)
shared/renderer/media/oxide_renderer_media_player_manager.cc (+1/-1)
shared/renderer/oxide_content_renderer_client.cc (+20/-0)
shared/renderer/oxide_content_renderer_client.h (+3/-0)
shared/shared.gyp (+11/-0)
To merge this branch: bzr merge lp:~justinmcp/oxide/media-arbitration
Reviewer Review Type Date Requested Status
Chris Coulson Pending
Review via email: mp+266517@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Justin McPherson (justinmcp) wrote :

The nature of this change makes it pretty intrusive. I've tried to cut it down, but we may need to chat about the details.

Originally I made a MediaArbitrator delegate class, but concerned about adding to much code in the patches, I pulled that and it mostly rests in RenderFrameImpl.

This is something that really belongs upstream.

Since support for the MH side of the arbitration is not available yet. At the time of this comment, this branch should not yet be merged.

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Hi,

So there's a couple of things I'm a bit concerned about with this:

- It's quite a big patch. It might be better to constrain the patch to just adding new content API's and then adding the actual additional IPC and other bits in Oxide instead. This is something I've been meaning to do with support-native-popup-menus.patch (I just want to shrink this down to a new method on ContentRendererClient which allows Oxide to create a blink::WebExternalPopupMenu and a small patch in RenderFrameImpl::createExternalPopupMenu to call it, rather than the gigantic patch to enable the Android + OSX bits).
- As it's implemented now, arbitration leaves blink in an inconsistent state. When blink calls play() on the blink::WebMediaPlayer implementation, it expects it to play. If it doesn't play, you need to ensure blink ends up in a consistent state (ie, not thinking that it's playing). I'm not sure how best to do that without even more intrusive changes. It looks like the Android player ends up in a paused state.

1179. By Justin McPherson

Better handling of process level arbitration permission

1180. By Justin McPherson

Merge from trunk.

1181. By Justin McPherson

Finish merging to trunk.

Unmerged revisions

1181. By Justin McPherson

Finish merging to trunk.

1180. By Justin McPherson

Merge from trunk.

1179. By Justin McPherson

Better handling of process level arbitration permission

1178. By Justin McPherson

Merge from trunk.

1177. By Justin McPherson

Cleanup

1176. By Justin McPherson

WIP

1175. By Justin McPherson

Fixup whitespace changes

1174. By Justin McPherson

WIP

1173. By Justin McPherson

WIP

1172. By Justin McPherson

WIP

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-03-01 15:33:04 +0000
3+++ CMakeLists.txt 2016-04-08 06:30:30 +0000
4@@ -268,6 +268,11 @@
5 list(APPEND _GYP_COMMAND -Dcomponent=shared_library)
6 endif()
7 list(APPEND _GYP_COMMAND -Doxide_gettext_domain=${GETTEXT_PACKAGE})
8+if(DEFINED ENABLE_MEDIA_ARBITRATION AND ENABLE_MEDIA_ARBITRATION EQUAL 0)
9+ list(APPEND _GYP_COMMAND -Denable_media_arbitration=0)
10+else()
11+ list(APPEND _GYP_COMMAND -Denable_media_arbitration=1)
12+endif()
13 CHECK_INCLUDE_FILE_CXX("core/media/player.h" HAVE_MEDIAHUB "--std=c++11")
14 if(NOT HAVE_MEDIAHUB)
15 list(APPEND _GYP_COMMAND -Denable_mediahub=0)
16
17=== modified file 'shared/browser/media/mediahub_player_shim.cc'
18--- shared/browser/media/mediahub_player_shim.cc 2015-09-09 07:18:04 +0000
19+++ shared/browser/media/mediahub_player_shim.cc 2016-04-08 06:30:30 +0000
20@@ -12,6 +12,8 @@
21 typedef std::map<int, std::shared_ptr<Player> > player_map;
22
23 player_map g_mediahub_players;
24+std::shared_ptr<Player> g_proxy_player;
25+
26
27 player_map::iterator find_player(Player *player)
28 {
29@@ -42,6 +44,38 @@
30 }
31 }
32
33+MediaHubClientHandle
34+mediahub_create_proxy_player(MediaHubDelegate *delegate)
35+{
36+ try {
37+ g_proxy_player =
38+ Service::Client::instance()->create_proxy_session(
39+ Player::Client::default_configuration());
40+
41+ if (delegate) {
42+ setup_delegate(delegate, g_proxy_player);
43+ }
44+
45+ return MediaHubClientHandle(static_cast<void*>(g_proxy_player.get()));
46+ } catch (std::runtime_error& error) {
47+ std::cerr << __PRETTY_FUNCTION__ << " " << error.what() << std::endl;
48+ }
49+ return MediaHubClientHandle();
50+}
51+
52+void
53+mediahub_release_proxy_player(MediaHubClientHandle handle)
54+{
55+ try {
56+ auto player = static_cast<Player*>(handle);
57+ if (g_proxy_player.get() == player) {
58+ g_proxy_player.reset();
59+ }
60+ } catch (std::runtime_error& error) {
61+ std::cerr << __PRETTY_FUNCTION__ << " " << error.what() << std::endl;
62+ }
63+}
64+
65
66 MediaHubClientHandle
67 mediahub_create_player(int player_id, MediaHubDelegate *delegate)
68@@ -292,6 +326,20 @@
69 }
70 }
71
72+bool
73+mediahub_can_play(MediaHubClientHandle handle)
74+{
75+ try {
76+ Player* player = static_cast<Player*>(handle);
77+ if (player) {
78+ return player->can_play();
79+ }
80+ } catch (std::runtime_error& error) {
81+ std::cerr << __PRETTY_FUNCTION__ << " " << error.what() << std::endl;
82+ }
83+ return false;
84+}
85+
86 int
87 mediahub_can_pause(MediaHubClientHandle handle)
88 {
89
90=== modified file 'shared/browser/media/mediahub_player_shim.h'
91--- shared/browser/media/mediahub_player_shim.h 2015-09-09 07:18:04 +0000
92+++ shared/browser/media/mediahub_player_shim.h 2016-04-08 06:30:30 +0000
93@@ -25,6 +25,12 @@
94
95 enum Lifetime { normal, resumable };
96
97+MediaHubClientHandle
98+mediahub_create_proxy_player(MediaHubDelegate* delegate = 0);
99+
100+void
101+mediahub_release_proxy_player(MediaHubClientHandle handle);
102+
103 /**
104 * Creates a media hub player instance
105 */
106@@ -111,6 +117,9 @@
107 void
108 mediahub_seek_to(MediaHubClientHandle handle, int64_t offset);
109
110+bool
111+mediahub_can_play(MediaHubClientHandle handle);
112+
113 /**
114 *
115 */
116
117=== added file 'shared/browser/media/oxide_browser_media_arbitrator.cc'
118--- shared/browser/media/oxide_browser_media_arbitrator.cc 1970-01-01 00:00:00 +0000
119+++ shared/browser/media/oxide_browser_media_arbitrator.cc 2016-04-08 06:30:30 +0000
120@@ -0,0 +1,204 @@
121+// vim:expandtab:shiftwidth=2:tabstop=2:
122+// Copyright (C) 2013-2015 Canonical Ltd.
123+
124+// This library is free software; you can redistribute it and/or
125+// modify it under the terms of the GNU Lesser General Public
126+// License as published by the Free Software Foundation; either
127+// version 2.1 of the License, or (at your option) any later version.
128+
129+// This library is distributed in the hope that it will be useful,
130+// but WITHOUT ANY WARRANTY; without even the implied warranty of
131+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
132+// Lesser General Public License for more details.
133+
134+// You should have received a copy of the GNU Lesser General Public
135+// License along with this library; if not, write to the Free Software
136+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
137+
138+#include <set>
139+
140+#include "shared/browser/media/oxide_media_web_contents_observer.h"
141+
142+#include "shared/common/oxide_messages.h"
143+#include "content/common/media/media_player_delegate_messages.h"
144+
145+#include "base/memory/scoped_ptr.h"
146+#include "base/stl_util.h"
147+#include "content/public/browser/render_frame_host.h"
148+#include "content/public/browser/web_contents.h"
149+#include "shared/browser/media/oxide_browser_media_arbitrator.h"
150+
151+
152+namespace oxide {
153+
154+BrowserMediaArbitrator::BrowserMediaArbitrator(
155+ content::WebContents* contents)
156+ : content::WebContentsObserver(contents)
157+{
158+}
159+
160+BrowserMediaArbitrator::~BrowserMediaArbitrator()
161+{
162+}
163+
164+bool BrowserMediaArbitrator::OnMessageReceived(
165+ const IPC::Message& msg,
166+ content::RenderFrameHost* render_frame_host
167+) {
168+ bool handled = true;
169+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserMediaArbitrator, msg, render_frame_host)
170+ IPC_MESSAGE_HANDLER(OxideHostMsg_MediaShouldPlay, OnMediaShouldPlay)
171+ IPC_MESSAGE_HANDLER(OxideHostMsg_MediaPlayerPlaying, OnMediaPlayerPlaying)
172+ IPC_MESSAGE_HANDLER(OxideHostMsg_MediaPlayerPaused, OnMediaPlayerPaused)
173+ IPC_MESSAGE_HANDLER(OxideHostMsg_MediaPlayerGone, OnMediaPlayerGone)
174+ IPC_MESSAGE_UNHANDLED(handled = false)
175+ IPC_END_MESSAGE_MAP()
176+ return handled;
177+}
178+
179+void BrowserMediaArbitrator::WebContentsDestroyed() {
180+ delete this;
181+}
182+
183+void BrowserMediaArbitrator::OnMediaShouldPlay(
184+ content::RenderFrameHost* render_frame_host,
185+ int player_cookie
186+) {
187+ AddPlayer(player_cookie, render_frame_host);
188+
189+#if defined(ENABLE_MEDIAHUB)
190+ if (mediahub_can_play(mediahub_client_handle_)) {
191+ Send(new OxideMsg_MediaCanPlay(
192+ render_frame_host->GetRoutingID(), player_cookie, true));
193+ Send(new MediaPlayerDelegateMsg_Play(render_frame_host->GetRoutingID(), player_cookie));
194+ } else {
195+ Send(new OxideMsg_MediaCanPlay(
196+ render_frame_host->GetRoutingID(), player_cookie, false));
197+ }
198+#else
199+ Send(new OxideMsg_MediaCanPlay(
200+ render_frame_host->GetRoutingID(), player_cookie, true));
201+ Send(new MediaPlayerDelegateMsg_Play(render_frame_host->GetRoutingID(), player_cookie));
202+#endif
203+}
204+
205+void BrowserMediaArbitrator::OnMediaPlayerPlaying(
206+ content::RenderFrameHost* render_frame_host,
207+ int player_cookie
208+) {
209+ if (players_[player_cookie].playing) {
210+ return;
211+ }
212+#if defined(ENABLE_MEDIAHUB)
213+ if (players_.size() == 1) {
214+ mediahub_play(mediahub_client_handle_);
215+ } else {
216+ int playing_count =
217+ std::accumulate(players_.begin(), players_.end(), 0,
218+ [](const int acc, const player_map::value_type& val) {
219+ return acc + (val.second.playing ? 1 : 0);
220+ });
221+ if (playing_count == 0) {
222+ mediahub_play(mediahub_client_handle_);
223+ }
224+ }
225+#endif
226+ players_[player_cookie].playing = true;
227+}
228+
229+void BrowserMediaArbitrator::OnMediaPlayerPaused(
230+ content::RenderFrameHost* render_frame_host,
231+ int player_cookie
232+) {
233+ if (!players_[player_cookie].playing) {
234+ return;
235+ }
236+ players_[player_cookie].playing = false;
237+
238+#if defined(ENABLE_MEDIAHUB)
239+ int playing_count =
240+ std::accumulate(players_.begin(), players_.end(), 0,
241+ [](const int acc, const player_map::value_type& val) {
242+ return acc + (val.second.playing ? 1 : 0);
243+ });
244+ if (playing_count == 0) {
245+ mediahub_pause(mediahub_client_handle_);
246+ }
247+#endif
248+}
249+
250+void BrowserMediaArbitrator::OnMediaPlayerGone(
251+ content::RenderFrameHost* render_frame_host,
252+ int player_cookie
253+) {
254+ RemovePlayer(player_cookie);
255+}
256+
257+void BrowserMediaArbitrator::AddPlayer(
258+ int player_cookie,
259+ content::RenderFrameHost* render_frame_host
260+) {
261+ players_.insert(std::make_pair(player_cookie, player_info{false, render_frame_host}));
262+#if defined(ENABLE_MEDIAHUB)
263+ if (players_.size() == 1) {
264+ mediahub_client_handle_ = mediahub_create_proxy_player(this);
265+ }
266+#endif
267+}
268+
269+void BrowserMediaArbitrator::RemovePlayer(int player_cookie) {
270+ players_.erase(player_cookie);
271+#if defined(ENABLE_MEDIAHUB)
272+ if (players_.empty()) {
273+ mediahub_release_proxy_player(mediahub_client_handle_);
274+ }
275+#endif
276+}
277+
278+#if defined(ENABLE_MEDIAHUB)
279+void BrowserMediaArbitrator::seeked_to(int64_t /*pos*/)
280+{
281+}
282+
283+void BrowserMediaArbitrator::end_of_stream()
284+{
285+}
286+
287+void BrowserMediaArbitrator::playback_status_changed(MediaHubDelegate::Status status)
288+{
289+ std::set<content::RenderFrameHost*> render_frame_hosts;
290+ for (auto& info : players_) {
291+ render_frame_hosts.insert(info.second.host);
292+ }
293+
294+ switch (status) {
295+ case null:
296+ case ready:
297+ break;
298+ case playing:
299+ for (auto& host : render_frame_hosts) {
300+ Send(new OxideMsg_MediaResumeAll(host->GetRoutingID()));
301+ }
302+
303+ for (auto& it : players_) {
304+ info.second.playing = true;
305+ Send(new MediaPlayerDelegateMsg_Play(it.second.host->GetRoutingID(), it.first));
306+ }
307+ break;
308+ case paused:
309+ for (auto& host : render_frame_hosts) {
310+ Send(new OxideMsg_MediaPauseAll(host->GetRoutingID()));
311+ }
312+
313+ for (auto& it : players_) {
314+ info.second.playing = false;
315+ Send(new MediaPlayerDelegateMsg_Pause(it.second.host->GetRoutingID(), it.first));
316+ }
317+ break;
318+ case stopped:
319+ break;
320+ }
321+}
322+#endif
323+
324+} // namespace content
325
326=== added file 'shared/browser/media/oxide_browser_media_arbitrator.h'
327--- shared/browser/media/oxide_browser_media_arbitrator.h 1970-01-01 00:00:00 +0000
328+++ shared/browser/media/oxide_browser_media_arbitrator.h 2016-04-08 06:30:30 +0000
329@@ -0,0 +1,89 @@
330+// vim:expandtab:shiftwidth=2:tabstop=2:
331+// Copyright (C) 2013-2015 Canonical Ltd.
332+
333+// This library is free software; you can redistribute it and/or
334+// modify it under the terms of the GNU Lesser General Public
335+// License as published by the Free Software Foundation; either
336+// version 2.1 of the License, or (at your option) any later version.
337+
338+// This library is distributed in the hope that it will be useful,
339+// but WITHOUT ANY WARRANTY; without even the implied warranty of
340+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
341+// Lesser General Public License for more details.
342+
343+// You should have received a copy of the GNU Lesser General Public
344+// License along with this library; if not, write to the Free Software
345+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
346+
347+#ifndef _OXIDE_BROWSER_MEDIA_ARBITRATOR_H_
348+#define _OXIDE_BROWSER_MEDIA_ARBITRATOR_H_
349+
350+#include <map>
351+
352+#include "base/compiler_specific.h"
353+#include "base/containers/scoped_ptr_hash_map.h"
354+#include "content/common/content_export.h"
355+#include "content/public/browser/web_contents_observer.h"
356+#if defined(ENABLE_MEDIAHUB)
357+#include "shared/browser/media/mediahub_player_shim.h"
358+#endif
359+
360+namespace content {
361+class WebContents;
362+class RenderFrameHost;
363+}
364+
365+namespace oxide {
366+
367+class BrowserMediaArbitrator :
368+ public content::WebContentsObserver
369+#if defined(ENABLE_MEDIAHUB)
370+ , public MediaHubDelegate
371+#endif
372+{
373+ public:
374+ explicit BrowserMediaArbitrator(content::WebContents* contents);
375+ ~BrowserMediaArbitrator();
376+
377+ bool OnMessageReceived(const IPC::Message& message,
378+ content::RenderFrameHost* render_frame_host) override;
379+
380+ void WebContentsDestroyed() override;
381+
382+ private:
383+ void OnMediaShouldPlay(content::RenderFrameHost* render_frame_host,
384+ int player_cookie);
385+ void OnMediaPlayerPlaying(
386+ content::RenderFrameHost* render_frame_host,
387+ int player_cookie
388+ );
389+ void OnMediaPlayerPaused(content::RenderFrameHost* render_frame_host,
390+ int player_cookie);
391+ void OnMediaPlayerGone(content::RenderFrameHost* render_frame_host,
392+ int player_cookie);
393+
394+#if defined(ENABLE_MEDIAHUB)
395+ void seeked_to(int64_t pos);
396+ void end_of_stream();
397+ void playback_status_changed(MediaHubDelegate::Status status);
398+ MediaHubClientHandle mediahub_client_handle_;
399+#endif
400+
401+ void AddPlayer(int player_cookie,
402+ content::RenderFrameHost* render_frame_host);
403+ void RemovePlayer(int player_cookie);
404+
405+ struct player_info {
406+ bool playing;
407+ content::RenderFrameHost* host;
408+ };
409+
410+ typedef std::map<int, player_info> player_map;
411+ player_map players_;
412+
413+ DISALLOW_COPY_AND_ASSIGN(BrowserMediaArbitrator);
414+};
415+
416+} // namespace oxide
417+
418+#endif // _OXIDE_MEDIA_WEB_CONTENTS_OBSERVER_H_
419
420=== modified file 'shared/browser/media/oxide_media_web_contents_observer.cc'
421--- shared/browser/media/oxide_media_web_contents_observer.cc 2015-09-09 07:18:04 +0000
422+++ shared/browser/media/oxide_media_web_contents_observer.cc 2016-04-08 06:30:30 +0000
423@@ -54,13 +54,13 @@
424 IPC_MESSAGE_FORWARD(OxideHostMsg_MediaPlayer_DestroyMediaPlayer,
425 GetMediaPlayerManager(render_frame_host),
426 BrowserMediaPlayerManager::OnDestroyPlayer)
427- IPC_MESSAGE_UNHANDLED(handled = false)
428+ IPC_MESSAGE_UNHANDLED(handled = false)
429 IPC_END_MESSAGE_MAP()
430 return handled;
431 }
432
433 void MediaWebContentsObserver::WebContentsDestroyed() {
434- delete this;
435+ delete this;
436 }
437
438 BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager(
439
440=== modified file 'shared/browser/oxide_browser_process_main.cc'
441--- shared/browser/oxide_browser_process_main.cc 2016-04-02 10:08:16 +0000
442+++ shared/browser/oxide_browser_process_main.cc 2016-04-08 06:30:30 +0000
443@@ -311,6 +311,10 @@
444 command_line->AppendSwitch(switches::kAllowSandboxDebugging);
445 }
446
447+ if (IsEnvironmentOptionEnabled("ENABLE_MEDIA_ARBITRATION")) {
448+ command_line->AppendSwitch(switches::kEnableMediaArbitration);
449+ }
450+
451 if (IsEnvironmentOptionEnabled("ENABLE_MEDIA_HUB_AUDIO")) {
452 command_line->AppendSwitch(switches::kEnableMediaHubAudio);
453 }
454
455=== modified file 'shared/browser/oxide_content_browser_client.cc'
456--- shared/browser/oxide_content_browser_client.cc 2016-02-01 20:17:09 +0000
457+++ shared/browser/oxide_content_browser_client.cc 2016-04-08 06:30:30 +0000
458@@ -125,7 +125,8 @@
459 static const char* const kSwitchNames[] = {
460 switches::kEnableMediaHubAudio,
461 switches::kFormFactor,
462- switches::kMediaHubFixedSessionDomains
463+ switches::kMediaHubFixedSessionDomains,
464+ switches::kEnableMediaArbitration,
465 };
466 command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
467 kSwitchNames, arraysize(kSwitchNames));
468
469=== modified file 'shared/browser/oxide_web_view.cc'
470--- shared/browser/oxide_web_view.cc 2016-03-21 15:33:21 +0000
471+++ shared/browser/oxide_web_view.cc 2016-04-08 06:30:30 +0000
472@@ -95,6 +95,10 @@
473 #include "shared/browser/media/oxide_media_web_contents_observer.h"
474 #endif
475
476+#if defined(ENABLE_MEDIA_ARBITRATION)
477+#include "shared/browser/media/oxide_browser_media_arbitrator.h"
478+#endif
479+
480 #define DCHECK_VALID_SOURCE_CONTENTS DCHECK_EQ(source, web_contents());
481
482 namespace oxide {
483@@ -129,6 +133,9 @@
484 CertificateErrorDispatcher::CreateForWebContents(contents);
485 PermissionRequestDispatcher::CreateForWebContents(contents);
486 ScriptMessageContentsHelper::CreateForWebContents(contents);
487+#if defined(ENABLE_MEDIA_ARBITRATION)
488+ new BrowserMediaArbitrator(contents);
489+#endif
490 #if defined(ENABLE_MEDIAHUB)
491 new MediaWebContentsObserver(contents);
492 #endif
493
494=== modified file 'shared/common/oxide_constants.cc'
495--- shared/common/oxide_constants.cc 2015-11-07 23:49:10 +0000
496+++ shared/common/oxide_constants.cc 2016-04-08 06:30:30 +0000
497@@ -25,6 +25,7 @@
498 const char kFormFactorPhone[] = "phone";
499 const char kIncognito[] = "incognito";
500 const char kEnableMediaHubAudio[] = "enable-media-hub-audio";
501+const char kEnableMediaArbitration[] = "enable-media-arbitraion";
502 const char kMediaHubFixedSessionDomains[] = "media-hub-fixed-session-domains";
503
504 } // namespace switches
505
506=== modified file 'shared/common/oxide_constants.h'
507--- shared/common/oxide_constants.h 2015-11-07 23:49:10 +0000
508+++ shared/common/oxide_constants.h 2016-04-08 06:30:30 +0000
509@@ -25,6 +25,7 @@
510 extern const char kFormFactorTablet[];
511 extern const char kFormFactorPhone[];
512 extern const char kIncognito[];
513+extern const char kEnableMediaArbitration[];
514 extern const char kEnableMediaHubAudio[];
515 extern const char kMediaHubFixedSessionDomains[];
516
517
518=== modified file 'shared/common/oxide_messages.h'
519--- shared/common/oxide_messages.h 2015-09-09 07:18:04 +0000
520+++ shared/common/oxide_messages.h 2016-04-08 06:30:30 +0000
521@@ -205,3 +205,32 @@
522 IPC_MESSAGE_CONTROL2(OxideHostMsg_MediaPlayer_DurationChanged,
523 int /* demuxer_client_id */,
524 base::TimeDelta /* duration */)
525+
526+// Messages for Media Arbitration
527+#if defined(ENABLE_MEDIA_ARBITRATION)
528+// Request the browser to arbitrate whether the media should play
529+IPC_MESSAGE_ROUTED1(OxideHostMsg_MediaShouldPlay,
530+ int /* internal id */)
531+
532+IPC_MESSAGE_ROUTED1(OxideHostMsg_MediaPlayerPlaying,
533+ int /* internal id */)
534+
535+IPC_MESSAGE_ROUTED1(OxideHostMsg_MediaPlayerPaused,
536+ int /* internal id */)
537+
538+// Tell browser player is no longer active
539+IPC_MESSAGE_ROUTED1(OxideHostMsg_MediaPlayerGone,
540+ int /* internal id */)
541+
542+
543+// Indicate whether media can play
544+IPC_MESSAGE_ROUTED2(OxideMsg_MediaCanPlay,
545+ int, /* internal id */
546+ bool /* can player play*/)
547+
548+// Pause all playing media players
549+IPC_MESSAGE_ROUTED0(OxideMsg_MediaPauseAll)
550+
551+// Reume media players (if previously playing)
552+IPC_MESSAGE_ROUTED0(OxideMsg_MediaResumeAll)
553+#endif
554
555=== added file 'shared/renderer/media/oxide_renderer_media_arbitrator.cc'
556--- shared/renderer/media/oxide_renderer_media_arbitrator.cc 1970-01-01 00:00:00 +0000
557+++ shared/renderer/media/oxide_renderer_media_arbitrator.cc 2016-04-08 06:30:30 +0000
558@@ -0,0 +1,148 @@
559+// vim:expandtab:shiftwidth=2:tabstop=2:
560+// Copyright (C) 2013-2015 Canonical Ltd.
561+
562+// This library is free software; you can redistribute it and/or
563+// modify it under the terms of the GNU Lesser General Public
564+// License as published by the Free Software Foundation; either
565+// version 2.1 of the License, or (at your option) any later version.
566+
567+// This library is distributed in the hope that it will be useful,
568+// but WITHOUT ANY WARRANTY; without even the implied warranty of
569+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
570+// Lesser General Public License for more details.
571+
572+// You should have received a copy of the GNU Lesser General Public
573+// License along with this library; if not, write to the Free Software
574+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
575+
576+#include "oxide_renderer_media_arbitrator.h"
577+
578+#include "base/command_line.h"
579+#include "shared/common/oxide_constants.h"
580+#include "shared/common/oxide_messages.h"
581+#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
582+
583+
584+namespace oxide {
585+
586+RendererMediaArbitrator::RendererMediaArbitrator(
587+ content::RenderFrame* render_frame)
588+ : RenderFrameObserver(render_frame)
589+ , RenderFrameObserverTracker<RendererMediaArbitrator>(render_frame)
590+{
591+ const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
592+ arbitration_enabled_ = command_line.HasSwitch(switches::kEnableMediaArbitration);
593+}
594+
595+RendererMediaArbitrator::~RendererMediaArbitrator() {
596+}
597+
598+bool RendererMediaArbitrator::CanDelegatePlay(int delegate_id)
599+{
600+ if (!arbitration_enabled_) {
601+ return true;
602+ }
603+
604+#if defined(ENABLE_MEDIAHUB)
605+ const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
606+ // Each media-hub player session is already managed.
607+ if (command_line.HasSwitch(switches::kEnableMediaHubAudio)) {
608+ return true;
609+ }
610+#endif
611+
612+ auto it = registered_delegates_.find(delegate_id);
613+ if (it != registered_delegates_.end() && it->second.authorised) {
614+ return true;
615+ }
616+
617+ registered_delegates_.insert(std::make_pair(delegate_id, {false, false}));
618+ Send(new OxideHostMsg_MediaShouldPlay( routing_id(), delegate_id);
619+
620+ return false;
621+}
622+
623+bool RendererMediaArbitrator::DelegateWillPlay(int delegate_id)
624+{
625+ auto it = registered_delegates_.find(delegate_id);
626+ if (it != registered_delegates_.end() && it->second.authorised) {
627+ return true;
628+ }
629+ return false;
630+}
631+
632+void RendererMediaArbitrator::DelegateWillPause(int delegate_id)
633+{
634+}
635+
636+void RendererMediaArbitrator::DelegateDidPlay(int delegate_id)
637+{
638+ if (!arbitration_enabled_) {
639+ return;
640+ }
641+ auto it = registered_delegates_.find(delegate_id);
642+ if (it != registered_delegates_.end()) {
643+ it->second.playing = true;
644+ Send(new OxideHostMsg_MediaPlayerPlaying(routing_id(), delegate_id));
645+ }
646+}
647+
648+void RendererMediaArbitrator::DelegateDidPause(int delegate_id)
649+{
650+ if (!arbitration_enabled_) {
651+ return;
652+ }
653+ auto it = registered_delegates_.find(delegate_id);
654+ if (it != registered_delegates_.end() && it->second.authorised) {
655+ it->second.playing = false;
656+ Send(new OxideHostMsg_MediaPlayerPaused(routing_id(), delegate_id));
657+ }
658+}
659+
660+void RendererMediaArbitrator::DelegateDidGo(int delegate_id)
661+{
662+ if (!arbitration_enabled_) {
663+ return;
664+ }
665+ registered_delegates_.erase(delegate_id));
666+ Send(new OxideHostMsg_MediaPlayerGone( routing_id(), delegate_id));
667+}
668+
669+bool RendererMediaArbitrator::OnMessageReceived(const IPC::Message& msg) {
670+ bool handled = true;
671+ IPC_BEGIN_MESSAGE_MAP(RendererMediaArbitrator, msg)
672+ IPC_MESSAGE_HANDLER(OxideMsg_MediaCanPlay, OnMediaCanPlay)
673+ IPC_MESSAGE_HANDLER(OxideMsg_MediaPauseAll, OnMediaPauseAll)
674+ IPC_MESSAGE_HANDLER(OxideMsg_MediaResumeAll, OnMediaResumeAll)
675+ IPC_MESSAGE_UNHANDLED(handled = false)
676+ IPC_END_MESSAGE_MAP()
677+ return handled;
678+}
679+
680+void RendererMediaArbitrator::OnMediaCanPlay(int delegate_id, bool can_play)
681+{
682+ auto it = registered_delegates_.find(player_cookie);
683+ if (it != registered_delegates_.end()) {
684+ return;
685+ }
686+ it->second.authorised = can_play;
687+}
688+
689+void RendererMediaArbitrator::OnMediaPauseAll()
690+{
691+ for (auto& it : registered_delegates_) {
692+ it.second.authorised = false;
693+ }
694+}
695+
696+void RendererMediaArbitrator::OnMediaResumeAll()
697+{
698+ for (auto& it : registered_delegates_) {
699+ if (it.second.playing && !it.second.authorised) {
700+ info.second.authorised = true;
701+ }
702+ }
703+}
704+
705+
706+} // ns oxide
707
708=== added file 'shared/renderer/media/oxide_renderer_media_arbitrator.h'
709--- shared/renderer/media/oxide_renderer_media_arbitrator.h 1970-01-01 00:00:00 +0000
710+++ shared/renderer/media/oxide_renderer_media_arbitrator.h 2016-04-08 06:30:30 +0000
711@@ -0,0 +1,61 @@
712+// vim:expandtab:shiftwidth=2:tabstop=2:
713+// Copyright (C) 2013-2015 Canonical Ltd.
714+
715+// This library is free software; you can redistribute it and/or
716+// modify it under the terms of the GNU Lesser General Public
717+// License as published by the Free Software Foundation; either
718+// version 2.1 of the License, or (at your option) any later version.
719+
720+// This library is distributed in the hope that it will be useful,
721+// but WITHOUT ANY WARRANTY; without even the implied warranty of
722+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
723+// Lesser General Public License for more details.
724+
725+// You should have received a copy of the GNU Lesser General Public
726+// License along with this library; if not, write to the Free Software
727+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
728+
729+#ifndef _OXIDE_RENDERER_MEDIA_ARBITRATOR_H_
730+#define _OXIDE_RENDERER_MEDIA_ARBITRATOR_H_
731+
732+#include "content/public/renderer/content_media_arbitrator.h"
733+#include "content/public/renderer/render_frame_observer.h"
734+#include "content/public/renderer/render_frame_observer_tracker.h"
735+
736+namespace oxide {
737+
738+class RendererMediaArbitrator :
739+ public content::MediaArbitrator,
740+ public content::RenderFrameObserver,
741+ public content::RenderFrameObserverTracker<RendererMediaArbitrator> {
742+ public:
743+ explicit RendererMediaArbitrator(content::RenderFrame* render_frame);
744+ ~RendererMediaArbitrator();
745+
746+ bool CanDelegatePlay(int delegate_id);
747+ bool DelegateWillPlay(int delegate_id);
748+ void DelegateWillPause(int delegate_id);
749+ void DelegateDidPlay(int delegate_id);
750+ void DelegateDidPause(int delegate_id);
751+ void DelegateDidGo(int delegate_id);
752+
753+ bool OnMessageReceived(const IPC::Message& msg) override;
754+
755+ private:
756+ void OnMediaCanPlay(int64_t player_cookie, bool can_play);
757+ void OnMediaPauseAll();
758+ void OnMediaResumeAll();
759+
760+ bool arbitration_enabled_;
761+
762+ struct delegate_info {
763+ bool authorised;
764+ bool playing;
765+ };
766+
767+ std::map<int, delegate_info> registered_delegates_;
768+};
769+
770+} // ns oxide
771+
772+#endif // _OXIDE_RENDERER_MEDIA_ARBITRATOR_H_
773
774=== modified file 'shared/renderer/media/oxide_renderer_media_player_manager.cc'
775--- shared/renderer/media/oxide_renderer_media_player_manager.cc 2015-09-09 07:18:04 +0000
776+++ shared/renderer/media/oxide_renderer_media_player_manager.cc 2016-04-08 06:30:30 +0000
777@@ -49,7 +49,7 @@
778 IPC_MESSAGE_HANDLER(OxideMsg_MediaPlayer_DidMediaPlayerPlay, OnPlayerPlay)
779 IPC_MESSAGE_HANDLER(OxideMsg_MediaPlayer_DidMediaPlayerPause, OnPlayerPause)
780 IPC_MESSAGE_HANDLER(OxideMsg_MediaPlayer_PauseVideo, OnPauseVideo)
781- IPC_MESSAGE_UNHANDLED(handled = false)
782+ IPC_MESSAGE_UNHANDLED(handled = false)
783 IPC_END_MESSAGE_MAP()
784 return handled;
785 }
786
787=== modified file 'shared/renderer/oxide_content_renderer_client.cc'
788--- shared/renderer/oxide_content_renderer_client.cc 2016-03-30 18:33:11 +0000
789+++ shared/renderer/oxide_content_renderer_client.cc 2016-04-08 06:30:30 +0000
790@@ -55,6 +55,11 @@
791 #include "media/oxide_web_media_player.h"
792 #endif
793
794+#if defined(ENABLE_MEDIA_ARBITRATION)
795+#include "media/oxide_renderer_media_arbitrator.h"
796+#endif
797+
798+
799 namespace oxide {
800
801 void ContentRendererClient::RenderThreadStarted() {
802@@ -87,6 +92,9 @@
803 #if defined(ENABLE_MEDIAHUB)
804 new RendererMediaPlayerManager(render_frame);
805 #endif
806+#if defined(ENABLE_MEDIA_ARBITRATION)
807+ new RendererMediaArbitrator(render_frame);
808+#endif
809 }
810
811 void ContentRendererClient::RenderViewCreated(
812@@ -157,6 +165,18 @@
813 }
814 #endif
815
816+#if defined(ENABLE_MEDIA_ARBITRATION)
817+content::MediaArbitrator* ContentRendererClient::GetMediaArbitrator(
818+ blink::WebFrame *frame
819+) {
820+ RendererMediaArbitrator* ma = RendererMediaArbitrator::Get(
821+ content::RenderFrame::FromWebFrame(frame));
822+ DCHECK(ma);
823+
824+ return ma;
825+}
826+#endif
827+
828 void ContentRendererClient::OverrideCompositorSettings(
829 cc::LayerTreeSettings* settings) {
830 // XXX: If we support overlay scrollbars on desktop, then we'll want to
831
832=== modified file 'shared/renderer/oxide_content_renderer_client.h'
833--- shared/renderer/oxide_content_renderer_client.h 2016-03-30 18:33:11 +0000
834+++ shared/renderer/oxide_content_renderer_client.h 2016-04-08 06:30:30 +0000
835@@ -53,6 +53,9 @@
836 base::WeakPtr<media::WebMediaPlayerDelegate> delegate,
837 media::MediaLog* media_log) override;
838 #endif
839+#if defined(ENABLE_MEDIA_ARBITRATION)
840+ content::MediaArbitrator* GetMediaArbitrator(blink::WebFrame* frame) final;
841+#endif
842 void OverrideCompositorSettings(cc::LayerTreeSettings* settings) override;
843 std::string GetUserAgentOverrideForURL(const GURL& url) override;
844
845
846=== modified file 'shared/shared.gyp'
847--- shared/shared.gyp 2016-04-04 17:56:47 +0000
848+++ shared/shared.gyp 2016-04-08 06:30:30 +0000
849@@ -608,6 +608,17 @@
850 '<(DEPTH)/ppapi/ppapi_internal.gyp:ppapi_shared',
851 ],
852 }],
853+ ['enable_media_arbitration==1', {
854+ 'defines': [
855+ 'ENABLE_MEDIA_ARBITRATION=1'
856+ ],
857+ 'sources': [
858+ 'browser/media/oxide_browser_media_arbitrator.cc',
859+ 'browser/media/oxide_browser_media_arbitrator.h',
860+ 'renderer/media/oxide_renderer_media_arbitrator.cc',
861+ 'renderer/media/oxide_renderer_media_arbitrator.h',
862+ ]
863+ }],
864 ['enable_mediahub==1', {
865 'defines': [
866 'ENABLE_MEDIAHUB=1'

Subscribers

People subscribed via source and target branches