Skip to main content

settings_privacy/
privacy_controller.rs

1// Copyright 2019 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::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}