1use crate::audio::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(crate) 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(crate) 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(crate) 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 use super::*;
101 use crate::audio::types::{AudioInfoV1, AudioInfoV2, AudioInfoV3};
102 use fuchsia_async::TestExecutor;
103 use fuchsia_inspect::component;
104 use settings_storage::device_storage::DeviceStorageCompatible;
105 use settings_test_common::helpers::move_executor_forward_and_get;
106
107 const CONFIG_AUDIO_INFO: AudioInfo = AudioInfo {
108 streams: [
109 AudioStream {
110 stream_type: AudioStreamType::Background,
111 source: AudioSettingSource::System,
112 user_volume_level: 0.6,
113 user_volume_muted: true,
114 },
115 AudioStream {
116 stream_type: AudioStreamType::Media,
117 source: AudioSettingSource::System,
118 user_volume_level: 0.7,
119 user_volume_muted: true,
120 },
121 AudioStream {
122 stream_type: AudioStreamType::Interruption,
123 source: AudioSettingSource::System,
124 user_volume_level: 0.2,
125 user_volume_muted: true,
126 },
127 AudioStream {
128 stream_type: AudioStreamType::SystemAgent,
129 source: AudioSettingSource::User,
130 user_volume_level: 0.3,
131 user_volume_muted: true,
132 },
133 AudioStream {
134 stream_type: AudioStreamType::Communication,
135 source: AudioSettingSource::User,
136 user_volume_level: 0.4,
137 user_volume_muted: false,
138 },
139 AudioStream {
140 stream_type: AudioStreamType::Accessibility,
141 source: AudioSettingSource::User,
142 user_volume_level: 0.35,
143 user_volume_muted: false,
144 },
145 ],
146 modified_counters: None,
147 };
148
149 fn make_default_settings() -> DefaultSetting<AudioInfo, &'static str> {
151 let config_logger =
152 Rc::new(Mutex::new(InspectConfigLogger::new(component::inspector().root())));
153 build_audio_default_settings(config_logger)
154 }
155
156 fn load_default_settings(
158 default_settings: &mut DefaultSetting<AudioInfo, &'static str>,
159 ) -> AudioInfo {
160 default_settings
161 .load_default_value()
162 .expect("if config exists, it should be parseable")
163 .expect("default value should always exist")
164 }
165
166 #[fuchsia::test(allow_stalls = false)]
167 async fn test_audio_config() {
168 let mut default_settings = make_default_settings();
169 let current_from_storage = load_default_settings(&mut default_settings);
170 assert_eq!(CONFIG_AUDIO_INFO, current_from_storage);
172 }
173
174 #[fuchsia::test(allow_stalls = false)]
175 async fn test_audio_info_migration_v1_to_v2() {
176 let mut default_settings = make_default_settings();
177 let mut v1_settings =
178 AudioInfoV1::default_value(load_default_settings(&mut default_settings));
179 let updated_mic_mute_val = !v1_settings.input.mic_mute;
180 v1_settings.input.mic_mute = updated_mic_mute_val;
181 v1_settings.streams[0].user_volume_level = 0.9;
182 v1_settings.streams[0].user_volume_muted = false;
183
184 let serialized_v1 = serde_json::to_string(&v1_settings).expect("default should serialize");
185 let v2_from_v1 = AudioInfoV2::try_deserialize_from(&serialized_v1)
186 .expect("deserialization should succeed");
187
188 assert_eq!(v2_from_v1.input.mic_mute, updated_mic_mute_val);
190 assert_eq!(v2_from_v1.streams[0].user_volume_level, 0.9);
191 assert_eq!(v2_from_v1.streams[0].user_volume_muted, false);
192 }
193
194 #[fuchsia::test(allow_stalls = false)]
195 async fn test_audio_info_migration_v2_to_v3() {
196 let mut default_settings = make_default_settings();
197 let mut v2_settings =
198 AudioInfoV1::default_value(load_default_settings(&mut default_settings));
199 v2_settings.streams[0].user_volume_level = 0.9;
200 v2_settings.streams[0].user_volume_muted = false;
201
202 let serialized_v2 = serde_json::to_string(&v2_settings).expect("default should serialize");
203 let v3_from_v2 = AudioInfoV3::try_deserialize_from(&serialized_v2)
204 .expect("deserialization should succeed");
205
206 assert_eq!(v3_from_v2.streams[0].user_volume_level, 0.9);
208 assert_eq!(v3_from_v2.streams[0].user_volume_muted, false);
209 }
210
211 #[fuchsia::test]
212 fn test_audio_info_migration_v3_to_current() {
213 let mut executor = TestExecutor::new_with_fake_time();
214 let mut default_settings = make_default_settings();
215 let current_defaults = load_default_settings(&mut default_settings);
216
217 let mut v3_settings = move_executor_forward_and_get(
218 &mut executor,
219 async { AudioInfoV3::default_value(current_defaults) },
220 "Unable to get V3 default value",
221 );
222 v3_settings.streams[0].user_volume_level = 0.9;
223 v3_settings.streams[0].user_volume_muted = false;
224
225 let serialized_v3 = serde_json::to_string(&v3_settings).expect("default should serialize");
226 let current_from_v3 = AudioInfo::try_deserialize_from(&serialized_v3)
227 .expect("deserialization should succeed");
228
229 assert_eq!(current_from_v3.streams[0].user_volume_level, 0.9);
231 assert_eq!(current_from_v3.streams[0].user_volume_muted, false);
232 assert_eq!(current_from_v3.streams[5], DEFAULT_AUDIO_INFO.streams[5]);
234 }
235
236 #[fuchsia::test]
237 fn test_audio_info_migration_v2_to_current() {
238 let mut executor = TestExecutor::new_with_fake_time();
239 let mut default_settings = make_default_settings();
240 let current_defaults = load_default_settings(&mut default_settings);
241
242 let mut v2_settings = move_executor_forward_and_get(
243 &mut executor,
244 async { AudioInfoV2::default_value(current_defaults) },
245 "Unable to get V2 default value",
246 );
247 let updated_mic_mute_val = !v2_settings.input.mic_mute;
248 v2_settings.input.mic_mute = updated_mic_mute_val;
249 v2_settings.streams[0].user_volume_level = 0.9;
250 v2_settings.streams[0].user_volume_muted = false;
251
252 let serialized_v2 = serde_json::to_string(&v2_settings).expect("default should serialize");
253 let current_from_v2 = AudioInfo::try_deserialize_from(&serialized_v2)
254 .expect("deserialization should succeed");
255
256 assert_eq!(current_from_v2.streams[0].user_volume_level, 0.9);
258 assert_eq!(current_from_v2.streams[0].user_volume_muted, false);
259 assert_eq!(current_from_v2.streams[5], DEFAULT_AUDIO_INFO.streams[5]);
261 }
262
263 #[fuchsia::test]
264 fn test_audio_info_migration_v1_to_current() {
265 let mut executor = TestExecutor::new_with_fake_time();
266 let mut default_settings = make_default_settings();
267 let current_defaults = load_default_settings(&mut default_settings);
268
269 let mut v1_settings = move_executor_forward_and_get(
270 &mut executor,
271 async { AudioInfoV1::default_value(current_defaults) },
272 "Unable to get V1 default value",
273 );
274 let updated_mic_mute_val = !v1_settings.input.mic_mute;
275 v1_settings.input.mic_mute = updated_mic_mute_val;
276 v1_settings.streams[0].user_volume_level = 0.9;
277 v1_settings.streams[0].user_volume_muted = false;
278
279 let serialized_v1 = serde_json::to_string(&v1_settings).expect("default should serialize");
280 let current_from_v1 = AudioInfo::try_deserialize_from(&serialized_v1)
281 .expect("deserialization should succeed");
282
283 assert_eq!(current_from_v1.streams[0].user_volume_level, 0.9);
285 assert_eq!(current_from_v1.streams[0].user_volume_muted, false);
286 assert_eq!(current_from_v1.streams[5], DEFAULT_AUDIO_INFO.streams[5]);
288 }
289}