Merge "Revert "releasetools: Deprecate GKI build rules"" into main
diff --git a/core/Makefile b/core/Makefile
index b93c321..845f7c8 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2122,6 +2122,7 @@
 $(if $(BOARD_$(_var)IMAGE_EXTFS_INODE_COUNT),$(hide) echo "$(1)_extfs_inode_count=$(BOARD_$(_var)IMAGE_EXTFS_INODE_COUNT)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_EXTFS_RSV_PCT),$(hide) echo "$(1)_extfs_rsv_pct=$(BOARD_$(_var)IMAGE_EXTFS_RSV_PCT)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_F2FS_SLOAD_COMPRESS_FLAGS),$(hide) echo "$(1)_f2fs_sldc_flags=$(BOARD_$(_var)IMAGE_F2FS_SLOAD_COMPRESS_FLAGS)" >> $(2))
+$(if $(BOARD_$(_var)IMAGE_F2FS_BLOCKSIZE),$(hide) echo "$(1)_f2fs_blocksize=$(BOARD_$(_var)IMAGE_F2FS_BLOCKSIZE)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_FILE_SYSTEM_COMPRESS),$(hide) echo "$(1)_f2fs_compress=$(BOARD_$(_var)IMAGE_FILE_SYSTEM_COMPRESS)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_FILE_SYSTEM_TYPE),$(hide) echo "$(1)_fs_type=$(BOARD_$(_var)IMAGE_FILE_SYSTEM_TYPE)" >> $(2))
 $(if $(BOARD_$(_var)IMAGE_JOURNAL_SIZE),$(hide) echo "$(1)_journal_size=$(BOARD_$(_var)IMAGE_JOURNAL_SIZE)" >> $(2))
@@ -2212,6 +2213,7 @@
 $(if $(BOARD_EROFS_SHARE_DUP_BLOCKS),$(hide) echo "erofs_share_dup_blocks=$(BOARD_EROFS_SHARE_DUP_BLOCKS)" >> $(1))
 $(if $(BOARD_EROFS_USE_LEGACY_COMPRESSION),$(hide) echo "erofs_use_legacy_compression=$(BOARD_EROFS_USE_LEGACY_COMPRESSION)" >> $(1))
 $(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
+$(if $(BOARD_F2FS_BLOCKSIZE),$(hide) echo "f2fs_blocksize=$(BOARD_F2FS_BLOCKSIZE)" >> $(1))
 $(if $(BOARD_FLASH_LOGICAL_BLOCK_SIZE), $(hide) echo "flash_logical_block_size=$(BOARD_FLASH_LOGICAL_BLOCK_SIZE)" >> $(1))
 $(if $(BOARD_FLASH_ERASE_BLOCK_SIZE), $(hide) echo "flash_erase_block_size=$(BOARD_FLASH_ERASE_BLOCK_SIZE)" >> $(1))
 $(if $(filter eng, $(TARGET_BUILD_VARIANT)),$(hide) echo "verity_disable=true" >> $(1))
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index e731fa3..c74aa49 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -181,7 +181,13 @@
 else
   SYSTEM_OPTIMIZE_JAVA ?= true
 endif
+
+ifeq (true,$(FULL_SYSTEM_OPTIMIZE_JAVA))
+  SYSTEM_OPTIMIZE_JAVA := true
+endif
+
 $(call add_soong_config_var,ANDROID,SYSTEM_OPTIMIZE_JAVA)
+$(call add_soong_config_var,ANDROID,FULL_SYSTEM_OPTIMIZE_JAVA)
 
 # Check for SupplementalApi module.
 ifeq ($(wildcard packages/modules/SupplementalApi),)
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index b141a98..2671956 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -85,11 +85,6 @@
 my_prebuilt_src_file := $(my_extracted_apk)
 my_extracted_apk :=
 my_extract_apk :=
-ifeq ($(PRODUCT_ALWAYS_PREOPT_EXTRACTED_APK),true)
-# If the product property is set, always preopt for extracted modules to prevent executing out of
-# the APK.
-my_preopt_for_extracted_apk := true
-endif
 endif
 
 rs_compatibility_jni_libs :=
diff --git a/core/config.mk b/core/config.mk
index 40f0818..fbf6764 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -1312,3 +1312,9 @@
 .KATI_READONLY := DEFAULT_DATA_OUT_MODULES
 
 include $(BUILD_SYSTEM)/dumpvar.mk
+
+ifeq (true,$(FULL_SYSTEM_OPTIMIZE_JAVA))
+ifeq (,$(SYSTEM_OPTIMIZE_JAVA))
+$(error SYSTEM_OPTIMIZE_JAVA must be enabled when FULL_SYSTEM_OPTIMIZE_JAVA is enabled)
+endif
+endif
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 0155c67..151591e 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -60,10 +60,8 @@
   LOCAL_DEX_PREOPT :=
 endif
 
-ifneq (true,$(my_preopt_for_extracted_apk))
-  ifeq (true,$(WITH_DEXPREOPT_ART_BOOT_IMG_ONLY))
-    LOCAL_DEX_PREOPT :=
-  endif
+ifeq (true,$(WITH_DEXPREOPT_ART_BOOT_IMG_ONLY))
+  LOCAL_DEX_PREOPT :=
 endif
 
 my_process_profile :=
@@ -392,7 +390,6 @@
   $(call add_json_list, DexPreoptImageLocationsOnDevice,$(my_dexpreopt_image_locations_on_device))
   $(call add_json_list, PreoptBootClassPathDexFiles,    $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES))
   $(call add_json_list, PreoptBootClassPathDexLocations,$(DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS))
-  $(call add_json_bool, PreoptExtractedApk,             $(my_preopt_for_extracted_apk))
   $(call add_json_bool, NoCreateAppImage,               $(filter false,$(LOCAL_DEX_PREOPT_APP_IMAGE)))
   $(call add_json_bool, ForceCreateAppImage,            $(filter true,$(LOCAL_DEX_PREOPT_APP_IMAGE)))
   $(call add_json_bool, PresignedPrebuilt,              $(filter PRESIGNED,$(LOCAL_CERTIFICATE)))
diff --git a/core/notice_files.mk b/core/notice_files.mk
index 7465cbf..6935115 100644
--- a/core/notice_files.mk
+++ b/core/notice_files.mk
@@ -2,30 +2,6 @@
 ## Track NOTICE files
 ###########################################################
 
