cranpose_services/
background.rs1use std::sync::Arc;
11use std::sync::Mutex;
12use std::sync::OnceLock;
13
14pub trait BackgroundActivity: Send + Sync {
18 fn set_active(&self, active: bool);
21}
22
23pub type BackgroundActivityRef = Arc<dyn BackgroundActivity>;
24
25fn slot() -> &'static Mutex<Option<BackgroundActivityRef>> {
26 static SLOT: OnceLock<Mutex<Option<BackgroundActivityRef>>> = OnceLock::new();
27 SLOT.get_or_init(|| Mutex::new(None))
28}
29
30pub fn set_platform_background_activity(activity: BackgroundActivityRef) {
32 if let Ok(mut s) = slot().lock() {
33 *s = Some(activity);
34 }
35}
36
37pub fn clear_platform_background_activity() {
39 if let Ok(mut s) = slot().lock() {
40 *s = None;
41 }
42}
43
44pub fn background_activity() -> Option<BackgroundActivityRef> {
46 slot().lock().ok().and_then(|s| s.clone())
47}
48
49pub fn set_background_active(active: bool) {
51 if let Some(activity) = background_activity() {
52 activity.set_active(active);
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use std::sync::atomic::{AtomicBool, Ordering};
60
61 #[test]
62 fn registration_round_trips() {
63 clear_platform_background_activity();
64 set_background_active(true); struct Rec(AtomicBool);
66 impl BackgroundActivity for Rec {
67 fn set_active(&self, active: bool) {
68 self.0.store(active, Ordering::SeqCst);
69 }
70 }
71 let rec = Arc::new(Rec(AtomicBool::new(false)));
72 set_platform_background_activity(rec.clone());
73 set_background_active(true);
74 assert!(rec.0.load(Ordering::SeqCst));
75 clear_platform_background_activity();
76 }
77}