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