-ifneq ($(LOCAL_NOTICE_FILE),)
-  notice_file:=$(strip $(LOCAL_NOTICE_FILE))
-else
-  notice_file:=$(strip $(wildcard $(LOCAL_PATH)/LICENSE $(LOCAL_PATH)/LICENCE $(LOCAL_PATH)/NOTICE))
-endif
-
-ifeq ($(LOCAL_MODULE_CLASS),GYP)
-  # We ignore NOTICE files for modules of type GYP.
-  notice_file :=
-endif
-
-ifeq ($(LOCAL_MODULE_CLASS),FAKE)
-  # We ignore NOTICE files for modules of type FAKE.
-  notice_file :=
-endif
-
-# Soong generates stub libraries that don't need NOTICE files
-ifdef LOCAL_NO_NOTICE_FILE
-  ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-    $(call pretty-error,LOCAL_NO_NOTICE_FILE should not be used by Android.mk files)
-  endif
-  notice_file :=
-endif
-
 module_license_metadata := $(call local-meta-intermediates-dir)/$(my_register_name).meta_lic
 
 $(foreach target,$(ALL_MODULES.$(my_register_name).BUILT) $(ALL_MODULES.$(my_register_name).INSTALLED) $(foreach bi,$(LOCAL_SOONG_BUILT_INSTALLED),$(call word-colon,1,$(bi))),\
@@ -45,6 +21,30 @@
   # Make modules don't have enough information to produce a license metadata rule until after fix-notice-deps
   # has been called, store the necessary information until later.
 
+  ifneq ($(LOCAL_NOTICE_FILE),)
+    notice_file:=$(strip $(LOCAL_NOTICE_FILE))
+  else
+    notice_file:=$(strip $(wildcard $(LOCAL_PATH)/LICENSE $(LOCAL_PATH)/LICENCE $(LOCAL_PATH)/NOTICE))
+  endif
+
+  ifeq ($(LOCAL_MODULE_CLASS),GYP)
+    # We ignore NOTICE files for modules of type GYP.
+    notice_file :=
+  endif
+
+  ifeq ($(LOCAL_MODULE_CLASS),FAKE)
+    # We ignore NOTICE files for modules of type FAKE.
+    notice_file :=
+  endif
+
+  # Soong generates stub libraries that don't need NOTICE files
+  ifdef LOCAL_NO_NOTICE_FILE
+    ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+      $(call pretty-error,LOCAL_NO_NOTICE_FILE should not be used by Android.mk files)
+    endif
+    notice_file :=
+  endif
+
   ifneq (,$(strip $(LOCAL_LICENSE_PACKAGE_NAME)))
     license_package_name:=$(strip $(LOCAL_LICENSE_PACKAGE_NAME))
   else
@@ -136,8 +136,9 @@
   ALL_MODULES.$(my_register_name).NOTICE_DEPS := $(ALL_MODULES.$(my_register_name).NOTICE_DEPS) $(notice_deps)
   ALL_MODULES.$(my_register_name).IS_CONTAINER := $(strip $(filter-out false,$(ALL_MODULES.$(my_register_name).IS_CONTAINER) $(is_container)))
   ALL_MODULES.$(my_register_name).PATH := $(strip $(ALL_MODULES.$(my_register_name).PATH) $(local_path))
+
+  ifdef notice_file
+    ALL_MODULES.$(my_register_name).NOTICES := $(ALL_MODULES.$(my_register_name).NOTICES) $(notice_file)
+  endif  # notice_file
 endif
 
-ifdef notice_file
-ALL_MODULES.$(my_register_name).NOTICES := $(ALL_MODULES.$(my_register_name).NOTICES) $(notice_file)
-endif  # notice_file
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 5bea9b6..9462640 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -63,4 +63,3 @@
 $(built_module) : $(LOCAL_ADDITIONAL_DEPENDENCIES)
 
 my_prebuilt_src_file :=
-my_preopt_for_extracted_apk :=
diff --git a/core/product.mk b/core/product.mk
index be5ec47..91b811d 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -183,8 +183,6 @@
 # Set to true to disable <uses-library> checks for a product.
 _product_list_vars += PRODUCT_BROKEN_VERIFY_USES_LIBRARIES
 
-# All of the apps that we force preopt, this overrides WITH_DEXPREOPT.
-_product_list_vars += PRODUCT_ALWAYS_PREOPT_EXTRACTED_APK
 _product_list_vars += PRODUCT_DEXPREOPT_SPEED_APPS
 _product_list_vars += PRODUCT_LOADED_BY_PRIVILEGED_MODULES
 _product_single_value_vars += PRODUCT_VBOOT_SIGNING_KEY
@@ -449,6 +447,7 @@
 _product_list_vars += PRODUCT_AFDO_PROFILES
 
 _product_single_value_vars += PRODUCT_NEXT_RELEASE_HIDE_FLAGGED_API
+_product_single_value_vars += PRODUCT_SCUDO_ALLOCATION_RING_BUFFER_SIZE
 
 _product_list_vars += PRODUCT_RELEASE_CONFIG_MAPS
 
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 9744abf..7f85231 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -93,26 +93,11 @@
   $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_res_package))
 
   my_transitive_res_packages := $(intermediates.COMMON)/transitive-res-packages
-  $(my_transitive_res_packages): PRIVATE_TRANSITIVE_RES_PACKAGES := $(filter-out $(LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE),$(LOCAL_SOONG_TRANSITIVE_RES_PACKAGES))
-  $(my_transitive_res_packages):
-	@echo Write transitive resource package list $@
-	rm -f $@
-	touch $@
-	$(foreach f,$(PRIVATE_TRANSITIVE_RES_PACKAGES),\
-	  echo "$f" >> $@; )
-
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_TRANSITIVE_RES_PACKAGES),$(my_transitive_res_packages)))
   $(call add-dependency,$(my_res_package),$(my_transitive_res_packages))
 
   my_proguard_flags := $(intermediates.COMMON)/export_proguard_flags
-  $(my_proguard_flags): $(LOCAL_SOONG_EXPORT_PROGUARD_FLAGS)
-	@echo "Export proguard flags: $@"
-	rm -f $@
-	touch $@
-	for f in $+; do \
-		echo -e "\n# including $$f" >>$@; \
-		cat $$f >>$@; \
-	done
-
+  $(eval $(call copy-one-file,$(LOCAL_SOONG_EXPORT_PROGUARD_FLAGS),$(my_proguard_flags)))
   $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_proguard_flags))
 
   my_static_library_extra_packages := $(intermediates.COMMON)/extra_packages
diff --git a/target/product/fullmte.mk b/target/product/fullmte.mk
index 5726c06..5e2a694 100644
--- a/target/product/fullmte.mk
+++ b/target/product/fullmte.mk
@@ -25,3 +25,4 @@
   SANITIZE_TARGET_DIAG := $(strip $(SANITIZE_TARGET_DIAG) memtag_heap)
 endif
 PRODUCT_PRODUCT_PROPERTIES += persist.arm64.memtag.default=sync
+PRODUCT_SCUDO_ALLOCATION_RING_BUFFER_SIZE := 131072
diff --git a/target/product/go_defaults_common.mk b/target/product/go_defaults_common.mk
index 51a1ef6..ba0912c 100644
--- a/target/product/go_defaults_common.mk
+++ b/target/product/go_defaults_common.mk
@@ -24,10 +24,6 @@
 # Speed profile services and wifi-service to reduce RAM and storage.
 PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := speed-profile
 
