Limit System SDK to 34 for Java modules in the vendor partition
This change disallows Java modules in the vendor partition to use System
SDK that is newer than API level 34; 34 is the latest allowed.
Background 1: with Trunk Stable, the system/vendor interface is released
at Q2 whereas the system/app interface is released at Q3. In other
words, at Q2, the APIs which will be added to the system SDK at Q3 are
not available. Since the system/vendor interface (which is fronzen at
Q2) is what the modules in the vendor partition will be building
against, they can't and shouldn't use those new APIs that will be added
in the future (Q3). Using those APIs is risky because there's a chance
that those APIs get removed or changed between Q2 and Q3. For example,
2024 Q2 is technically still Android U, not Android V.
Background 2: The use of Java APIs in the vendor partition had many
issues. Most significantly, those "vendor" Java apps are categorized as
part of the system partition because all Java app processes require
access to platform internal libraries that are prohibited to vendor
processes. Furthermore, since the Project Treble, the vendor partition
was re-purposed to a partition to host SoC-dependent bits - usually
HALs. Implementing HALs in Java has never been officially supported and
has had many loop holes.
We'd like to use both background 1 and 2 as a chance to disallow any
Java code in the vendor partition. However, since there are already some
Java modules in the partition, we can't suddenly ban it. The deprecation
will be made gradually, and this CL is the start.
This CL implements the "Make" part of the restriction. The "Soong" part
will follow.
Note that LOCAL_SDK_VERSION := current or LOCAL_SDK_VERSION :=
system_current is automatically overridden into 34 or system_34. This is
to prevent sudden breakage of vendor modules that have been targetting
the latest (i.e. current) API level. They will however fail if they use
APIs newer than API level 34.
Bug: 314011075
Test: The following Android.mk module fails as expected.
some/Android.mk:
include $(CLEAR_VARS)
LOCAL_MODULE := example_module
LOCAL_VENDOR_MODULE := true
LOCAL_SDK_VERSION := system_35
LOCAL_SRC_FILES := Foo.java
include $(BUILD_JAVA_LIBRARY)
FAILED:
some/Android.mk: error: example_module: Incompatible
LOCAL_SDK_VERSION 'system_35'. System SDK version '35' is not supported.
Supported versions are: 28 29 30 31 32 33 34
Change-Id: I44c29c6dc45b91a9a30b8a21cd2baae685fa27fb
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f533358..d3066c8 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -121,9 +121,17 @@
$(LOCAL_PROPRIETARY_MODULE))
include $(BUILD_SYSTEM)/local_vndk.mk
-include $(BUILD_SYSTEM)/local_systemsdk.mk
+
+# local_current_sdk needs to run before local_systemsdk because the former may override
+# LOCAL_SDK_VERSION which is used by the latter.
include $(BUILD_SYSTEM)/local_current_sdk.mk
+# Check if the use of System SDK is correct. Note that, for Soong modules, the system sdk version
+# check is done in Soong. No need to do it twice.
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+include $(BUILD_SYSTEM)/local_systemsdk.mk
+endif
+
# Ninja has an implicit dependency on the command being run, and kati will
# regenerate the ninja manifest if any read makefile changes, so there is no
# need to have dependencies on makefiles.
diff --git a/core/local_current_sdk.mk b/core/local_current_sdk.mk
index ea7da8a..ccdbf77 100644
--- a/core/local_current_sdk.mk
+++ b/core/local_current_sdk.mk
@@ -14,13 +14,24 @@
# limitations under the License.
#
ifdef BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES
- ifneq (current,$(BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES))
+ _override_to := $(BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES)
+
+ # b/314011075: apks and jars in the vendor or odm partitions cannot use
+ # system SDK 35 and beyond. In order not to suddenly break those vendor
+ # modules using current or system_current as their LOCAL_SDK_VERSION,
+ # override it to 34, which is the maximum API level allowed for them.
+ ifneq (,$(filter JAVA_LIBRARIES APPS,$(LOCAL_MODULE_CLASS)))
+ _override_to := 34
+ endif
+
+ ifneq (current,$(_override_to))
ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
ifeq (current,$(LOCAL_SDK_VERSION))
- LOCAL_SDK_VERSION := $(BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES)
+ LOCAL_SDK_VERSION := $(_override_to)
else ifeq (system_current,$(LOCAL_SDK_VERSION))
- LOCAL_SDK_VERSION := system_$(BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES)
+ LOCAL_SDK_VERSION := system_$(_override_to)
endif
endif
endif
+ _override_to :=
endif
diff --git a/core/local_systemsdk.mk b/core/local_systemsdk.mk
index 460073d..fcde700 100644
--- a/core/local_systemsdk.mk
+++ b/core/local_systemsdk.mk
@@ -33,6 +33,9 @@
# Runtime resource overlays are exempted from building against System SDK.
# TODO(b/155027019): remove this, after no product/vendor apps rely on this behavior.
LOCAL_SDK_VERSION := system_current
+ # We have run below again since LOCAL_SDK_VERSION is newly set and the "_current"
+ # may have to be updated
+ include $(BUILD_SYSTEM)/local_current_sdk.mk
endif
endif
endif
@@ -54,7 +57,30 @@
# If not, vendor apks are treated equally to system apps
_supported_systemsdk_versions := $(PLATFORM_SYSTEMSDK_VERSIONS)
endif
+
+ # b/314011075: apks and jars in the vendor or odm partitions cannot use system SDK 35 and beyond.
+ # This is to discourage the use of Java APIs in the partitions, which hasn't been supported since
+ # the beginning of the project Treble back in Android 10. Ultimately, we'd like to completely
+ # disallow any Java API in the partitions, but it shall be done progressively.
+ ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
+ # 28 is the API level when BOARD_SYSTEMSDK_VERSIONS was introduced. So, it's the oldset API
+ # we allow.
+ _supported_systemsdk_versions := $(call int_range_list, 28, 34)
+ endif
+
+ # Extract version number from LOCAL_SDK_VERSION (ex: system_34 -> 34)
_system_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+ # However, the extraction may fail if it doesn't have any number (i.e. current, core_current,
+ # system_current, or similar) Then use the latest platform SDK version number or the actual
+ # codename.
+ ifeq (,$(_system_sdk_version)
+ ifeq (REL,$(PLATFORM_VERSION_CODENAME))
+ _system_sdk_version := $(PLATFORM_SDK_VERSION)
+ else
+ _system_sdk_version := $(PLATFORM_VERSION_CODENAME)
+ endif
+ endif
+
ifneq ($(_system_sdk_version),$(filter $(_system_sdk_version),$(_supported_systemsdk_versions)))
$(call pretty-error,Incompatible LOCAL_SDK_VERSION '$(LOCAL_SDK_VERSION)'. \
System SDK version '$(_system_sdk_version)' is not supported. Supported versions are: $(_supported_systemsdk_versions))