Merge "Set JAVA_HOME for runtime via soong AndroidTest.xml template" into main
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 797a20e..40e2aa1 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -514,6 +514,7 @@
     logtagd.rc \
     ot-cli-ftd \
     ot-ctl \
+    overlay_remounter \
     procrank \
     profcollectd \
     profcollectctl \
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index f21e4b3..82b6e76 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -679,6 +679,7 @@
             "logtagd.rc",
             "ot-cli-ftd",
             "ot-ctl",
+            "overlay_remounter",
             "procrank",
             "profcollectctl",
             "profcollectd",
diff --git a/target/product/generic_system.mk b/target/product/generic_system.mk
index b9a623d..2482afc 100644
--- a/target/product/generic_system.mk
+++ b/target/product/generic_system.mk
@@ -36,11 +36,6 @@
     Stk \
     Tag \
 
-ifeq ($(RELEASE_AVATAR_PICKER_APP),true)
-  PRODUCT_PACKAGES += \
-    AvatarPicker
-endif
-
 # OTA support
 PRODUCT_PACKAGES += \
     recovery-refresh \
diff --git a/target/product/handheld_system.mk b/target/product/handheld_system.mk
index 2b055c7..6799066 100644
--- a/target/product/handheld_system.mk
+++ b/target/product/handheld_system.mk
@@ -34,6 +34,7 @@
 
 PRODUCT_PACKAGES += \
     android.software.window_magnification.prebuilt.xml \
+    $(if $(RELEASE_AVATAR_PICKER_APP), AvatarPicker,) \
     BasicDreams \
     BlockedNumberProvider \
     BluetoothMidiService \
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index fa65a4e..71138ac 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -158,15 +158,14 @@
     dalvik.vm.minidebuginfo=true \
     dalvik.vm.dex2oat-minidebuginfo=true
 
-# Enable Madvising of the whole art, odex and vdex files to MADV_WILLNEED.
+# Enable Madvising of the whole odex and vdex files to MADV_WILLNEED.
 # The size specified here is the size limit of how much of the file
 # (in bytes) is madvised.
-# We madvise the whole .art file to MADV_WILLNEED with UINT_MAX limit.
 # For odex and vdex files, we limit madvising to 100MB.
+# For art files, we defer to the runtime for default behavior.
 PRODUCT_SYSTEM_PROPERTIES += \
     dalvik.vm.madvise.vdexfile.size=104857600 \
-    dalvik.vm.madvise.odexfile.size=104857600 \
-    dalvik.vm.madvise.artfile.size=4294967295
+    dalvik.vm.madvise.odexfile.size=104857600
 
 # Properties for the Unspecialized App Process Pool
 PRODUCT_SYSTEM_PROPERTIES += \
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 44bb8aa..d6988c4 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -74,10 +74,7 @@
     };
     let mut template = TinyTemplate::new();
     template.add_template("Flags.java", include_str!("../../templates/Flags.java.template"))?;
-    template.add_template(
-        "FeatureFlagsImpl.java",
-        include_str!("../../templates/FeatureFlagsImpl.java.template"),
-    )?;
+    add_feature_flags_impl_template(&context, &mut template)?;
     template.add_template(
         "FeatureFlags.java",
         include_str!("../../templates/FeatureFlags.java.template"),
@@ -233,6 +230,63 @@
     format!("mProperties{}{}", &name[0..1].to_ascii_uppercase(), &name[1..])
 }
 
