DO NOT MERGE: manually cherry pick

Change-Id: I47b6d783f32b7c260dd806898ed880901b5f784b
Test: presubmit
Bug: n/a
diff --git a/tools/aconfig/aflags/src/aconfig_storage_source.rs b/tools/aconfig/aflags/src/aconfig_storage_source.rs
index 0dfb956..a2c6012 100644
--- a/tools/aconfig/aflags/src/aconfig_storage_source.rs
+++ b/tools/aconfig/aflags/src/aconfig_storage_source.rs
@@ -1,136 +1,125 @@
-use crate::{Flag, FlagPermission, FlagSource, FlagValue, ValuePickedFrom};
-use anyhow::{anyhow, Result};
-
-use std::collections::HashMap;
-use std::fs::File;
-use std::io::Read;
+use crate::{Flag, FlagSource};
+use crate::{FlagPermission, FlagValue, ValuePickedFrom};
+use aconfigd_protos::{
+    ProtoFlagQueryReturnMessage, ProtoListStorageMessage, ProtoListStorageMessageMsg,
+    ProtoStorageRequestMessage, ProtoStorageRequestMessageMsg, ProtoStorageRequestMessages,
+    ProtoStorageReturnMessage, ProtoStorageReturnMessageMsg, ProtoStorageReturnMessages,
+};
+use anyhow::anyhow;
+use anyhow::Result;
+use protobuf::Message;
+use protobuf::SpecialFields;
+use std::io::{Read, Write};
+use std::net::Shutdown;
+use std::os::unix::net::UnixStream;
 
 pub struct AconfigStorageSource {}
 
-use aconfig_storage_file::protos::ProtoStorageFileInfo;
-use aconfig_storage_file::protos::ProtoStorageFiles;
-use aconfig_storage_file::FlagValueAndInfoSummary;
+fn convert(msg: ProtoFlagQueryReturnMessage) -> Result<Flag> {
+    let (value, value_picked_from) = match (
+        &msg.boot_flag_value,
+        msg.default_flag_value,
+        msg.local_flag_value,
+        msg.has_local_override,
+    ) {
+        (_, _, Some(local), Some(has_local)) if has_local => {
+            (FlagValue::try_from(local.as_str())?, ValuePickedFrom::Local)
+        }
+        (Some(boot), Some(default), _, _) => {
+            let value = FlagValue::try_from(boot.as_str())?;
+            if *boot == default {
+                (value, ValuePickedFrom::Default)
+            } else {
+                (value, ValuePickedFrom::Server)
+            }
+        }
+        _ => return Err(anyhow!("missing override")),
+    };
 
-static STORAGE_INFO_FILE_PATH: &str = "/metadata/aconfig/storage_records.pb";
+    let staged_value = match (msg.boot_flag_value, msg.server_flag_value, msg.has_server_override) {
+        (Some(boot), Some(server), _) if boot == server => None,
+        (Some(boot), Some(server), Some(has_server)) if boot != server && has_server => {
+            Some(FlagValue::try_from(server.as_str())?)
+        }
+        _ => None,
+    };
 
-fn read_default_values(file_info: ProtoStorageFileInfo) -> Result<HashMap<String, FlagValue>> {
-    let package_map =
-        file_info.package_map.ok_or(anyhow!("storage file is missing package map"))?;
-    let flag_map = file_info.flag_map.ok_or(anyhow!("storage file is missing flag map"))?;
-    let flag_val = file_info.flag_val.ok_or(anyhow!("storage file is missing flag val"))?;
+    let permission = match msg.is_readwrite {
+        Some(is_readwrite) => {
+            if is_readwrite {
+                FlagPermission::ReadWrite
+            } else {
+                FlagPermission::ReadOnly
+            }
+        }
+        None => return Err(anyhow!("missing permission")),
+    };
 
-    let mut result = HashMap::new();
-    for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)? {
-        let value = FlagValue::try_from(listed_flag.flag_value.as_str())?;
-        result.insert(listed_flag.package_name + &listed_flag.flag_name, value);
-    }
-    Ok(result)
+    Ok(Flag {
+        name: msg.flag_name.ok_or(anyhow!("missing flag name"))?,
+        package: msg.package_name.ok_or(anyhow!("missing package name"))?,
+        value,
+        permission,
+        value_picked_from,
+        staged_value,
+        container: msg.container.ok_or(anyhow!("missing container"))?,
+
+        // TODO: remove once DeviceConfig is not in the CLI.
+        namespace: "-".to_string(),
+    })
 }
 
