Skip to main content

settings_test_common/fakes/
camera3_service.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::fakes::service::Service;
6use anyhow::{Error, format_err};
7use fidl::endpoints::ServerEnd;
8use fidl::prelude::*;
9use fidl_fuchsia_camera3::{
10    DeviceRequest, DeviceWatcherMarker, DeviceWatcherRequest, WatchDevicesEvent,
11};
12use fuchsia_async::{self as fasync, DurationExt};
13use futures::TryStreamExt;
14use settings_camera::CAMERA_WATCHER_TIMEOUT;
15use std::rc::Rc;
16use std::sync::atomic::{AtomicBool, Ordering};
17use zx::MonotonicDuration;
18
19pub struct Camera3Service {
20    camera_sw_muted: Rc<AtomicBool>,
21    // If true, sends the camera device response immediately. If false, sends
22    // an empty device list. If None, delay_camera_device should be provided.
23    has_camera_device: Rc<AtomicBool>,
24    // If true, first sends an empty device list on watch, then delays, then
25    // sends the camera device response.
26    delay_camera_device: Rc<AtomicBool>,
27}
28
29impl Camera3Service {
30    pub fn new(has_camera_device: bool) -> Self {
31        Self {
32            camera_sw_muted: Rc::new(AtomicBool::new(false)),
33            has_camera_device: Rc::new(AtomicBool::new(has_camera_device)),
34            delay_camera_device: Rc::new(AtomicBool::new(false)),
35        }
36    }
37
38    pub fn new_delayed_devices(delay_camera_device: bool) -> Self {
39        Self {
40            camera_sw_muted: Rc::new(AtomicBool::new(false)),
41            has_camera_device: Rc::new(AtomicBool::new(false)),
42            delay_camera_device: Rc::new(AtomicBool::new(delay_camera_device)),
43        }
44    }
45
46    pub fn camera_sw_muted(&self) -> bool {
47        (*self.camera_sw_muted).load(Ordering::Relaxed)
48    }
49
50    pub fn set_camera_sw_muted(&self, muted: bool) {
51        let _ = (*self.camera_sw_muted).swap(muted, Ordering::Relaxed);
52    }
53}
54
55impl Service for Camera3Service {
56    fn can_handle_service(&self, service_name: &str) -> bool {
57        service_name == DeviceWatcherMarker::PROTOCOL_NAME
58    }
59
60    fn process_stream(&mut self, service_name: &str, channel: zx::Channel) -> Result<(), Error> {
61        if !self.can_handle_service(service_name) {
62            return Err(format_err!("can't handle service"));
63        }
64
65        let mut device_watcher_stream =
66            ServerEnd::<DeviceWatcherMarker>::new(channel).into_stream();
67
68        let camera_sw_muted = Rc::clone(&self.camera_sw_muted);
69        let has_camera_device = Rc::clone(&self.has_camera_device);
70        let delay_camera_device = Rc::clone(&self.delay_camera_device);
71        let mut watch_count = 0;
72        fasync::Task::local(async move {
73            while let Some(req) = device_watcher_stream.try_next().await.unwrap() {
74                // Support future expansion of FIDL.
75                #[allow(unreachable_patterns)]
76                match req {
77                    DeviceWatcherRequest::WatchDevices { responder } => {
78                        let camera_device = WatchDevicesEvent::Added(1);
79                        let camera_devices = &[camera_device][..];
80                        let empty_devices = &[][..];
81
82                        let devices = if delay_camera_device.load(Ordering::Relaxed) {
83                            if watch_count == 0 {
84                                watch_count += 1;
85                                empty_devices
86                            } else {
87                                let timer = fasync::Timer::new(
88                                    MonotonicDuration::from_millis(CAMERA_WATCHER_TIMEOUT / 2)
89                                        .after_now(),
90                                );
91                                timer.await;
92                                camera_devices
93                            }
94                        } else if has_camera_device.load(Ordering::Relaxed) {
95                            camera_devices
96                        } else {
97                            empty_devices
98                        };
99                        responder.send(devices).expect("Failed to send devices response");
100                    }
101                    DeviceWatcherRequest::ConnectToDevice {
102                        id: _,
103                        request, // ServerEnd<DeviceMarker>
104                        control_handle: _,
105                    } => {
106                        let mut stream = request.into_stream();
107                        let camera_sw_muted = Rc::clone(&camera_sw_muted);
108                        fasync::Task::local(async move {
109                            while let Some(req) = stream.try_next().await.unwrap() {
110                                // Support future expansion of FIDL.
111                                match req {
112                                    DeviceRequest::SetSoftwareMuteState { muted, responder } => {
113                                        let _ = camera_sw_muted.swap(muted, Ordering::Relaxed);
114                                        let _ = responder.send();
115                                    }
116                                    DeviceRequest::WatchMuteState { responder } => {
117                                        let _ = responder
118                                            .send(camera_sw_muted.load(Ordering::Relaxed), false);
119                                    }
120                                    _ => {}
121                                }
122                            }
123                        })
124                        .detach();
125                    }
126                    _ => {}
127                }
128            }
129        })
130        .detach();
131
132        Ok(())
133    }
134}