+fn add_feature_flags_impl_template(
+    context: &Context,
+    template: &mut TinyTemplate,
+) -> Result<(), tinytemplate::error::Error> {
+    if context.is_test_mode {
+        // Test mode has its own template, so use regardless of any other settings.
+        template.add_template(
+            "FeatureFlagsImpl.java",
+            include_str!("../../templates/FeatureFlagsImpl.test_mode.java.template"),
+        )?;
+        return Ok(());
+    }
+
+    println!("lib exported: {}", context.library_exported);
+    println!("new_exp: {}", context.new_exported);
+    println!("allow in: {}", context.allow_instrumentation);
+    match (context.library_exported, context.new_exported, context.allow_instrumentation) {
+        // Exported library with new_exported enabled, use new storage exported template.
+        (true, true, _) => {
+            println!("new exported template");
+            template.add_template(
+                "FeatureFlagsImpl.java",
+                include_str!("../../templates/FeatureFlagsImpl.exported.java.template"),
+            )?;
+        }
+
+        // Exported library with new_exported NOT enabled, use legacy (device
+        // config) template, because regardless of allow_instrumentation, we use
+        // device config for exported libs if new_exported isn't enabled.
+        // Remove once new_exported is fully rolled out.
+        (true, false, _) => {
+            println!("old exported, old template");
+            template.add_template(
+                "FeatureFlagsImpl.java",
+                include_str!("../../templates/FeatureFlagsImpl.java.template"),
+            )?;
+        }
+
+        // New storage internal mode.
+        (false, _, true) => {
+            template.add_template(
+                "FeatureFlagsImpl.java",
+                include_str!("../../templates/FeatureFlagsImpl.new_storage.java.template"),
+            )?;
+        }
+
+        // Device config internal mode. Use legacy (device config) template.
+        (false, _, false) => {
+            template.add_template(
+                "FeatureFlagsImpl.java",
+                include_str!("../../templates/FeatureFlagsImpl.java.template"),
+            )?;
+        }
+    };
+    Ok(())
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/tools/aconfig/aconfig/src/codegen/mod.rs b/tools/aconfig/aconfig/src/codegen/mod.rs
index 1ea3b37..9ed66db 100644
--- a/tools/aconfig/aconfig/src/codegen/mod.rs
+++ b/tools/aconfig/aconfig/src/codegen/mod.rs
@@ -50,67 +50,6 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use aconfig_protos::is_valid_container_ident;
-
-    #[test]
-    fn test_is_valid_name_ident() {
-        assert!(is_valid_name_ident("foo"));
-        assert!(is_valid_name_ident("foo_bar_123"));
-        assert!(is_valid_name_ident("foo_"));
-
-        assert!(!is_valid_name_ident(""));
-        assert!(!is_valid_name_ident("123_foo"));
-        assert!(!is_valid_name_ident("foo-bar"));
-        assert!(!is_valid_name_ident("foo-b\u{00e5}r"));
-        assert!(!is_valid_name_ident("foo__bar"));
-        assert!(!is_valid_name_ident("_foo"));
-    }
-
-    #[test]
-    fn test_is_valid_package_ident() {
-        assert!(is_valid_package_ident("foo.bar"));
-        assert!(is_valid_package_ident("foo.bar_baz"));
-        assert!(is_valid_package_ident("foo.bar.a123"));
-
-        assert!(!is_valid_package_ident("foo_bar_123"));
-        assert!(!is_valid_package_ident("foo"));
-        assert!(!is_valid_package_ident("foo._bar"));
-        assert!(!is_valid_package_ident(""));
-        assert!(!is_valid_package_ident("123_foo"));
-        assert!(!is_valid_package_ident("foo-bar"));
-        assert!(!is_valid_package_ident("foo-b\u{00e5}r"));
-        assert!(!is_valid_package_ident("foo.bar.123"));
-        assert!(!is_valid_package_ident(".foo.bar"));
-        assert!(!is_valid_package_ident("foo.bar."));
-        assert!(!is_valid_package_ident("."));
-        assert!(!is_valid_package_ident(".."));
-        assert!(!is_valid_package_ident("foo..bar"));
-        assert!(!is_valid_package_ident("foo.__bar"));
-    }
-
-    #[test]
-    fn test_is_valid_container_ident() {
-        assert!(is_valid_container_ident("foo.bar"));
-        assert!(is_valid_container_ident("foo.bar_baz"));
-        assert!(is_valid_container_ident("foo.bar.a123"));
-        assert!(is_valid_container_ident("foo"));
-        assert!(is_valid_container_ident("foo_bar_123"));
-
-        assert!(!is_valid_container_ident(""));
-        assert!(!is_valid_container_ident("foo._bar"));
-        assert!(!is_valid_container_ident("_foo"));
-        assert!(!is_valid_container_ident("123_foo"));
-        assert!(!is_valid_container_ident("foo-bar"));
-        assert!(!is_valid_container_ident("foo-b\u{00e5}r"));
-        assert!(!is_valid_container_ident("foo.bar.123"));
-        assert!(!is_valid_container_ident(".foo.bar"));
-        assert!(!is_valid_container_ident("foo.bar."));
-        assert!(!is_valid_container_ident("."));
-        assert!(!is_valid_container_ident(".."));
-        assert!(!is_valid_container_ident("foo..bar"));
-        assert!(!is_valid_container_ident("foo.__bar"));
-    }
-
     #[test]
     fn test_create_device_config_ident() {
         assert_eq!(
diff --git a/tools/aconfig/aconfig/src/main.rs b/tools/aconfig/aconfig/src/main.rs
index e2fa554..14bbcc3 100644
--- a/tools/aconfig/aconfig/src/main.rs
+++ b/tools/aconfig/aconfig/src/main.rs
@@ -40,9 +40,86 @@
 
 use commands::{Input, OutputFile};
 
+const HELP_DUMP_CACHE: &str = r#"
+An aconfig cache file, created via `aconfig create-cache`.
+"#;
+
+const HELP_DUMP_FORMAT: &str = r#"
+Change the output format for each flag.
+
+The argument to --format is a format string. Each flag will be a copy of this string, with certain
+placeholders replaced by attributes of the flag. The placeholders are
+
+  {package}
+  {name}
+  {namespace}
+  {description}
+  {bug}
+  {state}
+  {state:bool}
+  {permission}
+  {trace}
+  {trace:paths}
+  {is_fixed_read_only}
+  {is_exported}
+  {container}
+  {metadata}
+  {fully_qualified_name}
+
+Note: the format strings "textproto" and "protobuf" are handled in a special way: they output all
+flag attributes in text or binary protobuf format.
+
+Examples:
+
+  # See which files were read to determine the value of a flag; the files were read in the order
+  # listed.
+  --format='{fully_qualified_name} {trace}'
+
+  # Trace the files read for a specific flag. Useful during debugging.
+  --filter=fully_qualified_name:com.foo.flag_name --format='{trace}'
+
+  # Print a somewhat human readable description of each flag.
+  --format='The flag {name} in package {package} is {state} and has permission {permission}.'
+"#;
+
 const HELP_DUMP_FILTER: &str = r#"
-Limit which flags to output. If multiple --filter arguments are provided, the output will be
-limited to flags that match any of the filters.
+Limit which flags to output. If --filter is omitted, all flags will be printed. If multiple
+--filter options are provided, the output will be limited to flags that match any of the filters.
+
+The argument to --filter is a search query. Multiple queries can be AND-ed together by
+concatenating them with a plus sign.
+
+Valid queries are:
+
+  package:<string>
+  name:<string>
+  namespace:<string>
+  bug:<string>
+  state:ENABLED|DISABLED
+  permission:READ_ONLY|READ_WRITE
+  is_fixed_read_only:true|false
+  is_exported:true|false
+  container:<string>
+  fully_qualified_name:<string>
+
+Note: there is currently no support for filtering based on these flag attributes: description,
+trace, metadata.
+
+Examples:
+
+  # Print a single flag:
+  --filter=fully_qualified_name:com.foo.flag_name
+
+  # Print all known information about a single flag:
+  --filter=fully_qualified_name:com.foo.flag_name --format=textproto
+
+  # Print all flags in the com.foo package, and all enabled flags in the com.bar package:
+  --filter=package:com.foo --filter=package.com.bar+state:ENABLED
+"#;
+
+const HELP_DUMP_DEDUP: &str = r#"
+Allow the same flag to be present in multiple cache files; if duplicates are found, collapse into
+a single instance.
 "#;
 
 fn cli() -> Command {
@@ -150,22 +227,34 @@
         .subcommand(
             Command::new("dump-cache")
                 .alias("dump")
-                .arg(Arg::new("cache").long("cache").action(ArgAction::Append))
+                .arg(
+                    Arg::new("cache")
+                        .long("cache")
+                        .action(ArgAction::Append)
+                        .long_help(HELP_DUMP_CACHE.trim()),
+                )
                 .arg(
                     Arg::new("format")
                         .long("format")
                         .value_parser(|s: &str| DumpFormat::try_from(s))
                         .default_value(
                             "{fully_qualified_name} [{container}]: {permission} + {state}",
-                        ),
+                        )
+                        .long_help(HELP_DUMP_FORMAT.trim()),
                 )
                 .arg(
                     Arg::new("filter")
                         .long("filter")
                         .action(ArgAction::Append)
-                        .help(HELP_DUMP_FILTER.trim()),
+                        .long_help(HELP_DUMP_FILTER.trim()),
                 )
-                .arg(Arg::new("dedup").long("dedup").num_args(0).action(ArgAction::SetTrue))
+                .arg(
+                    Arg::new("dedup")
+                        .long("dedup")
+                        .num_args(0)
+                        .action(ArgAction::SetTrue)
+                        .long_help(HELP_DUMP_DEDUP.trim()),
+                )
                 .arg(Arg::new("out").long("out").default_value("-")),
         )
         .subcommand(
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
new file mode 100644
index 0000000..8b60824
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
@@ -0,0 +1,44 @@
+package {package_name}; {#- CODEGEN FOR EXPORTED MODE FOR NEW STORAGE #}
+
+import android.os.Build;
+import android.os.flagging.AconfigPackage;
+import android.util.Log;
+/** @hide */
+public final class FeatureFlagsImpl implements FeatureFlags \{
+    private static final String TAG = "FeatureFlagsImplExport";
+    private static volatile boolean isCached = false;
+{{ for flag in flag_elements }}
+    private static boolean {flag.method_name} = false;
+{{ -endfor }} {#- end flag_elements #}
+    private void init() \{
+        try \{
+            AconfigPackage reader = AconfigPackage.load("{package_name}");
+            {{ -for namespace_with_flags in namespace_flags }}
+            {{ -for flag in namespace_with_flags.flags }}
+            {{ -if flag.finalized_sdk_present }}
+            {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+            {{ - else }} {#- else finalized_sdk_present #}
+            {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+            {{ -endif}}  {#- end finalized_sdk_present#}
+            {{ -endfor }} {#- end namespace_with_flags.flags #}
+            {{ -endfor }} {#- end namespace_flags #}
+        } catch (Exception e) \{
+            // pass
+            Log.e(TAG, e.toString());
+        } catch (LinkageError e) \{
+            // for mainline module running on older devices.
+            // This should be replaces to version check, after the version bump.
+            Log.e(TAG, e.toString());
+        }
+        isCached = true;
+    }
+{{ -for flag in flag_elements }}
+    @Override
+    public boolean {flag.method_name}() \{
+        if (!isCached) \{
+            init();
+        }
+        return {flag.method_name};
+    }
+{{ endfor }} {#- end flag_elements #}
+}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index 5baa475..ea2a2ee 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -8,11 +8,11 @@
 import android.os.Build;
 {{ if is_platform_container }}
 import android.os.flagging.PlatformAconfigPackageInternal;
-{{ -else }}
+{{ -else }} {#- else is_platform_container #}
 import android.os.flagging.AconfigPackageInternal;
-{{ -endif }}
+{{ -endif }} {#- end of is_platform_container#}
 import android.util.Log;
-{{ -endif }}
+{{ -endif }} {#- end of runtime_lookup_required#}
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
 {{ -if runtime_lookup_required }}
@@ -21,21 +21,21 @@
 {{ for flag in flag_elements }}
 {{ -if flag.is_read_write }}
     private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }}
+{{ -endif }} {#- end of is_read_write#}
 {{ -endfor }}
 
     private void init() \{
         try \{
 {{ if is_platform_container }}
             PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -else }}
+{{ -else }} {#- else is_platform_container #}
             AconfigPackageInternal reader = AconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -endif }}
+{{ -endif }} {#- end of is_platform_container#}
         {{ -for namespace_with_flags in namespace_flags }}
         {{ -for flag in namespace_with_flags.flags }}
         {{ -if flag.is_read_write }}
             {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
-        {{ -endif }}
+        {{ -endif }} {#- is_read_write#}
         {{ -endfor }}
         {{ -endfor }}
         } catch (Exception e) \{
@@ -58,9 +58,9 @@
             init();
         }
         return {flag.method_name};
-{{ -else }}
+{{ -else }}{#- else is_read_write #}
         return {flag.default_value};
-{{ -endif }}
+{{ -endif }}  {#- end of is_read_write#}
     }
 {{ endfor }}
 }
@@ -83,9 +83,9 @@
             {{ -for flag in namespace_with_flags.flags }}
             {{ -if flag.finalized_sdk_present }}
             {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
-            {{ - else }}
+            {{ - else }} {#- else finalized_sdk_present #}
             {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
-            {{ -endif}}
+            {{ -endif}}  {#- end of finalized_sdk_present#}
             {{ -endfor }}
             {{ -endfor }}
         } catch (Exception e) \{
@@ -120,7 +120,7 @@
 {{ for flag in flag_elements }}
 {{ -if flag.is_read_write }}
     private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }}
+{{ -endif }}  {#- end of is_read_write#}
 {{ -endfor }}
 {{ for namespace_with_flags in namespace_flags }}
     private void load_overrides_{namespace_with_flags.namespace}() \{
@@ -131,7 +131,7 @@
 {{ -if flag.is_read_write }}
             {flag.method_name} =
                 properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }}
+{{ -endif }}  {#- end of is_read_write#}
 {{ -endfor }}
         } catch (NullPointerException e) \{
             throw new RuntimeException(
@@ -166,13 +166,13 @@
 {{ if not library_exported- }}
 // TODO(b/303773055): Remove the annotation after access issue is resolved.
 import android.compat.annotation.UnsupportedAppUsage;
-{{ -endif }}
+{{ -endif }} {#- end of not library_exported#}
 
 {{ -if runtime_lookup_required }}
 import android.os.Binder;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfig.Properties;
-{{ -endif }}
+{{ -endif }}  {#- end of runtime_lookup_required#}
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
 {{ -if runtime_lookup_required }}
@@ -183,7 +183,7 @@
 {{ for flag in flag_elements }}
 {{- if flag.is_read_write }}
     private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }}
+{{ -endif }} {#- end of is_read_write#}
 {{ -endfor }}
 {{ for namespace_with_flags in namespace_flags }}
     private void load_overrides_{namespace_with_flags.namespace}() \{
@@ -194,7 +194,7 @@
 {{ -if flag.is_read_write }}
             {flag.method_name} =
                 properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }}
+{{ -endif }} {#- end of is_read_write#}
 {{ -endfor }}
         } catch (NullPointerException e) \{
             throw new RuntimeException(
@@ -217,16 +217,16 @@
 {{ -if not library_exported }}
     @com.android.aconfig.annotations.AconfigFlagAccessor
     @UnsupportedAppUsage
-{{ -endif }}
+{{ -endif }}{#- end of not library_exported #}
     public boolean {flag.method_name}() \{
 {{ -if flag.is_read_write }}
         if (!{flag.device_config_namespace}_is_cached) \{
             load_overrides_{flag.device_config_namespace}();
         }
         return {flag.method_name};
-{{ -else }}
+{{ -else }} {#- else is_read_write #}
         return {flag.default_value};
-{{ -endif }}
+{{ -endif }}{#- end of is_read_write #}
     }
 {{ endfor }}
 }
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template
new file mode 100644
index 0000000..9492a83
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.new_storage.java.template
@@ -0,0 +1,63 @@
+package {package_name}; {#- CODEGEN FOR INTERNAL MODE FOR NEW STORAGE #}
+// TODO(b/303773055): Remove the annotation after access issue is resolved.
+import android.compat.annotation.UnsupportedAppUsage;
+{{ -if runtime_lookup_required }}
+import android.os.Build;
+{{ if is_platform_container }}
+import android.os.flagging.PlatformAconfigPackageInternal;
+{{ -else }} {#- else is_platform_container #}
+import android.os.flagging.AconfigPackageInternal;
+{{ -endif }} {#- end of is_platform_container#}
+import android.util.Log;
+{{ -endif }} {#- end of runtime_lookup_required#}
+/** @hide */
+public final class FeatureFlagsImpl implements FeatureFlags \{
+{{ -if runtime_lookup_required }}
+    private static final String TAG = "FeatureFlagsImpl";
+    private static volatile boolean isCached = false;
+{{ for flag in flag_elements }}
+{{ -if flag.is_read_write }}
+    private static boolean {flag.method_name} = {flag.default_value};
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }} {#- else flag_elements #}
+
+    private void init() \{
+        try \{
+{{ if is_platform_container }}
+            PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{package_name}", {package_fingerprint});
+{{ -else }} {#- else is_platform_container #}
+            AconfigPackageInternal reader = AconfigPackageInternal.load("{package_name}", {package_fingerprint});
+{{ -endif }} {#- end of is_platform_container#}
+        {{ -for namespace_with_flags in namespace_flags }}
+        {{ -for flag in namespace_with_flags.flags }}
+        {{ -if flag.is_read_write }}
+            {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
+        {{ -endif }} {#- is_read_write#}
+        {{ -endfor }} {#- else namespace_with_flags.flags #}
+        {{ -endfor }}  {#- else namespace_flags #}
+        } catch (Exception e) \{
+            Log.e(TAG, e.toString());
+        } catch (LinkageError e) \{
+            // for mainline module running on older devices.
+            // This should be replaces to version check, after the version bump.
+            Log.e(TAG, e.toString());
+        }
+        isCached = true;
+    }
+{{ -endif }}{#- end of runtime_lookup_required #}
+{{ -for flag in flag_elements }}
+    @Override
+    @com.android.aconfig.annotations.AconfigFlagAccessor
+    @UnsupportedAppUsage
+    public boolean {flag.method_name}() \{
+{{ -if flag.is_read_write }}
+        if (!isCached) \{
+            init();
+        }
+        return {flag.method_name};
+{{ -else }}{#- else is_read_write #}
+        return {flag.default_value};
+{{ -endif }}  {#- end of is_read_write#}
+    }
+{{ endfor }} {#- else flag_elements #}
+}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.test_mode.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.test_mode.java.template
new file mode 100644
index 0000000..8eda263
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.test_mode.java.template
@@ -0,0 +1,14 @@
+package {package_name}; {#- CODEGEN FOR TEST MODE #}
+/** @hide */
+public final class FeatureFlagsImpl implements FeatureFlags \{
+{{ for flag in flag_elements }}
+    @Override
+{{ -if not library_exported }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
+{{ -endif }}
+    public boolean {flag.method_name}() \{
+        throw new UnsupportedOperationException(
+            "Method is not implemented.");
+    }
+{{ endfor- }}
+}
diff --git a/tools/aconfig/aconfig_protos/src/lib.rs b/tools/aconfig/aconfig_protos/src/lib.rs
index 81bbd7e..64b82d6 100644
--- a/tools/aconfig/aconfig_protos/src/lib.rs
+++ b/tools/aconfig/aconfig_protos/src/lib.rs
@@ -1073,4 +1073,63 @@
         // two identical flags with dedup enabled
         assert_eq!(first, parsed_flags::merge(vec![first.clone(), first.clone()], true).unwrap());
     }
+
+    #[test]
+    fn test_is_valid_name_ident() {
+        assert!(is_valid_name_ident("foo"));
+        assert!(is_valid_name_ident("foo_bar_123"));
+        assert!(is_valid_name_ident("foo_"));
+
+        assert!(!is_valid_name_ident(""));
+        assert!(!is_valid_name_ident("123_foo"));
+        assert!(!is_valid_name_ident("foo-bar"));
+        assert!(!is_valid_name_ident("foo-b\u{00e5}r"));
+        assert!(!is_valid_name_ident("foo__bar"));
+        assert!(!is_valid_name_ident("_foo"));
+    }
+
+    #[test]
+    fn test_is_valid_package_ident() {
+        assert!(is_valid_package_ident("foo.bar"));
+        assert!(is_valid_package_ident("foo.bar_baz"));
+        assert!(is_valid_package_ident("foo.bar.a123"));
+
+        assert!(!is_valid_package_ident("foo_bar_123"));
+        assert!(!is_valid_package_ident("foo"));
+        assert!(!is_valid_package_ident("foo._bar"));
+        assert!(!is_valid_package_ident(""));
+        assert!(!is_valid_package_ident("123_foo"));
+        assert!(!is_valid_package_ident("foo-bar"));
+        assert!(!is_valid_package_ident("foo-b\u{00e5}r"));
+        assert!(!is_valid_package_ident("foo.bar.123"));
+        assert!(!is_valid_package_ident(".foo.bar"));
+        assert!(!is_valid_package_ident("foo.bar."));
+        assert!(!is_valid_package_ident("."));
+        assert!(!is_valid_package_ident(".."));
+        assert!(!is_valid_package_ident("foo..bar"));
+        assert!(!is_valid_package_ident("foo.__bar"));
+    }
+
+    #[test]
+    fn test_is_valid_container_ident() {
+        assert!(is_valid_container_ident("foo.bar"));
+        assert!(is_valid_container_ident("foo.bar_baz"));
+        assert!(is_valid_container_ident("foo.bar.a123"));
+        assert!(is_valid_container_ident("foo"));
+        assert!(is_valid_container_ident("foo_bar_123"));
+
+        assert!(!is_valid_container_ident(""));
+        assert!(!is_valid_container_ident("foo._bar"));
+        assert!(!is_valid_container_ident("_foo"));
+        assert!(!is_valid_container_ident("123_foo"));
+        assert!(!is_valid_container_ident("foo-bar"));
+        assert!(!is_valid_container_ident("foo-b\u{00e5}r"));
+        assert!(!is_valid_container_ident("foo.bar.123"));
+        assert!(!is_valid_container_ident(".foo.bar"));
+        assert!(!is_valid_container_ident("foo.bar."));
+        assert!(!is_valid_container_ident("."));
+        assert!(!is_valid_container_ident(".."));
+        assert!(!is_valid_container_ident("foo..bar"));
+        assert!(!is_valid_container_ident("foo.__bar"));
+    }
 }
diff --git a/tools/ide_query/prober_scripts/cpp/general.cc b/tools/ide_query/prober_scripts/cpp/general.cc
index 0f0639b..ac88282 100644
--- a/tools/ide_query/prober_scripts/cpp/general.cc
+++ b/tools/ide_query/prober_scripts/cpp/general.cc
@@ -56,7 +56,7 @@
 
 void TestNavigation() {
   std::vector<int> ints;
-  //               |   | ints
+  //               ^   ^ ints
   //      ^
 
   // step
diff --git a/tools/ide_query/prober_scripts/jvm/Foo.java b/tools/ide_query/prober_scripts/jvm/Foo.java
index 9397bc4..2c8ceb6 100644
--- a/tools/ide_query/prober_scripts/jvm/Foo.java
+++ b/tools/ide_query/prober_scripts/jvm/Foo.java
@@ -20,7 +20,7 @@
 
 /** Foo class. */
 public final class Foo {
-//               |  | foo_def
+//               ^  ^ foo_def
 
   void testParameterInfo() {
     // Test signature help for type parameters.
diff --git a/tools/sbom/compliance_metadata.py b/tools/sbom/compliance_metadata.py
index 9910217..aba61a8 100644
--- a/tools/sbom/compliance_metadata.py
+++ b/tools/sbom/compliance_metadata.py
@@ -94,7 +94,7 @@
     cursor.close()
     rows = []
     for m in multi_built_file_modules:
-      built_files = m['installed_file'].strip().split(' ')
+      built_files = m['built_file'].strip().split(' ')
       for f in built_files:
         rows.append((m['module_id'], m['module_name'], m['package'], f))
     self.conn.executemany('insert into module_built_file values (?, ?, ?, ?)', rows)
diff --git a/tools/sbom/gen_sbom.py b/tools/sbom/gen_sbom.py
index 756d9db..77bccbb 100644
--- a/tools/sbom/gen_sbom.py
+++ b/tools/sbom/gen_sbom.py
@@ -92,6 +92,7 @@
     'SVN',
     'Hg',
     'Darcs',
+    'Piper',
     'VCS',
     'Archive',
     'PrebuiltByAlphabet',
@@ -708,7 +709,10 @@
         'installed_file': dep_file,
         'is_prebuilt_make_module': False
     }
-    file_metadata.update(db.get_soong_module_of_built_file(dep_file))
+    soong_module = db.get_soong_module_of_built_file(dep_file)
+    if not soong_module:
+      continue
+    file_metadata.update(soong_module)
     if is_source_package(file_metadata) or is_prebuilt_package(file_metadata):
       add_package_of_file(file_id, file_metadata, doc, report)
     else: