Merge "core/Makefile: Make PACK_DESKTOP_{RECOVERY,UPDATE}_IMAGE into product variable" into main
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 10d365c..0607b71 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -253,3 +253,13 @@
   #BOARD_LIBACRYL_G2D_HDR_PLUGIN is set in each board config
   $(call soong_config_set_bool,acryl,libacryl_use_g2d_hdr_plugin,true)
 endif
+
+# Export related variables to soong for hardware/google/graphics/common/BoardConfigCFlags.mk
+$(call soong_config_set_bool,google_graphics,hwc_no_support_skip_validate,$(if $(filter true,$(HWC_NO_SUPPORT_SKIP_VALIDATE)),true,false))
+$(call soong_config_set_bool,google_graphics,hwc_support_color_transform,$(if $(filter true,$(HWC_SUPPORT_COLOR_TRANSFORM)),true,false))
+$(call soong_config_set_bool,google_graphics,hwc_support_render_intent,$(if $(filter true,$(HWC_SUPPORT_RENDER_INTENT)),true,false))
+$(call soong_config_set_bool,google_graphics,board_uses_virtual_display,$(if $(filter true,$(BOARD_USES_VIRTUAL_DISPLAY)),true,false))
+$(call soong_config_set_bool,google_graphics,board_uses_dt,$(if $(filter true,$(BOARD_USES_DT)),true,false))
+$(call soong_config_set_bool,google_graphics,board_uses_decon_64bit_address,$(if $(filter true,$(BOARD_USES_DECON_64BIT_ADDRESS)),true,false))
+$(call soong_config_set_bool,google_graphics,board_uses_hdrui_gles_conversion,$(if $(filter true,$(BOARD_USES_HDRUI_GLES_CONVERSION)),true,false))
+$(call soong_config_set_bool,google_graphics,uses_idisplay_intf_sec,$(if $(filter true,$(USES_IDISPLAY_INTF_SEC)),true,false))
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 5a5a713..cc77b53 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -433,6 +433,10 @@
   $(call add_json_list, VendorLinkerConfigSrcs, $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS))
   $(call add_json_list, ProductLinkerConfigSrcs, $(PRODUCT_PRODUCT_LINKER_CONFIG_FRAGMENTS))
 
+  # Used to generate _dlkm partitions
+  $(call add_json_bool, BuildingSystemDlkmImage,               $(BUILDING_SYSTEM_DLKM_IMAGE))
+  $(call add_json_list, SystemKernelModules, $(BOARD_SYSTEM_KERNEL_MODULES))
+
   $(call add_json_map, ProductCopyFiles)
   $(foreach pair,$(PRODUCT_COPY_FILES),\
     $(call add_json_str,$(word 1,$(subst :, ,$(pair))),$(word 2,$(subst :, ,$(pair)))))
diff --git a/target/product/virtual_ab_ota/compression.mk b/target/product/virtual_ab_ota/compression.mk
index dc1ee3e..e77c36f 100644
--- a/target/product/virtual_ab_ota/compression.mk
+++ b/target/product/virtual_ab_ota/compression.mk
@@ -18,9 +18,12 @@
 
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
 
+# Optional assignment. On low memory devices, disabling io_uring can relieve cpu and memory
+# pressure during an OTA.
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled?=true
+
 # Enabling this property, will improve OTA install time
 # but will use an additional CPU core
 # PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.threads=true
diff --git a/target/product/virtual_ab_ota/vabc_features.mk b/target/product/virtual_ab_ota/vabc_features.mk
index e2745a1..d092699 100644
--- a/target/product/virtual_ab_ota/vabc_features.mk
+++ b/target/product/virtual_ab_ota/vabc_features.mk
@@ -31,14 +31,15 @@
 
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
+
+# Optional assignments, low memory devices may benefit from overriding these.
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled?=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled?=true
+
 # Low memory device configurations. If memory usage and cpu utilization is
 # a bottleneck during OTA, the below configurations can be added to a
