settings_privacy/
privacy_fidl_handler.rs1use crate::privacy_controller::{PrivacyController, PrivacyError, Request};
6use crate::types::PrivacyInfo;
7use async_utils::hanging_get::server;
8use fidl_fuchsia_settings::{
9 Error as SettingsError, PrivacyRequest, PrivacyRequestStream, PrivacySettings,
10 PrivacyWatchResponder,
11};
12use fuchsia_async as fasync;
13use futures::StreamExt;
14use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
15use futures::channel::oneshot;
16use settings_common::inspect::event::{
17 HangingGetObserver, RequestType, ResponseType, UsagePublisher,
18};
19
20impl From<PrivacyInfo> for PrivacySettings {
21 fn from(info: PrivacyInfo) -> Self {
22 PrivacySettings {
23 user_data_sharing_consent: info.user_data_sharing_consent,
24 ..Default::default()
25 }
26 }
27}
28
29pub(super) type SubscriberObject = HangingGetObserver<PrivacyInfo, PrivacyWatchResponder>;
30type HangingFn = fn(&PrivacyInfo, SubscriberObject) -> bool;
31pub(super) type HangingGet = server::HangingGet<PrivacyInfo, SubscriberObject, HangingFn>;
32pub(super) type Publisher = server::Publisher<PrivacyInfo, SubscriberObject, HangingFn>;
33pub(super) type Subscriber = server::Subscriber<PrivacyInfo, SubscriberObject, HangingFn>;
34
35pub struct PrivacyFidlHandler {
36 hanging_get: HangingGet,
37 controller_tx: UnboundedSender<Request>,
38 usage_publisher: UsagePublisher<PrivacyInfo>,
39}
40
41impl PrivacyFidlHandler {
42 pub(crate) fn new(
43 privacy_controller: &mut PrivacyController,
44 usage_publisher: UsagePublisher<PrivacyInfo>,
45 initial_value: PrivacyInfo,
46 ) -> (Self, UnboundedReceiver<Request>) {
47 let hanging_get = HangingGet::new(initial_value, PrivacyFidlHandler::hanging_get);
48 privacy_controller.register_publisher(hanging_get.new_publisher());
49 let (controller_tx, request_rx) = mpsc::unbounded();
50 (Self { hanging_get, controller_tx, usage_publisher }, request_rx)
51 }
52
53 fn hanging_get(info: &PrivacyInfo, observer: SubscriberObject) -> bool {
54 let (usage_responder, responder) = observer.into_parts();
55 usage_responder.respond(format!("{info:?}"), ResponseType::OkSome);
56 if let Err(e) = responder.send(&PrivacySettings::from(*info)) {
57 log::warn!("Failed to respond to watch request: {e:?}");
58 return false;
59 }
60 true
61 }
62
63 pub fn handle_stream(&mut self, mut stream: PrivacyRequestStream) {
64 let request_handler = RequestHandler {
65 subscriber: self.hanging_get.new_subscriber(),
66 controller_tx: self.controller_tx.clone(),
67 usage_publisher: self.usage_publisher.clone(),
68 };
69 fasync::Task::local(async move {
70 while let Some(Ok(request)) = stream.next().await {
71 request_handler.handle_request(request).await;
72 }
73 })
74 .detach();
75 }
76}
77
78#[derive(Debug)]
79enum HandlerError {
80 AlreadySubscribed,
81 ControllerStopped,
82 Controller(PrivacyError),
83}
84
85impl From<&HandlerError> for ResponseType {
86 fn from(error: &HandlerError) -> Self {
87 match error {
88 HandlerError::AlreadySubscribed => ResponseType::AlreadySubscribed,
89 HandlerError::ControllerStopped => ResponseType::UnexpectedError,
90 HandlerError::Controller(e) => ResponseType::from(e),
91 }
92 }
93}
94
95struct RequestHandler {
96 subscriber: Subscriber,
97 controller_tx: UnboundedSender<Request>,
98 usage_publisher: UsagePublisher<PrivacyInfo>,
99}
100
101impl RequestHandler {
102 async fn handle_request(&self, request: PrivacyRequest) {
103 match request {
104 PrivacyRequest::Watch { responder } => {
105 let usage_res = self.usage_publisher.request("Watch".to_string(), RequestType::Get);
106 let observer = HangingGetObserver::new(usage_res, responder);
107 if let Err(observer) = self.subscriber.register2(observer) {
108 let e = HandlerError::AlreadySubscribed;
109 let (usage_res, responder) = observer.into_parts();
110 usage_res.respond(format!("Err({e:?})"), ResponseType::from(&e));
111 drop(responder);
112 }
113 }
114 PrivacyRequest::Set { settings, responder } => {
115 let usage_res = self
116 .usage_publisher
117 .request(format!("Set{{settings:{settings:?}}}"), RequestType::Set);
118 if let Err(e) = self.set(settings).await {
119 usage_res.respond(format!("Err({e:?}"), ResponseType::from(&e));
120 let _ = responder.send(Err(SettingsError::Failed));
121 } else {
122 usage_res.respond("Ok(())".to_string(), ResponseType::OkNone);
123 let _ = responder.send(Ok(()));
124 }
125 }
126 }
127 }
128
129 async fn set(&self, settings: PrivacySettings) -> Result<(), HandlerError> {
130 let (set_tx, set_rx) = oneshot::channel();
131 self.controller_tx
132 .unbounded_send(Request::Set(settings.user_data_sharing_consent, set_tx))
133 .map_err(|_| HandlerError::ControllerStopped)?;
134 set_rx
135 .await
136 .map_err(|_| HandlerError::ControllerStopped)
137 .and_then(|res| res.map_err(HandlerError::Controller))
138 }
139}