audb_core/features/app/
stop.rs1use crate::features::config::{device_store::DeviceStore, state::DeviceState};
11use crate::tools::{
12 macros::print_info,
13 session::DeviceSession,
14 types::DeviceIdentifier,
15};
16use anyhow::{anyhow, Context, Result};
17
18pub async fn execute(app_name: &str) -> Result<()> {
19 validate_app_name(app_name)?;
21
22 let current_host = DeviceState::get_current()?;
24 let device_id = DeviceIdentifier::Host(current_host);
25 let device = DeviceStore::find(&device_id)?;
26
27 print_info(format!("Stopping {} on device {}", app_name, device.display_name()));
28 print_info(format!("Connecting to {}:{}...", device.host, device.port));
29
30 let mut session = DeviceSession::connect(&device)
31 .context("Failed to connect to device")?;
32
33 let stop_command = format!(
36 "gdbus call --system --dest ru.omp.RuntimeManager \
37 --object-path /ru/omp/RuntimeManager/Control1 \
38 --method ru.omp.RuntimeManager.Control1.Terminate \"{}\"",
39 app_name
40 );
41
42 print_info("Stopping application...");
43
44 let output = session.exec(&stop_command)
45 .context("Failed to stop application")?;
46
47 for line in &output {
49 if !line.is_empty() {
50 println!("{}", line);
51 }
52 }
53
54 print_info("Application stopped successfully");
55 Ok(())
56}
57
58fn validate_app_name(app_name: &str) -> Result<()> {
59 if app_name.is_empty() {
60 return Err(anyhow!("App name cannot be empty"));
61 }
62 if !app_name.contains('.') {
63 return Err(anyhow!(
64 "Invalid app name: '{}'. Expected D-Bus format: ru.domain.AppName",
65 app_name
66 ));
67 }
68 if app_name.len() > 255 {
69 return Err(anyhow!("App name exceeds D-Bus limit of 255 characters"));
70 }
71 Ok(())
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_validate_app_name_valid() {
80 assert!(validate_app_name("ru.auroraos.MLPackLearning").is_ok());
81 assert!(validate_app_name("com.example.App").is_ok());
82 }
83
84 #[test]
85 fn test_validate_app_name_empty() {
86 assert!(validate_app_name("").is_err());
87 }
88
89 #[test]
90 fn test_validate_app_name_no_dot() {
91 assert!(validate_app_name("InvalidAppName").is_err());
92 }
93
94 #[test]
95 fn test_validate_app_name_too_long() {
96 let long_name = "a".repeat(256);
97 assert!(validate_app_name(&long_name).is_err());
98 }
99}