-# Always preopt extracted APKs to prevent extracting out of the APK for gms
-# modules.
-PRODUCT_ALWAYS_PREOPT_EXTRACTED_APK := true
-
 # Use a profile based boot image for this device. Note that this is currently a
 # generic profile and not Android Go optimized.
 PRODUCT_USE_PROFILE_FOR_BOOT_IMAGE := true
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 1e01b33..a9d478d 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -134,23 +134,8 @@
 # This option is for faster iteration during development and should never be enabled for production.
 ifneq (,$(filter true,$(OVERRIDE_DISABLE_DEXOPT_ALL)))
   PRODUCT_SYSTEM_PROPERTIES += \
-    pm.dexopt.post-boot=skip \
-    pm.dexopt.first-boot=skip \
-    pm.dexopt.boot-after-ota=skip \
-    pm.dexopt.boot-after-mainline-update=skip \
-    pm.dexopt.install=skip \
-    pm.dexopt.install-fast=skip \
-    pm.dexopt.install-bulk=skip \
-    pm.dexopt.install-bulk-secondary=skip \
-    pm.dexopt.install-bulk-downgraded=skip \
-    pm.dexopt.install-bulk-secondary-downgraded=skip \
-    pm.dexopt.bg-dexopt=skip \
-    pm.dexopt.ab-ota=skip \
-    pm.dexopt.inactive=skip \
-    pm.dexopt.cmdline=skip \
-    pm.dexopt.shared=skip
-
-  PRODUCT_SYSTEM_PROPERTIES += dalvik.vm.disable-odrefresh=true
+    dalvik.vm.disable-art-service-dexopt=true \
+    dalvik.vm.disable-odrefresh=true
 
   # Disable all dexpreopt activities except for the ART boot image.
   # We have to dexpreopt the ART boot image because they are used by ART tests. This should not
diff --git a/tools/OWNERS b/tools/OWNERS
deleted file mode 100644
index 7d666f1..0000000
--- a/tools/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-per-file warn.py,checkowners.py = chh@google.com
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index 5aa373a..c536260 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -162,6 +162,8 @@
 
     virtual bool disabled_rw() = 0;
 
+    virtual bool disabled_rw_exported() = 0;
+
     virtual bool disabled_rw_in_other_namespace() = 0;
 
     virtual bool enabled_fixed_ro() = 0;
@@ -181,6 +183,10 @@
     return provider_->disabled_rw();
 }
 
+inline bool disabled_rw_exported() {
+    return provider_->disabled_rw_exported();
+}
+
 inline bool disabled_rw_in_other_namespace() {
     return provider_->disabled_rw_in_other_namespace();
 }
@@ -206,6 +212,8 @@
 
 bool com_android_aconfig_test_disabled_rw();
 
+bool com_android_aconfig_test_disabled_rw_exported();
+
 bool com_android_aconfig_test_disabled_rw_in_other_namespace();
 
 bool com_android_aconfig_test_enabled_fixed_ro();
@@ -241,6 +249,10 @@
 
     virtual void disabled_rw(bool val) = 0;
 
+    virtual bool disabled_rw_exported() = 0;
+
+    virtual void disabled_rw_exported(bool val) = 0;
+
     virtual bool disabled_rw_in_other_namespace() = 0;
 
     virtual void disabled_rw_in_other_namespace(bool val) = 0;
@@ -278,6 +290,14 @@
     provider_->disabled_rw(val);
 }
 
+inline bool disabled_rw_exported() {
+    return provider_->disabled_rw_exported();
+}
+
+inline void disabled_rw_exported(bool val) {
+    provider_->disabled_rw_exported(val);
+}
+
 inline bool disabled_rw_in_other_namespace() {
     return provider_->disabled_rw_in_other_namespace();
 }
@@ -327,6 +347,10 @@
 
 void set_com_android_aconfig_test_disabled_rw(bool val);
 
+bool com_android_aconfig_test_disabled_rw_exported();
+
+void set_com_android_aconfig_test_disabled_rw_exported(bool val);
+
 bool com_android_aconfig_test_disabled_rw_in_other_namespace();
 
 void set_com_android_aconfig_test_disabled_rw_in_other_namespace(bool val);
@@ -377,14 +401,24 @@
                 return cache_[0];
             }
 
-            virtual bool disabled_rw_in_other_namespace() override {
+            virtual bool disabled_rw_exported() override {
                 if (cache_[1] == -1) {
                     cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
+                        "aconfig_flags.aconfig_test",
+                        "com.android.aconfig.test.disabled_rw_exported",
+                        "false") == "true";
+                }
+                return cache_[1];
+            }
+
+            virtual bool disabled_rw_in_other_namespace() override {
+                if (cache_[2] == -1) {
+                    cache_[2] = server_configurable_flags::GetServerConfigurableFlag(
                         "aconfig_flags.other_namespace",
                         "com.android.aconfig.test.disabled_rw_in_other_namespace",
                         "false") == "true";
                 }
-                return cache_[1];
+                return cache_[2];
             }
 
             virtual bool enabled_fixed_ro() override {
@@ -396,17 +430,17 @@
             }
 
             virtual bool enabled_rw() override {
-                if (cache_[2] == -1) {
-                    cache_[2] = server_configurable_flags::GetServerConfigurableFlag(
+                if (cache_[3] == -1) {
+                    cache_[3] = server_configurable_flags::GetServerConfigurableFlag(
                         "aconfig_flags.aconfig_test",
                         "com.android.aconfig.test.enabled_rw",
                         "true") == "true";
                 }
-                return cache_[2];
+                return cache_[3];
             }
 
     private:
-        std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1);
+        std::vector<int8_t> cache_ = std::vector<int8_t>(4, -1);
     };
 
     std::unique_ptr<flag_provider_interface> provider_ =
@@ -421,6 +455,10 @@
     return com::android::aconfig::test::disabled_rw();
 }
 
+bool com_android_aconfig_test_disabled_rw_exported() {
+    return com::android::aconfig::test::disabled_rw_exported();
+}
+
 bool com_android_aconfig_test_disabled_rw_in_other_namespace() {
     return com::android::aconfig::test::disabled_rw_in_other_namespace();
 }
@@ -485,6 +523,22 @@
                 overrides_["disabled_rw"] = val;
             }
 
