1 use crate::{Flag, FlagPermission, FlagSource, FlagValue, ValuePickedFrom};
2 use anyhow::{anyhow, Result};
3 
4 use std::fs::File;
5 use std::io::Read;
6 
7 pub struct AconfigStorageSource {}
8 
9 use aconfig_storage_file::protos::ProtoStorageFiles;
10 
11 static STORAGE_INFO_FILE_PATH: &str = "/metadata/aconfig/persistent_storage_file_records.pb";
12 
13 impl FlagSource for AconfigStorageSource {
list_flags() -> Result<Vec<Flag>>14     fn list_flags() -> Result<Vec<Flag>> {
15         let mut result = Vec::new();
16 
17         let mut file = File::open(STORAGE_INFO_FILE_PATH)?;
18         let mut bytes = Vec::new();
19         file.read_to_end(&mut bytes)?;
20         let storage_file_info: ProtoStorageFiles = protobuf::Message::parse_from_bytes(&bytes)?;
21 
22         for file_info in storage_file_info.files {
23             let package_map =
24                 file_info.package_map.ok_or(anyhow!("storage file is missing package map"))?;
25             let flag_map = file_info.flag_map.ok_or(anyhow!("storage file is missing flag map"))?;
26             let flag_val = file_info.flag_val.ok_or(anyhow!("storage file is missing flag val"))?;
27             let container =
28                 file_info.container.ok_or(anyhow!("storage file is missing container"))?;
29 
30             for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
31             {
32                 result.push(Flag {
33                     name: listed_flag.flag_name,
34                     package: listed_flag.package_name,
35                     value: FlagValue::try_from(listed_flag.flag_value.as_str())?,
36                     container: container.to_string(),
37 
38                     // TODO(b/324436145): delete namespace field once DeviceConfig isn't in CLI.
39                     namespace: "-".to_string(),
40 
41                     // TODO(b/324436145): Populate with real values once API is available.
42                     staged_value: None,
43                     permission: FlagPermission::ReadOnly,
44                     value_picked_from: ValuePickedFrom::Default,
45                 });
46             }
47         }
48 
49         Ok(result)
50     }
51 
override_flag(_namespace: &str, _qualified_name: &str, _value: &str) -> Result<()>52     fn override_flag(_namespace: &str, _qualified_name: &str, _value: &str) -> Result<()> {
53         todo!()
54     }
55 }
56