-fn read_next_boot_values(
-    listed_flags: &[FlagValueAndInfoSummary],
-) -> Result<HashMap<String, FlagValue>> {
-    let mut result = HashMap::new();
-    for flag in listed_flags {
-        result.insert(
-            flag.package_name.clone() + &flag.flag_name,
-            FlagValue::try_from(flag.flag_value.as_str())?,
-        );
+fn read_from_socket() -> Result<Vec<ProtoFlagQueryReturnMessage>> {
+    let messages = ProtoStorageRequestMessages {
+        msgs: vec![ProtoStorageRequestMessage {
+            msg: Some(ProtoStorageRequestMessageMsg::ListStorageMessage(ProtoListStorageMessage {
+                msg: Some(ProtoListStorageMessageMsg::All(true)),
+                special_fields: SpecialFields::new(),
+            })),
+            special_fields: SpecialFields::new(),
+        }],
+        special_fields: SpecialFields::new(),
+    };
+
+    let mut socket = UnixStream::connect("/dev/socket/aconfigd")?;
+
+    let message_buffer = messages.write_to_bytes()?;
+    let mut message_length_buffer: [u8; 4] = [0; 4];
+    let message_size = &message_buffer.len();
+    message_length_buffer[0] = (message_size >> 24) as u8;
+    message_length_buffer[1] = (message_size >> 16) as u8;
+    message_length_buffer[2] = (message_size >> 8) as u8;
+    message_length_buffer[3] = *message_size as u8;
+    socket.write_all(&message_length_buffer)?;
+    socket.write_all(&message_buffer)?;
+    socket.shutdown(Shutdown::Write)?;
+
+    let mut response_length_buffer: [u8; 4] = [0; 4];
+    socket.read_exact(&mut response_length_buffer)?;
+    let response_length = u32::from_be_bytes(response_length_buffer) as usize;
+    let mut response_buffer = vec![0; response_length];
+    socket.read_exact(&mut response_buffer)?;
+
+    let response: ProtoStorageReturnMessages =
+        protobuf::Message::parse_from_bytes(&response_buffer)?;
+
+    match response.msgs.as_slice() {
+        [ProtoStorageReturnMessage {
+            msg: Some(ProtoStorageReturnMessageMsg::ListStorageMessage(list_storage_message)),
+            ..
+        }] => Ok(list_storage_message.flags.clone()),
+        _ => Err(anyhow!("unexpected response from aconfigd")),
     }
-    Ok(result)
-}
-
-fn reconcile(
-    default_values: HashMap<String, FlagValue>,
-    next_boot_values: HashMap<String, FlagValue>,
-    flags_current_boot: &[FlagValueAndInfoSummary],
-    container: &str,
-) -> Result<Vec<Flag>> {
-    let mut result = Vec::new();
-    for listed_flag in flags_current_boot {
-        let default_value = default_values
-            .get(&(listed_flag.package_name.clone() + &listed_flag.flag_name))
-            .copied();
-
-        let name = listed_flag.flag_name.clone();
-        let package = listed_flag.package_name.clone();
-        let value = FlagValue::try_from(listed_flag.flag_value.as_str())?;
-        let container = container.to_string();
-        let staged_value = next_boot_values
-            .get(&(listed_flag.package_name.clone() + &listed_flag.flag_name))
-            .filter(|&v| value != *v)
-            .copied();
-        let permission = if listed_flag.is_readwrite {
-            FlagPermission::ReadWrite
-        } else {
-            FlagPermission::ReadOnly
-        };
-        let value_picked_from = if listed_flag.has_local_override {
-            ValuePickedFrom::Local
-        } else if Some(value) == default_value {
-            ValuePickedFrom::Default
-        } else {
-            ValuePickedFrom::Server
-        };
-
-        result.push(Flag {
-            name,
-            package,
-            value,
-            container,
-            staged_value,
-            permission,
-            value_picked_from,
-
-            // TODO(b/324436145): delete namespace field once DeviceConfig isn't in CLI.
-            namespace: "-".to_string(),
-        });
-    }
-    Ok(result)
 }
 
 impl FlagSource for AconfigStorageSource {
     fn list_flags() -> Result<Vec<Flag>> {
-        let mut result = Vec::new();
-
-        let mut file = File::open(STORAGE_INFO_FILE_PATH)?;
-        let mut bytes = Vec::new();
-        file.read_to_end(&mut bytes)?;
-        let storage_file_info: ProtoStorageFiles = protobuf::Message::parse_from_bytes(&bytes)?;
-
-        for file_info in storage_file_info.files {
-            let default_values = read_default_values(file_info.clone())?;
-
-            let container =
-                file_info.container.ok_or(anyhow!("storage file is missing container"))?;
-            let package_map = format!("/metadata/aconfig/maps/{container}.package.map");
-            let flag_map = format!("/metadata/aconfig/maps/{container}.flag.map");
-            let flag_info = format!("/metadata/aconfig/boot/{container}.info");
-
-            let flag_val_current_boot = format!("/metadata/aconfig/boot/{container}.val");
-            let flag_val_next_boot = format!("/metadata/aconfig/flags/{container}.val");
-
-            let flags_next_boot = aconfig_storage_file::list_flags_with_info(
-                &package_map,
-                &flag_map,
-                &flag_val_next_boot,
-                &flag_info,
-            )?;
-            let flags_current_boot = aconfig_storage_file::list_flags_with_info(
-                &package_map,
-                &flag_map,
-                &flag_val_current_boot,
-                &flag_info,
-            )?;
-
-            let next_boot_values = read_next_boot_values(&flags_next_boot)?;
-            let processed_flags =
-                reconcile(default_values, next_boot_values, &flags_current_boot, &container)?;
-
-            result.extend(processed_flags);
-        }
-
-        Ok(result)
+        read_from_socket()
+            .map(|query_messages| {
+                query_messages.iter().map(|message| convert(message.clone())).collect::<Vec<_>>()
+            })?
+            .into_iter()
+            .collect()
     }
 
     fn override_flag(_namespace: &str, _qualified_name: &str, _value: &str) -> Result<()> {
diff --git a/tools/aconfig/aflags/src/main.rs b/tools/aconfig/aflags/src/main.rs
index 0a5c989..d8912a9 100644
--- a/tools/aconfig/aflags/src/main.rs
+++ b/tools/aconfig/aflags/src/main.rs
@@ -289,7 +289,7 @@
     let output = match cli.command {
         Command::List { use_new_storage: true, container } => {
             list(FlagSourceType::AconfigStorage, container)
-                .map_err(|_| anyhow!("storage may not be enabled"))
+                .map_err(|err| anyhow!("storage may not be enabled: {err}"))
                 .map(Some)
         }
         Command::List { use_new_storage: false, container } => {