settings/factory_reset/
factory_reset_fidl_handler.rs

1// Copyright 2020 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::base::{SettingInfo, SettingType};
6use crate::handler::base::{Request, Response};
7use crate::ingress::{request, watch, Scoped};
8use crate::job::source::ErrorResponder;
9use crate::job::Job;
10use fidl::prelude::*;
11use fidl_fuchsia_settings::{
12    Error, FactoryResetRequest, FactoryResetSetResponder, FactoryResetSetResult,
13    FactoryResetSettings, FactoryResetWatchResponder,
14};
15
16use crate::job::source::Error as JobError;
17
18impl ErrorResponder for FactoryResetSetResponder {
19    fn id(&self) -> &'static str {
20        "FactoryReset_Set"
21    }
22
23    fn respond(self: Box<Self>, error: fidl_fuchsia_settings::Error) -> Result<(), fidl::Error> {
24        self.send(Err(error))
25    }
26}
27
28impl From<Response> for Scoped<FactoryResetSetResult> {
29    fn from(response: Response) -> Self {
30        Scoped(response.map_or(Err(Error::Failed), |_| Ok(())))
31    }
32}
33
34impl request::Responder<Scoped<FactoryResetSetResult>> for FactoryResetSetResponder {
35    fn respond(self, Scoped(response): Scoped<FactoryResetSetResult>) {
36        let _ = self.send(response);
37    }
38}
39
40impl watch::Responder<FactoryResetSettings, zx::Status> for FactoryResetWatchResponder {
41    fn respond(self, response: Result<FactoryResetSettings, zx::Status>) {
42        match response {
43            Ok(settings) => {
44                let _ = self.send(&settings);
45            }
46            Err(error) => {
47                self.control_handle().shutdown_with_epitaph(error);
48            }
49        }
50    }
51}
52
53impl TryFrom<FactoryResetRequest> for Job {
54    type Error = JobError;
55    fn try_from(item: FactoryResetRequest) -> Result<Self, Self::Error> {
56        #[allow(unreachable_patterns)]
57        match item {
58            FactoryResetRequest::Set { settings, responder } => match to_request(settings) {
59                Some(request) => {
60                    Ok(request::Work::new(SettingType::FactoryReset, request, responder).into())
61                }
62                None => Err(JobError::InvalidInput(Box::new(responder))),
63            },
64            FactoryResetRequest::Watch { responder } => {
65                Ok(watch::Work::new_job(SettingType::FactoryReset, responder))
66            }
67            _ => {
68                log::warn!("Received a call to an unsupported API: {:?}", item);
69                Err(JobError::Unsupported)
70            }
71        }
72    }
73}
74
75impl From<SettingInfo> for FactoryResetSettings {
76    fn from(response: SettingInfo) -> Self {
77        if let SettingInfo::FactoryReset(info) = response {
78            FactoryResetSettings {
79                is_local_reset_allowed: Some(info.is_local_reset_allowed),
80                ..Default::default()
81            }
82        } else {
83            panic!("incorrect value sent to factory_reset");
84        }
85    }
86}
87
88fn to_request(settings: FactoryResetSettings) -> Option<Request> {
89    settings.is_local_reset_allowed.map(Request::SetLocalResetAllowed)
90}
91#[cfg(test)]
92mod tests {
93    use super::*;
94    use crate::job::{execution, work};
95    use assert_matches::assert_matches;
96    use fidl_fuchsia_settings::{FactoryResetMarker, FactoryResetRequestStream};
97    use futures::StreamExt;
98
99    #[fuchsia::test]
100    fn to_request_maps_correctly() {
101        let result = to_request(FactoryResetSettings {
102            is_local_reset_allowed: Some(true),
103            ..Default::default()
104        });
105        assert_matches!(result, Some(Request::SetLocalResetAllowed(true)));
106    }
107
108    #[fuchsia::test(allow_stalls = false)]
109    async fn try_from_set_handles_missing_params() {
110        let (proxy, server) = fidl::endpoints::create_proxy::<FactoryResetMarker>();
111        let _fut = proxy.set(&FactoryResetSettings::default());
112        let mut request_stream: FactoryResetRequestStream = server.into_stream();
113        let request = request_stream
114            .next()
115            .await
116            .expect("should have on request before stream is closed")
117            .expect("should have gotten a request");
118        let job = Job::try_from(request);
119        assert_matches!(job, Err(crate::job::source::Error::InvalidInput(_)));
120    }
121
122    #[fuchsia::test(allow_stalls = false)]
123    async fn try_from_set_converts_supplied_params() {
124        let (proxy, server) = fidl::endpoints::create_proxy::<FactoryResetMarker>();
125        let _fut = proxy.set(&FactoryResetSettings {
126            is_local_reset_allowed: Some(true),
127            ..Default::default()
128        });
129        let mut request_stream: FactoryResetRequestStream = server.into_stream();
130        let request = request_stream
131            .next()
132            .await
133            .expect("should have on request before stream is closed")
134            .expect("should have gotten a request");
135        let job = Job::try_from(request);
136        let job = job.as_ref();
137        assert_matches!(job.map(|j| j.workload()), Ok(work::Load::Independent(_)));
138        assert_matches!(job.map(|j| j.execution_type()), Ok(execution::Type::Independent));
139    }
140
141    #[fuchsia::test(allow_stalls = false)]
142    async fn try_from_watch_converts_supplied_params() {
143        let (proxy, server) = fidl::endpoints::create_proxy::<FactoryResetMarker>();
144        let _fut = proxy.watch();
145        let mut request_stream: FactoryResetRequestStream = server.into_stream();
146        let request = request_stream
147            .next()
148            .await
149            .expect("should have on request before stream is closed")
150            .expect("should have gotten a request");
151        let job = Job::try_from(request);
152        let job = job.as_ref();
153        assert_matches!(job.map(|j| j.workload()), Ok(work::Load::Sequential(_, _)));
154        assert_matches!(job.map(|j| j.execution_type()), Ok(execution::Type::Sequential(_)));
155    }
156}