-# device's .mk file improve performance for low mem devices. Disabling
-# ro.virtual_ab.compression.xor.enabled and ro.virtual_ab.io_uring.enabled
-# is also recommended
+# device's .mk file improve performance for low mem devices.
 #
 # PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.read_ahead_size=16
 # PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.o_direct.enabled=true
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/AconfigPackageImpl.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/AconfigPackageImpl.java
index 4d020cf..5d8e7cb 100644
--- a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/AconfigPackageImpl.java
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/AconfigPackageImpl.java
@@ -19,8 +19,6 @@
 import android.os.StrictMode;
 
 import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
 
 /** @hide */
 public class AconfigPackageImpl {
@@ -29,25 +27,29 @@
     private PackageTable.Node mPNode;
 
     /** @hide */
-    public static AconfigPackageImpl load(String packageName, StorageFileProvider fileProvider) {
-        AconfigPackageImpl aPackage = new AconfigPackageImpl();
-        if (!aPackage.init(null, packageName, fileProvider)) {
-            return null;
-        }
-        return aPackage;
+    public static final int ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND = 1;
+
+    /** @hide */
+    public static final int ERROR_PACKAGE_NOT_FOUND = 2;
+
+    /** @hide */
+    public static final int ERROR_CONTAINER_NOT_FOUND = 3;
+
+    /** @hide */
+    public AconfigPackageImpl() {}
+
+    /** @hide */
+    public int load(String packageName, StorageFileProvider fileProvider) {
+        return init(null, packageName, fileProvider);
     }
 
     /** @hide */
-    public static AconfigPackageImpl load(
-            String container, String packageName, StorageFileProvider fileProvider) {
+    public int load(String container, String packageName, StorageFileProvider fileProvider) {
         if (container == null) {
-            return null;
+            return ERROR_CONTAINER_NOT_FOUND;
         }
-        AconfigPackageImpl aPackage = new AconfigPackageImpl();
-        if (!aPackage.init(container, packageName, fileProvider)) {
-            return null;
-        }
-        return aPackage;
+
+        return init(container, packageName, fileProvider);
     }
 
     /** @hide */
@@ -74,61 +76,56 @@
         return mPNode.hasPackageFingerprint();
     }
 
-    private boolean init(
-            String containerName, String packageName, StorageFileProvider fileProvider) {
+    private int init(String containerName, String packageName, StorageFileProvider fileProvider) {
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
         String container = containerName;
         try {
             // for devices don't have new storage directly return
             if (!fileProvider.containerFileExists(null)) {
-                return false;
+                return ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND;
             }
             PackageTable.Node pNode = null;
 
             if (container == null) {
-                PackageTable pTable = null;
-                // check if device has flag files on the system partition
-                // if the device has then search system partition first
+                // Check if the device has flag files on the system partition.
+                // If the device does, search the system partition first.
                 container = "system";
                 if (fileProvider.containerFileExists(container)) {
-                    pTable = fileProvider.getPackageTable(container);
-                    pNode = pTable.get(packageName);
-                }
-                List<Path> mapFiles = new ArrayList<>();
-                if (pNode == null) {
-                    mapFiles = fileProvider.listPackageMapFiles();
-                    if (mapFiles.isEmpty()) return false;
+                    pNode = fileProvider.getPackageTable(container).get(packageName);
                 }
 
-                for (Path p : mapFiles) {
-                    pTable = StorageFileProvider.getPackageTable(p);
-                    pNode = pTable.get(packageName);
-                    if (pNode != null) {
-                        container = pTable.getHeader().getContainer();
-                        break;
+                if (pNode == null) {
+                    // Search all package map files if not found in the system partition.
+                    for (Path p : fileProvider.listPackageMapFiles()) {
+                        PackageTable pTable = StorageFileProvider.getPackageTable(p);
+                        pNode = pTable.get(packageName);
+                        if (pNode != null) {
+                            container = pTable.getHeader().getContainer();
+                            break;
+                        }
                     }
                 }
             } else {
+                if (!fileProvider.containerFileExists(container)) {
+                    return ERROR_CONTAINER_NOT_FOUND;
+                }
                 pNode = fileProvider.getPackageTable(container).get(packageName);
             }
 
             if (pNode == null) {
                 // for the case package is not found in all container, return instead of throwing
                 // error
-                return false;
+                return ERROR_PACKAGE_NOT_FOUND;
             }
 
             mFlagTable = fileProvider.getFlagTable(container);
             mFlagValueList = fileProvider.getFlagValueList(container);
             mPNode = pNode;
         } catch (Exception e) {
-            throw new AconfigStorageException(
-                    String.format(
-                            "cannot load package %s, from container %s", packageName, container),
-                    e);
+            throw e;
         } finally {
             StrictMode.setThreadPolicy(oldPolicy);
         }
-        return true;
+        return 0;
     }
 }
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageFileProvider.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageFileProvider.java
index f586150..1f84a51 100644
--- a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageFileProvider.java
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageFileProvider.java
@@ -53,7 +53,7 @@
     /** @hide */
     public boolean containerFileExists(String container) {
         if (container == null) {
-            return Files.exists(Paths.get(DEFAULT_MAP_PATH));
+            return Files.exists(Paths.get(mMapPath));
         }
         return Files.exists(Paths.get(mMapPath, container + PMAP_FILE_EXT));
     }
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/java/AconfigPackageImplTest.java b/tools/aconfig/aconfig_storage_read_api/tests/java/AconfigPackageImplTest.java
index 0f3be7a..8a72f0a 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/java/AconfigPackageImplTest.java
+++ b/tools/aconfig/aconfig_storage_read_api/tests/java/AconfigPackageImplTest.java
@@ -16,6 +16,7 @@
 
 package android.aconfig.storage.test;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThrows;
@@ -25,6 +26,7 @@
 import android.aconfig.storage.AconfigStorageException;
 import android.aconfig.storage.StorageFileProvider;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -32,33 +34,62 @@
 @RunWith(JUnit4.class)
 public class AconfigPackageImplTest {
 
+    private StorageFileProvider pr;
+
+    @Before
+    public void setup() {
+        pr = new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
+    }
+
     @Test
     public void testLoad_onlyPackageName() throws Exception {
-        StorageFileProvider pr =
-                new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
-        AconfigPackageImpl p = AconfigPackageImpl.load("com.android.aconfig.storage.test_1", pr);
+        AconfigPackageImpl p = new AconfigPackageImpl();
+        p.load("com.android.aconfig.storage.test_1", pr);
         assertNotNull(p);
     }
 
     @Test
     public void testLoad_groupNameFingerprint() throws Exception {
-        StorageFileProvider pr =
-                new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
-        AconfigPackageImpl p =
-                AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr);
+        AconfigPackageImpl p = new AconfigPackageImpl();
+        p.load("mockup", "com.android.aconfig.storage.test_1", pr);
         assertNotNull(p);
+    }
 
+    @Test
+    public void testLoad_error() throws Exception {
+        AconfigPackageImpl p = new AconfigPackageImpl();
+        // cannot find package
+        assertEquals(
+                AconfigPackageImpl.ERROR_PACKAGE_NOT_FOUND,
+                p.load("mockup", "com.android.aconfig.storage.test_10", pr));
+        // cannot find package
+        assertEquals(
+                AconfigPackageImpl.ERROR_PACKAGE_NOT_FOUND,
+                p.load("com.android.aconfig.storage.test_10", pr));
+        // cannot find container
+        assertEquals(
+                AconfigPackageImpl.ERROR_CONTAINER_NOT_FOUND,
+                p.load(null, "com.android.aconfig.storage.test_1", pr));
+        assertEquals(
+                AconfigPackageImpl.ERROR_CONTAINER_NOT_FOUND,
+                p.load("test", "com.android.aconfig.storage.test_1", pr));
+
+        // new storage doesn't exist
+        pr = new StorageFileProvider("fake/path/", "fake/path/");
+        assertEquals(
+                AconfigPackageImpl.ERROR_NEW_STORAGE_SYSTEM_NOT_FOUND, p.load("fake_package", pr));
+
+        // file read issue
+        pr = new StorageFileProvider(TestDataUtils.TESTDATA_PATH, "fake/path/");
         assertThrows(
                 AconfigStorageException.class,
-                () -> AconfigPackageImpl.load("test", "com.android.aconfig.storage.test_1", pr));
+                () -> p.load("mockup", "com.android.aconfig.storage.test_1", pr));
     }
 
     @Test
     public void testGetBooleanFlagValue_flagName() throws Exception {
-        StorageFileProvider pr =
-                new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
-        AconfigPackageImpl p =
-                AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr);
+        AconfigPackageImpl p = new AconfigPackageImpl();
+        p.load("mockup", "com.android.aconfig.storage.test_1", pr);
         assertFalse(p.getBooleanFlagValue("disabled_rw", true));
         assertTrue(p.getBooleanFlagValue("enabled_ro", false));
         assertTrue(p.getBooleanFlagValue("enabled_rw", false));
@@ -67,10 +98,8 @@
 
     @Test
     public void testGetBooleanFlagValue_index() throws Exception {
-        StorageFileProvider pr =
-                new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
-        AconfigPackageImpl p =
-                AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr);
+        AconfigPackageImpl p = new AconfigPackageImpl();
+        p.load("mockup", "com.android.aconfig.storage.test_1", pr);
         assertFalse(p.getBooleanFlagValue(0));
         assertTrue(p.getBooleanFlagValue(1));
         assertTrue(p.getBooleanFlagValue(2));
@@ -78,10 +107,8 @@
 
     @Test
     public void testHasPackageFingerprint() throws Exception {
-        StorageFileProvider pr =
-                new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
-        AconfigPackageImpl p =
-                AconfigPackageImpl.load("mockup", "com.android.aconfig.storage.test_1", pr);
+        AconfigPackageImpl p = new AconfigPackageImpl();
+        p.load("mockup", "com.android.aconfig.storage.test_1", pr);
         assertFalse(p.hasPackageFingerprint());
     }
 }
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/java/jarjar.txt b/tools/aconfig/aconfig_storage_read_api/tests/java/jarjar.txt
index 64ba09c..24952ec 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/java/jarjar.txt
+++ b/tools/aconfig/aconfig_storage_read_api/tests/java/jarjar.txt
@@ -7,7 +7,7 @@
 rule android.aconfig.storage.FileType android.aconfig.storage.test.FileType
 rule android.aconfig.storage.FlagValueList android.aconfig.storage.test.FlagValueList
 rule android.aconfig.storage.TableUtils android.aconfig.storage.test.TableUtils
-rule android.aconfig.storage.Package android.aconfig.storage.test.Package
+rule android.aconfig.storage.AconfigPackageImpl android.aconfig.storage.test.AconfigPackageImpl
 rule android.aconfig.storage.StorageFileProvider android.aconfig.storage.test.StorageFileProvider