omaha_client_fuchsia/
app_set.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 channel_config::ChannelConfigs;
6use omaha_client::app_set::AppSet;
7use omaha_client::common::App;
8
9#[derive(Debug, Eq, PartialEq, Copy, Clone)]
10pub enum AppIdSource {
11    VbMetadata,
12    ChannelConfig,
13    DefaultEmpty,
14}
15
16#[derive(Debug, Eq, PartialEq, Copy, Clone)]
17pub struct AppMetadata {
18    // The source from which the app's ID was derived.
19    pub appid_source: AppIdSource,
20}
21
22pub struct FuchsiaAppSet {
23    system_app: App,
24    system_app_metadata: AppMetadata,
25    eager_packages: Vec<EagerPackage>,
26}
27
28impl FuchsiaAppSet {
29    pub fn new(system_app: App, system_app_metadata: AppMetadata) -> Self {
30        Self { system_app, system_app_metadata, eager_packages: vec![] }
31    }
32
33    pub fn add_eager_package(&mut self, package: EagerPackage) {
34        self.eager_packages.push(package);
35    }
36
37    /// Get the system product id.
38    /// Returns empty string if product id not set for the system app.
39    pub fn get_system_product_id(&self) -> &str {
40        self.system_app.extra_fields.get("product_id").map(|s| &**s).unwrap_or("")
41    }
42
43    /// Get the current channel name from cohort name, returns empty string if no cohort name set
44    /// for the app.
45    pub fn get_system_current_channel(&self) -> &str {
46        self.system_app.get_current_channel()
47    }
48
49    /// Get the target channel name from cohort hint, fallback to current channel if no hint.
50    pub fn get_system_target_channel(&self) -> &str {
51        self.system_app.get_target_channel()
52    }
53
54    /// Set the cohort hint of system app to |channel| and |id|.
55    pub fn set_system_target_channel(&mut self, channel: Option<String>, id: Option<String>) {
56        self.system_app.set_target_channel(channel, id);
57    }
58
59    pub fn get_system_app_metadata(&self) -> &AppMetadata {
60        &self.system_app_metadata
61    }
62}
63
64impl AppSet for FuchsiaAppSet {
65    fn get_apps(&self) -> Vec<App> {
66        std::iter::once(&self.system_app)
67            .chain(self.eager_packages.iter().map(|pg| &pg.app))
68            .cloned()
69            .collect()
70    }
71    fn iter_mut_apps(&mut self) -> Box<dyn Iterator<Item = &mut App> + '_> {
72        Box::new(
73            std::iter::once(&mut self.system_app)
74                .chain(self.eager_packages.iter_mut().map(|pg| &mut pg.app)),
75        )
76    }
77    fn get_system_app_id(&self) -> &str {
78        &self.system_app.id
79    }
80}
81
82pub struct EagerPackage {
83    app: App,
84    #[expect(dead_code)]
85    channel_configs: Option<ChannelConfigs>,
86}
87
88impl EagerPackage {
89    pub fn new(app: App, channel_configs: Option<ChannelConfigs>) -> Self {
90        Self { app, channel_configs }
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97
98    #[test]
99    fn test_get_apps() {
100        let app = App::builder().id("some_id").version([0, 1]).build();
101        let app_metadata = AppMetadata { appid_source: AppIdSource::VbMetadata };
102        let mut app_set = FuchsiaAppSet::new(app.clone(), app_metadata);
103        assert_eq!(app_set.get_apps(), vec![app.clone()]);
104
105        let eager_package_app = App::builder().id("package_id").version([5]).build();
106        let eager_package = EagerPackage { app: eager_package_app.clone(), channel_configs: None };
107        app_set.add_eager_package(eager_package);
108        assert_eq!(app_set.get_apps(), vec![app, eager_package_app]);
109    }
110
111    #[test]
112    fn test_iter_mut_apps() {
113        let app = App::builder().id("id1").version([1]).build();
114        let app_metadata = AppMetadata { appid_source: AppIdSource::VbMetadata };
115        let mut app_set = FuchsiaAppSet::new(app, app_metadata);
116        let eager_package = EagerPackage {
117            app: App::builder().id("package_id").version([5]).build(),
118            channel_configs: None,
119        };
120        app_set.add_eager_package(eager_package);
121
122        for app in app_set.iter_mut_apps() {
123            app.id += "_mutated";
124        }
125        assert_eq!(
126            app_set.get_apps(),
127            vec![
128                App::builder().id("id1_mutated").version([1]).build(),
129                App::builder().id("package_id_mutated").version([5]).build()
130            ]
131        );
132    }
133}