settings_privacy/
privacy_controller.rs1use crate::privacy_fidl_handler::Publisher;
6use crate::types::PrivacyInfo;
7use anyhow::Error;
8use fuchsia_async as fasync;
9use futures::StreamExt;
10use futures::channel::mpsc::UnboundedReceiver;
11use futures::channel::oneshot::Sender;
12use settings_common::inspect::event::{ResponseType, SettingValuePublisher};
13use settings_storage::UpdateState;
14use settings_storage::device_storage::{DeviceStorage, DeviceStorageCompatible};
15use settings_storage::storage_factory::{NoneT, StorageAccess, StorageFactory};
16use std::rc::Rc;
17
18impl DeviceStorageCompatible for PrivacyInfo {
19 type Loader = NoneT;
20 const KEY: &'static str = "privacy_info";
21}
22
23#[derive(thiserror::Error, Debug)]
24pub(crate) enum PrivacyError {
25 #[error("Write failed for Setup: {0:?}")]
26 WriteFailure(Error),
27}
28
29impl From<&PrivacyError> for ResponseType {
30 fn from(error: &PrivacyError) -> Self {
31 match error {
32 PrivacyError::WriteFailure(..) => ResponseType::StorageFailure,
33 }
34 }
35}
36
37pub(crate) enum Request {
38 Set(Option<bool>, Sender<Result<(), PrivacyError>>),
39}
40
41pub struct PrivacyController {
42 store: Rc<DeviceStorage>,
43 publisher: Option<Publisher>,
44 setting_value_publisher: SettingValuePublisher<PrivacyInfo>,
45}
46
47impl PrivacyController {
48 pub(super) async fn new<F>(
49 storage_factory: Rc<F>,
50 setting_value_publisher: SettingValuePublisher<PrivacyInfo>,
51 ) -> Self
52 where
53 F: StorageFactory<Storage = DeviceStorage>,
54 {
55 PrivacyController {
56 store: storage_factory.get_store().await,
57 publisher: None,
58 setting_value_publisher,
59 }
60 }
61
62 pub(super) fn register_publisher(&mut self, publisher: Publisher) {
63 self.publisher = Some(publisher);
64 }
65
66 fn publish(&self, info: PrivacyInfo) {
67 let _ = self.setting_value_publisher.publish(&info);
68 if let Some(publisher) = self.publisher.as_ref() {
69 publisher.set(info);
70 }
71 }
72
73 pub(super) async fn handle(
74 self,
75 mut request_rx: UnboundedReceiver<Request>,
76 ) -> fasync::Task<()> {
77 fasync::Task::local(async move {
78 while let Some(request) = request_rx.next().await {
79 let Request::Set(user_data_sharing_consent, tx) = request;
80 let res = self.set(user_data_sharing_consent).await.map(|info| {
81 if let Some(info) = info {
82 self.publish(info);
83 }
84 });
85 let _ = tx.send(res);
86 }
87 })
88 }
89
90 async fn set(
91 &self,
92 user_data_sharing_consent: Option<bool>,
93 ) -> Result<Option<PrivacyInfo>, PrivacyError> {
94 let mut info = self.store.get::<PrivacyInfo>().await;
95 info.user_data_sharing_consent = user_data_sharing_consent;
96
97 self.store
98 .write(&info)
99 .await
100 .map(|state| (UpdateState::Updated == state).then_some(info))
101 .map_err(PrivacyError::WriteFailure)
102 }
103
104 pub(super) async fn restore(&self) -> PrivacyInfo {
105 self.store.get::<PrivacyInfo>().await
106 }
107}
108
109impl StorageAccess for PrivacyController {
110 type Storage = DeviceStorage;
111 type Data = PrivacyInfo;
112 const STORAGE_KEY: &'static str = PrivacyInfo::KEY;
113}