Merge "aconfig: add a storage file read api to get file version number" into main
diff --git a/core/Makefile b/core/Makefile
index 2165700..f132db3 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -6082,7 +6082,7 @@
# $1: root directory
# $2: add prefix
define fs_config
-(cd $(1); find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,$(2),' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) -R "$(2)"
+(cd $(1); find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,$(2),' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -R "$(2)"
endef
define filter-out-missing-vendor
diff --git a/core/binary.mk b/core/binary.mk
index 6dab49c..b17ab00 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -481,6 +481,34 @@
my_cflags += $(CLANG_EXTERNAL_CFLAGS)
endif
+# Extra cflags for projects under hardware/ directory.
+# This should match the definition of `thirdPartyDirPrefixExceptions`
+# in build/soong/android/paths.go.
+# Get the second element of LOCAL_PATH
+ifneq ($(filter hardware/%,$(LOCAL_PATH)),)
+ my_subdir := $(word 2,$(subst /,$(space),$(LOCAL_PATH)))
+ must_compile_hardware_subdirs := \
+ hardware/google/% \
+ hardware/interfaces/% \
+ hardware/libhardware/% \
+ hardware/libhardware_legacy/% \
+ hardware/ril/%
+ ifeq ($(filter $(must_compile_hardware_subdirs),$(my_subdir)),)
+ my_cflags += $(CLANG_EXTERNAL_CFLAGS)
+ endif
+endif
+
+# Extra cflags for projects under vendor/ directory.
+# This should match the definition of `thirdPartyDirPrefixExceptions`
+# in build/soong/android/paths.go.
+ifneq ($(filter vendor/%,$(LOCAL_PATH)),)
+ my_subdir := $(word 2,$(subst /,$(space),$(LOCAL_PATH)))
+ # Do not add the flags for any subdir that contains the string "google".
+ ifneq ($(findstring google,$(my_subdir)),)
+ my_cflags += $(CLANG_EXTERNAL_CFLAGS)
+ endif
+endif
+
# arch-specific static libraries go first so that generic ones can depend on them
my_static_libraries := $(LOCAL_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_static_libraries)
my_whole_static_libraries := $(LOCAL_WHOLE_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_WHOLE_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_whole_static_libraries)
diff --git a/core/product_config.mk b/core/product_config.mk
index 500735e..4525423 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -606,6 +606,15 @@
endif
endef
+ifndef PRODUCT_VIRTUAL_AB_COW_VERSION
+ PRODUCT_VIRTUAL_AB_COW_VERSION := 2
+ ifdef PRODUCT_SHIPPING_API_LEVEL
+ ifeq (true,$(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),34))
+ PRODUCT_VIRTUAL_AB_COW_VERSION := 3
+ endif
+ endif
+endif
+
# Copy and check the value of each PRODUCT_BUILD_*_IMAGE variable
$(foreach image, \
PVMFW \
diff --git a/target/product/virtual_ab_ota/android_t_baseline.mk b/target/product/virtual_ab_ota/android_t_baseline.mk
index af0f7a9..418aaa4 100644
--- a/target/product/virtual_ab_ota/android_t_baseline.mk
+++ b/target/product/virtual_ab_ota/android_t_baseline.mk
@@ -20,5 +20,3 @@
#
# All U+ launching devices should instead use vabc_features.mk.
$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)
-
-PRODUCT_VIRTUAL_AB_COW_VERSION ?= 2
diff --git a/tools/aconfig/aconfig/Android.bp b/tools/aconfig/aconfig/Android.bp
index 2c26166..00a6fee 100644
--- a/tools/aconfig/aconfig/Android.bp
+++ b/tools/aconfig/aconfig/Android.bp
@@ -47,6 +47,7 @@
aconfig_declarations {
name: "aconfig.test.exported.flags",
package: "com.android.aconfig.test.exported",
+ exportable: true,
container: "system",
srcs: ["tests/test_exported.aconfig"],
}
diff --git a/tools/aconfig/aflags/src/device_config_source.rs b/tools/aconfig/aflags/src/device_config_source.rs
index 12a62cf..1cea6ed 100644
--- a/tools/aconfig/aflags/src/device_config_source.rs
+++ b/tools/aconfig/aflags/src/device_config_source.rs
@@ -64,7 +64,7 @@
fn read_pb_files() -> Result<Vec<Flag>> {
let mut flags: BTreeMap<String, Flag> = BTreeMap::new();
for partition in ["system", "system_ext", "product", "vendor"] {
- let path = format!("/{}/etc/aconfig_flags.pb", partition);
+ let path = format!("/{partition}/etc/aconfig_flags.pb");
let Ok(bytes) = fs::read(&path) else {
eprintln!("warning: failed to read {}", path);
continue;
@@ -98,11 +98,13 @@
Ok(flags)
}
-fn read_device_config_output(command: &str) -> Result<String> {
- let output = Command::new("/system/bin/device_config").arg(command).output()?;
+fn read_device_config_output(command: &[&str]) -> Result<String> {
+ let output = Command::new("/system/bin/device_config").args(command).output()?;
if !output.status.success() {
let reason = match output.status.code() {
- Some(code) => format!("exit code {}", code),
+ Some(code) => {
+ format!("exit code {}, output was {}", code, str::from_utf8(&output.stdout)?)
+ }
None => "terminated by signal".to_string(),
};
bail!("failed to execute device_config: {}", reason);
@@ -111,7 +113,7 @@
}
fn read_device_config_flags() -> Result<HashMap<String, String>> {
- let list_output = read_device_config_output("list")?;
+ let list_output = read_device_config_output(&["list"])?;
parse_device_config(&list_output)
}
@@ -145,6 +147,10 @@
let flags = reconcile(&pb_flags, dc_flags);
Ok(flags)
}
+
+ fn override_flag(namespace: &str, qualified_name: &str, value: &str) -> Result<()> {
+ read_device_config_output(&["put", namespace, qualified_name, value]).map(|_| ())
+ }
}
#[cfg(test)]
diff --git a/tools/aconfig/aflags/src/main.rs b/tools/aconfig/aflags/src/main.rs
index 1e2a7a0..ef0195f 100644
--- a/tools/aconfig/aflags/src/main.rs
+++ b/tools/aconfig/aflags/src/main.rs
@@ -16,7 +16,7 @@
//! `aflags` is a device binary to read and write aconfig flags.
-use anyhow::Result;
+use anyhow::{anyhow, Result};
use clap::Parser;
mod device_config_source;
@@ -63,8 +63,15 @@
value_picked_from: ValuePickedFrom,
}
+impl Flag {
+ fn qualified_name(&self) -> String {
+ format!("{}.{}", self.package, self.name)
+ }
+}
+
trait FlagSource {
fn list_flags() -> Result<Vec<Flag>>;
+ fn override_flag(namespace: &str, qualified_name: &str, value: &str) -> Result<()>;
}
const ABOUT_TEXT: &str = "Tool for reading and writing flags.
@@ -94,6 +101,18 @@
enum Command {
/// List all aconfig flags on this device.
List,
+
+ /// Enable an aconfig flag on this device, on the next boot.
+ Enable {
+ /// <package>.<flag_name>
+ qualified_name: String,
+ },
+
+ /// Disable an aconfig flag on this device, on the next boot.
+ Disable {
+ /// <package>.<flag_name>
+ qualified_name: String,
+ },
}
struct PaddingInfo {
@@ -125,6 +144,23 @@
format!("{pkg:p0$}{name:p1$}{val:p2$}{value_picked_from:p3$}{perm:p4$}{container}\n")
}
+fn set_flag(qualified_name: &str, value: &str) -> Result<()> {
+ let flags_binding = DeviceConfigSource::list_flags()?;
+ let flag = flags_binding.iter().find(|f| f.qualified_name() == qualified_name).ok_or(
+ anyhow!("no aconfig flag '{qualified_name}'. Does the flag have an .aconfig definition?"),
+ )?;
+
+ if let FlagPermission::ReadOnly = flag.permission {
+ return Err(anyhow!(
+ "could not write flag '{qualified_name}', it is read-only for the current release configuration.",
+ ));
+ }
+
+ DeviceConfigSource::override_flag(&flag.namespace, qualified_name, value)?;
+
+ Ok(())
+}
+
fn list() -> Result<String> {
let flags = DeviceConfigSource::list_flags()?;
let padding_info = PaddingInfo {
@@ -154,10 +190,13 @@
fn main() {
let cli = Cli::parse();
let output = match cli.command {
- Command::List => list(),
+ Command::List => list().map(Some),
+ Command::Enable { qualified_name } => set_flag(&qualified_name, "true").map(|_| None),
+ Command::Disable { qualified_name } => set_flag(&qualified_name, "false").map(|_| None),
};
match output {
- Ok(text) => println!("{text}"),
- Err(msg) => println!("Error: {}", msg),
+ Ok(Some(text)) => println!("{text}"),
+ Ok(None) => (),
+ Err(message) => println!("Error: {message}"),
}
}
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index 55fdca4..bd9543a 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -35,7 +35,6 @@
srcs: ["fs_config.c"],
shared_libs: [
"libcutils",
- "libselinux",
],
cflags: ["-Werror"],
}
diff --git a/tools/fs_config/fs_config.c b/tools/fs_config/fs_config.c
index 2a75add..80bd3c1 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -22,9 +22,6 @@
#include <string.h>
#include <inttypes.h>
-#include <selinux/selinux.h>
-#include <selinux/label.h>
-
#include "private/android_filesystem_config.h"
#include "private/fs_config.h"
@@ -35,8 +32,8 @@
//
// After the first 4 columns, optional key=value pairs are emitted
// for each file. Currently, the following keys are supported:
-// * -S: selabel=[selinux_label]
-// * -C: capabilities=[hex capabilities value]
+//
+// -C: capabilities=[hex capabilities value]
//
// Example input:
//
@@ -48,45 +45,24 @@
// system/etc/dbus.conf 1002 1002 440
// data/app 1000 1000 771
//
-// or if, for example, -S is used:
-//
-// system/etc/dbus.conf 1002 1002 440 selabel=u:object_r:system_file:s0
-// data/app 1000 1000 771 selabel=u:object_r:apk_data_file:s0
-//
// Note that the output will omit the trailing slash from
// directories.
-static struct selabel_handle* get_sehnd(const char* context_file) {
- struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, context_file } };
- struct selabel_handle* sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
-
- if (!sehnd) {
- perror("error running selabel_open");
- exit(EXIT_FAILURE);
- }
- return sehnd;
-}
-
static void usage() {
- fprintf(stderr, "Usage: fs_config [-D product_out_path] [-S context_file] [-R root] [-C]\n");
+ fprintf(stderr, "Usage: fs_config [-D product_out_path] [-R root] [-C]\n");
}
int main(int argc, char** argv) {
char buffer[1024];
- const char* context_file = NULL;
const char* product_out_path = NULL;
char* root_path = NULL;
- struct selabel_handle* sehnd = NULL;
int print_capabilities = 0;
int opt;
- while((opt = getopt(argc, argv, "CS:R:D:")) != -1) {
+ while((opt = getopt(argc, argv, "CR:D:")) != -1) {
switch(opt) {
case 'C':
print_capabilities = 1;
break;
- case 'S':
- context_file = optarg;
- break;
case 'R':
root_path = optarg;
break;
@@ -99,10 +75,6 @@
}
}
- if (context_file != NULL) {
- sehnd = get_sehnd(context_file);
- }
-
if (root_path != NULL) {
size_t root_len = strlen(root_path);
/* Trim any trailing slashes from the root path. */
@@ -141,33 +113,6 @@
}
printf("%s %d %d %o", buffer, uid, gid, mode);
- if (sehnd != NULL) {
- size_t buffer_strlen = strnlen(buffer, sizeof(buffer));
- if (buffer_strlen >= sizeof(buffer)) {
- fprintf(stderr, "non null terminated buffer, aborting\n");
- exit(EXIT_FAILURE);
- }
- size_t full_name_size = buffer_strlen + 2;
- char* full_name = (char*) malloc(full_name_size);
- if (full_name == NULL) {
- perror("malloc");
- exit(EXIT_FAILURE);
- }
-
- full_name[0] = '/';
- strncpy(full_name + 1, buffer, full_name_size - 1);
- full_name[full_name_size - 1] = '\0';
-
- char* secontext;
- if (selabel_lookup(sehnd, &secontext, full_name, ( mode | (is_dir ? S_IFDIR : S_IFREG)))) {
- secontext = strdup("u:object_r:unlabeled:s0");
- }
-
- printf(" selabel=%s", secontext);
- free(full_name);
- freecon(secontext);
- }
-
if (print_capabilities) {
printf(" capabilities=0x%" PRIx64, capabilities);
}