+            virtual bool disabled_rw_exported() override {
+                auto it = overrides_.find("disabled_rw_exported");
+                  if (it != overrides_.end()) {
+                      return it->second;
+                } else {
+                  return server_configurable_flags::GetServerConfigurableFlag(
+                      "aconfig_flags.aconfig_test",
+                      "com.android.aconfig.test.disabled_rw_exported",
+                      "false") == "true";
+                }
+            }
+
+            virtual void disabled_rw_exported(bool val) override {
+                overrides_["disabled_rw_exported"] = val;
+            }
+
             virtual bool disabled_rw_in_other_namespace() override {
                 auto it = overrides_.find("disabled_rw_in_other_namespace");
                   if (it != overrides_.end()) {
@@ -570,11 +624,20 @@
     com::android::aconfig::test::disabled_rw(val);
 }
 
+
+bool com_android_aconfig_test_disabled_rw_exported() {
+    return com::android::aconfig::test::disabled_rw_exported();
+}
+
+void set_com_android_aconfig_test_disabled_rw_exported(bool val) {
+    com::android::aconfig::test::disabled_rw_exported(val);
+}
+
+
 bool com_android_aconfig_test_disabled_rw_in_other_namespace() {
     return com::android::aconfig::test::disabled_rw_in_other_namespace();
 }
 
-
 void set_com_android_aconfig_test_disabled_rw_in_other_namespace(bool val) {
     com::android::aconfig::test::disabled_rw_in_other_namespace(val);
 }
@@ -634,6 +697,8 @@
                 match mode {
                     CodegenMode::Production => EXPORTED_PROD_HEADER_EXPECTED,
                     CodegenMode::Test => EXPORTED_TEST_HEADER_EXPECTED,
+                    CodegenMode::Exported =>
+                        todo!("exported mode not yet supported for cpp, see b/313894653."),
                 },
                 generated_files_map.get(&target_file_path).unwrap()
             )
@@ -647,6 +712,8 @@
                 match mode {
                     CodegenMode::Production => PROD_SOURCE_FILE_EXPECTED,
                     CodegenMode::Test => TEST_SOURCE_FILE_EXPECTED,
+                    CodegenMode::Exported =>
+                        todo!("exported mode not yet supported for cpp, see b/313894653."),
                 },
                 generated_files_map.get(&target_file_path).unwrap()
             )
diff --git a/tools/aconfig/src/codegen_java.rs b/tools/aconfig/src/codegen_java.rs
index a822cd5..b3e5e6c 100644
--- a/tools/aconfig/src/codegen_java.rs
+++ b/tools/aconfig/src/codegen_java.rs
@@ -39,6 +39,7 @@
         flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect();
     let is_read_write = flag_elements.iter().any(|elem| elem.is_read_write);
     let is_test_mode = codegen_mode == CodegenMode::Test;
+    let library_exported = codegen_mode == CodegenMode::Exported;
     let context = Context {
         flag_elements,
         namespace_flags,
@@ -46,6 +47,7 @@
         is_read_write,
         properties_set,
         package_name: package.to_string(),
+        library_exported,
     };
     let mut template = TinyTemplate::new();
     template.add_template("Flags.java", include_str!("../templates/Flags.java.template"))?;
@@ -103,6 +105,7 @@
     pub is_read_write: bool,
     pub properties_set: BTreeSet<String>,
     pub package_name: String,
+    pub library_exported: bool,
 }
 
 #[derive(Serialize, Debug)]
@@ -120,6 +123,7 @@
     pub is_read_write: bool,
     pub method_name: String,
     pub properties: String,
+    pub exported: bool,
 }
 
 fn create_flag_element(package: &str, pf: &ProtoParsedFlag) -> FlagElement {
@@ -133,6 +137,7 @@
         is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE,
         method_name: format_java_method_name(pf.name()),
         properties: format_property_name(pf.namespace()),
+        exported: pf.is_exported.unwrap_or(false),
     }
 }
 
@@ -179,6 +184,8 @@
         @UnsupportedAppUsage
         boolean disabledRw();
         @UnsupportedAppUsage
+        boolean disabledRwExported();
+        @UnsupportedAppUsage
         boolean disabledRwInOtherNamespace();
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
@@ -202,6 +209,8 @@
         /** @hide */
         public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
         /** @hide */
+        public static final String FLAG_DISABLED_RW_EXPORTED = "com.android.aconfig.test.disabled_rw_exported";
+        /** @hide */
         public static final String FLAG_DISABLED_RW_IN_OTHER_NAMESPACE = "com.android.aconfig.test.disabled_rw_in_other_namespace";
         /** @hide */
         public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro";
@@ -220,6 +229,10 @@
             return FEATURE_FLAGS.disabledRw();
         }
         @UnsupportedAppUsage
+        public static boolean disabledRwExported() {
+            return FEATURE_FLAGS.disabledRwExported();
+        }
+        @UnsupportedAppUsage
         public static boolean disabledRwInOtherNamespace() {
             return FEATURE_FLAGS.disabledRwInOtherNamespace();
         }
@@ -262,6 +275,11 @@
         }
         @Override
         @UnsupportedAppUsage
+        public boolean disabledRwExported() {
+            return getValue(Flags.FLAG_DISABLED_RW_EXPORTED);
+        }
+        @Override
+        @UnsupportedAppUsage
         public boolean disabledRwInOtherNamespace() {
             return getValue(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE);
         }
@@ -302,6 +320,7 @@
             Map.ofEntries(
                 Map.entry(Flags.FLAG_DISABLED_RO, false),
                 Map.entry(Flags.FLAG_DISABLED_RW, false),
+                Map.entry(Flags.FLAG_DISABLED_RW_EXPORTED, false),
                 Map.entry(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false),
                 Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false),
                 Map.entry(Flags.FLAG_ENABLED_RO, false),
@@ -336,6 +355,7 @@
             private static boolean aconfig_test_is_cached = false;
             private static boolean other_namespace_is_cached = false;
             private static boolean disabledRw = false;
+            private static boolean disabledRwExported = false;
             private static boolean disabledRwInOtherNamespace = false;
             private static boolean enabledRw = true;
 
@@ -345,6 +365,8 @@
                     Properties properties = DeviceConfig.getProperties("aconfig_test");
                     disabledRw =
                         properties.getBoolean("com.android.aconfig.test.disabled_rw", false);
+                    disabledRwExported =
+                        properties.getBoolean("com.android.aconfig.test.disabled_rw_exported", false);
                     enabledRw =
                         properties.getBoolean("com.android.aconfig.test.enabled_rw", true);
                 } catch (NullPointerException e) {
@@ -394,6 +416,14 @@
             }
             @Override
             @UnsupportedAppUsage
+            public boolean disabledRwExported() {
+                if (!aconfig_test_is_cached) {
+                    load_overrides_aconfig_test();
+                }
+                return disabledRwExported;
+            }
+            @Override
+            @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 if (!other_namespace_is_cached) {
                     load_overrides_other_namespace();
@@ -449,6 +479,202 @@
     }
 
     #[test]
