Merge "Convert the otatools.zip to soong for jars, cert files and releasetools" into main
diff --git a/common/math.mk b/common/math.mk
index 829ceb5..0444631 100644
--- a/common/math.mk
+++ b/common/math.mk
@@ -89,6 +89,11 @@
 $(strip $(if $(call math_is_number_in_100,$(1)),true,$(call _math_ext_is_number,$(1))))
 endef
 
+# Returns true if $(1) is a positive or negative integer.
+define math_is_int
+$(call math_is_number,$(patsubst -%,%,$(1)))
+endef
+
 define math_is_zero
 $(strip \
   $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
@@ -100,6 +105,12 @@
 $(call math-expect-true,(call math_is_number,202412))
 $(call math-expect-false,(call math_is_number,foo))
 $(call math-expect-false,(call math_is_number,-1))
+$(call math-expect-true,(call math_is_int,50))
+$(call math-expect-true,(call math_is_int,-1))
+$(call math-expect-true,(call math_is_int,-528))
+$(call math-expect-true,(call math_is_int,-0))
+$(call math-expect-false,(call math_is_int,--1))
+$(call math-expect-false,(call math_is_int,-))
 $(call math-expect-error,(call math_is_number,1 2),Multiple words in a single argument: 1 2)
 $(call math-expect-error,(call math_is_number,no 2),Multiple words in a single argument: no 2)
 
diff --git a/core/Makefile b/core/Makefile
index 9db50a3..f80ee8a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -6119,6 +6119,7 @@
 ifneq ($(BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST),)
 	$(hide) echo "partial_ota_update_partitions_list=$(BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST)" >> $@
 endif
+	$(hide) sort -o $@ $@
 
 $(call declare-0p-target,$(INSTALLED_FASTBOOT_INFO_TARGET))
 
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index b2c4fb5..1a40ccc 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -176,6 +176,7 @@
 else ifneq (platform:services,$(lastword $(PRODUCT_SYSTEM_SERVER_JARS)))
   # If services is not the final jar in the dependency ordering, don't assume
   # it can be safely optimized in isolation, as there may be dependent jars.
+  # TODO(b/212737576): Remove this exception after integrating use of `$(system_server_trace_refs)`.
   SYSTEM_OPTIMIZE_JAVA ?= false
 else
   SYSTEM_OPTIMIZE_JAVA ?= true
@@ -188,6 +189,20 @@
 $(call add_soong_config_var,ANDROID,SYSTEM_OPTIMIZE_JAVA)
 $(call add_soong_config_var,ANDROID,FULL_SYSTEM_OPTIMIZE_JAVA)
 
+ifeq (true, $(SYSTEM_OPTIMIZE_JAVA))
+  # Create a list of (non-prefixed) system server jars that follow `services` in
+  # the classpath. This can be used when optimizing `services` to trace any
+  # downstream references that need keeping.
+  # Example: "foo:service1 platform:services bar:services2" -> "services2"
+  system_server_jars_dependent_on_services := $(shell \
+      echo "$(PRODUCT_SYSTEM_SERVER_JARS)" | \
+      awk '{found=0; for(i=1;i<=NF;i++){if($$i=="platform:services"){found=1; continue} if(found){split($$i,a,":"); print a[2]}}}' | \
+      xargs)
+  ifneq ($(strip $(system_server_jars_dependent_on_services)),)
+    $(call soong_config_set_string_list,ANDROID,system_server_trace_refs,$(system_server_jars_dependent_on_services))
+  endif
+endif
+
 # TODO(b/319697968): Remove this build flag support when metalava fully supports flagged api
 $(call soong_config_set,ANDROID,release_hidden_api_exportable_stubs,$(RELEASE_HIDDEN_API_EXPORTABLE_STUBS))
 
diff --git a/core/config.mk b/core/config.mk
index fafdfe1..38f3f5b 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -330,6 +330,19 @@
 $(eval SOONG_CONFIG_TYPE_$(strip $1)_$(strip $2):=bool)
 endef
 
+# soong_config_set_int is the same as soong_config_set, but it will
+# also type the variable as an integer, so that when using select() expressions
+# in blueprint files they can use integer values instead of strings.
+# It will error out if a non-integer is supplied
+# $1 is the namespace. $2 is the variable name. $3 is the variable value.
+# Ex: $(call soong_config_set_bool,acme,COOL_FEATURE,34)
+define soong_config_set_int
+$(call soong_config_define_internal,$1,$2) \
+$(if $(call math_is_int,$3),,$(error soong_config_set_int called with non-integer value $(3)))
+$(eval SOONG_CONFIG_$(strip $1)_$(strip $2):=$(strip $3))
+$(eval SOONG_CONFIG_TYPE_$(strip $1)_$(strip $2):=int)
+endef
+
 # soong_config_set_string_list is the same as soong_config_set, but it will
 # also type the variable as a list of strings, so that when using select() expressions
 # in blueprint files they can use list values instead of strings.
diff --git a/core/layoutlib_data.mk b/core/layoutlib_data.mk
index f228ef6..5dde50f 100644
--- a/core/layoutlib_data.mk
+++ b/core/layoutlib_data.mk
@@ -77,15 +77,23 @@
 LAYOUTLIB_RES := $(call intermediates-dir-for,PACKAGING,layoutlib-res,HOST,COMMON)
 LAYOUTLIB_RES_FILES := $(shell find frameworks/base/core/res/res -type f -not -path 'frameworks/base/core/res/res/values-m[nc]c*' | sort)
 EMULATED_OVERLAYS_FILES := $(shell find frameworks/base/packages/overlays/*/res/ | sort)
-DEVICE_OVERLAYS_FILES := $(shell find device/generic/goldfish/phone/overlay/frameworks/base/packages/overlays/*/AndroidOverlay/res/ | sort)
-$(LAYOUTLIB_RES)/layoutlib-res.zip: $(SOONG_ZIP) $(HOST_OUT_EXECUTABLES)/aapt2 $(LAYOUTLIB_RES_FILES) $(EMULATED_OVERLAYS_FILES) $(DEVICE_OVERLAYS_FILES)
+LAYOUTLIB_SUPPORTED_DEVICES := raviole/oriole raviole/raven bluejay/bluejay pantah/panther pantah/cheetah lynx/lynx felix/felix shusky/shiba shusky/husky akita/akita caimito/tokay caimito/caiman caimito/komodo comet/comet tangorpro/tangorpro
+LAYOUTLIB_DEVICE_OVERLAYS_FILES := $(addsuffix /overlay/frameworks/base/core/res/res/values/*, $(addprefix device/google/, $(LAYOUTLIB_SUPPORTED_DEVICES)))
+LAYOUTLIB_DEVICE_OVERLAYS_FILES := $(shell find $(LAYOUTLIB_DEVICE_OVERLAYS_FILES) | sort)
+$(LAYOUTLIB_RES)/layoutlib-res.zip: $(SOONG_ZIP) $(HOST_OUT_EXECUTABLES)/aapt2 $(LAYOUTLIB_RES_FILES) $(EMULATED_OVERLAYS_FILES) $(LAYOUTLIB_DEVICE_OVERLAYS_FILES) frameworks/layoutlib/overlay_codenames.txt
 	rm -rf $@
 	echo $(LAYOUTLIB_RES_FILES) > $(LAYOUTLIB_RES)/filelist_res.txt
 	$(SOONG_ZIP) -C frameworks/base/core/res -l $(LAYOUTLIB_RES)/filelist_res.txt -o $(LAYOUTLIB_RES)/temp_res.zip
 	echo $(EMULATED_OVERLAYS_FILES) > $(LAYOUTLIB_RES)/filelist_emulated_overlays.txt
 	$(SOONG_ZIP) -C frameworks/base/packages -l $(LAYOUTLIB_RES)/filelist_emulated_overlays.txt -o $(LAYOUTLIB_RES)/temp_emulated_overlays.zip
-	echo $(DEVICE_OVERLAYS_FILES) > $(LAYOUTLIB_RES)/filelist_device_overlays.txt
-	$(SOONG_ZIP) -C device/generic/goldfish/phone/overlay/frameworks/base/packages -l $(LAYOUTLIB_RES)/filelist_device_overlays.txt -o $(LAYOUTLIB_RES)/temp_device_overlays.zip
+	for line in $$(cut -f 1 frameworks/layoutlib/overlay_codenames.txt); \
+	  do splitLine=($${line//:/ }) \
+	  origin_dir=device/google/*/$${splitLine[0]}/overlay/frameworks/base/core/res/res/values; \
+	  target_dir=$(LAYOUTLIB_RES)/overlays/$${splitLine[1]}/res/; \
+	  mkdir -p $$target_dir; \
+	  cp -r $$origin_dir $$target_dir; \
+	done
+	$(SOONG_ZIP) -C $(LAYOUTLIB_RES) -D $(LAYOUTLIB_RES)/overlays/ -o $(LAYOUTLIB_RES)/temp_device_overlays.zip
 	rm -rf $(LAYOUTLIB_RES)/data && unzip -q -d $(LAYOUTLIB_RES)/data $(LAYOUTLIB_RES)/temp_res.zip
 	unzip -q -d $(LAYOUTLIB_RES)/data $(LAYOUTLIB_RES)/temp_emulated_overlays.zip
 	unzip -q -d $(LAYOUTLIB_RES)/data $(LAYOUTLIB_RES)/temp_device_overlays.zip
@@ -163,14 +171,18 @@
 	  echo $(_path),,,,,,Y,$f,,, >> $@; \
 	)
 
-	$(foreach f,$(DEVICE_OVERLAYS_FILES), \
-	  $(eval _path := $(subst device/generic/goldfish/phone/overlay/frameworks/base/packages,data,$f)) \
-	  echo $(_path),,,,,,Y,$f,,, >> $@; \
-	)
+	for line in $$(cut -f 1 frameworks/layoutlib/overlay_codenames.txt); do \
+	  splitLine=($${line//:/ }); \
+	  for f in $(LAYOUTLIB_DEVICE_OVERLAYS_FILES); do \
+	    if [[ $$f == */$${splitLine[0]}/* ]]; then \
+	      echo data/overlays/$${splitLine[1]}/res/values/$$(basename $$f),,,,,,Y,$$f,,, >> $@; \
+	    fi \
+	  done \
+	done
 
 .PHONY: layoutlib-sbom
 layoutlib-sbom: $(LAYOUTLIB_SBOM)/layoutlib.spdx.json
-$(LAYOUTLIB_SBOM)/layoutlib.spdx.json: $(PRODUCT_OUT)/always_dirty_file.txt $(GEN_SBOM) $(LAYOUTLIB_SBOM)/sbom-metadata.csv $(_layoutlib_font_config_files) $(_layoutlib_fonts_files) $(LAYOUTLIB_BUILD_PROP)/layoutlib-build.prop $(_layoutlib_keyboard_files) $(_layoutlib_hyphen_files) $(LAYOUTLIB_RES_FILES) $(EMULATED_OVERLAYS_FILES) $(DEVICE_OVERLAYS_FILES)
+$(LAYOUTLIB_SBOM)/layoutlib.spdx.json: $(PRODUCT_OUT)/always_dirty_file.txt $(GEN_SBOM) $(LAYOUTLIB_SBOM)/sbom-metadata.csv $(_layoutlib_font_config_files) $(_layoutlib_fonts_files) $(LAYOUTLIB_BUILD_PROP)/layoutlib-build.prop $(_layoutlib_keyboard_files) $(_layoutlib_hyphen_files) $(LAYOUTLIB_RES_FILES) $(EMULATED_OVERLAYS_FILES) $(LAYOUTLIB_DEVICE_OVERLAYS_FILES) frameworks/layoutlib/overlay_codenames.txt
 	rm -rf $@
 	$(GEN_SBOM) --output_file $@ --metadata $(LAYOUTLIB_SBOM)/sbom-metadata.csv --build_version $(BUILD_FINGERPRINT_FROM_FILE) --product_mfr "$(PRODUCT_MANUFACTURER)" --module_name "layoutlib" --json
 
diff --git a/core/tasks/device-tests.mk b/core/tasks/device-tests.mk
index 062ac23..209bd3e 100644
--- a/core/tasks/device-tests.mk
+++ b/core/tasks/device-tests.mk
@@ -14,6 +14,7 @@
 
 
 .PHONY: device-tests
+.PHONY: device-tests-files-list
 
 device-tests-zip := $(PRODUCT_OUT)/device-tests.zip
 # Create an artifact to include a list of test config files in device-tests.
@@ -21,6 +22,7 @@
 # Create an artifact to include all test config files in device-tests.
 device-tests-configs-zip := $(PRODUCT_OUT)/device-tests_configs.zip
 my_host_shared_lib_for_device_tests := $(call copy-many-files,$(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES))
+device_tests_files_list := $(PRODUCT_OUT)/device-tests_files
 
 $(device-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-tests-list-zip) $(device-tests-configs-zip)
 $(device-tests-zip) : PRIVATE_device_tests_list := $(PRODUCT_OUT)/device-tests_list
@@ -45,7 +47,14 @@
 	rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
 		$(PRIVATE_device_tests_list)
 
+$(device_tests_files_list) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_device_tests)
+$(device_tests_files_list) :
+	echo $(sort $(COMPATIBILITY.device-tests.FILES) $(COMPATIBILITY.device-tests.SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES)) | tr " " "\n" > $@.full_list
+	grep $(HOST_OUT_TESTCASES) $@.full_list > $@ || true
+	grep $(TARGET_OUT_TESTCASES) $@.full_list >> $@ || true
+
 device-tests: $(device-tests-zip)
+device-tests-files-list: $(device_tests_files_list)
 
 $(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip))
 
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
index dcfcfad..44476cb 100644
--- a/core/tasks/general-tests.mk
+++ b/core/tasks/general-tests.mk
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 .PHONY: general-tests
+.PHONY: general-tests-files-list
 
 general_tests_tools := \
     $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar \
@@ -63,6 +64,10 @@
         $(eval _cmf_dest := $(word 3,$(_cmf_tuple))) \
         $(_cmf_dest)))
 
+general_tests_files_list := $(PRODUCT_OUT)/general-tests_files
+general_tests_host_files_list := $(PRODUCT_OUT)/general-tests_host_files
+general_tests_target_files_list := $(PRODUCT_OUT)/general-tests_target_files
+
 $(general_tests_zip) : PRIVATE_general_tests_list_zip := $(general_tests_list_zip)
 $(general_tests_zip) : .KATI_IMPLICIT_OUTPUTS := $(general_tests_list_zip) $(general_tests_configs_zip)
 $(general_tests_zip) : PRIVATE_TOOLS := $(general_tests_tools)
@@ -100,7 +105,16 @@
 	grep -e .*\\.config$$ $(PRIVATE_INTERMEDIATES_DIR)/target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
 	$(SOONG_ZIP) -d -o $(PRIVATE_general_tests_list_zip) -C $(PRIVATE_INTERMEDIATES_DIR) -f $(PRIVATE_INTERMEDIATES_DIR)/general-tests_list
 
+$(general_tests_files_list) : PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
+$(general_tests_files_list) : PRIVATE_general_tests_host_files_list := $(general_tests_host_files_list)
+$(general_tests_files_list) : PRIVATE_general_tests_target_files_list := $(general_tests_target_files_list)
+$(general_tests_files_list) :
+	echo $(sort $(COMPATIBILITY.general-tests.FILES) $(COMPATIBILITY.device-tests.SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES)) | tr " " "\n" > $@
+	grep $(HOST_OUT_TESTCASES) $@ > $(PRIVATE_general_tests_host_files_list) || true
+	grep $(TARGET_OUT_TESTCASES) $@ >> $(PRIVATE_general_tests_target_files_list) || true
+
 general-tests: $(general_tests_zip)
+general-tests-files-list: $(general_tests_files_list)
 $(call dist-for-goals, general-tests, $(general_tests_zip) $(general_tests_list_zip) $(general_tests_configs_zip) $(general_tests_shared_libs_zip))
 
 $(call declare-1p-container,$(general_tests_zip),)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 3fe97ba..ab4abac 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -395,10 +395,6 @@
     system_manifest.xml \
     system_compatibility_matrix.xml \
 
-# Base modules when shipping api level is less than or equal to 34
-PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
-    android.hidl.memory@1.0-impl \
-
 # hwservicemanager is now installed on system_ext, but apexes might be using
 # old libraries that are expecting it to be installed on system. This allows
 # those apexes to continue working. The symlink can be removed once we are sure
diff --git a/target/product/base_system_ext.mk b/target/product/base_system_ext.mk
index 6767b9a..ad6828a 100644
--- a/target/product/base_system_ext.mk
+++ b/target/product/base_system_ext.mk
@@ -30,6 +30,7 @@
 PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
     hwservicemanager \
     android.hidl.allocator@1.0-service \
+    android.hidl.memory@1.0-impl \
 
 # AppFunction Extensions
 ifneq (,$(RELEASE_APPFUNCTION_SIDECAR))
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index c90c61c..0a32a55 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -124,6 +124,14 @@
         target: "/data/cache",
         name: "cache",
     },
+    {
+        target: "/odm/odm_dlkm/etc",
+        name: "odm_dlkm/etc",
+    },
+    {
+        target: "/vendor/vendor_dlkm/etc",
+        name: "vendor_dlkm/etc",
+    },
 ]
 
 extra_vendor_symlinks = [
@@ -382,6 +390,11 @@
         "android.hidl.allocator@1.0-service",
 
         ///////////////////////////////////////////
+        // media_system_ext
+        ///////////////////////////////////////////
+        "StatementService",
+
+        ///////////////////////////////////////////
         // window_extensions_base
         ///////////////////////////////////////////
         "androidx.window.extensions",
@@ -809,7 +822,6 @@
                 "Shell", // base_system
                 "SimAppDialog", // handheld_system
                 "SoundPicker", // not installed by anyone
-                "StatementService", // media_system
                 "Stk", // generic_system
                 "Tag", // generic_system
                 "TeleService", // handheld_system
diff --git a/target/product/media_system.mk b/target/product/media_system.mk
index af3857e..4df7151 100644
--- a/target/product/media_system.mk
+++ b/target/product/media_system.mk
@@ -35,7 +35,6 @@
     libwebviewchromium_plat_support \
     make_f2fs \
     requestsync \
-    StatementService \
 
 PRODUCT_HOST_PACKAGES += \
     fsck.f2fs \
diff --git a/target/product/media_system_ext.mk b/target/product/media_system_ext.mk
index e79a7eb..455a253 100644
--- a/target/product/media_system_ext.mk
+++ b/target/product/media_system_ext.mk
@@ -20,5 +20,8 @@
 # base_system_ext.mk.
 $(call inherit-product, $(SRC_TARGET_DIR)/product/base_system_ext.mk)
 
+PRODUCT_PACKAGES += \
+    StatementService \
+
 # Window Extensions
 $(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions_base.mk)
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
index 63baf9e..3dd24b2 100644
--- a/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/os/flagging/PlatformAconfigPackage.java
@@ -120,11 +120,11 @@
             return aconfigPackage;
         } catch (AconfigStorageException e) {
             throw new AconfigStorageReadException(
-                    e.getErrorCode(), "Fail to create AconfigPackage", e);
+                    e.getErrorCode(), "Fail to create PlatformAconfigPackage: " + packageName, e);
         } catch (Exception e) {
             throw new AconfigStorageReadException(
                     AconfigStorageReadException.ERROR_GENERIC,
-                    "Fail to create PlatformAconfigPackage",
+                    "Fail to create PlatformAconfigPackage: " + packageName,
                     e);
         }
     }
diff --git a/tools/aconfig/convert_finalized_flags/Android.bp b/tools/aconfig/convert_finalized_flags/Android.bp
index 5b39560..9ace805 100644
--- a/tools/aconfig/convert_finalized_flags/Android.bp
+++ b/tools/aconfig/convert_finalized_flags/Android.bp
@@ -50,7 +50,11 @@
     srcs: [
         "//prebuilts/sdk:finalized-api-flags",
     ],
+    tool_files: ["extended_flags_list_35.txt"],
     out: ["finalized_flags_record.json"],
     tools: ["convert_finalized_flags"],
-    cmd: "args=\"\" && for f in $(locations //prebuilts/sdk:finalized-api-flags); do args=\"$$args --flag_file_path $$f\"; done && $(location convert_finalized_flags) $$args > $(out)",
+    cmd: "args=\"\" && " +
+        "for f in $(locations //prebuilts/sdk:finalized-api-flags); " +
+        " do args=\"$$args --flag_file_path $$f\"; done && " +
+        "$(location convert_finalized_flags) $$args  --extended-flag-file-path $(location extended_flags_list_35.txt) > $(out)",
 }
diff --git a/tools/aconfig/convert_finalized_flags/extended_flags_list_35.txt b/tools/aconfig/convert_finalized_flags/extended_flags_list_35.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/aconfig/convert_finalized_flags/extended_flags_list_35.txt
diff --git a/tools/aconfig/convert_finalized_flags/src/lib.rs b/tools/aconfig/convert_finalized_flags/src/lib.rs
index 10faa39..d79c509 100644
--- a/tools/aconfig/convert_finalized_flags/src/lib.rs
+++ b/tools/aconfig/convert_finalized_flags/src/lib.rs
@@ -39,6 +39,9 @@
 #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
 pub struct ApiLevel(pub i32);
 
+/// API level of the extended flags file of version 35
+pub const EXTENDED_FLAGS_35_APILEVEL: ApiLevel = ApiLevel(35);
+
 /// Contains all flags finalized for a given API level.
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
 pub struct FinalizedFlagMap(HashMap<ApiLevel, HashSet<FinalizedFlag>>);
@@ -78,6 +81,8 @@
     }
 }
 
+const EXTENDED_FLAGS_LIST_35: &str = "extended_flags_list_35.txt";
+
 /// Converts a string to an int. Will parse to int even if the string is "X.0".
 /// Returns error for "X.1".
 fn str_to_api_level(numeric_string: &str) -> Result<ApiLevel> {
@@ -117,30 +122,49 @@
             continue;
         };
 
-        let file = fs::File::open(flag_file)?;
-        let reader = io::BufReader::new(file);
+        let file = fs::File::open(&flag_file)?;
 
-        for qualified_flag_name in reader.lines() {
-            // Split the qualified flag name into package and flag name:
-            // com.my.package.name.my_flag_name -> ['com.my.package.name', 'my_flag_name'].
-            let mut flag: Vec<String> =
-                qualified_flag_name?.rsplitn(2, '.').map(|s| s.to_string()).collect();
-
-            if flag.len() != 2 {
-                continue;
-            }
-
-            let package_name = flag.pop().ok_or(anyhow!("Missing flag package."))?;
-            let flag_name = flag.pop().ok_or(anyhow!("Missing flag name."))?;
-
-            // Only add the flag if it wasn't added in a prior file.
-            data_map.insert_if_new(api_level, FinalizedFlag { flag_name, package_name });
-        }
+        io::BufReader::new(file).lines().for_each(|flag| {
+            let flag =
+                flag.unwrap_or_else(|_| panic!("Failed to read line from file {}", flag_file));
+            let finalized_flag = build_finalized_flag(&flag)
+                .unwrap_or_else(|_| panic!("cannot build finalized flag {}", flag));
+            data_map.insert_if_new(api_level, finalized_flag);
+        });
     }
 
     Ok(data_map)
 }
 
+/// Read the qualified flag names into a FinalizedFlag set
+pub fn read_extend_file_to_map_using_path(extened_file: String) -> Result<HashSet<FinalizedFlag>> {
+    let (_, file_name) =
+        extened_file.rsplit_once('/').ok_or(anyhow!("Invalid file: '{}'", extened_file))?;
+    if file_name != EXTENDED_FLAGS_LIST_35 {
+        return Err(anyhow!("Provided incorrect file, must be {}", EXTENDED_FLAGS_LIST_35));
+    }
+    let file = fs::File::open(extened_file)?;
+    let extended_flags = io::BufReader::new(file)
+        .lines()
+        .map(|flag| {
+            let flag = flag.expect("Failed to read line from extended file");
+            build_finalized_flag(&flag)
+                .unwrap_or_else(|_| panic!("cannot build finalized flag {}", flag))
+        })
+        .collect::<HashSet<FinalizedFlag>>();
+    Ok(extended_flags)
+}
+
+fn build_finalized_flag(qualified_flag_name: &String) -> Result<FinalizedFlag> {
+    // Split the qualified flag name into package and flag name:
+    // com.my.package.name.my_flag_name -> ('com.my.package.name', 'my_flag_name')
+    let (package_name, flag_name) = qualified_flag_name
+        .rsplit_once('.')
+        .ok_or(anyhow!("Invalid qualified flag name format: '{}'", qualified_flag_name))?;
+
+    Ok(FinalizedFlag { flag_name: flag_name.to_string(), package_name: package_name.to_string() })
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -392,4 +416,49 @@
         assert_eq!(map.get_finalized_level(&flags[0]).unwrap(), l35);
         assert_eq!(map.get_finalized_level(&flags[1]).unwrap(), l36);
     }
+
+    #[test]
+    fn test_read_flag_from_extended_file() {
+        let flags = create_test_flags();
+
+        // Create the file <temp_dir>/35/extended_flags_list_35.txt
+        let temp_dir = tempdir().unwrap();
+        let mut file_path = temp_dir.path().to_path_buf();
+        file_path.push("35");
+        fs::create_dir_all(&file_path).unwrap();
+        file_path.push(EXTENDED_FLAGS_LIST_35);
+        let mut file = File::create(&file_path).unwrap();
+
+        // Write all flags to the file.
+        add_flags_to_file(&mut file, &[flags[0].clone(), flags[1].clone()]);
+
+        let flags_set =
+            read_extend_file_to_map_using_path(file_path.to_string_lossy().to_string()).unwrap();
+        assert_eq!(flags_set.len(), 2);
+        assert!(flags_set.contains(&flags[0]));
+        assert!(flags_set.contains(&flags[1]));
+    }
+
+    #[test]
+    fn test_read_flag_from_wrong_extended_file_err() {
+        let flags = create_test_flags();
+
+        // Create the file <temp_dir>/35/extended_flags_list.txt
+        let temp_dir = tempdir().unwrap();
+        let mut file_path = temp_dir.path().to_path_buf();
+        file_path.push("35");
+        fs::create_dir_all(&file_path).unwrap();
+        file_path.push("extended_flags_list.txt");
+        let mut file = File::create(&file_path).unwrap();
+
+        // Write all flags to the file.
+        add_flags_to_file(&mut file, &[flags[0].clone(), flags[1].clone()]);
+
+        let err = read_extend_file_to_map_using_path(file_path.to_string_lossy().to_string())
+            .unwrap_err();
+        assert_eq!(
+            format!("{:?}", err),
+            "Provided incorrect file, must be extended_flags_list_35.txt"
+        );
+    }
 }
diff --git a/tools/aconfig/convert_finalized_flags/src/main.rs b/tools/aconfig/convert_finalized_flags/src/main.rs
index 38300f6..605e964 100644
--- a/tools/aconfig/convert_finalized_flags/src/main.rs
+++ b/tools/aconfig/convert_finalized_flags/src/main.rs
@@ -23,7 +23,9 @@
 use anyhow::Result;
 use clap::Parser;
 
-use convert_finalized_flags::read_files_to_map_using_path;
+use convert_finalized_flags::{
+    read_extend_file_to_map_using_path, read_files_to_map_using_path, EXTENDED_FLAGS_35_APILEVEL,
+};
 
 const ABOUT_TEXT: &str = "Tool for processing finalized-flags.txt files.
 
@@ -45,11 +47,18 @@
     /// Flags files.
     #[arg(long = "flag_file_path")]
     flag_file_path: Vec<String>,
+
+    #[arg(long)]
+    extended_flag_file_path: String,
 }
 
 fn main() -> Result<()> {
     let cli = Cli::parse();
-    let finalized_flags_map = read_files_to_map_using_path(cli.flag_file_path)?;
+    let mut finalized_flags_map = read_files_to_map_using_path(cli.flag_file_path)?;
+    let extended_flag_set = read_extend_file_to_map_using_path(cli.extended_flag_file_path)?;
+    for flag in extended_flag_set {
+        finalized_flags_map.insert_if_new(EXTENDED_FLAGS_35_APILEVEL, flag);
+    }
 
     let json_str = serde_json::to_string(&finalized_flags_map)?;
     println!("{}", json_str);
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
index d323c20..25cba9c 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -282,7 +282,8 @@
               callable.parameters().joinTo(this, separator = "") { it.type().internalName() }
               append(")")
             }
-            val symbol = Symbol.createMethod(callable.containingClass().qualifiedName(), callableSignature)
+            val symbol =
+                Symbol.createMethod(callable.containingClass().qualifiedName(), callableSignature)
             output.add(Pair(symbol, flag))
           }
         }
@@ -291,7 +292,7 @@
           return item.modifiers
               .findAnnotation("android.annotation.FlaggedApi")
               ?.findAttribute("value")
-              ?.value
+              ?.legacyValue
               ?.let { Flag(it.value() as String) }
         }
       }
@@ -468,8 +469,7 @@
         val classFlagValue =
             flaggedSymbolsInSource
                 .find { it.first.toPrettyString() == symbol.clazz }
-                ?.let { flags.getValue(it.second) }
-                ?: true
+                ?.let { flags.getValue(it.second) } ?: true
         return classFlagValue
       }
     }