From c810962d7814a85fdfa394742e621f6ebb75b866 Mon Sep 17 00:00:00 2001 From: Fernando Jimenez Moreno Date: Wed, 27 Nov 2019 16:44:23 +0100 Subject: [PATCH 1/5] Hololens - MediaSession controls UI --- support/hololens/ServoApp/BrowserPage.cpp | 7 +++++++ support/hololens/ServoApp/BrowserPage.h | 4 ++++ support/hololens/ServoApp/BrowserPage.xaml | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index b940d42019c..6653ebb233a 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -143,4 +143,11 @@ void BrowserPage::OnURLEdited(IInspectable const &, } } +void BrowserPage::OnMediaControlsPlayClicked( + Windows::Foundation::IInspectable const &, + Windows::UI::Xaml::RoutedEventArgs const &) {} +void BrowserPage::OnMediaControlsPauseClicked( + Windows::Foundation::IInspectable const &, + Windows::UI::Xaml::RoutedEventArgs const &) {} + } // namespace winrt::ServoApp::implementation diff --git a/support/hololens/ServoApp/BrowserPage.h b/support/hololens/ServoApp/BrowserPage.h index f5fe8b3566b..f0f1d49c482 100644 --- a/support/hololens/ServoApp/BrowserPage.h +++ b/support/hololens/ServoApp/BrowserPage.h @@ -41,6 +41,10 @@ public: Windows::UI::Xaml::RoutedEventArgs const &); void OnXRPkgWarningDismissClick(Windows::Foundation::IInspectable const &, Windows::UI::Xaml::RoutedEventArgs const &); + void OnMediaControlsPlayClicked(Windows::Foundation::IInspectable const &, + Windows::UI::Xaml::RoutedEventArgs const &); + void OnMediaControlsPauseClicked(Windows::Foundation::IInspectable const &, + Windows::UI::Xaml::RoutedEventArgs const &); private: void BindServoEvents(); diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml index c0b2839da7d..8d68ecf533b 100644 --- a/support/hololens/ServoApp/BrowserPage.xaml +++ b/support/hololens/ServoApp/BrowserPage.xaml @@ -137,5 +137,14 @@ + + + + + + + + + From d633c8b9da39c1dbf7e92debb907a58cd13de0da Mon Sep 17 00:00:00 2001 From: Fernando Jimenez Moreno Date: Thu, 28 Nov 2019 16:37:50 +0100 Subject: [PATCH 2/5] Hololens - Show/hide media controls according to playback state --- support/hololens/ServoApp/BrowserPage.cpp | 14 +++++++++++ support/hololens/ServoApp/BrowserPage.xaml | 6 ++--- .../hololens/ServoApp/ServoControl/Servo.cpp | 16 ++++++++++++- .../hololens/ServoApp/ServoControl/Servo.h | 2 ++ .../ServoApp/ServoControl/ServoControl.cpp | 9 ++++++++ .../ServoApp/ServoControl/ServoControl.h | 23 +++++++++++++++++++ .../ServoApp/ServoControl/ServoControl.idl | 3 +++ 7 files changed, 69 insertions(+), 4 deletions(-) diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index 6653ebb233a..536f1f378b1 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -70,6 +70,20 @@ void BrowserPage::BindServoEvents() { servoControl().OnCaptureGesturesEnded( [=] { navigationBar().IsHitTestVisible(true); }); urlTextbox().GotFocus(std::bind(&BrowserPage::OnURLFocused, this, _1)); + servoControl().OnMediaSessionMetadata( + [=](hstring title, hstring artist, hstring album) {}); + servoControl().OnMediaSessionPlaybackStateChange([=](const auto &, + int state) { + if (state == 1 /* none */) { + mediaControls().Visibility(Visibility::Collapsed); + return; + } + mediaControls().Visibility(Visibility::Visible); + playButton().Visibility(state == 3 /* paused */ ? Visibility::Visible + : Visibility::Collapsed); + pauseButton().Visibility(state == 3 /* paused */ ? Visibility::Collapsed + : Visibility::Visible); + }); } void BrowserPage::OnURLFocused(Windows::Foundation::IInspectable const &) { diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml index 8d68ecf533b..727e73e11cc 100644 --- a/support/hololens/ServoApp/BrowserPage.xaml +++ b/support/hololens/ServoApp/BrowserPage.xaml @@ -137,9 +137,9 @@ - - - + + + diff --git a/support/hololens/ServoApp/ServoControl/Servo.cpp b/support/hololens/ServoApp/ServoControl/Servo.cpp index 8c66e8cdeb3..afe3539efe9 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.cpp +++ b/support/hololens/ServoApp/ServoControl/Servo.cpp @@ -56,6 +56,16 @@ const char *get_clipboard_contents() { return nullptr; } +void on_media_session_metadata(const char *title, const char *album, + const char *artist) { + return sServo->Delegate().OnServoMediaSessionMetadata( + char2hstring(title), char2hstring(album), char2hstring(artist)); +} + +void on_media_session_playback_state_change(const int state) { + return sServo->Delegate().OnServoMediaSessionPlaybackStateChange(state); +} + Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, float dpi, ServoDelegate &aDelegate) : mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) { @@ -63,7 +73,8 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, capi::CInitOptions o; hstring defaultPrefs = L" --pref dom.webxr.enabled"; o.args = *hstring2char(args + defaultPrefs); - o.url = *hstring2char(url); + o.url = + "https://ferjm.github.io/web-api-tests/video/mp4.html"; //*hstring2char(url); o.width = mWindowWidth; o.height = mWindowHeight; o.density = dpi; @@ -110,6 +121,9 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, c.on_ime_state_changed = &on_ime_state_changed; c.get_clipboard_contents = &get_clipboard_contents; c.set_clipboard_contents = &set_clipboard_contents; + c.on_media_session_metadata = &on_media_session_metadata; + c.on_media_session_playback_state_change = + &on_media_session_playback_state_change; capi::register_panic_handler(&on_panic); diff --git a/support/hololens/ServoApp/ServoControl/Servo.h b/support/hololens/ServoApp/ServoControl/Servo.h index 5cf4e113e33..2e76256f021 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.h +++ b/support/hololens/ServoApp/ServoControl/Servo.h @@ -36,6 +36,8 @@ public: virtual void OnServoIMEStateChanged(bool) = 0; virtual void Flush() = 0; virtual void MakeCurrent() = 0; + virtual void OnServoMediaSessionMetadata(hstring, hstring, hstring) = 0; + virtual void OnServoMediaSessionPlaybackStateChange(int) = 0; protected: virtual ~ServoDelegate(){}; diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.cpp b/support/hololens/ServoApp/ServoControl/ServoControl.cpp index 38cc4f284f4..d1d19118a29 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.cpp +++ b/support/hololens/ServoApp/ServoControl/ServoControl.cpp @@ -432,6 +432,15 @@ void ServoControl::OnServoIMEStateChanged(bool aShow) { // https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-implementingtextandtextrange } +void ServoControl::OnServoMediaSessionMetadata(hstring title, hstring artist, + hstring album) { + RunOnUIThread([=] { mOnMediaSessionMetadataEvent(title, artist, album); }); +} + +void ServoControl::OnServoMediaSessionPlaybackStateChange(int state) { + RunOnUIThread([=] { mOnMediaSessionPlaybackStateChangeEvent(*this, state); }); +} + template void ServoControl::RunOnUIThread(Callable cb) { Dispatcher().RunAsync(CoreDispatcherPriority::High, cb); } diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.h b/support/hololens/ServoApp/ServoControl/ServoControl.h index fea53fdb5bb..5daa227f126 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.h +++ b/support/hololens/ServoApp/ServoControl/ServoControl.h @@ -70,6 +70,23 @@ struct ServoControl : ServoControlT, public servo::ServoDelegate { mOnCaptureGesturesEndedEvent.remove(token); } + winrt::event_token + OnMediaSessionMetadata(MediaSessionMetadataDelegate const &handler) { + return mOnMediaSessionMetadataEvent.add(handler); + }; + void OnMediaSessionMetadata(winrt::event_token const &token) noexcept { + mOnMediaSessionMetadataEvent.remove(token); + } + + winrt::event_token OnMediaSessionPlaybackStateChange( + Windows::Foundation::EventHandler const &handler) { + return mOnMediaSessionPlaybackStateChangeEvent.add(handler); + }; + void + OnMediaSessionPlaybackStateChange(winrt::event_token const &token) noexcept { + mOnMediaSessionPlaybackStateChangeEvent.remove(token); + } + void SetTransientMode(bool transient) { mTransient = transient; } void SetArgs(hstring args) { mArgs = args; } @@ -87,6 +104,9 @@ struct ServoControl : ServoControlT, public servo::ServoDelegate { virtual bool OnServoAllowNavigation(winrt::hstring); virtual void OnServoAnimatingChanged(bool); virtual void OnServoIMEStateChanged(bool); + virtual void OnServoMediaSessionMetadata(winrt::hstring, winrt::hstring, + winrt::hstring); + virtual void OnServoMediaSessionPlaybackStateChange(int); private: winrt::event> mOnURLChangedEvent; @@ -96,6 +116,9 @@ private: winrt::event mOnLoadEndedEvent; winrt::event mOnCaptureGesturesStartedEvent; winrt::event mOnCaptureGesturesEndedEvent; + winrt::event mOnMediaSessionMetadataEvent; + winrt::event> + mOnMediaSessionPlaybackStateChangeEvent; float mDPI = 1; hstring mInitialURL = DEFAULT_URL; diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.idl b/support/hololens/ServoApp/ServoControl/ServoControl.idl index f6ba55b3b56..3a5698e1601 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.idl +++ b/support/hololens/ServoApp/ServoControl/ServoControl.idl @@ -2,6 +2,7 @@ namespace ServoApp { delegate void EventDelegate(); delegate void HistoryChangedDelegate(Boolean back, Boolean forward); + delegate void MediaSessionMetadataDelegate(String title, String artist, String album); runtimeclass ServoControl : Windows.UI.Xaml.Controls.Control { ServoControl(); @@ -20,5 +21,7 @@ namespace ServoApp { event HistoryChangedDelegate OnHistoryChanged; event Windows.Foundation.EventHandler OnTitleChanged; event Windows.Foundation.EventHandler OnURLChanged; + event MediaSessionMetadataDelegate OnMediaSessionMetadata; + event Windows.Foundation.EventHandler OnMediaSessionPlaybackStateChange; } } // namespace ServoApp From d5200ba453a5c70780498a894b1194a6398027a7 Mon Sep 17 00:00:00 2001 From: Fernando Jimenez Moreno Date: Fri, 29 Nov 2019 12:44:26 +0100 Subject: [PATCH 3/5] Hololens - Trigger MediaSessionActions for play and pause buttons --- ports/libsimpleservo/capi/src/lib.rs | 8 ++++ support/hololens/ServoApp/BrowserPage.cpp | 37 ++++++++++++------- support/hololens/ServoApp/BrowserPage.xaml | 4 -- support/hololens/ServoApp/MediaSession.h | 21 +++++++++++ support/hololens/ServoApp/ServoApp.vcxproj | 1 + .../ServoApp/ServoApp.vcxproj.filters | 3 ++ .../hololens/ServoApp/ServoControl/Servo.cpp | 3 +- .../hololens/ServoApp/ServoControl/Servo.h | 3 ++ .../ServoApp/ServoControl/ServoControl.cpp | 4 ++ .../ServoApp/ServoControl/ServoControl.h | 2 + .../ServoApp/ServoControl/ServoControl.idl | 5 ++- 11 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 support/hololens/ServoApp/MediaSession.h diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index 8ca727213a3..26c2046df88 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -607,6 +607,14 @@ pub extern "C" fn click(x: f32, y: f32) { }); } +#[no_mangle] +pub extern "C" fn media_session_action(action: i32) { + catch_any_panic(|| { + debug!("media_session_action"); + call(|s| s.media_session_action(action)); + }); +} + pub struct WakeupCallback(extern "C" fn()); impl WakeupCallback { diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index 536f1f378b1..695a62555da 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -7,6 +7,7 @@ #include "BrowserPage.h" #include "BrowserPage.g.cpp" #include "DefaultUrl.h" +#include "MediaSession.h" using namespace std::placeholders; using namespace winrt::Windows::Foundation; @@ -72,18 +73,20 @@ void BrowserPage::BindServoEvents() { urlTextbox().GotFocus(std::bind(&BrowserPage::OnURLFocused, this, _1)); servoControl().OnMediaSessionMetadata( [=](hstring title, hstring artist, hstring album) {}); - servoControl().OnMediaSessionPlaybackStateChange([=](const auto &, - int state) { - if (state == 1 /* none */) { - mediaControls().Visibility(Visibility::Collapsed); - return; - } - mediaControls().Visibility(Visibility::Visible); - playButton().Visibility(state == 3 /* paused */ ? Visibility::Visible - : Visibility::Collapsed); - pauseButton().Visibility(state == 3 /* paused */ ? Visibility::Collapsed - : Visibility::Visible); - }); + servoControl().OnMediaSessionPlaybackStateChange( + [=](const auto &, int state) { + if (state == servo::PlaybackState::NONE) { + mediaControls().Visibility(Visibility::Collapsed); + return; + } + mediaControls().Visibility(Visibility::Visible); + playButton().Visibility(state == servo::PlaybackState::PAUSED + ? Visibility::Visible + : Visibility::Collapsed); + pauseButton().Visibility(state == servo::PlaybackState::PAUSED + ? Visibility::Collapsed + : Visibility::Visible); + }); } void BrowserPage::OnURLFocused(Windows::Foundation::IInspectable const &) { @@ -159,9 +162,15 @@ void BrowserPage::OnURLEdited(IInspectable const &, void BrowserPage::OnMediaControlsPlayClicked( Windows::Foundation::IInspectable const &, - Windows::UI::Xaml::RoutedEventArgs const &) {} + Windows::UI::Xaml::RoutedEventArgs const &) { + servoControl().SendMediaSessionAction( + static_cast(servo::MediaSessionAction::PLAY)); +} void BrowserPage::OnMediaControlsPauseClicked( Windows::Foundation::IInspectable const &, - Windows::UI::Xaml::RoutedEventArgs const &) {} + Windows::UI::Xaml::RoutedEventArgs const &) { + servoControl().SendMediaSessionAction( + static_cast(servo::MediaSessionAction::PAUSE)); +} } // namespace winrt::ServoApp::implementation diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml index 727e73e11cc..f735e0ab993 100644 --- a/support/hololens/ServoApp/BrowserPage.xaml +++ b/support/hololens/ServoApp/BrowserPage.xaml @@ -140,10 +140,6 @@ - - - - diff --git a/support/hololens/ServoApp/MediaSession.h b/support/hololens/ServoApp/MediaSession.h new file mode 100644 index 00000000000..78deae85424 --- /dev/null +++ b/support/hololens/ServoApp/MediaSession.h @@ -0,0 +1,21 @@ +#pragma once + +namespace winrt::servo { + enum PlaybackState { + NONE = 1, + PLAYING, + PAUSED + }; + + enum MediaSessionAction { + PLAY = 1, + PAUSE, + SEEK_BACKWARD, + SEEK_FORWARD, + PREVIOUS_TRACK, + NEXT_TRACK, + SKIP_AD, + STOP, + SEEK_TO + }; +} \ No newline at end of file diff --git a/support/hololens/ServoApp/ServoApp.vcxproj b/support/hololens/ServoApp/ServoApp.vcxproj index f752011dff0..9a21cb89afe 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj +++ b/support/hololens/ServoApp/ServoApp.vcxproj @@ -122,6 +122,7 @@ + App.xaml diff --git a/support/hololens/ServoApp/ServoApp.vcxproj.filters b/support/hololens/ServoApp/ServoApp.vcxproj.filters index 3cf5c9555d5..367a4223876 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj.filters +++ b/support/hololens/ServoApp/ServoApp.vcxproj.filters @@ -40,6 +40,9 @@ + + ServoControl + diff --git a/support/hololens/ServoApp/ServoControl/Servo.cpp b/support/hololens/ServoApp/ServoControl/Servo.cpp index afe3539efe9..d3e13c5b1d9 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.cpp +++ b/support/hololens/ServoApp/ServoControl/Servo.cpp @@ -73,8 +73,7 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, capi::CInitOptions o; hstring defaultPrefs = L" --pref dom.webxr.enabled"; o.args = *hstring2char(args + defaultPrefs); - o.url = - "https://ferjm.github.io/web-api-tests/video/mp4.html"; //*hstring2char(url); + o.url = *hstring2char(url); o.width = mWindowWidth; o.height = mWindowHeight; o.density = dpi; diff --git a/support/hololens/ServoApp/ServoControl/Servo.h b/support/hololens/ServoApp/ServoControl/Servo.h index 2e76256f021..e21bd4cafbd 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.h +++ b/support/hololens/ServoApp/ServoControl/Servo.h @@ -88,6 +88,9 @@ public: capi::resize(mWindowWidth, mWindowHeight); } } + void SendMediaSessionAction(int32_t action) { + capi::media_session_action(action); + } private: ServoDelegate &mDelegate; diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.cpp b/support/hololens/ServoApp/ServoControl/ServoControl.cpp index d1d19118a29..032e3642276 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.cpp +++ b/support/hololens/ServoApp/ServoControl/ServoControl.cpp @@ -271,6 +271,10 @@ hstring ServoControl::LoadURIOrSearch(hstring input) { return searchUri; } +void ServoControl::SendMediaSessionAction(int32_t action) { + RunOnGLThread([=] { mServo->SendMediaSessionAction(action); }); +} + void ServoControl::TryLoadUri(hstring input) { if (!mLooping) { mInitialURL = input; diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.h b/support/hololens/ServoApp/ServoControl/ServoControl.h index 5daa227f126..a7c2a1f9698 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.h +++ b/support/hololens/ServoApp/ServoControl/ServoControl.h @@ -3,6 +3,7 @@ #include "OpenGLES.h" #include "Servo.h" #include "DefaultUrl.h" +#include "MediaSession.h" namespace winrt::ServoApp::implementation { struct ServoControl : ServoControlT, public servo::ServoDelegate { @@ -15,6 +16,7 @@ struct ServoControl : ServoControlT, public servo::ServoDelegate { void Stop(); void Shutdown(); hstring LoadURIOrSearch(hstring); + void SendMediaSessionAction(int32_t); void OnLoaded(IInspectable const &, Windows::UI::Xaml::RoutedEventArgs const &); diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.idl b/support/hololens/ServoApp/ServoControl/ServoControl.idl index 3a5698e1601..90a5fae8fe3 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.idl +++ b/support/hololens/ServoApp/ServoControl/ServoControl.idl @@ -14,6 +14,7 @@ namespace ServoApp { void SetTransientMode(Boolean transient); void SetArgs(String args); void Shutdown(); + void SendMediaSessionAction(UInt32 action); event EventDelegate OnLoadStarted; event EventDelegate OnLoadEnded; event EventDelegate OnCaptureGesturesStarted; @@ -21,7 +22,7 @@ namespace ServoApp { event HistoryChangedDelegate OnHistoryChanged; event Windows.Foundation.EventHandler OnTitleChanged; event Windows.Foundation.EventHandler OnURLChanged; - event MediaSessionMetadataDelegate OnMediaSessionMetadata; - event Windows.Foundation.EventHandler OnMediaSessionPlaybackStateChange; + event MediaSessionMetadataDelegate OnMediaSessionMetadata; + event Windows.Foundation.EventHandler OnMediaSessionPlaybackStateChange; } } // namespace ServoApp From b01e3fdc7ee2c3cd8b11455ec31a5c86ffec7e80 Mon Sep 17 00:00:00 2001 From: Fernando Jimenez Moreno Date: Mon, 2 Dec 2019 16:40:37 +0100 Subject: [PATCH 4/5] Introduce CMediaSessionPlaybackState and CMediaSessionActionType --- ports/libsimpleservo/api/src/lib.rs | 14 +++-- ports/libsimpleservo/capi/src/lib.rs | 59 +++++++++++++++++-- support/hololens/ServoApp/BrowserPage.cpp | 1 - support/hololens/ServoApp/MediaSession.h | 21 ------- support/hololens/ServoApp/ServoApp.vcxproj | 1 - .../ServoApp/ServoApp.vcxproj.filters | 3 - .../hololens/ServoApp/ServoControl/Servo.cpp | 3 +- .../hololens/ServoApp/ServoControl/Servo.h | 4 +- .../ServoApp/ServoControl/ServoControl.cpp | 5 +- .../ServoApp/ServoControl/ServoControl.h | 1 - 10 files changed, 71 insertions(+), 41 deletions(-) delete mode 100644 support/hololens/ServoApp/MediaSession.h diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 05a8bf9d32c..468a3b2d331 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -7,7 +7,8 @@ extern crate log; pub mod gl_glue; -pub use servo::script_traits::MouseButton; +pub use servo::embedder_traits::MediaSessionPlaybackState; +pub use servo::script_traits::{MediaSessionActionType, MouseButton}; use getopts::Options; use servo::compositing::windowing::{ @@ -133,7 +134,7 @@ pub trait HostTrait { /// Called when we get the media session metadata/ fn on_media_session_metadata(&self, title: String, artist: String, album: String); /// Called when the media session playback state changes. - fn on_media_session_playback_state_change(&self, state: i32); + fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState); /// Called when the media session position state is set. fn on_media_session_set_position_state(&self, duration: f64, position: f64, playback_rate: f64); } @@ -472,9 +473,12 @@ impl ServoGlue { self.process_event(WindowEvent::Keyboard(key_event)) } - pub fn media_session_action(&mut self, action: i32) -> Result<(), &'static str> { + pub fn media_session_action( + &mut self, + action: MediaSessionActionType, + ) -> Result<(), &'static str> { info!("Media session action {:?}", action); - self.process_event(WindowEvent::MediaSessionAction(action.into())) + self.process_event(WindowEvent::MediaSessionAction(action)) } fn process_event(&mut self, event: WindowEvent) -> Result<(), &'static str> { @@ -595,7 +599,7 @@ impl ServoGlue { MediaSessionEvent::PlaybackStateChange(state) => self .callbacks .host_callbacks - .on_media_session_playback_state_change(state as i32), + .on_media_session_playback_state_change(state), MediaSessionEvent::SetPositionState(position_state) => self .callbacks .host_callbacks diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index 26c2046df88..73bdb2de77c 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -17,7 +17,8 @@ use env_logger; use log::LevelFilter; use simpleservo::{self, gl_glue, ServoGlue, SERVO}; use simpleservo::{ - Coordinates, EventLoopWaker, HostTrait, InitOptions, MouseButton, VRInitOptions, + Coordinates, EventLoopWaker, HostTrait, InitOptions, MediaSessionActionType, + MediaSessionPlaybackState, MouseButton, VRInitOptions, }; use std::ffi::{CStr, CString}; #[cfg(target_os = "windows")] @@ -218,7 +219,7 @@ pub struct CHostCallbacks { pub set_clipboard_contents: extern "C" fn(contents: *const c_char), pub on_media_session_metadata: extern "C" fn(title: *const c_char, album: *const c_char, artist: *const c_char), - pub on_media_session_playback_state_change: extern "C" fn(state: i32), + pub on_media_session_playback_state_change: extern "C" fn(state: CMediaSessionPlaybackState), pub on_media_session_set_position_state: extern "C" fn(duration: f64, position: f64, playback_rate: f64), } @@ -254,6 +255,52 @@ impl CMouseButton { } } +#[repr(C)] +pub enum CMediaSessionPlaybackState { + None = 1, + Playing, + Paused, +} + +impl From for CMediaSessionPlaybackState { + fn from(state: MediaSessionPlaybackState) -> Self { + match state { + MediaSessionPlaybackState::None_ => CMediaSessionPlaybackState::None, + MediaSessionPlaybackState::Playing => CMediaSessionPlaybackState::Playing, + MediaSessionPlaybackState::Paused => CMediaSessionPlaybackState::Paused, + } + } +} + +#[repr(C)] +pub enum CMediaSessionActionType { + Play = 1, + Pause, + SeekBackward, + SeekForward, + PreviousTrack, + NextTrack, + SkipAd, + Stop, + SeekTo, +} + +impl CMediaSessionActionType { + pub fn convert(&self) -> MediaSessionActionType { + match self { + CMediaSessionActionType::Play => MediaSessionActionType::Play, + CMediaSessionActionType::Pause => MediaSessionActionType::Pause, + CMediaSessionActionType::SeekBackward => MediaSessionActionType::SeekBackward, + CMediaSessionActionType::SeekForward => MediaSessionActionType::SeekForward, + CMediaSessionActionType::PreviousTrack => MediaSessionActionType::PreviousTrack, + CMediaSessionActionType::NextTrack => MediaSessionActionType::NextTrack, + CMediaSessionActionType::SkipAd => MediaSessionActionType::SkipAd, + CMediaSessionActionType::Stop => MediaSessionActionType::Stop, + CMediaSessionActionType::SeekTo => MediaSessionActionType::SeekTo, + } + } +} + /// The returned string is not freed. This will leak. #[no_mangle] pub extern "C" fn servo_version() -> *const c_char { @@ -608,10 +655,10 @@ pub extern "C" fn click(x: f32, y: f32) { } #[no_mangle] -pub extern "C" fn media_session_action(action: i32) { +pub extern "C" fn media_session_action(action: CMediaSessionActionType) { catch_any_panic(|| { debug!("media_session_action"); - call(|s| s.media_session_action(action)); + call(|s| s.media_session_action(action.convert())); }); } @@ -733,9 +780,9 @@ impl HostTrait for HostCallbacks { (self.0.on_media_session_metadata)(title.as_ptr(), artist.as_ptr(), album.as_ptr()); } - fn on_media_session_playback_state_change(&self, state: i32) { + fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState) { debug!("on_media_session_playback_state_change {:?}", state); - (self.0.on_media_session_playback_state_change)(state); + (self.0.on_media_session_playback_state_change)(state.into()); } fn on_media_session_set_position_state( diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index 695a62555da..c68017541aa 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -7,7 +7,6 @@ #include "BrowserPage.h" #include "BrowserPage.g.cpp" #include "DefaultUrl.h" -#include "MediaSession.h" using namespace std::placeholders; using namespace winrt::Windows::Foundation; diff --git a/support/hololens/ServoApp/MediaSession.h b/support/hololens/ServoApp/MediaSession.h deleted file mode 100644 index 78deae85424..00000000000 --- a/support/hololens/ServoApp/MediaSession.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -namespace winrt::servo { - enum PlaybackState { - NONE = 1, - PLAYING, - PAUSED - }; - - enum MediaSessionAction { - PLAY = 1, - PAUSE, - SEEK_BACKWARD, - SEEK_FORWARD, - PREVIOUS_TRACK, - NEXT_TRACK, - SKIP_AD, - STOP, - SEEK_TO - }; -} \ No newline at end of file diff --git a/support/hololens/ServoApp/ServoApp.vcxproj b/support/hololens/ServoApp/ServoApp.vcxproj index 9a21cb89afe..f752011dff0 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj +++ b/support/hololens/ServoApp/ServoApp.vcxproj @@ -122,7 +122,6 @@ - App.xaml diff --git a/support/hololens/ServoApp/ServoApp.vcxproj.filters b/support/hololens/ServoApp/ServoApp.vcxproj.filters index 367a4223876..3cf5c9555d5 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj.filters +++ b/support/hololens/ServoApp/ServoApp.vcxproj.filters @@ -40,9 +40,6 @@ - - ServoControl - diff --git a/support/hololens/ServoApp/ServoControl/Servo.cpp b/support/hololens/ServoApp/ServoControl/Servo.cpp index d3e13c5b1d9..6a3a93cc34b 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.cpp +++ b/support/hololens/ServoApp/ServoControl/Servo.cpp @@ -62,7 +62,8 @@ void on_media_session_metadata(const char *title, const char *album, char2hstring(title), char2hstring(album), char2hstring(artist)); } -void on_media_session_playback_state_change(const int state) { +void on_media_session_playback_state_change( + const capi::CMediaSessionPlaybackState state) { return sServo->Delegate().OnServoMediaSessionPlaybackStateChange(state); } diff --git a/support/hololens/ServoApp/ServoControl/Servo.h b/support/hololens/ServoApp/ServoControl/Servo.h index e21bd4cafbd..43da0160755 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.h +++ b/support/hololens/ServoApp/ServoControl/Servo.h @@ -50,6 +50,8 @@ public: ServoDelegate &Delegate() { return mDelegate; } typedef capi::CMouseButton MouseButton; + typedef capi::CMediaSessionActionType MediaSessionActionType; + typedef capi::CMediaSessionPlaybackState MediaSessionPlaybackState; void PerformUpdates() { capi::perform_updates(); } void DeInit() { capi::deinit(); } @@ -88,7 +90,7 @@ public: capi::resize(mWindowWidth, mWindowHeight); } } - void SendMediaSessionAction(int32_t action) { + void SendMediaSessionAction(capi::CMediaSessionActionType action) { capi::media_session_action(action); } diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.cpp b/support/hololens/ServoApp/ServoControl/ServoControl.cpp index 032e3642276..9e3321f74b9 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.cpp +++ b/support/hololens/ServoApp/ServoControl/ServoControl.cpp @@ -272,7 +272,10 @@ hstring ServoControl::LoadURIOrSearch(hstring input) { } void ServoControl::SendMediaSessionAction(int32_t action) { - RunOnGLThread([=] { mServo->SendMediaSessionAction(action); }); + RunOnGLThread([=] { + mServo->SendMediaSessionAction( + static_cast(action)); + }); } void ServoControl::TryLoadUri(hstring input) { diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.h b/support/hololens/ServoApp/ServoControl/ServoControl.h index a7c2a1f9698..5ca3f906e99 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.h +++ b/support/hololens/ServoApp/ServoControl/ServoControl.h @@ -3,7 +3,6 @@ #include "OpenGLES.h" #include "Servo.h" #include "DefaultUrl.h" -#include "MediaSession.h" namespace winrt::ServoApp::implementation { struct ServoControl : ServoControlT, public servo::ServoDelegate { From 58623a6f5bd45f1e0e3f94fca15ab4a3793eb933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 2 Dec 2019 17:14:46 +0100 Subject: [PATCH 5/5] Fix libsimpleservo build after MediaSession C enums change --- ports/libsimpleservo/api/src/lib.rs | 2 +- ports/libsimpleservo/capi/src/lib.rs | 2 +- ports/libsimpleservo/jniapi/src/lib.rs | 9 ++++++--- support/hololens/ServoApp/BrowserPage.cpp | 20 +++++++++++--------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 468a3b2d331..0b127eddb9a 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -134,7 +134,7 @@ pub trait HostTrait { /// Called when we get the media session metadata/ fn on_media_session_metadata(&self, title: String, artist: String, album: String); /// Called when the media session playback state changes. - fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState); + fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState); /// Called when the media session position state is set. fn on_media_session_set_position_state(&self, duration: f64, position: f64, playback_rate: f64); } diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index 73bdb2de77c..89d3b0f5c1a 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -219,7 +219,7 @@ pub struct CHostCallbacks { pub set_clipboard_contents: extern "C" fn(contents: *const c_char), pub on_media_session_metadata: extern "C" fn(title: *const c_char, album: *const c_char, artist: *const c_char), - pub on_media_session_playback_state_change: extern "C" fn(state: CMediaSessionPlaybackState), + pub on_media_session_playback_state_change: extern "C" fn(state: CMediaSessionPlaybackState), pub on_media_session_set_position_state: extern "C" fn(duration: f64, position: f64, playback_rate: f64), } diff --git a/ports/libsimpleservo/jniapi/src/lib.rs b/ports/libsimpleservo/jniapi/src/lib.rs index 74db8774a15..1c4020652e8 100644 --- a/ports/libsimpleservo/jniapi/src/lib.rs +++ b/ports/libsimpleservo/jniapi/src/lib.rs @@ -15,7 +15,9 @@ use jni::{errors, JNIEnv, JavaVM}; use libc::{dup2, pipe, read}; use log::Level; use simpleservo::{self, gl_glue, ServoGlue, SERVO}; -use simpleservo::{Coordinates, EventLoopWaker, HostTrait, InitOptions, VRInitOptions}; +use simpleservo::{ + Coordinates, EventLoopWaker, HostTrait, InitOptions, MediaSessionPlaybackState, VRInitOptions, +}; use std::os::raw::{c_char, c_int, c_void}; use std::ptr::{null, null_mut}; use std::sync::Arc; @@ -340,7 +342,7 @@ pub fn Java_org_mozilla_servoview_JNIServo_mediaSessionAction( action: jint, ) { debug!("mediaSessionAction"); - call(&env, |s| s.media_session_action(action as i32)); + call(&env, |s| s.media_session_action((action as i32).into())); } pub struct WakeupCallback { @@ -548,9 +550,10 @@ impl HostTrait for HostCallbacks { .unwrap(); } - fn on_media_session_playback_state_change(&self, state: i32) { + fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState) { info!("on_media_session_playback_state_change {:?}", state); let env = self.jvm.get_env().unwrap(); + let state = state as i32; let state = JValue::Int(state as jint); env.call_method( self.callbacks.as_obj(), diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index c68017541aa..daf29c27340 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -74,17 +74,19 @@ void BrowserPage::BindServoEvents() { [=](hstring title, hstring artist, hstring album) {}); servoControl().OnMediaSessionPlaybackStateChange( [=](const auto &, int state) { - if (state == servo::PlaybackState::NONE) { + if (state == servo::Servo::MediaSessionPlaybackState::None) { mediaControls().Visibility(Visibility::Collapsed); return; } mediaControls().Visibility(Visibility::Visible); - playButton().Visibility(state == servo::PlaybackState::PAUSED - ? Visibility::Visible - : Visibility::Collapsed); - pauseButton().Visibility(state == servo::PlaybackState::PAUSED - ? Visibility::Collapsed - : Visibility::Visible); + playButton().Visibility( + state == servo::Servo::MediaSessionPlaybackState::Paused + ? Visibility::Visible + : Visibility::Collapsed); + pauseButton().Visibility( + state == servo::Servo::MediaSessionPlaybackState::Paused + ? Visibility::Collapsed + : Visibility::Visible); }); } @@ -163,13 +165,13 @@ void BrowserPage::OnMediaControlsPlayClicked( Windows::Foundation::IInspectable const &, Windows::UI::Xaml::RoutedEventArgs const &) { servoControl().SendMediaSessionAction( - static_cast(servo::MediaSessionAction::PLAY)); + static_cast(servo::Servo::MediaSessionActionType::Play)); } void BrowserPage::OnMediaControlsPauseClicked( Windows::Foundation::IInspectable const &, Windows::UI::Xaml::RoutedEventArgs const &) { servoControl().SendMediaSessionAction( - static_cast(servo::MediaSessionAction::PAUSE)); + static_cast(servo::Servo::MediaSessionActionType::Pause)); } } // namespace winrt::ServoApp::implementation