diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 41e2a2bc6..87b3378b8 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "ec8622ad7e424559f85247a40b5f3b070428ba7a3012b6ed374ae6a1f5e86867", + "checksum": "6552a18409e08d902d41d75034fe7bff20904b637497f2ba52d60bf440e60cc5", "crates": { "addr2line 0.20.0": { "name": "addr2line", diff --git a/Cargo.lock b/Cargo.lock index 401dd400c..3fdb96918 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,6 +416,7 @@ dependencies = [ name = "cras_s2" version = "0.1.0" dependencies = [ + "cras_common", "libc", "log", "once_cell", diff --git a/cras/common/BUILD.bazel b/cras/common/BUILD.bazel index 6a0712c1e..94edcf0c0 100644 --- a/cras/common/BUILD.bazel +++ b/cras/common/BUILD.bazel @@ -33,10 +33,7 @@ cras_rust_library( ), crate_name = "cras_common", edition = "2021", - visibility = [ - "//cras/server/platform:__subpackages__", - "//cras/src/server/rust:__pkg__", - ], + visibility = ["//visibility:public"], deps = [ "@pkg_config//openssl", ] + all_crate_deps(normal = True), diff --git a/cras/server/main_message.h b/cras/server/main_message.h index 5a4df6ae4..adea7afe3 100644 --- a/cras/server/main_message.h +++ b/cras/server/main_message.h @@ -30,6 +30,7 @@ enum CRAS_MAIN_MESSAGE_TYPE { CRAS_MAIN_FEATURE_CHANGED, CRAS_MAIN_NOTIFY_RTC, CRAS_MAIN_EWMA_POWER_REPORT, + CRAS_MAIN_DLC_INSTALLED, }; /* Structure of the header of the message handled by main thread. diff --git a/cras/server/platform/dlc/dlc.h b/cras/server/platform/dlc/dlc.h index 5c0283018..93dedc5aa 100644 --- a/cras/server/platform/dlc/dlc.h +++ b/cras/server/platform/dlc/dlc.h @@ -23,7 +23,7 @@ struct CrasDlcDownloadConfig { bool dlcs_to_download[NUM_CRAS_DLCS]; }; -typedef int (*CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc)(enum CrasDlcId, int32_t); +typedef int (*DlcInstallOnSuccessCallback)(enum CrasDlcId, int32_t); /** * Returns `true` if the DLC package is ready for use, otherwise @@ -54,7 +54,7 @@ void cras_dlc_reset_overrides_for_testing(void); * Start a thread to download all DLCs. */ void download_dlcs_until_installed_with_thread(struct CrasDlcDownloadConfig download_config, - CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc cras_server_metrics_dlc_install_retried_times_on_success); + DlcInstallOnSuccessCallback dlc_install_on_success_callback); /** * Returns `true` if the DLC package is ready for use, otherwise @@ -85,7 +85,7 @@ void cras_dlc_reset_overrides_for_testing(void); * Start a thread to download all DLCs. */ void download_dlcs_until_installed_with_thread(struct CrasDlcDownloadConfig download_config, - CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc cras_server_metrics_dlc_install_retried_times_on_success); + DlcInstallOnSuccessCallback dlc_install_on_success_callback); #endif /* CRAS_SERVER_PLATFORM_DLC_DLC_H_ */ diff --git a/cras/server/platform/dlc/src/bindings.rs b/cras/server/platform/dlc/src/bindings.rs index faac2f545..e5ebbc545 100644 --- a/cras/server/platform/dlc/src/bindings.rs +++ b/cras/server/platform/dlc/src/bindings.rs @@ -12,7 +12,7 @@ use super::get_dlc_state_cached; use super::CrasDlcId; use super::Result; use crate::download_dlcs_until_installed; -use crate::CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc; +use crate::DlcInstallOnSuccessCallback; fn get_dlc_root_path(id: CrasDlcId) -> Result { let dlc_state = get_dlc_state_cached(id); @@ -73,15 +73,12 @@ pub extern "C" fn cras_dlc_reset_overrides_for_testing() { #[no_mangle] pub extern "C" fn download_dlcs_until_installed_with_thread( download_config: super::CrasDlcDownloadConfig, - cras_server_metrics_dlc_install_retried_times_on_success: CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc, + dlc_install_on_success_callback: DlcInstallOnSuccessCallback, ) { thread::Builder::new() .name("cras-dlc".into()) .spawn(move || { - download_dlcs_until_installed( - download_config, - cras_server_metrics_dlc_install_retried_times_on_success, - ) + download_dlcs_until_installed(download_config, dlc_install_on_success_callback) }) .unwrap(); } diff --git a/cras/server/platform/dlc/src/lib.rs b/cras/server/platform/dlc/src/lib.rs index 1e2954f5d..2a1c54c2a 100644 --- a/cras/server/platform/dlc/src/lib.rs +++ b/cras/server/platform/dlc/src/lib.rs @@ -92,8 +92,10 @@ fn reset_overrides() { STATE_OVERRIDES.lock().unwrap().clear(); } -type CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc = - extern "C" fn(CrasDlcId, i32) -> libc::c_int; +// Called when a dlc is installed successfully, with the following arguments: +// - CrasDlcId: the id of the installed dlc. +// - i32: the number of retried times. +type DlcInstallOnSuccessCallback = extern "C" fn(CrasDlcId, i32) -> libc::c_int; #[repr(C)] pub struct CrasDlcDownloadConfig { @@ -102,7 +104,7 @@ pub struct CrasDlcDownloadConfig { fn download_dlcs_until_installed( download_config: CrasDlcDownloadConfig, - cras_server_metrics_dlc_install_retried_times_on_success: CrasServerMetricsDlcInstallRetriedTimesOnSuccessFunc, + dlc_install_on_success_callback: DlcInstallOnSuccessCallback, ) { let mut retry_sleep = time::Duration::from_secs(30); let max_retry_sleep = time::Duration::from_secs(300); @@ -119,8 +121,8 @@ fn download_dlcs_until_installed( Ok(state) => { log::info!("successfully installed {dlc}"); STATE_CACHE.lock().unwrap().insert(*dlc, state); - cras_server_metrics_dlc_install_retried_times_on_success(*dlc, retry_count); - cras_s2::global::set_dlc_installed(&dlc.as_str()); + cras_s2::global::cras_s2_set_dlc_installed(*dlc); + dlc_install_on_success_callback(*dlc, retry_count); } Err(e) => { log::info!("failed to install {dlc}: {e}"); diff --git a/cras/server/s2/BUILD.bazel b/cras/server/s2/BUILD.bazel index 79e5ac662..b284a821b 100644 --- a/cras/server/s2/BUILD.bazel +++ b/cras/server/s2/BUILD.bazel @@ -17,7 +17,9 @@ cras_rust_library( crate_name = "cras_s2", edition = "2021", visibility = ["//visibility:public"], - deps = all_crate_deps(normal = True), + deps = all_crate_deps(normal = True) + [ + "//cras/common:rust_common", + ], ) rust_test( @@ -31,6 +33,10 @@ cras_cbindgen( srcs = ["src/global.rs"], out = "s2.h", copyright_year = 2023, + extra_args = [ + "--with-include=cras/common/rust_common.h", + "--add-keyword-enum", + ], ) cc_library( diff --git a/cras/server/s2/Cargo.toml b/cras/server/s2/Cargo.toml index 503791699..f03864adf 100644 --- a/cras/server/s2/Cargo.toml +++ b/cras/server/s2/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cras_common = "*" libc = "0.2.44" log = "0.4.17" once_cell = "1.17.0" diff --git a/cras/server/s2/s2.h b/cras/server/s2/s2.h index 535345491..f1f29da14 100644 --- a/cras/server/s2/s2.h +++ b/cras/server/s2/s2.h @@ -17,6 +17,7 @@ extern "C" { #include #include #include +#include "cras/common/rust_common.h" void cras_s2_set_ap_nc_featured_allowed(bool allowed); @@ -24,6 +25,8 @@ void cras_s2_set_ap_nc_segmentation_allowed(bool allowed); void cras_s2_set_ap_nc_feature_tier_allowed(bool allowed); +void cras_s2_set_dlc_installed(enum CrasDlcId dlc); + bool cras_s2_get_ap_nc_allowed(void); void cras_s2_set_style_transfer_featured_allowed(bool allowed); @@ -42,6 +45,8 @@ bool cras_s2_get_beamforming_supported(void); char *cras_s2_dump_json(void); +void cras_s2_reset_for_testing(void); + #endif /* CRAS_SERVER_S2_S2_H_ */ #ifdef __cplusplus diff --git a/cras/server/s2/src/global.rs b/cras/server/s2/src/global.rs index 2ac227916..edfe3b38b 100644 --- a/cras/server/s2/src/global.rs +++ b/cras/server/s2/src/global.rs @@ -9,6 +9,8 @@ use std::sync::Mutex; use std::sync::MutexGuard; use std::sync::OnceLock; +use cras_common::types_internal::CrasDlcId; + fn state() -> MutexGuard<'static, crate::S2> { static CELL: OnceLock> = OnceLock::new(); CELL.get_or_init(|| Mutex::new(crate::S2::new())) @@ -35,7 +37,8 @@ pub fn set_dlc_manager_ready() { state().set_dlc_manager_ready(); } -pub fn set_dlc_installed(dlc: &str) { +#[no_mangle] +pub extern "C" fn cras_s2_set_dlc_installed(dlc: CrasDlcId) { state().set_dlc_installed(dlc); } @@ -96,3 +99,8 @@ pub extern "C" fn cras_s2_dump_json() -> *mut c_char { let s = serde_json::to_string_pretty(state().deref()).expect("serde_json::to_string_pretty"); CString::new(s).expect("CString::new").into_raw() } + +#[no_mangle] +pub extern "C" fn cras_s2_reset_for_testing() { + state().reset_for_testing(); +} diff --git a/cras/server/s2/src/lib.rs b/cras/server/s2/src/lib.rs index 40804ae29..68c4e6836 100644 --- a/cras/server/s2/src/lib.rs +++ b/cras/server/s2/src/lib.rs @@ -4,6 +4,7 @@ use std::collections::HashSet; +use cras_common::types_internal::CrasDlcId; use serde::Serialize; pub mod global; @@ -90,8 +91,8 @@ impl S2 { self.update(); } - fn set_dlc_installed(&mut self, dlc: &str) { - self.input.dlc_installed.insert(dlc.to_string()); + fn set_dlc_installed(&mut self, dlc: CrasDlcId) { + self.input.dlc_installed.insert(dlc.as_str().to_string()); self.update(); } @@ -118,12 +119,18 @@ impl S2 { fn update(&mut self) { self.output = resolve(&self.input); } + + fn reset_for_testing(&mut self) { + *self = Self::new(); + } } #[cfg(test)] mod tests { use std::collections::HashSet; + use cras_common::types_internal::CrasDlcId; + use crate::S2; #[test] @@ -194,12 +201,18 @@ mod tests { s.set_dlc_manager_ready(); assert!(s.input.dlc_manager_ready); - s.set_dlc_installed("dlc-1"); - assert_eq!(s.input.dlc_installed, HashSet::from(["dlc-1".to_string()])); - s.set_dlc_installed("dlc-2"); + s.set_dlc_installed(CrasDlcId::CrasDlcNcAp); + assert_eq!( + s.input.dlc_installed, + HashSet::from([CrasDlcId::CrasDlcNcAp.as_str().to_string()]) + ); + s.set_dlc_installed(CrasDlcId::CrasDlcIntelligoBeamforming); assert_eq!( s.input.dlc_installed, - HashSet::from(["dlc-1".to_string(), "dlc-2".to_string()]) + HashSet::from([ + CrasDlcId::CrasDlcNcAp.as_str().to_string(), + CrasDlcId::CrasDlcIntelligoBeamforming.as_str().to_string() + ]) ); s.set_dlc_manager_done(); diff --git a/cras/src/server/cras_dlc_manager.c b/cras/src/server/cras_dlc_manager.c index b2bf0114e..95773edcc 100644 --- a/cras/src/server/cras_dlc_manager.c +++ b/cras/src/server/cras_dlc_manager.c @@ -4,10 +4,34 @@ #include "cras/src/server/cras_dlc_manager.h" +#include "cras/server/main_message.h" #include "cras/server/platform/dlc/dlc.h" +#include "cras/src/server/cras_iodev_list.h" #include "cras/src/server/cras_server_metrics.h" +static int32_t dlc_install_on_success_callback(enum CrasDlcId dlc_id, + int32_t retry_count) { + const int ret = cras_server_metrics_dlc_install_retried_times_on_success( + dlc_id, retry_count); + + struct cras_main_message msg = { + .length = sizeof(msg), + .type = CRAS_MAIN_DLC_INSTALLED, + }; + cras_main_message_send(&msg); + + return ret; +} + +static void notify_dlc_install_success() { + cras_iodev_list_update_device_list(); + cras_iodev_list_notify_nodes_changed(); +} + void cras_dlc_manager_init(struct CrasDlcDownloadConfig dl_cfg) { - download_dlcs_until_installed_with_thread( - dl_cfg, cras_server_metrics_dlc_install_retried_times_on_success); + cras_main_message_add_handler(CRAS_MAIN_DLC_INSTALLED, + notify_dlc_install_success, NULL); + + download_dlcs_until_installed_with_thread(dl_cfg, + dlc_install_on_success_callback); }