+    fn test_generate_java_code_exported() {
+        let parsed_flags = crate::test::parse_test_flags();
+        let generated_files = generate_java_code(
+            crate::test::TEST_PACKAGE,
+            parsed_flags.parsed_flag.iter(),
+            CodegenMode::Exported,
+        )
+        .unwrap();
+
+        let expect_flags_content = r#"
+        package com.android.aconfig.test;
+        // TODO(b/303773055): Remove the annotation after access issue is resolved.
+        import android.compat.annotation.UnsupportedAppUsage;
+        /** @hide */
+        public final class Flags {
+            /** @hide */
+            public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
+            /** @hide */
+            public static final String FLAG_DISABLED_RW_EXPORTED = "com.android.aconfig.test.disabled_rw_exported";
+
+            @UnsupportedAppUsage
+            public static boolean disabledRw() {
+                return FEATURE_FLAGS.disabledRw();
+            }
+            @UnsupportedAppUsage
+            public static boolean disabledRwExported() {
+                return FEATURE_FLAGS.disabledRwExported();
+            }
+            private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
+        }
+        "#;
+
+        let expect_feature_flags_content = r#"
+        package com.android.aconfig.test;
+        // TODO(b/303773055): Remove the annotation after access issue is resolved.
+        import android.compat.annotation.UnsupportedAppUsage;
+        /** @hide */
+        public interface FeatureFlags {
+            @UnsupportedAppUsage
+            boolean disabledRw();
+            @UnsupportedAppUsage
+            boolean disabledRwExported();
+        }
+        "#;
+
+        let expect_feature_flags_impl_content = r#"
+        package com.android.aconfig.test;
+        // TODO(b/303773055): Remove the annotation after access issue is resolved.
+        import android.compat.annotation.UnsupportedAppUsage;
+        import android.provider.DeviceConfig;
+        import android.provider.DeviceConfig.Properties;
+        /** @hide */
+        public final class FeatureFlagsImpl implements FeatureFlags {
+            private static boolean aconfig_test_is_cached = false;
+            private static boolean other_namespace_is_cached = false;
+            private static boolean disabledRw = false;
+            private static boolean disabledRwExported = false;
+
+
+            private void load_overrides_aconfig_test() {
+                try {
+                    Properties properties = DeviceConfig.getProperties("aconfig_test");
+                    disabledRw =
+                        properties.getBoolean("com.android.aconfig.test.disabled_rw", false);
+                    disabledRwExported =
+                        properties.getBoolean("com.android.aconfig.test.disabled_rw_exported", false);
+                } catch (NullPointerException e) {
+                    throw new RuntimeException(
+                        "Cannot read value from namespace aconfig_test "
+                        + "from DeviceConfig. It could be that the code using flag "
+                        + "executed before SettingsProvider initialization. Please use "
+                        + "fixed read-only flag by adding is_fixed_read_only: true in "
+                        + "flag declaration.",
+                        e
+                    );
+                }
+                aconfig_test_is_cached = true;
+            }
+
+            private void load_overrides_other_namespace() {
+                try {
+                    Properties properties = DeviceConfig.getProperties("other_namespace");
+                } catch (NullPointerException e) {
+                    throw new RuntimeException(
+                        "Cannot read value from namespace other_namespace "
+                        + "from DeviceConfig. It could be that the code using flag "
+                        + "executed before SettingsProvider initialization. Please use "
+                        + "fixed read-only flag by adding is_fixed_read_only: true in "
+                        + "flag declaration.",
+                        e
+                    );
+                }
+                other_namespace_is_cached = true;
+            }
+
+            @Override
+            @UnsupportedAppUsage
+            public boolean disabledRw() {
+                if (!aconfig_test_is_cached) {
+                    load_overrides_aconfig_test();
+                }
+                return disabledRw;
+            }
+
+            @Override
+            @UnsupportedAppUsage
+            public boolean disabledRwExported() {
+                if (!aconfig_test_is_cached) {
+                    load_overrides_aconfig_test();
+                }
+                return disabledRwExported;
+            }
+        }"#;
+
+        let expect_fake_feature_flags_impl_content = r#"
+        package com.android.aconfig.test;
+        // TODO(b/303773055): Remove the annotation after access issue is resolved.
+        import android.compat.annotation.UnsupportedAppUsage;
+        import java.util.HashMap;
+        import java.util.Map;
+        /** @hide */
+        public class FakeFeatureFlagsImpl implements FeatureFlags {
+            public FakeFeatureFlagsImpl() {
+                resetAll();
+            }
+            @Override
+            @UnsupportedAppUsage
+            public boolean disabledRw() {
+                return getValue(Flags.FLAG_DISABLED_RW);
+            }
+            @Override
+            @UnsupportedAppUsage
+            public boolean disabledRwExported() {
+                return getValue(Flags.FLAG_DISABLED_RW_EXPORTED);
+            }
+            public void setFlag(String flagName, boolean value) {
+                if (!this.mFlagMap.containsKey(flagName)) {
+                    throw new IllegalArgumentException("no such flag " + flagName);
+                }
+                this.mFlagMap.put(flagName, value);
+            }
+            public void resetAll() {
+                for (Map.Entry entry : mFlagMap.entrySet()) {
+                    entry.setValue(null);
+                }
+            }
+            private boolean getValue(String flagName) {
+                Boolean value = this.mFlagMap.get(flagName);
+                if (value == null) {
+                    throw new IllegalArgumentException(flagName + " is not set");
+                }
+                return value;
+            }
+            private Map<String, Boolean> mFlagMap = new HashMap<>(
+                Map.ofEntries(
+                    Map.entry(Flags.FLAG_DISABLED_RO, false),
+                    Map.entry(Flags.FLAG_DISABLED_RW, false),
+                    Map.entry(Flags.FLAG_DISABLED_RW_EXPORTED, false),
+                    Map.entry(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false),
+                    Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false),
+                    Map.entry(Flags.FLAG_ENABLED_RO, false),
+                    Map.entry(Flags.FLAG_ENABLED_RW, false)
+                )
+            );
+        }
+    "#;
+
+        let mut file_set = HashMap::from([
+            ("com/android/aconfig/test/Flags.java", expect_flags_content),
+            ("com/android/aconfig/test/FeatureFlags.java", expect_feature_flags_content),
+            ("com/android/aconfig/test/FeatureFlagsImpl.java", expect_feature_flags_impl_content),
+            (
+                "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
+                expect_fake_feature_flags_impl_content,
+            ),
+        ]);
+
+        for file in generated_files {
+            let file_path = file.path.to_str().unwrap();
+            assert!(file_set.contains_key(file_path), "Cannot find {}", file_path);
+            assert_eq!(
+                None,
+                crate::test::first_significant_code_diff(
+                    file_set.get(file_path).unwrap(),
+                    &String::from_utf8(file.contents).unwrap()
+                ),
+                "File {} content is not correct",
+                file_path
+            );
+            file_set.remove(file_path);
+        }
+
+        assert!(file_set.is_empty());
+    }
+
+    #[test]
     fn test_generate_java_code_test() {
         let parsed_flags = crate::test::parse_test_flags();
         let generated_files = generate_java_code(
@@ -489,6 +715,12 @@
             }
             @Override
             @UnsupportedAppUsage
+            public boolean disabledRwExported() {
+                throw new UnsupportedOperationException(
+                    "Method is not implemented.");
+            }
+            @Override
+            @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
diff --git a/tools/aconfig/src/codegen_rust.rs b/tools/aconfig/src/codegen_rust.rs
index d8675e7..502cec8 100644
--- a/tools/aconfig/src/codegen_rust.rs
+++ b/tools/aconfig/src/codegen_rust.rs
@@ -45,6 +45,9 @@
         match codegen_mode {
             CodegenMode::Production => include_str!("../templates/rust_prod.template"),
             CodegenMode::Test => include_str!("../templates/rust_test.template"),
+            CodegenMode::Exported => {
+                todo!("exported mode not yet supported for rust, see b/313894653.")
+            }
         },
     )?;
     let contents = template.render("rust_code_gen", &context)?;
