pub fn spawn_audio_controller(
    service_context_handle: Arc<RwLock<ServiceContext>>,
    storage: Arc<Mutex<DeviceStorage<AudioInfo>>>,
) -> futures::channel::mpsc::UnboundedSender<Command> {
    let (audio_handler_tx, mut audio_handler_rx) = futures::channel::mpsc::unbounded::<Command>();

    let default_audio_settings = default_audio_info();

    let notifier_lock = Arc::<RwLock<Option<Notifier>>>::new(RwLock::new(None));
    let mic_mute_state =
        Arc::<RwLock<bool>>::new(RwLock::new(default_audio_settings.input.mic_mute));

    let input_service_connected = Arc::<RwLock<bool>>::new(RwLock::new(false));
    let audio_service_connected = Arc::<RwLock<bool>>::new(RwLock::new(false));

    let mut sound_player_connection = None;
    let mut stream_volume_controls = HashMap::new();

    let (input_tx, mut input_rx) = futures::channel::mpsc::unbounded::<MediaButtonsEvent>();

    {
        let mut input_service_connected_lock = input_service_connected.write();
        *input_service_connected_lock =
            monitor_mic_mute(service_context_handle.clone(), input_tx.clone()).is_ok();
    }

    let mic_mute_state_clone = mic_mute_state.clone();
    let notifier_lock_clone = notifier_lock.clone();
    fasync::spawn(async move {
        while let Some(event) = input_rx.next().await {
            if let Some(mic_mute) = event.mic_mute {
                if *mic_mute_state_clone.read() != mic_mute {
                    *mic_mute_state_clone.write() = mic_mute;
                    if let Some(notifier) = (*notifier_lock_clone.read()).clone() {
                        notifier.unbounded_send(SettingType::Audio).unwrap();
                    }
                }
            }
        }
    });

    let input_service_connected_clone = input_service_connected.clone();
    fasync::spawn(async move {
        check_and_bind_volume_controls(
            audio_service_connected.clone(),
            service_context_handle.clone(),
            &mut stream_volume_controls,
        )
        .ok();

        // Load data from persistent storage.
        let mut stored_value: AudioInfo;
        {
            let mut storage_lock = storage.lock().await;
            stored_value = storage_lock.get().await;
        }
        let mut sound_player_added_files: HashSet<&str> = HashSet::new();

        let stored_streams = stored_value.streams.iter().cloned().collect();
        update_volume_stream(&stored_streams, &mut stream_volume_controls).await;

        while let Some(command) = audio_handler_rx.next().await {
            match command {
                Command::ChangeState(state) => match state {
                    State::Listen(notifier) => {
                        *notifier_lock.write() = Some(notifier);
                    }
                    State::EndListen => {
                        *notifier_lock.write() = None;
                    }
                },
                Command::HandleRequest(request, responder) => {
                    #[allow(unreachable_patterns)]
                    match request {
                        SettingRequest::SetVolume(volume) => {
                            // Connect to the SoundPlayer the first time a volume event occurs.
                            if sound_player_connection.is_none() {
                                sound_player_connection = connect_to_sound_player();
                            }

                            if check_and_bind_volume_controls(
                                audio_service_connected.clone(),
                                service_context_handle.clone(),
                                &mut stream_volume_controls,
                            )
                            .is_err()
                            {
                                continue;
                            };

                            // TODO(fxb/43075): Test that the sounds are played on volume change and
                            // not played on mute change once the earcons is moved into its own
                            // service.
                            play_media_volume_sound(
                                sound_player_connection.clone(),
                                &volume,
                                &stream_volume_controls,
                                &mut sound_player_added_files,
                            )
                            .await;

                            update_volume_stream(&volume, &mut stream_volume_controls).await;
                            stored_value.streams =
                                get_streams_array_from_map(&stream_volume_controls);
                            persist_audio_info(stored_value.clone(), storage.clone()).await;

                            let _ = responder.send(Ok(None)).ok();
                            if let Some(notifier) = (*notifier_lock.read()).clone() {
                                notifier.unbounded_send(SettingType::Audio).unwrap();
                            }
                        }
                        SettingRequest::Get => {
                            {
                                let mut input_service_connected_lock =
                                    input_service_connected_clone.write();

                                if !*input_service_connected_lock {
                                    *input_service_connected_lock = monitor_mic_mute(
                                        service_context_handle.clone(),
                                        input_tx.clone(),
                                    )
                                    .is_ok();
                                }
                            }

                            check_and_bind_volume_controls(
                                audio_service_connected.clone(),
                                service_context_handle.clone(),
                                &mut stream_volume_controls,
                            )
                            .ok();

                            let _ = responder
                                .send(Ok(Some(SettingResponse::Audio(AudioInfo {
                                    streams: stored_value.streams,
                                    input: AudioInputInfo { mic_mute: *mic_mute_state.read() },
                                }))))
                                .ok();
                        }
                        _ => panic!("Unexpected command to audio"),
                    }
                }
            }
        }
    });
    audio_handler_tx
}
/// Controller that handles commands for SettingType::Audio.
/// TODO(go/fxb/35988): Hook up the presentation service to listen for the mic mute state.
Controller that handles commands for SettingType::Audio.
TODO(go/fxb/35988): Hook up the presentation service to listen for the mic mute state.
Controller that handles commands for SettingType :: Audio . TODO ( go / fxb / 35988 ) : Hook up the presentation service to listen for the mic mute state .
pub fn spawn_audio_controller(
    service_context_handle: Arc<RwLock<ServiceContext>>,
    storage: Arc<Mutex<DeviceStorage<AudioInfo>>>,
) -> futures::channel::mpsc::UnboundedSender<Command> {
    let (audio_handler_tx, mut audio_handler_rx) = futures::channel::mpsc::unbounded::<Command>();
    let default_audio_settings = default_audio_info();
    let notifier_lock = Arc::<RwLock<Option<Notifier>>>::new(RwLock::new(None));
    let mic_mute_state =
        Arc::<RwLock<bool>>::new(RwLock::new(default_audio_settings.input.mic_mute));
    let input_service_connected = Arc::<RwLock<bool>>::new(RwLock::new(false));
    let audio_service_connected = Arc::<RwLock<bool>>::new(RwLock::new(false));
    let mut sound_player_connection = None;
    let mut stream_volume_controls = HashMap::new();
    let (input_tx, mut input_rx) = futures::channel::mpsc::unbounded::<MediaButtonsEvent>();
    {
        let mut input_service_connected_lock = input_service_connected.write();
        *input_service_connected_lock =
            monitor_mic_mute(service_context_handle.clone(), input_tx.clone()).is_ok();
    }
    let mic_mute_state_clone = mic_mute_state.clone();
    let notifier_lock_clone = notifier_lock.clone();
    fasync::spawn(async move {
        while let Some(event) = input_rx.next().await {
            if let Some(mic_mute) = event.mic_mute {
                if *mic_mute_state_clone.read() != mic_mute {
                    *mic_mute_state_clone.write() = mic_mute;
                    if let Some(notifier) = (*notifier_lock_clone.read()).clone() {
                        notifier.unbounded_send(SettingType::Audio).unwrap();
                    }
                }
            }
        }
    });
    let input_service_connected_clone = input_service_connected.clone();
    fasync::spawn(async move {
        check_and_bind_volume_controls(
            audio_service_connected.clone(),
            service_context_handle.clone(),
            &mut stream_volume_controls,
        )
        .ok();
        // Load data from persistent storage.
        let mut stored_value: AudioInfo;
        {
            let mut storage_lock = storage.lock().await;
            stored_value = storage_lock.get().await;
        }
        let mut sound_player_added_files: HashSet<&str> = HashSet::new();
        let stored_streams = stored_value.streams.iter().cloned().collect();
        update_volume_stream(&stored_streams, &mut stream_volume_controls).await;
        while let Some(command) = audio_handler_rx.next().await {
            match command {
                Command::ChangeState(state) => match state {
                    State::Listen(notifier) => {
                        *notifier_lock.write() = Some(notifier);
                    }
                    State::EndListen => {
                        *notifier_lock.write() = None;
                    }
                },
                Command::HandleRequest(request, responder) => {
                    #[allow(unreachable_patterns)]
                    match request {
                        SettingRequest::SetVolume(volume) => {
                            // Connect to the SoundPlayer the first time a volume event occurs.
                            if sound_player_connection.is_none() {
                                sound_player_connection = connect_to_sound_player();
                            }
                            if check_and_bind_volume_controls(
                                audio_service_connected.clone(),
                                service_context_handle.clone(),
                                &mut stream_volume_controls,
                            )
                            .is_err()
                            {
                                continue;
                            };
                            // TODO(fxb/43075): Test that the sounds are played on volume change and
                            // not played on mute change once the earcons is moved into its own
                            // service.
                            play_media_volume_sound(
                                sound_player_connection.clone(),
                                &volume,
                                &stream_volume_controls,
                                &mut sound_player_added_files,
                            )
                            .await;
                            update_volume_stream(&volume, &mut stream_volume_controls).await;
                            stored_value.streams =
                                get_streams_array_from_map(&stream_volume_controls);
                            persist_audio_info(stored_value.clone(), storage.clone()).await;
                            let _ = responder.send(Ok(None)).ok();
                            if let Some(notifier) = (*notifier_lock.read()).clone() {
                                notifier.unbounded_send(SettingType::Audio).unwrap();
                            }
                        }
                        SettingRequest::Get => {
                            {
                                let mut input_service_connected_lock =
                                    input_service_connected_clone.write();
                                if !*input_service_connected_lock {
                                    *input_service_connected_lock = monitor_mic_mute(
                                        service_context_handle.clone(),
                                        input_tx.clone(),
                                    )
                                    .is_ok();
                                }
                            }
                            check_and_bind_volume_controls(
                                audio_service_connected.clone(),
                                service_context_handle.clone(),
                                &mut stream_volume_controls,
                            )
                            .ok();
                            let _ = responder
                                .send(Ok(Some(SettingResponse::Audio(AudioInfo {
                                    streams: stored_value.streams,
                                    input: AudioInputInfo { mic_mute: *mic_mute_state.read() },
                                }))))
                                .ok();
                        }
                        _ => panic!("Unexpected command to audio"),
                    }
                }
            }
        }
    });
    audio_handler_tx
}
pub fn spawn_audio_controller ( service_context_handle : Arc < RwLock < ServiceContext > > , storage : Arc < Mutex < DeviceStorage < AudioInfo > > > , ) -> futures :: channel :: mpsc :: UnboundedSender < Command > { let ( audio_handler_tx , mut audio_handler_rx ) = futures :: channel :: mpsc :: unbounded :: < Command > ( ) ; let default_audio_settings = default_audio_info ( ) ; let notifier_lock = Arc :: < RwLock < Option < Notifier > > > :: new ( RwLock :: new ( None ) ) ; let mic_mute_state = Arc :: < RwLock < bool > > :: new ( RwLock :: new ( default_audio_settings . input . mic_mute ) ) ; let input_service_connected = Arc :: < RwLock < bool > > :: new ( RwLock :: new ( false ) ) ; let audio_service_connected = Arc :: < RwLock < bool > > :: new ( RwLock :: new ( false ) ) ; let mut sound_player_connection = None ; let mut stream_volume_controls = HashMap :: new ( ) ; let ( input_tx , mut input_rx ) = futures :: channel :: mpsc :: unbounded :: < MediaButtonsEvent > ( ) ; { let mut input_service_connected_lock = input_service_connected . write ( ) ; * input_service_connected_lock = monitor_mic_mute ( service_context_handle . clone ( ) , input_tx . clone ( ) ) . is_ok ( ) ; } let mic_mute_state_clone = mic_mute_state . clone ( ) ; let notifier_lock_clone = notifier_lock . clone ( ) ; fasync :: spawn ( async move { while let Some ( event ) = input_rx . next ( ) . await { if let Some ( mic_mute ) = event . mic_mute { if * mic_mute_state_clone . read ( ) != mic_mute { * mic_mute_state_clone . write ( ) = mic_mute ; if let Some ( notifier ) = ( * notifier_lock_clone . read ( ) ) . clone ( ) { notifier . unbounded_send ( SettingType :: Audio ) . unwrap ( ) ; } } } } } ) ; let input_service_connected_clone = input_service_connected . clone ( ) ; fasync :: spawn ( async move { check_and_bind_volume_controls ( audio_service_connected . clone ( ) , service_context_handle . clone ( ) , & mut stream_volume_controls , ) . ok ( ) ; // Load data from persistent storage. let mut stored_value : AudioInfo ; { let mut storage_lock = storage . lock ( ) . await ; stored_value = storage_lock . get ( ) . await ; } let mut sound_player_added_files : HashSet < & str > = HashSet :: new ( ) ; let stored_streams = stored_value . streams . iter ( ) . cloned ( ) . collect ( ) ; update_volume_stream ( & stored_streams , & mut stream_volume_controls ) . await ; while let Some ( command ) = audio_handler_rx . next ( ) . await { match command { Command :: ChangeState ( state ) => match state { State :: Listen ( notifier ) => { * notifier_lock . write ( ) = Some ( notifier ) ; } State :: EndListen => { * notifier_lock . write ( ) = None ; } } , Command :: HandleRequest ( request , responder ) => { # [ allow ( unreachable_patterns ) ] match request { SettingRequest :: SetVolume ( volume ) => { // Connect to the SoundPlayer the first time a volume event occurs. if sound_player_connection . is_none ( ) { sound_player_connection = connect_to_sound_player ( ) ; } if check_and_bind_volume_controls ( audio_service_connected . clone ( ) , service_context_handle . clone ( ) , & mut stream_volume_controls , ) . is_err ( ) { continue ; } ; // TODO(fxb/43075): Test that the sounds are played on volume change and // not played on mute change once the earcons is moved into its own // service. play_media_volume_sound ( sound_player_connection . clone ( ) , & volume , & stream_volume_controls , & mut sound_player_added_files , ) . await ; update_volume_stream ( & volume , & mut stream_volume_controls ) . await ; stored_value . streams = get_streams_array_from_map ( & stream_volume_controls ) ; persist_audio_info ( stored_value . clone ( ) , storage . clone ( ) ) . await ; let _ = responder . send ( Ok ( None ) ) . ok ( ) ; if let Some ( notifier ) = ( * notifier_lock . read ( ) ) . clone ( ) { notifier . unbounded_send ( SettingType :: Audio ) . unwrap ( ) ; } } SettingRequest :: Get => { { let mut input_service_connected_lock = input_service_connected_clone . write ( ) ; if ! * input_service_connected_lock { * input_service_connected_lock = monitor_mic_mute ( service_context_handle . clone ( ) , input_tx . clone ( ) , ) . is_ok ( ) ; } } check_and_bind_volume_controls ( audio_service_connected . clone ( ) , service_context_handle . clone ( ) , & mut stream_volume_controls , ) . ok ( ) ; let _ = responder . send ( Ok ( Some ( SettingResponse :: Audio ( AudioInfo { streams : stored_value . streams , input : AudioInputInfo { mic_mute : * mic_mute_state . read ( ) } , } ) ) ) ) . ok ( ) ; } _ => panic ! ( " " ) , } } } } } ) ; audio_handler_tx }
Controller that handles commands for SettingType::Audio.
Controller that handles commands for SettingType :: Audio .
service_context_handle
Arc<RwLock<ServiceContext>>
storage
Arc<Mutex<DeviceStorage<AudioInfo>>>