mirror of
https://github.com/SteamFramelyHomebrew/framely.git
synced 2026-10-18 05:01:23 +02:00
Request AirPlay consent on media setup and renew pending reconnects
This commit is contained in:
1 parent
05f172e467
commit
c44fad4fc4
2 files changed
+49
No files matched your search
@@ -35,3 +35,30 @@ if 'framely_client_device' not in s:
|
||||
}
|
||||
'''+marker)
|
||||
p.write_text(s)
|
||||
|
||||
# A GStreamer sink can survive successive audio sessions. Announce each valid
|
||||
# media SETUP independently of its first decoded buffer.
|
||||
s=p.read_text()
|
||||
if 'framely_media_request' not in s:
|
||||
marker=' unsigned char type;\n LOGI("ct=%d'
|
||||
assert marker in s
|
||||
s=s.replace(marker,''' // framely_media_request: a new SETUP needs fresh consent after teardown.
|
||||
const char* directory=getenv("FRAMELY_CAST_DIR"),*id=getenv("FRAMELY_CAST_ID");
|
||||
if(directory&&id)FrameSink(directory,id,"AirPlay").event("request");
|
||||
unsigned char type;
|
||||
LOGI("ct=%d''',1)
|
||||
p.write_text(s)
|
||||
|
||||
# Mirroring may have no audio stream. Its size report arrives before decoding,
|
||||
# so it must also request consent independently of the decoder's first frame.
|
||||
s=p.read_text()
|
||||
if 'framely_mirror_request' not in s:
|
||||
marker='extern "C" void video_report_size(void *cls, float *width_source, float *height_source, float *width, float *height) {'
|
||||
assert marker in s
|
||||
s=s.replace(marker,marker+'''
|
||||
// framely_mirror_request: notify even while the video decoder is starting.
|
||||
const char* directory=getenv("FRAMELY_CAST_DIR"),*id=getenv("FRAMELY_CAST_ID");
|
||||
if(directory&&id&&*width_source>0&&*width_source<=4096&&*height_source>0&&*height_source<=4096)
|
||||
FrameSink(directory,id,"AirPlay").event("request",(unsigned)*width_source,(unsigned)*height_source);
|
||||
''',1)
|
||||
p.write_text(s)
|
||||
@@ -216,6 +216,10 @@ impl Receivers {
|
||||
self.sessions.insert(id.clone(), e.clone());
|
||||
self.events
|
||||
.push_back(json!({"kind":"cast.request","session":e}));
|
||||
} else if kind=="request" && e["protocol"]=="AirPlay" && self.sessions[&id]["accepted"]!=true {
|
||||
// SETUP can recur on an open control connection after the
|
||||
// previous consent toast expired. Renew the pending request.
|
||||
self.events.push_back(json!({"kind":"cast.request","session":self.sessions[&id]}));
|
||||
} else if matches!(kind, "video" | "audio") {
|
||||
let session = self.sessions.get_mut(&id).unwrap();
|
||||
if kind == "video" {
|
||||
@@ -500,6 +504,24 @@ fn stop_child(child: &mut Child) {
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn airplay_setup_requests_consent_before_frames_and_after_reconnect() {
|
||||
let root=tempfile::tempdir().unwrap();
|
||||
let mut r=Receivers::new(root.path().to_owned(),root.path().join("bin"));
|
||||
r.airplay_id="0123".into();
|
||||
for _ in 0..2 {
|
||||
r.event(json!({"event":"request","id":"0123","protocol":"AirPlay"}));
|
||||
assert_eq!(r.events.pop_front().unwrap()["kind"],"cast.request");
|
||||
assert!(r.window("0123").is_err());
|
||||
r.event(json!({"event":"request","id":"0123","protocol":"AirPlay"}));
|
||||
assert_eq!(r.events.pop_front().unwrap()["kind"],"cast.request");
|
||||
r.control("0123","accept",json!({})).unwrap();
|
||||
assert_eq!(r.window("0123").unwrap()["accepted"],true);
|
||||
r.event(json!({"event":"ended","id":"0123","protocol":"AirPlay"}));
|
||||
assert!(!root.path().join("0123.accept").exists());
|
||||
r.events.clear();
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn consent_blocks_playback_controls_and_rejects_stale_airplay_sessions() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let mut r = Receivers::new(root.path().to_owned(), root.path().join("bin"));
|
||||
|
||||
Reference in new issue
Block a user