@@ -104,6 +107,12 @@
         "com.android.aconfig.test.disabled_rw",
         "false") == "true";
 
+    /// flag value cache for disabled_rw_exported
+    static ref CACHED_disabled_rw_exported: bool = flags_rust::GetServerConfigurableFlag(
+        "aconfig_flags.aconfig_test",
+        "com.android.aconfig.test.disabled_rw_exported",
+        "false") == "true";
+
     /// flag value cache for disabled_rw_in_other_namespace
     static ref CACHED_disabled_rw_in_other_namespace: bool = flags_rust::GetServerConfigurableFlag(
         "aconfig_flags.other_namespace",
@@ -115,6 +124,7 @@
         "aconfig_flags.aconfig_test",
         "com.android.aconfig.test.enabled_rw",
         "true") == "true";
+
 }
 
 impl FlagProvider {
@@ -128,6 +138,11 @@
         *CACHED_disabled_rw
     }
 
+    /// query flag disabled_rw_exported
+    pub fn disabled_rw_exported(&self) -> bool {
+        *CACHED_disabled_rw_exported
+    }
+
     /// query flag disabled_rw_in_other_namespace
     pub fn disabled_rw_in_other_namespace(&self) -> bool {
         *CACHED_disabled_rw_in_other_namespace
@@ -164,6 +179,12 @@
     PROVIDER.disabled_rw()
 }
 
+/// query flag disabled_rw_exported
+#[inline(always)]
+pub fn disabled_rw_exported() -> bool {
+    PROVIDER.disabled_rw_exported()
+}
+
 /// query flag disabled_rw_in_other_namespace
 #[inline(always)]
 pub fn disabled_rw_in_other_namespace() -> bool {
@@ -228,6 +249,21 @@
         self.overrides.insert("disabled_rw", val);
     }
 
+    /// query flag disabled_rw_exported
+    pub fn disabled_rw_exported(&self) -> bool {
+        self.overrides.get("disabled_rw_exported").copied().unwrap_or(
+            flags_rust::GetServerConfigurableFlag(
+                "aconfig_flags.aconfig_test",
+                "com.android.aconfig.test.disabled_rw_exported",
+                "false") == "true"
+        )
+    }
+
+    /// set flag disabled_rw_exported
+    pub fn set_disabled_rw_exported(&mut self, val: bool) {
+        self.overrides.insert("disabled_rw_exported", val);
+    }
+
     /// query flag disabled_rw_in_other_namespace
     pub fn disabled_rw_in_other_namespace(&self) -> bool {
         self.overrides.get("disabled_rw_in_other_namespace").copied().unwrap_or(
@@ -317,6 +353,18 @@
     PROVIDER.lock().unwrap().set_disabled_rw(val);
 }
 
+/// query flag disabled_rw_exported
+#[inline(always)]
+pub fn disabled_rw_exported() -> bool {
+    PROVIDER.lock().unwrap().disabled_rw_exported()
+}
+
+/// set flag disabled_rw_exported
+#[inline(always)]
+pub fn set_disabled_rw_exported(val: bool) {
+    PROVIDER.lock().unwrap().set_disabled_rw_exported(val);
+}
+
 /// query flag disabled_rw_in_other_namespace
 #[inline(always)]
 pub fn disabled_rw_in_other_namespace() -> bool {
@@ -383,6 +431,8 @@
                 match mode {
                     CodegenMode::Production => PROD_EXPECTED,
                     CodegenMode::Test => TEST_EXPECTED,
+                    CodegenMode::Exported =>
+                        todo!("exported mode not yet supported for rust, see b/313894653."),
                 },
                 &String::from_utf8(generated.contents).unwrap()
             )
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index ff0df1f..47e90ac 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -171,6 +171,7 @@
 pub enum CodegenMode {
     Production,
     Test,
+    Exported,
 }
 
 pub fn create_java_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Vec<OutputFile>> {
@@ -335,7 +336,7 @@
         assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state());
         assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.trace[2].permission());
 
