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