1use crate::types::{
6 AUDIO_STREAM_TYPE_COUNT, AudioInfo, AudioSettingSource, AudioStream, AudioStreamType,
7};
8use settings_common::config::default_settings::DefaultSetting;
9use settings_common::inspect::config_logger::InspectConfigLogger;
10use settings_storage::storage_factory::DefaultLoader;
11use std::collections::HashMap;
12use std::rc::Rc;
13use std::sync::Mutex;
14
15const DEFAULT_VOLUME_LEVEL: f32 = 0.5;
16const DEFAULT_VOLUME_MUTED: bool = false;
17
18const DEFAULT_STREAMS: [AudioStream; AUDIO_STREAM_TYPE_COUNT] = [
19 create_default_audio_stream(AudioStreamType::Background),
20 create_default_audio_stream(AudioStreamType::Media),
21 create_default_audio_stream(AudioStreamType::Interruption),
22 create_default_audio_stream(AudioStreamType::SystemAgent),
23 create_default_audio_stream(AudioStreamType::Communication),
24 create_default_audio_stream(AudioStreamType::Accessibility),
25];
26
27const DEFAULT_AUDIO_INFO: AudioInfo =
28 AudioInfo { streams: DEFAULT_STREAMS, modified_counters: None };
29
30pub type ModifiedCounters = HashMap<AudioStreamType, usize>;
34
35pub fn create_default_modified_counters() -> ModifiedCounters {
36 IntoIterator::into_iter([
37 AudioStreamType::Background,
38 AudioStreamType::Media,
39 AudioStreamType::Interruption,
40 AudioStreamType::SystemAgent,
41 AudioStreamType::Communication,
42 AudioStreamType::Accessibility,
43 ])
44 .map(|stream_type| (stream_type, 0))
45 .collect()
46}
47
48pub const fn create_default_audio_stream(stream_type: AudioStreamType) -> AudioStream {
49 AudioStream {
50 stream_type,
51 source: AudioSettingSource::User,
52 user_volume_level: DEFAULT_VOLUME_LEVEL,
53 user_volume_muted: DEFAULT_VOLUME_MUTED,
54 }
55}
56
57pub fn build_audio_default_settings(
58 config_logger: Rc<Mutex<InspectConfigLogger>>,
59) -> DefaultSetting<AudioInfo, &'static str> {
60 DefaultSetting::new(
61 Some(DEFAULT_AUDIO_INFO),
62 "/config/data/audio_config_data.json",
63 config_logger,
64 )
65}
66
67#[derive(Clone)]
73pub struct AudioInfoLoader {
74 audio_default_settings: Rc<Mutex<DefaultSetting<AudioInfo, &'static str>>>,
75}
76
77impl AudioInfoLoader {
78 pub fn new(audio_default_settings: DefaultSetting<AudioInfo, &'static str>) -> Self {
79 Self { audio_default_settings: Rc::new(Mutex::new(audio_default_settings)) }
80 }
81}
82
83impl DefaultLoader for AudioInfoLoader {
84 type Result = AudioInfo;
85
86 fn default_value(&self) -> Self::Result {
87 let mut default_audio_info: AudioInfo = DEFAULT_AUDIO_INFO.clone();
88
89 if let Ok(Some(audio_configuration)) =
90 self.audio_default_settings.lock().unwrap().get_cached_value()
91 {
92 default_audio_info.streams = audio_configuration.streams;
93 }
94 default_audio_info
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 #![allow(clippy::bool_assert_comparison)]
102
103 use super::*;
104 use crate::types::{AudioInfoV1, AudioInfoV2, AudioInfoV3};
105 use fuchsia_async::TestExecutor;
106 use fuchsia_inspect::component;
107 use settings_storage::device_storage::DeviceStorageCompatible;
108 use settings_test_common::helpers::move_executor_forward_and_get;
109
110 const CONFIG_AUDIO_INFO: AudioInfo = AudioInfo {
111 streams: [
112 AudioStream {
113 stream_type: AudioStreamType::Background,
114 source: AudioSettingSource::System,
115 user_volume_level: 0.6,
116 user_volume_muted: true,
117 },
118 AudioStream {
119 stream_type: AudioStreamType::Media,
120 source: AudioSettingSource::System,
121 user_volume_level: 0.7,
122 user_volume_muted: true,
123 },
124 AudioStream {
125 stream_type: AudioStreamType::Interruption,
126 source: AudioSettingSource::System,
127 user_volume_level: 0.2,
128 user_volume_muted: true,
129 },
130 AudioStream {
131 stream_type: AudioStreamType::SystemAgent,
132 source: AudioSettingSource::User,
133 user_volume_level: 0.3,
134 user_volume_muted: true,
135 },
136 AudioStream {
137 stream_type: AudioStreamType::Communication,
138 source: AudioSettingSource::User,
139 user_volume_level: 0.4,
140 user_volume_muted: false,
141 },
142 AudioStream {
143 stream_type: AudioStreamType::Accessibility,
144 source: AudioSettingSource::User,
145 user_volume_level: 0.35,
146 user_volume_muted: false,
147 },
148 ],
149 modified_counters: None,
150 };
151
152 fn make_default_settings() -> DefaultSetting<AudioInfo, &'static str> {
154 let config_logger =
155 Rc::new(Mutex::new(InspectConfigLogger::new(component::inspector().root())));
156 build_audio_default_settings(config_logger)
157 }
158
159 fn load_default_settings(
161 default_settings: &mut DefaultSetting<AudioInfo, &'static str>,
162 ) -> AudioInfo {
163 default_settings
164 .load_default_value()
165 .expect("if config exists, it should be parseable")
166 .expect("default value should always exist")
167 }
168
169 #[fuchsia::test(allow_stalls = false)]
170 async fn test_audio_config() {
171 let mut default_settings = make_default_settings();
172 let current_from_storage = load_default_settings(&mut default_settings);
173 assert_eq!(CONFIG_AUDIO_INFO, current_from_storage);
175 }
176
177 #[fuchsia::test(allow_stalls = false)]
178 async fn test_audio_info_migration_v1_to_v2() {
179 let mut default_settings = make_default_settings();
180 let mut v1_settings =
181 AudioInfoV1::default_value(load_default_settings(&mut default_settings));
182 let updated_mic_mute_val = !v1_settings.input.mic_mute;
183 v1_settings.input.mic_mute = updated_mic_mute_val;
184 v1_settings.streams[0].user_volume_level = 0.9;
185 v1_settings.streams[0].user_volume_muted = false;
186
187 let serialized_v1 = serde_json::to_string(&v1_settings).expect("default should serialize");
188 let v2_from_v1 = AudioInfoV2::try_deserialize_from(&serialized_v1)
189 .expect("deserialization should succeed");
190
191 assert_eq!(v2_from_v1.input.mic_mute, updated_mic_mute_val);
193 assert_eq!(v2_from_v1.streams[0].user_volume_level, 0.9);
194 assert_eq!(v2_from_v1.streams[0].user_volume_muted, false);
195 }
196
197 #[fuchsia::test(allow_stalls = false)]
198 async fn test_audio_info_migration_v2_to_v3() {
199 let mut default_settings = make_default_settings();
200 let mut v2_settings =
201 AudioInfoV1::default_value(load_default_settings(&mut default_settings));
202 v2_settings.streams[0].user_volume_level = 0.9;
203 v2_settings.streams[0].user_volume_muted = false;
204
205 let serialized_v2 = serde_json::to_string(&v2_settings).expect("default should serialize");
206 let v3_from_v2 = AudioInfoV3::try_deserialize_from(&serialized_v2)
207 .expect("deserialization should succeed");
208
209 assert_eq!(v3_from_v2.streams[0].user_volume_level, 0.9);
211 assert_eq!(v3_from_v2.streams[0].user_volume_muted, false);
212 }
213
214 #[fuchsia::test]
215 fn test_audio_info_migration_v3_to_current() {
216 let mut executor = TestExecutor::new_with_fake_time();
217 let mut default_settings = make_default_settings();
218 let current_defaults = load_default_settings(&mut default_settings);
219
220 let mut v3_settings = move_executor_forward_and_get(
221 &mut executor,
222 async { AudioInfoV3::default_value(current_defaults) },
223 "Unable to get V3 default value",
224 );
225 v3_settings.streams[0].user_volume_level = 0.9;
226 v3_settings.streams[0].user_volume_muted = false;
227
228 let serialized_v3 = serde_json::to_string(&v3_settings).expect("default should serialize");
229 let current_from_v3 = AudioInfo::try_deserialize_from(&serialized_v3)
230 .expect("deserialization should succeed");
231
232 assert_eq!(current_from_v3.streams[0].user_volume_level, 0.9);
234 assert_eq!(current_from_v3.streams[0].user_volume_muted, false);
235 assert_eq!(current_from_v3.streams[5], DEFAULT_AUDIO_INFO.streams[5]);
237 }
238
239 #[fuchsia::test]
240 fn test_audio_info_migration_v2_to_current() {
241 let mut executor = TestExecutor::new_with_fake_time();
242 let mut default_settings = make_default_settings();
243 let current_defaults = load_default_settings(&mut default_settings);
244
245 let mut v2_settings = move_executor_forward_and_get(
246 &mut executor,
247 async { AudioInfoV2::default_value(current_defaults) },
248 "Unable to get V2 default value",
249 );
250 let updated_mic_mute_val = !v2_settings.input.mic_mute;
251 v2_settings.input.mic_mute = updated_mic_mute_val;
252 v2_settings.streams[0].user_volume_level = 0.9;
253 v2_settings.streams[0].user_volume_muted = false;
254
255 let serialized_v2 = serde_json::to_string(&v2_settings).expect("default should serialize");
256 let current_from_v2 = AudioInfo::try_deserialize_from(&serialized_v2)
257 .expect("deserialization should succeed");
258
259 assert_eq!(current_from_v2.streams[0].user_volume_level, 0.9);
261 assert_eq!(current_from_v2.streams[0].user_volume_muted, false);
262 assert_eq!(current_from_v2.streams[5], DEFAULT_AUDIO_INFO.streams[5]);
264 }
265
266 #[fuchsia::test]
267 fn test_audio_info_migration_v1_to_current() {
268 let mut executor = TestExecutor::new_with_fake_time();
269 let mut default_settings = make_default_settings();
270 let current_defaults = load_default_settings(&mut default_settings);
271
272 let mut v1_settings = move_executor_forward_and_get(
273 &mut executor,
274 async { AudioInfoV1::default_value(current_defaults) },
275 "Unable to get V1 default value",
276 );
277 let updated_mic_mute_val = !v1_settings.input.mic_mute;
278 v1_settings.input.mic_mute = updated_mic_mute_val;
279 v1_settings.streams[0].user_volume_level = 0.9;
280 v1_settings.streams[0].user_volume_muted = false;
281
282 let serialized_v1 = serde_json::to_string(&v1_settings).expect("default should serialize");
283 let current_from_v1 = AudioInfo::try_deserialize_from(&serialized_v1)
284 .expect("deserialization should succeed");
285
286 assert_eq!(current_from_v1.streams[0].user_volume_level, 0.9);
288 assert_eq!(current_from_v1.streams[0].user_volume_muted, false);
289 assert_eq!(current_from_v1.streams[5], DEFAULT_AUDIO_INFO.streams[5]);
291 }
292}