Send MediaSessionAction from Android

This commit is contained in:
Fernando Jiménez Moreno 2019-10-18 22:29:11 +02:00
parent b494acbf19
commit 08f9f17ed3
10 changed files with 64 additions and 15 deletions

View file

@ -1913,12 +1913,6 @@ impl HTMLMediaElement {
self.media_element_load_algorithm(); self.media_element_load_algorithm();
} }
} }
fn send_media_session_event(&self, event: MediaSessionEvent) {
let global = self.global();
let media_session = global.as_window().Navigator().MediaSession();
media_session.send_event(event);
}
} }
// XXX Placeholder for [https://github.com/servo/servo/issues/22293] // XXX Placeholder for [https://github.com/servo/servo/issues/22293]

View file

@ -61,6 +61,7 @@ impl MediaSession {
} }
pub fn handle_action(&self, action: MediaSessionActionType) { pub fn handle_action(&self, action: MediaSessionActionType) {
println!("HANDLE ACTION {:?}", action);
if let Some(handler) = self.action_handlers.borrow().get(&action) { if let Some(handler) = self.action_handlers.borrow().get(&action) {
if handler.Call__(ExceptionHandling::Report).is_err() { if handler.Call__(ExceptionHandling::Report).is_err() {
warn!("Error calling MediaSessionActionHandler callback"); warn!("Error calling MediaSessionActionHandler callback");

View file

@ -1087,3 +1087,20 @@ pub enum MediaSessionActionType {
/// The action intent is to move the playback time to a specific time. /// The action intent is to move the playback time to a specific time.
SeekTo, SeekTo,
} }
impl From<i32> for MediaSessionActionType {
fn from(value: i32) -> MediaSessionActionType {
match value {
1 => MediaSessionActionType::Play,
2 => MediaSessionActionType::Pause,
3 => MediaSessionActionType::SeekBackward,
4 => MediaSessionActionType::SeekForward,
5 => MediaSessionActionType::PreviousTrack,
6 => MediaSessionActionType::NextTrack,
7 => MediaSessionActionType::SkipAd,
8 => MediaSessionActionType::Stop,
9 => MediaSessionActionType::SeekTo,
_ => panic!("Unknown MediaSessionActionType"),
}
}
}

View file

@ -19,7 +19,7 @@ use servo::embedder_traits::{EmbedderMsg, MediaSessionEvent};
use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use servo::keyboard_types::{Key, KeyState, KeyboardEvent}; use servo::keyboard_types::{Key, KeyState, KeyboardEvent};
use servo::msg::constellation_msg::TraversalDirection; use servo::msg::constellation_msg::TraversalDirection;
use servo::script_traits::{MediaSessionActionType, TouchEventType, TouchId}; use servo::script_traits::{TouchEventType, TouchId};
use servo::servo_config::opts; use servo::servo_config::opts;
use servo::servo_config::{pref, set_pref}; use servo::servo_config::{pref, set_pref};
use servo::servo_url::ServoUrl; use servo::servo_url::ServoUrl;
@ -470,13 +470,10 @@ impl ServoGlue {
self.process_event(WindowEvent::Keyboard(key_event)) self.process_event(WindowEvent::Keyboard(key_event))
} }
pub fn media_session_action( pub fn media_session_action(&mut self, action: i32) -> Result<(), &'static str> {
&mut self,
action: MediaSessionActionType,
) -> Result<(), &'static str> {
info!("Media session action {:?}", action); info!("Media session action {:?}", action);
let browser_id = self.get_browser_id()?; let browser_id = self.get_browser_id()?;
self.process_event(WindowEvent::MediaSessionAction(browser_id, action)) self.process_event(WindowEvent::MediaSessionAction(browser_id, action.into()))
} }
fn process_event(&mut self, event: WindowEvent) -> Result<(), &'static str> { fn process_event(&mut self, event: WindowEvent) -> Result<(), &'static str> {

View file

@ -333,6 +333,16 @@ pub fn Java_org_mozilla_servoview_JNIServo_click(env: JNIEnv, _: JClass, x: jint
call(&env, |s| s.click(x as f32, y as f32)); call(&env, |s| s.click(x as f32, y as f32));
} }
#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_mediaSessionAction(
env: JNIEnv,
_: JClass,
action: jint,
) {
debug!("mediaSessionAction");
call(&env, |s| s.media_session_action(action as i32));
}
pub struct WakeupCallback { pub struct WakeupCallback {
callback: GlobalRef, callback: GlobalRef,
jvm: Arc<JavaVM>, jvm: Arc<JavaVM>,

View file

@ -241,11 +241,11 @@ public class MainActivity extends Activity implements Servo.Client {
mMediaSession = new MediaSession(mServoView, this, getApplicationContext()); mMediaSession = new MediaSession(mServoView, this, getApplicationContext());
} }
Log.d("SERVOMEDIA", "PLAYBACK STATE CHANGED " + state); Log.d("SERVOMEDIA", "PLAYBACK STATE CHANGED " + state);
if (state == 1 /* none */) { if (state == MediaSession.PLAYBACK_STATE_NONE) {
mMediaSession.hideMediaSessionControls(); mMediaSession.hideMediaSessionControls();
return; return;
} }
if (state == 2 /* playing */) { if (state == MediaSession.PLAYBACK_STATE_PLAYING) {
mMediaSession.showMediaSessionControls(); mMediaSession.showMediaSessionControls();
return; return;
} }

View file

@ -32,6 +32,22 @@ public class MediaSession {
} }
} }
// https://w3c.github.io/mediasession/#enumdef-mediasessionplaybackstate
public static final int PLAYBACK_STATE_NONE = 1;
public static final int PLAYBACK_STATE_PLAYING = 2;
public static final int PLAYBACK_STATE_PAUSED = 3;
// https://w3c.github.io/mediasession/#enumdef-mediasessionaction
private static final int ACTION_PLAY = 1;
private static final int ACTION_PAUSE = 2;
private static final int ACTON_SEEK_BACKWARD = 3;
private static final int ACTION_SEEK_FORWARD = 4;
private static final int ACTION_PREVIOUS_TRACK = 5;
private static final int ACTION_NEXT_TRACK = 6;
private static final int ACTION_SKIP_AD = 7;
private static final int ACTION_STOP = 8;
private static final int ACTION_SEEK_TO = 9;
private static final String MEDIA_CHANNEL_ID = "MediaNotificationChannel"; private static final String MEDIA_CHANNEL_ID = "MediaNotificationChannel";
private static final String KEY_MEDIA_PAUSE = "org.mozilla.servoview.MainActivity.pause"; private static final String KEY_MEDIA_PAUSE = "org.mozilla.servoview.MainActivity.pause";
private static final String KEY_MEDIA_PREV = "org.mozilla.servoview.MainActivity.prev"; private static final String KEY_MEDIA_PREV = "org.mozilla.servoview.MainActivity.prev";
@ -79,12 +95,16 @@ public class MediaSession {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(KEY_MEDIA_PAUSE)) { if (intent.getAction().equals(KEY_MEDIA_PAUSE)) {
mView.mediaSessionAction(ACTION_PAUSE);
Log.d("SERVOMEDIA", "PAUSE"); Log.d("SERVOMEDIA", "PAUSE");
} else if (intent.getAction().equals(KEY_MEDIA_STOP)) { } else if (intent.getAction().equals(KEY_MEDIA_STOP)) {
mView.mediaSessionAction(ACTION_STOP);
Log.d("SERVOMEDIA", "STOP"); Log.d("SERVOMEDIA", "STOP");
} else if (intent.getAction().equals(KEY_MEDIA_NEXT)) { } else if (intent.getAction().equals(KEY_MEDIA_NEXT)) {
mView.mediaSessionAction(ACTION_NEXT_TRACK);
Log.d("SERVOMEDIA", "NEXT"); Log.d("SERVOMEDIA", "NEXT");
} else if (intent.getAction().equals(KEY_MEDIA_PREV)) { } else if (intent.getAction().equals(KEY_MEDIA_PREV)) {
mView.mediaSessionAction(ACTION_PREVIOUS_TRACK);
Log.d("SERVOMEDIA", "PREV"); Log.d("SERVOMEDIA", "PREV");
} }
} }

View file

@ -66,6 +66,8 @@ public class JNIServo {
public native void click(float x, float y); public native void click(float x, float y);
public native void mediaSessionAction(int action);
public static class ServoOptions { public static class ServoOptions {
public String args; public String args;
public String url; public String url;

View file

@ -168,6 +168,10 @@ public class Servo {
mSuspended = suspended; mSuspended = suspended;
} }
public void mediaSessionAction(int action) {
mRunCallback.inGLThread(() -> mJNI.mediaSessionAction(action));
}
public interface Client { public interface Client {
void onAlert(String message); void onAlert(String message);

View file

@ -134,8 +134,12 @@ public class ServoView extends GLSurfaceView
} }
} }
public void mediaSessionAction(int action) {
mServo.mediaSessionAction(action);
}
public void flushGLBuffers() { public void flushGLBuffers() {
requestRender(); requestRender();
} }
// Scroll and click // Scroll and click