-        assert_eq!(6, parsed_flags.parsed_flag.len());
+        assert_eq!(7, parsed_flags.parsed_flag.len());
         for pf in parsed_flags.parsed_flag.iter() {
             if pf.name() == "enabled_fixed_ro" {
                 continue;
@@ -434,7 +435,7 @@
         let input = parse_test_flags_as_input();
         let bytes = create_device_config_defaults(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\nother_namespace:com.android.aconfig.test.disabled_rw_in_other_namespace=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
+        assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\naconfig_test:com.android.aconfig.test.disabled_rw_exported=disabled\nother_namespace:com.android.aconfig.test.disabled_rw_in_other_namespace=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
     }
 
     #[test]
@@ -442,7 +443,7 @@
         let input = parse_test_flags_as_input();
         let bytes = create_device_config_sysprops(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.disabled_rw_in_other_namespace=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
+        assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.disabled_rw_exported=false\npersist.device_config.com.android.aconfig.test.disabled_rw_in_other_namespace=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
     }
 
     #[test]
diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs
index 31c67b3..9f598d0 100644
--- a/tools/aconfig/src/test.rs
+++ b/tools/aconfig/src/test.rs
@@ -62,6 +62,27 @@
 }
 parsed_flag {
   package: "com.android.aconfig.test"
+  name: "disabled_rw_exported"
+  namespace: "aconfig_test"
+  description: "This flag is exported"
+  bug: "111"
+  state: DISABLED
+  permission: READ_WRITE
+  trace {
+    source: "tests/test.aconfig"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  trace {
+    source: "tests/first.values"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  is_fixed_read_only: false
+  is_exported: true
+}
+parsed_flag {
+  package: "com.android.aconfig.test"
   name: "disabled_rw_in_other_namespace"
   namespace: "other_namespace"
   description: "This flag is DISABLED + READ_WRITE, and is defined in another namespace"
diff --git a/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template b/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template
index 933d6a7..fd2e26a 100644
--- a/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template
+++ b/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template
@@ -12,11 +12,23 @@
     }
 
 {{ for item in flag_elements}}
+{{ if library_exported }}
+
+{{ if item.exported }}
     @Override
     @UnsupportedAppUsage
     public boolean {item.method_name}() \{
         return getValue(Flags.FLAG_{item.flag_name_constant_suffix});
     }
+{{ endif }}
+
+{{ else }}
+    @Override
+    @UnsupportedAppUsage
+    public boolean {item.method_name}() \{
+        return getValue(Flags.FLAG_{item.flag_name_constant_suffix});
+    }
+{{ endif }}
 {{ endfor}}
     public void setFlag(String flagName, boolean value) \{
         if (!this.mFlagMap.containsKey(flagName)) \{
diff --git a/tools/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/templates/FeatureFlags.java.template
index da850ae..180f882 100644
--- a/tools/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/templates/FeatureFlags.java.template
@@ -5,6 +5,15 @@
 /** @hide */
 public interface FeatureFlags \{
 {{ for item in flag_elements }}
+{{ if library_exported }}
+
+{{ if item.exported }}
+    @UnsupportedAppUsage
+    boolean {item.method_name}();
+{{ endif }}
+
+{{ else }}
+
 {{ -if not item.is_read_write }}
 {{ -if item.default_value }}
     @com.android.aconfig.annotations.AssumeTrueForR8
@@ -14,5 +23,7 @@
 {{ endif }}
     @UnsupportedAppUsage
     boolean {item.method_name}();
+
+{{ endif }}
 {{ endfor }}
 }
diff --git a/tools/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/templates/FeatureFlagsImpl.java.template
index ec8822c..a15c859 100644
--- a/tools/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/templates/FeatureFlagsImpl.java.template
@@ -14,9 +14,17 @@
 {{- endfor- }}
 
 {{ for flag in flag_elements }}
+{{ if library_exported }}
+{{ if flag.exported }}
+    private static boolean {flag.method_name} = false;
+{{ endif }}
+
+{{ else }}
+
 {{- if flag.is_read_write }}
     private static boolean {flag.method_name} = {flag.default_value};
 {{- endif- }}
+{{ endif }}
 {{ endfor }}
 
 {{ for namespace_with_flags in namespace_flags }}
@@ -25,10 +33,21 @@
             Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
 
             {{- for flag in namespace_with_flags.flags }}
-            {{- if flag.is_read_write }}
+            {{ if library_exported }}
+
+            {{ if flag.exported }}
+            {flag.method_name} =
+                properties.getBoolean("{flag.device_config_flag}", false);
+            {{ endif }}
+
+            {{ else }}
+
+            {{ if flag.is_read_write }}
             {flag.method_name} =
                 properties.getBoolean("{flag.device_config_flag}", {flag.default_value});
-            {{- endif- }}
+            {{ endif }}
+
+            {{ endif }}
             {{ endfor }}
         } catch (NullPointerException e) \{
             throw new RuntimeException(
@@ -46,6 +65,9 @@
 {{ endif- }}
 
 {{ for flag in flag_elements }}
+{{ if library_exported }}
+
+{{ if flag.exported }}
     @Override
     @UnsupportedAppUsage
     public boolean {flag.method_name}() \{
@@ -58,6 +80,23 @@
         return {flag.default_value};
     {{ endif- }}
     }
+{{ endif }}
+
+{{ else }}
+    @Override
+    @UnsupportedAppUsage
+    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 }}
+        return {flag.default_value};
+    {{ endif- }}
+    }
+{{ endif }}
+
 {{ endfor }}
 }
 {{ else }}
diff --git a/tools/aconfig/templates/Flags.java.template b/tools/aconfig/templates/Flags.java.template
index cf6604c..9f4c52f 100644
--- a/tools/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/templates/Flags.java.template
@@ -6,10 +6,28 @@
 /** @hide */
 public final class Flags \{
 {{- for item in flag_elements}}
+    {{ if library_exported }}
+    {{ if item.exported }}
     /** @hide */
     public static final String FLAG_{item.flag_name_constant_suffix} = "{item.device_config_flag}";
+    {{ endif }}
+    {{ else }}
+    /** @hide */
+    public static final String FLAG_{item.flag_name_constant_suffix} = "{item.device_config_flag}";
+    {{ endif }}
 {{- endfor }}
 {{ for item in flag_elements}}
+{{ if library_exported }}
+
+{{ if item.exported }}
+    @UnsupportedAppUsage
+    public static boolean {item.method_name}() \{
+        return FEATURE_FLAGS.{item.method_name}();
+    }
+{{ endif }}
+
+{{ else }}
+
 {{ -if not item.is_read_write }}
 {{ -if item.default_value }}
     @com.android.aconfig.annotations.AssumeTrueForR8
@@ -21,6 +39,7 @@
     public static boolean {item.method_name}() \{
         return FEATURE_FLAGS.{item.method_name}();
     }
+{{ endif }}
 {{ endfor }}
 {{ -if is_test_mode }}
     public static void setFeatureFlags(FeatureFlags featureFlags) \{
diff --git a/tools/aconfig/tests/first.values b/tools/aconfig/tests/first.values
index 07d8d1d..b248d43 100644
--- a/tools/aconfig/tests/first.values
+++ b/tools/aconfig/tests/first.values
@@ -28,3 +28,9 @@
     state: ENABLED
     permission: READ_ONLY
 }
+flag_value {
+    package: "com.android.aconfig.test"
+    name: "disabled_rw_exported"
+    state: DISABLED
+    permission: READ_WRITE
+}
diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig
index b49b665..8a1a913 100644
--- a/tools/aconfig/tests/test.aconfig
+++ b/tools/aconfig/tests/test.aconfig
@@ -59,3 +59,11 @@
     description: "This flag is DISABLED + READ_WRITE, and is defined in another namespace"
     bug: "999"
 }
+
+flag {
+    name: "disabled_rw_exported"
+    namespace: "aconfig_test"
+    description: "This flag is exported"
+    bug: "111"
+    is_exported: true
+}
\ No newline at end of file
diff --git a/tools/checkowners.py b/tools/checkowners.py
deleted file mode 100755
index f037321..0000000
--- a/tools/checkowners.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/python
-
-"""Parse and check syntax errors of a given OWNERS file."""
-
-import argparse
-import re
-import sys
-import urllib.request, urllib.parse, urllib.error
-import urllib.request, urllib.error, urllib.parse
-
-parser = argparse.ArgumentParser(description='Check OWNERS file syntax')
-parser.add_argument('-v', '--verbose', dest='verbose',
-                    action='store_true', default=False,
-                    help='Verbose output to debug')
-parser.add_argument('-c', '--check_address', dest='check_address',
-                    action='store_true', default=False,
-                    help='Check email addresses')
-parser.add_argument(dest='owners', metavar='OWNERS', nargs='+',
-                    help='Path to OWNERS file')
-args = parser.parse_args()
-
-gerrit_server = 'https://android-review.googlesource.com'
-checked_addresses = {}
-
-
-def echo(msg):
-  if args.verbose:
-    print(msg)
-
-
-def find_address(address):
-  if address not in checked_addresses:
-    request = (gerrit_server + '/accounts/?n=1&q=email:'
-               + urllib.parse.quote(address))
-    echo('Checking email address: ' + address)
-    result = urllib.request.urlopen(request).read()
-    checked_addresses[address] = result.find('"_account_id":') >= 0
-    if checked_addresses[address]:
-      echo('Found email address: ' + address)
-  return checked_addresses[address]
-
-
-def check_address(fname, num, address):
-  if find_address(address):
-    return 0
-  print('%s:%d: ERROR: unknown email address: %s' % (fname, num, address))
-  return 1
-
-
-def main():
-  # One regular expression to check all valid lines.
-  noparent = 'set +noparent'
-  email = '([^@ ]+@[^ @]+|\\*)'
-  emails = '(%s( *, *%s)*)' % (email, email)
-  file_directive = 'file: *([^ :]+ *: *)?[^ ]+'
-  directive = '(%s|%s|%s)' % (emails, noparent, file_directive)
-  glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
-  globs = '(%s( *, *%s)*)' % (glob, glob)
-  perfile = 'per-file +' + globs + ' *= *' + directive
-  include = 'include +([^ :]+ *: *)?[^ ]+'
-  pats = '(|%s|%s|%s|%s|%s)$' % (noparent, email, perfile, include, file_directive)
-  patterns = re.compile(pats)
-  address_pattern = re.compile('([^@ ]+@[^ @]+)')
-  perfile_pattern = re.compile('per-file +.*=(.*)')
-
-  error = 0
-  for fname in args.owners:
-    echo('Checking file: ' + fname)
-    num = 0
-    for line in open(fname, 'r'):
-      num += 1
-      stripped_line = re.sub('#.*$', '', line).strip()
-      if not patterns.match(stripped_line):
-        error += 1
-        print('%s:%d: ERROR: unknown line [%s]' % (fname, num, line.strip()))
-      elif args.check_address:
-        if perfile_pattern.match(stripped_line):
-          for addr in perfile_pattern.match(stripped_line).group(1).split(','):
-            a = addr.strip()
-            if a and a != '*':
-              error += check_address(fname, num, addr.strip())
-        elif address_pattern.match(stripped_line):
-          error += check_address(fname, num, stripped_line)
-  sys.exit(error)
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 34b7172..8571d74 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -437,6 +437,8 @@
         sldc_flags = sldc_flags_str.split()
         build_command.append(str(len(sldc_flags)))
         build_command.extend(sldc_flags)
+    f2fs_blocksize = prop_dict.get("f2fs_blocksize", "4096")
+    build_command.extend(["-b", f2fs_blocksize])
   else:
     raise BuildImageError(
         "Error: unknown filesystem type: {}".format(fs_type))
@@ -721,6 +723,7 @@
       "system_f2fs_compress",
       "system_f2fs_sldc_flags",
       "f2fs_sparse_flag",
+      "f2fs_blocksize",
       "skip_fsck",
       "ext_mkuserimg",
       "avb_enable",
@@ -770,6 +773,7 @@
       (True, "{}_extfs_inode_count", "extfs_inode_count"),
       (True, "{}_f2fs_compress", "f2fs_compress"),
       (True, "{}_f2fs_sldc_flags", "f2fs_sldc_flags"),
+      (True, "{}_f2fs_blocksize", "f2fs_block_size"),
       (True, "{}_reserved_size", "partition_reserved_size"),
       (True, "{}_squashfs_block_size", "squashfs_block_size"),
       (True, "{}_squashfs_compressor", "squashfs_compressor"),
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index 33624f5..d31f87e 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -218,12 +218,12 @@
   2. invoke apexd_host with vendor APEXes.
   """
 
-  apex_dir = os.path.join(inp, 'APEX')
+  apex_dir = common.MakeTempDir('APEX')
   # checkvintf needs /apex dirmap
   dirmap['/apex'] = apex_dir
 
   # Always create /apex directory for dirmap
-  os.makedirs(apex_dir)
+  os.makedirs(apex_dir, exist_ok=True)
 
   # Invoke apexd_host to activate vendor APEXes for checkvintf
   apex_host = os.path.join(OPTIONS.search_path, 'bin', 'apexd_host')
diff --git a/tools/releasetools/merge/merge_builds.py b/tools/releasetools/merge/merge_builds.py
index 3ac4ec4..032278c 100644
--- a/tools/releasetools/merge/merge_builds.py
+++ b/tools/releasetools/merge/merge_builds.py
@@ -47,6 +47,10 @@
       The optional path to a newline-separated config file containing keys to
       obtain from the framework instance of misc_info.txt, used for creating
       vbmeta.img. The remaining keys come from the vendor instance.
+
+  --avb_resolve_rollback_index_location_conflict
+      If provided, resolve the conflict AVB rollback index location when
+      necessary.
 """
 from __future__ import print_function
 
@@ -65,6 +69,7 @@
 OPTIONS.product_out_vendor = None
 OPTIONS.build_vbmeta = False
 OPTIONS.framework_misc_info_keys = None
+OPTIONS.avb_resolve_rollback_index_location_conflict = False
 
 
 def CreateImageSymlinks():
@@ -140,7 +145,8 @@
   output_vbmeta_path = os.path.join(OPTIONS.product_out_vendor, "vbmeta.img")
   OPTIONS.info_dict = merged_dict
   common.BuildVBMeta(output_vbmeta_path, partitions, "vbmeta",
-                     vbmeta_partitions)
+                     vbmeta_partitions,
+                     OPTIONS.avb_resolve_rollback_index_location_conflict)
 
 
 def MergeBuilds():
@@ -164,6 +170,8 @@
       OPTIONS.build_vbmeta = True
     elif o == "--framework_misc_info_keys":
       OPTIONS.framework_misc_info_keys = a
+    elif o == "--avb_resolve_rollback_index_location_conflict":
+      OPTIONS.avb_resolve_rollback_index_location_conflict = True
     else:
       return False
     return True
@@ -177,6 +185,7 @@
           "product_out_vendor=",
           "build_vbmeta",
           "framework_misc_info_keys=",
+          "avb_resolve_rollback_index_location_conflict"
       ],
       extra_option_handler=option_handler)