pub struct WindowManager { /* private fields */ }Expand description
Manages the collection of events into time windows.
Implementations§
Source§impl WindowManager
impl WindowManager
Sourcepub fn new(window_duration_secs: u64, session_gap_threshold_secs: u64) -> Self
pub fn new(window_duration_secs: u64, session_gap_threshold_secs: u64) -> Self
Create a new window manager with the given window duration.
Examples found in repository?
examples/capture_demo.rs (line 58)
26fn main() {
27 println!("Synheart Sensor Agent - Capture Demo");
28 println!("=====================================");
29 println!();
30
31 // Display privacy declaration
32 println!("{PRIVACY_DECLARATION}");
33 println!();
34
35 // Check for permission
36 print!("Checking Input Monitoring permission... ");
37 if check_permission() {
38 println!("OK ✓");
39 } else {
40 println!("FAILED ✗");
41 println!();
42 println!("Please grant Input Monitoring permission:");
43 println!("1. Open System Preferences");
44 println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45 println!("3. Add this application");
46 println!("4. Restart this demo");
47 return;
48 }
49 println!();
50
51 // Create components
52 let config = CollectorConfig {
53 capture_keyboard: true,
54 capture_mouse: true,
55 };
56
57 let mut collector = Collector::new(config);
58 let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59 let hsi_builder = HsiBuilder::new();
60 let transparency_log = TransparencyLog::new();
61
62 println!("Instance ID: {}", hsi_builder.instance_id());
63 println!();
64 println!("Starting capture for 30 seconds...");
65 println!("Try typing and moving your mouse!");
66 println!();
67
68 // Start collection
69 if let Err(e) = collector.start() {
70 eprintln!("Error starting collector: {e}");
71 return;
72 }
73
74 // Set up stop flag
75 let running = Arc::new(AtomicBool::new(true));
76 let r = running.clone();
77
78 // Set up Ctrl+C handler
79 ctrlc::set_handler(move || {
80 r.store(false, Ordering::SeqCst);
81 })
82 .expect("Error setting Ctrl+C handler");
83
84 // Run for 30 seconds
85 let start = std::time::Instant::now();
86 let receiver = collector.receiver().clone();
87 let mut event_count = 0;
88
89 while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90 // Receive events with timeout
91 match receiver.recv_timeout(Duration::from_millis(100)) {
92 Ok(event) => {
93 event_count += 1;
94
95 // Log event type
96 match &event {
97 SensorEvent::Keyboard(e) => {
98 transparency_log.record_keyboard_event();
99 if event_count <= 10 || event_count % 50 == 0 {
100 println!(
101 " Keyboard event: {} at {}",
102 if e.is_key_down { "down" } else { "up" },
103 e.timestamp.format("%H:%M:%S%.3f")
104 );
105 }
106 }
107 SensorEvent::Mouse(e) => {
108 transparency_log.record_mouse_event();
109 if event_count <= 10 || event_count % 100 == 0 {
110 println!(
111 " Mouse event: {:?} at {}",
112 e.event_type,
113 e.timestamp.format("%H:%M:%S%.3f")
114 );
115 }
116 }
117 }
118
119 // Process in window manager
120 window_manager.process_event(event);
121 }
122 Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
123 // Check for window expiry
124 window_manager.check_window_expiry();
125 }
126 Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
127 break;
128 }
129 }
130
131 // Process completed windows
132 for window in window_manager.take_completed_windows() {
133 transparency_log.record_window_completed();
134
135 let features = compute_features(&window);
136 let snapshot = hsi_builder.build(&window, &features);
137
138 println!();
139 println!("=== Window Completed ===");
140 println!(" Duration: {:.1}s", window.duration_secs());
141 println!(" Keyboard events: {}", window.keyboard_events.len());
142 println!(" Mouse events: {}", window.mouse_events.len());
143 println!();
144 println!(" Keyboard Features:");
145 println!(
146 " Typing rate: {:.2} keys/sec",
147 features.keyboard.typing_rate
148 );
149 println!(" Pause count: {}", features.keyboard.pause_count);
150 println!(" Burst index: {:.3}", features.keyboard.burst_index);
151 println!();
152 println!(" Mouse Features:");
153 println!(
154 " Activity rate: {:.2} moves/sec",
155 features.mouse.mouse_activity_rate
156 );
157 println!(" Mean velocity: {:.2}", features.mouse.mean_velocity);
158 println!(
159 " Click rate: {:.2} clicks/sec",
160 features.mouse.click_rate
161 );
162 println!();
163 println!(" Behavioral Signals:");
164 println!(
165 " Interaction rhythm: {:.3}",
166 features.behavioral.interaction_rhythm
167 );
168 println!(" Friction: {:.3}", features.behavioral.friction);
169 println!(
170 " Motor stability: {:.3}",
171 features.behavioral.motor_stability
172 );
173 println!(
174 " Focus continuity: {:.3}",
175 features.behavioral.focus_continuity_proxy
176 );
177 println!();
178
179 // Show snippet of HSI JSON
180 let json = serde_json::to_string_pretty(&snapshot).unwrap();
181 println!(" HSI Snapshot (truncated):");
182 for line in json.lines().take(20) {
183 println!(" {line}");
184 }
185 println!(" ...");
186 println!();
187 }
188
189 // Show progress
190 if event_count > 0 && event_count % 200 == 0 {
191 let elapsed = start.elapsed().as_secs();
192 println!(" [{elapsed}/30s] Processed {event_count} events...");
193 }
194 }
195
196 // Stop collection
197 println!();
198 println!("Stopping capture...");
199 collector.stop();
200
201 // Flush remaining window
202 window_manager.flush();
203 for window in window_manager.take_completed_windows() {
204 println!("Final window: {} events", window.event_count());
205 transparency_log.record_window_completed();
206 }
207
208 // Final statistics
209 println!();
210 println!("{}", transparency_log.summary());
211 println!();
212 println!("Demo complete!");
213}Sourcepub fn process_event(&mut self, event: SensorEvent)
pub fn process_event(&mut self, event: SensorEvent)
Process an incoming event.
This will:
- Detect session boundaries based on gaps
- Create new windows as needed
- Complete windows when their time expires
Examples found in repository?
examples/capture_demo.rs (line 120)
26fn main() {
27 println!("Synheart Sensor Agent - Capture Demo");
28 println!("=====================================");
29 println!();
30
31 // Display privacy declaration
32 println!("{PRIVACY_DECLARATION}");
33 println!();
34
35 // Check for permission
36 print!("Checking Input Monitoring permission... ");
37 if check_permission() {
38 println!("OK ✓");
39 } else {
40 println!("FAILED ✗");
41 println!();
42 println!("Please grant Input Monitoring permission:");
43 println!("1. Open System Preferences");
44 println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45 println!("3. Add this application");
46 println!("4. Restart this demo");
47 return;
48 }
49 println!();
50
51 // Create components
52 let config = CollectorConfig {
53 capture_keyboard: true,
54 capture_mouse: true,
55 };
56
57 let mut collector = Collector::new(config);
58 let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59 let hsi_builder = HsiBuilder::new();
60 let transparency_log = TransparencyLog::new();
61
62 println!("Instance ID: {}", hsi_builder.instance_id());
63 println!();
64 println!("Starting capture for 30 seconds...");
65 println!("Try typing and moving your mouse!");
66 println!();
67
68 // Start collection
69 if let Err(e) = collector.start() {
70 eprintln!("Error starting collector: {e}");
71 return;
72 }
73
74 // Set up stop flag
75 let running = Arc::new(AtomicBool::new(true));
76 let r = running.clone();
77
78 // Set up Ctrl+C handler
79 ctrlc::set_handler(move || {
80 r.store(false, Ordering::SeqCst);
81 })
82 .expect("Error setting Ctrl+C handler");
83
84 // Run for 30 seconds
85 let start = std::time::Instant::now();
86 let receiver = collector.receiver().clone();
87 let mut event_count = 0;
88
89 while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90 // Receive events with timeout
91 match receiver.recv_timeout(Duration::from_millis(100)) {
92 Ok(event) => {
93 event_count += 1;
94
95 // Log event type
96 match &event {
97 SensorEvent::Keyboard(e) => {
98 transparency_log.record_keyboard_event();
99 if event_count <= 10 || event_count % 50 == 0 {
100 println!(
101 " Keyboard event: {} at {}",
102 if e.is_key_down { "down" } else { "up" },
103 e.timestamp.format("%H:%M:%S%.3f")
104 );
105 }
106 }
107 SensorEvent::Mouse(e) => {
108 transparency_log.record_mouse_event();
109 if event_count <= 10 || event_count % 100 == 0 {
110 println!(
111 " Mouse event: {:?} at {}",
112 e.event_type,
113 e.timestamp.format("%H:%M:%S%.3f")
114 );
115 }
116 }
117 }
118
119 // Process in window manager
120 window_manager.process_event(event);
121 }
122 Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
123 // Check for window expiry
124 window_manager.check_window_expiry();
125 }
126 Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
127 break;
128 }
129 }
130
131 // Process completed windows
132 for window in window_manager.take_completed_windows() {
133 transparency_log.record_window_completed();
134
135 let features = compute_features(&window);
136 let snapshot = hsi_builder.build(&window, &features);
137
138 println!();
139 println!("=== Window Completed ===");
140 println!(" Duration: {:.1}s", window.duration_secs());
141 println!(" Keyboard events: {}", window.keyboard_events.len());
142 println!(" Mouse events: {}", window.mouse_events.len());
143 println!();
144 println!(" Keyboard Features:");
145 println!(
146 " Typing rate: {:.2} keys/sec",
147 features.keyboard.typing_rate
148 );
149 println!(" Pause count: {}", features.keyboard.pause_count);
150 println!(" Burst index: {:.3}", features.keyboard.burst_index);
151 println!();
152 println!(" Mouse Features:");
153 println!(
154 " Activity rate: {:.2} moves/sec",
155 features.mouse.mouse_activity_rate
156 );
157 println!(" Mean velocity: {:.2}", features.mouse.mean_velocity);
158 println!(
159 " Click rate: {:.2} clicks/sec",
160 features.mouse.click_rate
161 );
162 println!();
163 println!(" Behavioral Signals:");
164 println!(
165 " Interaction rhythm: {:.3}",
166 features.behavioral.interaction_rhythm
167 );
168 println!(" Friction: {:.3}", features.behavioral.friction);
169 println!(
170 " Motor stability: {:.3}",
171 features.behavioral.motor_stability
172 );
173 println!(
174 " Focus continuity: {:.3}",
175 features.behavioral.focus_continuity_proxy
176 );
177 println!();
178
179 // Show snippet of HSI JSON
180 let json = serde_json::to_string_pretty(&snapshot).unwrap();
181 println!(" HSI Snapshot (truncated):");
182 for line in json.lines().take(20) {
183 println!(" {line}");
184 }
185 println!(" ...");
186 println!();
187 }
188
189 // Show progress
190 if event_count > 0 && event_count % 200 == 0 {
191 let elapsed = start.elapsed().as_secs();
192 println!(" [{elapsed}/30s] Processed {event_count} events...");
193 }
194 }
195
196 // Stop collection
197 println!();
198 println!("Stopping capture...");
199 collector.stop();
200
201 // Flush remaining window
202 window_manager.flush();
203 for window in window_manager.take_completed_windows() {
204 println!("Final window: {} events", window.event_count());
205 transparency_log.record_window_completed();
206 }
207
208 // Final statistics
209 println!();
210 println!("{}", transparency_log.summary());
211 println!();
212 println!("Demo complete!");
213}Sourcepub fn flush(&mut self)
pub fn flush(&mut self)
Force completion of the current window (e.g., on pause or stop).
Examples found in repository?
examples/capture_demo.rs (line 202)
26fn main() {
27 println!("Synheart Sensor Agent - Capture Demo");
28 println!("=====================================");
29 println!();
30
31 // Display privacy declaration
32 println!("{PRIVACY_DECLARATION}");
33 println!();
34
35 // Check for permission
36 print!("Checking Input Monitoring permission... ");
37 if check_permission() {
38 println!("OK ✓");
39 } else {
40 println!("FAILED ✗");
41 println!();
42 println!("Please grant Input Monitoring permission:");
43 println!("1. Open System Preferences");
44 println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45 println!("3. Add this application");
46 println!("4. Restart this demo");
47 return;
48 }
49 println!();
50
51 // Create components
52 let config = CollectorConfig {
53 capture_keyboard: true,
54 capture_mouse: true,
55 };
56
57 let mut collector = Collector::new(config);
58 let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59 let hsi_builder = HsiBuilder::new();
60 let transparency_log = TransparencyLog::new();
61
62 println!("Instance ID: {}", hsi_builder.instance_id());
63 println!();
64 println!("Starting capture for 30 seconds...");
65 println!("Try typing and moving your mouse!");
66 println!();
67
68 // Start collection
69 if let Err(e) = collector.start() {
70 eprintln!("Error starting collector: {e}");
71 return;
72 }
73
74 // Set up stop flag
75 let running = Arc::new(AtomicBool::new(true));
76 let r = running.clone();
77
78 // Set up Ctrl+C handler
79 ctrlc::set_handler(move || {
80 r.store(false, Ordering::SeqCst);
81 })
82 .expect("Error setting Ctrl+C handler");
83
84 // Run for 30 seconds
85 let start = std::time::Instant::now();
86 let receiver = collector.receiver().clone();
87 let mut event_count = 0;
88
89 while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90 // Receive events with timeout
91 match receiver.recv_timeout(Duration::from_millis(100)) {
92 Ok(event) => {
93 event_count += 1;
94
95 // Log event type
96 match &event {
97 SensorEvent::Keyboard(e) => {
98 transparency_log.record_keyboard_event();
99 if event_count <= 10 || event_count % 50 == 0 {
100 println!(
101 " Keyboard event: {} at {}",
102 if e.is_key_down { "down" } else { "up" },
103 e.timestamp.format("%H:%M:%S%.3f")
104 );
105 }
106 }
107 SensorEvent::Mouse(e) => {
108 transparency_log.record_mouse_event();
109 if event_count <= 10 || event_count % 100 == 0 {
110 println!(
111 " Mouse event: {:?} at {}",
112 e.event_type,
113 e.timestamp.format("%H:%M:%S%.3f")
114 );
115 }
116 }
117 }
118
119 // Process in window manager
120 window_manager.process_event(event);
121 }
122 Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
123 // Check for window expiry
124 window_manager.check_window_expiry();
125 }
126 Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
127 break;
128 }
129 }
130
131 // Process completed windows
132 for window in window_manager.take_completed_windows() {
133 transparency_log.record_window_completed();
134
135 let features = compute_features(&window);
136 let snapshot = hsi_builder.build(&window, &features);
137
138 println!();
139 println!("=== Window Completed ===");
140 println!(" Duration: {:.1}s", window.duration_secs());
141 println!(" Keyboard events: {}", window.keyboard_events.len());
142 println!(" Mouse events: {}", window.mouse_events.len());
143 println!();
144 println!(" Keyboard Features:");
145 println!(
146 " Typing rate: {:.2} keys/sec",
147 features.keyboard.typing_rate
148 );
149 println!(" Pause count: {}", features.keyboard.pause_count);
150 println!(" Burst index: {:.3}", features.keyboard.burst_index);
151 println!();
152 println!(" Mouse Features:");
153 println!(
154 " Activity rate: {:.2} moves/sec",
155 features.mouse.mouse_activity_rate
156 );
157 println!(" Mean velocity: {:.2}", features.mouse.mean_velocity);
158 println!(
159 " Click rate: {:.2} clicks/sec",
160 features.mouse.click_rate
161 );
162 println!();
163 println!(" Behavioral Signals:");
164 println!(
165 " Interaction rhythm: {:.3}",
166 features.behavioral.interaction_rhythm
167 );
168 println!(" Friction: {:.3}", features.behavioral.friction);
169 println!(
170 " Motor stability: {:.3}",
171 features.behavioral.motor_stability
172 );
173 println!(
174 " Focus continuity: {:.3}",
175 features.behavioral.focus_continuity_proxy
176 );
177 println!();
178
179 // Show snippet of HSI JSON
180 let json = serde_json::to_string_pretty(&snapshot).unwrap();
181 println!(" HSI Snapshot (truncated):");
182 for line in json.lines().take(20) {
183 println!(" {line}");
184 }
185 println!(" ...");
186 println!();
187 }
188
189 // Show progress
190 if event_count > 0 && event_count % 200 == 0 {
191 let elapsed = start.elapsed().as_secs();
192 println!(" [{elapsed}/30s] Processed {event_count} events...");
193 }
194 }
195
196 // Stop collection
197 println!();
198 println!("Stopping capture...");
199 collector.stop();
200
201 // Flush remaining window
202 window_manager.flush();
203 for window in window_manager.take_completed_windows() {
204 println!("Final window: {} events", window.event_count());
205 transparency_log.record_window_completed();
206 }
207
208 // Final statistics
209 println!();
210 println!("{}", transparency_log.summary());
211 println!();
212 println!("Demo complete!");
213}Sourcepub fn take_completed_windows(&mut self) -> Vec<EventWindow>
pub fn take_completed_windows(&mut self) -> Vec<EventWindow>
Get and remove completed windows.
Examples found in repository?
examples/capture_demo.rs (line 132)
26fn main() {
27 println!("Synheart Sensor Agent - Capture Demo");
28 println!("=====================================");
29 println!();
30
31 // Display privacy declaration
32 println!("{PRIVACY_DECLARATION}");
33 println!();
34
35 // Check for permission
36 print!("Checking Input Monitoring permission... ");
37 if check_permission() {
38 println!("OK ✓");
39 } else {
40 println!("FAILED ✗");
41 println!();
42 println!("Please grant Input Monitoring permission:");
43 println!("1. Open System Preferences");
44 println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45 println!("3. Add this application");
46 println!("4. Restart this demo");
47 return;
48 }
49 println!();
50
51 // Create components
52 let config = CollectorConfig {
53 capture_keyboard: true,
54 capture_mouse: true,
55 };
56
57 let mut collector = Collector::new(config);
58 let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59 let hsi_builder = HsiBuilder::new();
60 let transparency_log = TransparencyLog::new();
61
62 println!("Instance ID: {}", hsi_builder.instance_id());
63 println!();
64 println!("Starting capture for 30 seconds...");
65 println!("Try typing and moving your mouse!");
66 println!();
67
68 // Start collection
69 if let Err(e) = collector.start() {
70 eprintln!("Error starting collector: {e}");
71 return;
72 }
73
74 // Set up stop flag
75 let running = Arc::new(AtomicBool::new(true));
76 let r = running.clone();
77
78 // Set up Ctrl+C handler
79 ctrlc::set_handler(move || {
80 r.store(false, Ordering::SeqCst);
81 })
82 .expect("Error setting Ctrl+C handler");
83
84 // Run for 30 seconds
85 let start = std::time::Instant::now();
86 let receiver = collector.receiver().clone();
87 let mut event_count = 0;
88
89 while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90 // Receive events with timeout
91 match receiver.recv_timeout(Duration::from_millis(100)) {
92 Ok(event) => {
93 event_count += 1;
94
95 // Log event type
96 match &event {
97 SensorEvent::Keyboard(e) => {
98 transparency_log.record_keyboard_event();
99 if event_count <= 10 || event_count % 50 == 0 {
100 println!(
101 " Keyboard event: {} at {}",
102 if e.is_key_down { "down" } else { "up" },
103 e.timestamp.format("%H:%M:%S%.3f")
104 );
105 }
106 }
107 SensorEvent::Mouse(e) => {
108 transparency_log.record_mouse_event();
109 if event_count <= 10 || event_count % 100 == 0 {
110 println!(
111 " Mouse event: {:?} at {}",
112 e.event_type,
113 e.timestamp.format("%H:%M:%S%.3f")
114 );
115 }
116 }
117 }
118
119 // Process in window manager
120 window_manager.process_event(event);
121 }
122 Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
123 // Check for window expiry
124 window_manager.check_window_expiry();
125 }
126 Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
127 break;
128 }
129 }
130
131 // Process completed windows
132 for window in window_manager.take_completed_windows() {
133 transparency_log.record_window_completed();
134
135 let features = compute_features(&window);
136 let snapshot = hsi_builder.build(&window, &features);
137
138 println!();
139 println!("=== Window Completed ===");
140 println!(" Duration: {:.1}s", window.duration_secs());
141 println!(" Keyboard events: {}", window.keyboard_events.len());
142 println!(" Mouse events: {}", window.mouse_events.len());
143 println!();
144 println!(" Keyboard Features:");
145 println!(
146 " Typing rate: {:.2} keys/sec",
147 features.keyboard.typing_rate
148 );
149 println!(" Pause count: {}", features.keyboard.pause_count);
150 println!(" Burst index: {:.3}", features.keyboard.burst_index);
151 println!();
152 println!(" Mouse Features:");
153 println!(
154 " Activity rate: {:.2} moves/sec",
155 features.mouse.mouse_activity_rate
156 );
157 println!(" Mean velocity: {:.2}", features.mouse.mean_velocity);
158 println!(
159 " Click rate: {:.2} clicks/sec",
160 features.mouse.click_rate
161 );
162 println!();
163 println!(" Behavioral Signals:");
164 println!(
165 " Interaction rhythm: {:.3}",
166 features.behavioral.interaction_rhythm
167 );
168 println!(" Friction: {:.3}", features.behavioral.friction);
169 println!(
170 " Motor stability: {:.3}",
171 features.behavioral.motor_stability
172 );
173 println!(
174 " Focus continuity: {:.3}",
175 features.behavioral.focus_continuity_proxy
176 );
177 println!();
178
179 // Show snippet of HSI JSON
180 let json = serde_json::to_string_pretty(&snapshot).unwrap();
181 println!(" HSI Snapshot (truncated):");
182 for line in json.lines().take(20) {
183 println!(" {line}");
184 }
185 println!(" ...");
186 println!();
187 }
188
189 // Show progress
190 if event_count > 0 && event_count % 200 == 0 {
191 let elapsed = start.elapsed().as_secs();
192 println!(" [{elapsed}/30s] Processed {event_count} events...");
193 }
194 }
195
196 // Stop collection
197 println!();
198 println!("Stopping capture...");
199 collector.stop();
200
201 // Flush remaining window
202 window_manager.flush();
203 for window in window_manager.take_completed_windows() {
204 println!("Final window: {} events", window.event_count());
205 transparency_log.record_window_completed();
206 }
207
208 // Final statistics
209 println!();
210 println!("{}", transparency_log.summary());
211 println!();
212 println!("Demo complete!");
213}Sourcepub fn has_completed_windows(&self) -> bool
pub fn has_completed_windows(&self) -> bool
Check if there are completed windows available.
Sourcepub fn completed_window_count(&self) -> usize
pub fn completed_window_count(&self) -> usize
Get the number of completed windows.
Sourcepub fn check_window_expiry(&mut self)
pub fn check_window_expiry(&mut self)
Check and complete the current window if it has expired.
Examples found in repository?
examples/capture_demo.rs (line 124)
26fn main() {
27 println!("Synheart Sensor Agent - Capture Demo");
28 println!("=====================================");
29 println!();
30
31 // Display privacy declaration
32 println!("{PRIVACY_DECLARATION}");
33 println!();
34
35 // Check for permission
36 print!("Checking Input Monitoring permission... ");
37 if check_permission() {
38 println!("OK ✓");
39 } else {
40 println!("FAILED ✗");
41 println!();
42 println!("Please grant Input Monitoring permission:");
43 println!("1. Open System Preferences");
44 println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45 println!("3. Add this application");
46 println!("4. Restart this demo");
47 return;
48 }
49 println!();
50
51 // Create components
52 let config = CollectorConfig {
53 capture_keyboard: true,
54 capture_mouse: true,
55 };
56
57 let mut collector = Collector::new(config);
58 let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59 let hsi_builder = HsiBuilder::new();
60 let transparency_log = TransparencyLog::new();
61
62 println!("Instance ID: {}", hsi_builder.instance_id());
63 println!();
64 println!("Starting capture for 30 seconds...");
65 println!("Try typing and moving your mouse!");
66 println!();
67
68 // Start collection
69 if let Err(e) = collector.start() {
70 eprintln!("Error starting collector: {e}");
71 return;
72 }
73
74 // Set up stop flag
75 let running = Arc::new(AtomicBool::new(true));
76 let r = running.clone();
77
78 // Set up Ctrl+C handler
79 ctrlc::set_handler(move || {
80 r.store(false, Ordering::SeqCst);
81 })
82 .expect("Error setting Ctrl+C handler");
83
84 // Run for 30 seconds
85 let start = std::time::Instant::now();
86 let receiver = collector.receiver().clone();
87 let mut event_count = 0;
88
89 while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90 // Receive events with timeout
91 match receiver.recv_timeout(Duration::from_millis(100)) {
92 Ok(event) => {
93 event_count += 1;
94
95 // Log event type
96 match &event {
97 SensorEvent::Keyboard(e) => {
98 transparency_log.record_keyboard_event();
99 if event_count <= 10 || event_count % 50 == 0 {
100 println!(
101 " Keyboard event: {} at {}",
102 if e.is_key_down { "down" } else { "up" },
103 e.timestamp.format("%H:%M:%S%.3f")
104 );
105 }
106 }
107 SensorEvent::Mouse(e) => {
108 transparency_log.record_mouse_event();
109 if event_count <= 10 || event_count % 100 == 0 {
110 println!(
111 " Mouse event: {:?} at {}",
112 e.event_type,
113 e.timestamp.format("%H:%M:%S%.3f")
114 );
115 }
116 }
117 }
118
119 // Process in window manager
120 window_manager.process_event(event);
121 }
122 Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
123 // Check for window expiry
124 window_manager.check_window_expiry();
125 }
126 Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
127 break;
128 }
129 }
130
131 // Process completed windows
132 for window in window_manager.take_completed_windows() {
133 transparency_log.record_window_completed();
134
135 let features = compute_features(&window);
136 let snapshot = hsi_builder.build(&window, &features);
137
138 println!();
139 println!("=== Window Completed ===");
140 println!(" Duration: {:.1}s", window.duration_secs());
141 println!(" Keyboard events: {}", window.keyboard_events.len());
142 println!(" Mouse events: {}", window.mouse_events.len());
143 println!();
144 println!(" Keyboard Features:");
145 println!(
146 " Typing rate: {:.2} keys/sec",
147 features.keyboard.typing_rate
148 );
149 println!(" Pause count: {}", features.keyboard.pause_count);
150 println!(" Burst index: {:.3}", features.keyboard.burst_index);
151 println!();
152 println!(" Mouse Features:");
153 println!(
154 " Activity rate: {:.2} moves/sec",
155 features.mouse.mouse_activity_rate
156 );
157 println!(" Mean velocity: {:.2}", features.mouse.mean_velocity);
158 println!(
159 " Click rate: {:.2} clicks/sec",
160 features.mouse.click_rate
161 );
162 println!();
163 println!(" Behavioral Signals:");
164 println!(
165 " Interaction rhythm: {:.3}",
166 features.behavioral.interaction_rhythm
167 );
168 println!(" Friction: {:.3}", features.behavioral.friction);
169 println!(
170 " Motor stability: {:.3}",
171 features.behavioral.motor_stability
172 );
173 println!(
174 " Focus continuity: {:.3}",
175 features.behavioral.focus_continuity_proxy
176 );
177 println!();
178
179 // Show snippet of HSI JSON
180 let json = serde_json::to_string_pretty(&snapshot).unwrap();
181 println!(" HSI Snapshot (truncated):");
182 for line in json.lines().take(20) {
183 println!(" {line}");
184 }
185 println!(" ...");
186 println!();
187 }
188
189 // Show progress
190 if event_count > 0 && event_count % 200 == 0 {
191 let elapsed = start.elapsed().as_secs();
192 println!(" [{elapsed}/30s] Processed {event_count} events...");
193 }
194 }
195
196 // Stop collection
197 println!();
198 println!("Stopping capture...");
199 collector.stop();
200
201 // Flush remaining window
202 window_manager.flush();
203 for window in window_manager.take_completed_windows() {
204 println!("Final window: {} events", window.event_count());
205 transparency_log.record_window_completed();
206 }
207
208 // Final statistics
209 println!();
210 println!("{}", transparency_log.summary());
211 println!();
212 println!("Demo complete!");
213}Auto Trait Implementations§
impl Freeze for WindowManager
impl RefUnwindSafe for WindowManager
impl Send for WindowManager
impl Sync for WindowManager
impl Unpin for WindowManager
impl UnwindSafe for WindowManager
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more