#!/usr/bin/env python3 # # Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # """A tool for generating {partition}/build.prop"""
# build_desc is human readable strings that describe this build. This has the same info as the # build fingerprint. # e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys"
config["BuildDesc"] = f"{config['DeviceProduct']}-{config['BuildVariant']} " \
f"{config['Platform_version_name']} {config['BuildId']} " \
f"{config['BuildNumber']} {config['BuildVersionTags']}"
def generate_common_build_props(args):
print("####################################")
print("# from generate-common-build-props")
print("# These properties identify this partition image.")
print("####################################")
if partition != "system": if config["ProductModelForAttestation"]:
print(f"ro.product.model_for_attestation={config['ProductModelForAttestation']}") if config["ProductBrandForAttestation"]:
print(f"ro.product.brand_for_attestation={config['ProductBrandForAttestation']}") if config["ProductNameForAttestation"]:
print(f"ro.product.name_for_attestation={config['ProductNameForAttestation']}") if config["ProductDeviceForAttestation"]:
print(f"ro.product.device_for_attestation={config['ProductDeviceForAttestation']}") if config["ProductManufacturerForAttestation"]:
print(f"ro.product.manufacturer_for_attestation={config['ProductManufacturerForAttestation']}")
if config["ZygoteForce64"]: if partition == "vendor":
print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList64']}")
print(f"ro.{partition}.product.cpu.abilist32=")
print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}") else: if partition == "system"or partition == "vendor"or partition == "odm":
print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList']}")
print(f"ro.{partition}.product.cpu.abilist32={config['DeviceAbiList32']}")
print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
print(f"ro.{partition}.build.date={config['Date']}")
print(f"ro.{partition}.build.date.utc={config['DateUtc']}") # Allow optional assignments for ARC forward-declarations (b/249168657) # TODO: Remove any tag-related inconsistencies once the goals from # go/arc-android-sigprop-changes have been achieved. if partition == "system":
print(f"ro.{partition}.build.fingerprint?={config['BuildSystemFingerprint']}") else:
print(f"ro.{partition}.build.fingerprint?={config['BuildFingerprint']}")
print(f"ro.{partition}.build.id?={config['BuildId']}")
print(f"ro.{partition}.build.uuid?={config['BuildUUID']}")
print(f"ro.{partition}.build.tags?={config['BuildVersionTags']}")
print(f"ro.{partition}.build.type={config['BuildVariant']}")
print(f"ro.{partition}.build.version.incremental={config['BuildNumber']}")
print(f"ro.{partition}.build.version.release={config['Platform_version_last_stable']}")
print(f"ro.{partition}.build.version.release_or_codename={config['Platform_version_name']}")
print(f"ro.{partition}.build.version.sdk={config['Platform_sdk_version']}")
print(f"ro.{partition}.build.version.sdk_full={config['Platform_sdk_version_full']}")
def generate_build_info(args):
print()
print("####################################")
print("# from gen_build_prop.py:generate_build_info")
print("####################################")
print("# begin build properties")
# ro.build.display.id is shown under Settings -> About Phone if config["BuildVariant"] == "user": # User builds should show: # release build number or branch.buld_number non-release builds
# Dev. branches should have DISPLAY_BUILD_NUMBER set if config["DisplayBuildNumber"]:
print(f"ro.build.display.id?={config['BuildId']}.{config['BuildNumber']} {config['BuildKeys']}") else:
print(f"ro.build.display.id?={config['BuildId']} {config['BuildKeys']}") else: # Non-user builds should show detailed build information (See build desc above)
print(f"ro.build.display.id?={config['BuildDesc']}")
print(f"ro.build.version.incremental={config['BuildNumber']}")
print(f"ro.build.version.sdk={config['Platform_sdk_version']}")
print(f"ro.build.version.sdk_full={config['Platform_sdk_version_full']}")
print(f"ro.build.version.preview_sdk={config['Platform_preview_sdk_version']}")
print(f"ro.build.version.preview_sdk_fingerprint={config['PlatformPreviewSdkFingerprint']}")
print(f"ro.build.version.codename={config['Platform_sdk_codename']}")
print(f"ro.build.version.all_codenames={','.join(config['Platform_version_active_codenames'])}")
print(f"ro.build.version.known_codenames={config['Platform_version_known_codenames']}")
print(f"ro.build.version.release={config['Platform_version_last_stable']}")
print(f"ro.build.version.release_or_codename={config['Platform_version_name']}")
print(f"ro.build.version.release_or_preview_display={config['Platform_display_version_name']}")
print(f"ro.build.version.security_patch={config['Platform_security_patch']}")
print(f"ro.build.version.base_os={config['Platform_base_os']}")
print(f"ro.build.version.min_supported_target_sdk={build_flags['RELEASE_PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION']}")
print(f"ro.build.date={config['Date']}")
print(f"ro.build.date.utc={config['DateUtc']}")
print(f"ro.build.type={config['BuildVariant']}")
print(f"ro.build.user={config['BuildUsername']}")
print(f"ro.build.host={config['BuildHostname']}") # TODO: Remove any tag-related optional property declarations once the goals # from go/arc-android-sigprop-changes have been achieved.
print(f"ro.build.tags?={config['BuildVersionTags']}") # ro.build.flavor are used only by the test harness to distinguish builds. # Only add _asan for a sanitized build if it isn't already a part of the # flavor (via a dedicated lunch config for example).
print(f"ro.build.flavor={config['BuildFlavor']}")
# These values are deprecated, use "ro.product.cpu.abilist" # instead (see below).
print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
print(f"# use ro.product.cpu.abilist instead.")
print(f"ro.product.cpu.abi={config['DeviceAbi'][0]}") if len(config["DeviceAbi"]) > 1:
print(f"ro.product.cpu.abi2={config['DeviceAbi'][1]}")
if config["ProductLocales"]:
print(f"ro.product.locale={config['ProductLocales'][0]}")
print(f"ro.wifi.channels={' '.join(config['ProductDefaultWifiChannels'])}")
print(f"# Do not try to parse description or thumbprint")
print(f"ro.build.description?={config['BuildDesc']}") if"BuildThumbprint"in config:
print(f"ro.build.thumbprint={config['BuildThumbprint']}")
print(f"# end build properties")
def write_properties_from_file(file): # Make and Soong use different intermediate files to build vendor/build.prop. # Although the sysprop contents are same, the absolute paths of these # intermediate files are different. # Print the filename for the intermediate files (files in OUT_DIR). # This helps with validating mk->soong migration of android partitions.
filename = os.path.basename(file.name) if file.name.startswith(os.environ.get("OUT_DIR")) else file.name
print()
print("####################################")
print(f"# from {filename}")
print("####################################")
print(file.read(), end="")
# Implement the legacy behavior when BUILD_BROKEN_DUP_SYSPROP is on. # Optional assignments are all converted to normal assignments and # when their duplicates the first one wins. if build_broken_dup_sysprop:
processed_props = []
seen_props = set() for line in props:
line = line.replace("?=", "=")
key, value = line.split("=", 1) if key in seen_props: continue
seen_props.add(key)
processed_props.append(line)
props = processed_props
# Add the product-defined properties to the build properties. ifnot config["PropertySplitEnabled"] ornot config["VendorImageFileSystemType"]: if"PRODUCT_PROPERTY_OVERRIDES"in config:
props += config["PRODUCT_PROPERTY_OVERRIDES"]
# We may be able to remove this property now and update all clients to assume # that treble is enabled.
props.append(f"ro.treble.enabled=true")
# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK # in the system partition supports. if config["VendorApiLevel"]:
props.append(f"ro.llndk.api_level={config['VendorApiLevel']}")
# Sets ro.actionable_compatible_property.enabled to know on runtime whether # the allowed list of actionable compatible properties is enabled or not.
props.append("ro.actionable_compatible_property.enabled=true")
# Enable core platform API violation warnings on userdebug and eng builds. if config["BuildVariant"] != "user":
props.append("persist.debug.dalvik.vm.core_platform_api_policy=just-warn")
# Define ro.sanitize.<name> properties for all global sanitizers. for sanitize_target in config["SanitizeDevice"]:
props.append(f"ro.sanitize.{sanitize_target}=true")
# Sets the default value of ro.postinstall.fstab.prefix to /system. # # Device board configs can override this to /product to use a # product-specific fstab.postinstall file (installed to # /product/etc/fstab.postinstall). If not overridden, the # system/extras/cppreopts/fstab.postinstall file (installed to # /system/etc/fstab.postinstall) will be used. # Note: The default fstab.postinstall is generic and may be slower # because it tries different mount options line by line to ensure # compatibility across various devices. # # PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product # # It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to # mount system_other partition.
props.append("ro.postinstall.fstab.prefix=/system")
enable_target_debugging = True
enable_dalvik_lock_contention_logging = True if config["BuildVariant"] == "user"or config["BuildVariant"] == "userdebug": # Target is secure in user builds.
props.append("ro.secure=1")
props.append("security.perf_harden=1")
if config["BuildVariant"] == "user": # Disable debugging in plain user builds.
props.append("ro.adb.secure=1")
enable_target_debugging = False
enable_dalvik_lock_contention_logging = False else: # Disable debugging in userdebug builds if PRODUCT_NOT_DEBUGGABLE_IN_USERDEBUG # is set. if config["ProductNotDebuggableInUserdebug"]:
enable_target_debugging = False
# Disallow mock locations by default for user builds
props.append("ro.allow.mock.location=0") else: # Turn on checkjni for non-user builds.
props.append("ro.kernel.android.checkjni=1") # Set device insecure for non-user builds.
props.append("ro.secure=0") # Allow mock locations by default for non user builds
props.append("ro.allow.mock.location=1")
if enable_dalvik_lock_contention_logging: # Enable Dalvik lock contention logging.
props.append("dalvik.vm.lockprof.threshold=500")
if enable_target_debugging: # Target is more debuggable and adbd is on by default
props.append("ro.debuggable=1") else: # Target is less debuggable and adbd is off by default
props.append("ro.debuggable=0")
if config["BuildVariant"] == "eng": if"ro.setupwizard.mode=ENABLED"in props: # Don't require the setup wizard on eng builds
props = list(filter(lambda x: not x.startswith("ro.setupwizard.mode="), props))
props.append("ro.setupwizard.mode=OPTIONAL")
# Add cpu properties for bionic and ART.
props.append(f"ro.bionic.arch={config['DeviceArch']}")
props.append(f"ro.bionic.cpu_variant={config['DeviceCpuVariantRuntime']}")
props.append(f"ro.bionic.2nd_arch={config['DeviceSecondaryArch']}")
props.append(f"ro.bionic.2nd_cpu_variant={config['DeviceSecondaryCpuVariantRuntime']}")
props.append(f"dalvik.vm.isa.{config['DeviceArch']}.variant={config['Dex2oatTargetCpuVariantRuntime']}") if config["Dex2oatTargetInstructionSetFeatures"]:
props.append(f"dalvik.vm.isa.{config['DeviceArch']}.features={config['Dex2oatTargetInstructionSetFeatures']}")
if config["DeviceSecondaryArch"]:
props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.variant={config['SecondaryDex2oatCpuVariantRuntime']}") if config["SecondaryDex2oatInstructionSetFeatures"]:
props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.features={config['SecondaryDex2oatInstructionSetFeatures']}")
# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger # mode (via libminui). if config["RecoveryDefaultRotation"]:
props.append(f"ro.minui.default_rotation={config['RecoveryDefaultRotation']}")
if config["RecoveryOverscanPercent"]:
props.append(f"ro.minui.overscan_percent={config['RecoveryOverscanPercent']}")
if config["RecoveryPixelFormat"]:
props.append(f"ro.minui.pixel_format={config['RecoveryPixelFormat']}")
if"RecoveryNoInitialModsetFlush"in config:
props.append(f"ro.minui.no_initial_modset_flush={'true' if config['RecoveryNoInitialModsetFlush'] else 'false'}")
if"UseDynamicPartitions"in config:
props.append(f"ro.boot.dynamic_partitions={'true' if config['UseDynamicPartitions'] else 'false'}")
if"RetrofitDynamicPartitions"in config:
props.append(f"ro.boot.dynamic_partitions_retrofit={'true' if config['RetrofitDynamicPartitions'] else 'false'}")
if config["ShippingApiLevel"]:
props.append(f"ro.product.first_api_level={config['ShippingApiLevel']}")
if config["BuildVariant"] != "user": if"BuildDebugfsRestrictionsEnabled"in config:
props.append(f"ro.product.debugfs_restrictions.enabled={'true' if config['BuildDebugfsRestrictionsEnabled'] else 'false'}")
# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level. # This must not be defined for the non-GRF devices. # The values of the GRF properties will be verified by post_process_props.py if config["BoardShippingApiLevel"]:
props.append(f"ro.board.first_api_level={config['BoardShippingApiLevel']}")
# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface. # This must not be altered outside of build system. if config["VendorApiLevel"]:
props.append(f"ro.board.api_level?={config['VendorApiLevel']}") if config["VendorApiLevelPropOverride"]:
props.append(f"ro.board.api_level={config['VendorApiLevelPropOverride']}")
# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen. if build_flags["RELEASE_BOARD_API_LEVEL_FROZEN"]:
props.append(f"ro.board.api_frozen=true")
# Set build prop. This prop is read by ota_from_target_files when generating OTA, # to decide if VABC should be disabled. if config["DontUseVabcOta"]:
props.append(f"ro.vendor.build.dont_use_vabc=true")
if config["ScreenDensity"]:
props.append(f"ro.sf.lcd_density={config['ScreenDensity']}")
if"AbOtaUpdater"in config:
props.append(f"ro.build.ab_update={'true' if config['AbOtaUpdater'] else 'false'}") if config["AbOtaUpdater"]:
props.append(f"ro.vendor.build.ab_ota_partitions={config['AbOtaPartitions']}")
config["ADDITIONAL_VENDOR_PROPERTIES"] = props
# Add the 16K developer args if it is defined for the product.
config["ADDITIONAL_VENDOR_PROPERTIES"].append(f"ro.product.build.16k_page.enabled={'true' if config['Product16KDeveloperOption'] else 'false'}")
# Add the system server compiler filter if they are specified for the product. if config["SystemServerCompilerFilter"]:
props.append(f"dalvik.vm.systemservercompilerfilter={config['SystemServerCompilerFilter']}")
props.append(f"ro.product.page_size={16384 if config['TargetBoots16K'] else 4096}")
if"AbOtaUpdater"in config and config["AbOtaUpdater"]:
props.append(f"ro.product.ab_ota_partitions={config['AbOtaPartitions']}")
# Set this property for VTS to skip large page size tests on unsupported devices.
props.append(f"ro.product.cpu.pagesize.max={config['DeviceMaxPageSizeSupported']}")
if config["NoBionicPageSizeMacro"]:
props.append(f"ro.product.build.no_bionic_page_size_macro=true")
# This is a temporary system property that controls the ART module. The plan is # to remove it by Aug 2025, at which time Mainline updates of the ART module # will ignore it as well. # If the value is "default", it will be mangled by post_process_props.py.
props.append(f"ro.dalvik.vm.enable_uffd_gc={config['EnableUffdGc']}")
config["ADDITIONAL_PRODUCT_PROPERTIES"] = props
def build_system_prop(args):
config = args.config
# Order matters here. When there are duplicates, the last one wins. # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = [ "ADDITIONAL_SYSTEM_PROPERTIES", "PRODUCT_SYSTEM_PROPERTIES", # TODO(b/117892318): deprecate this "PRODUCT_SYSTEM_DEFAULT_PROPERTIES",
]
# Order matters here. When there are duplicates, the last one wins. # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = ["PRODUCT_SYSTEM_EXT_PROPERTIES"]
# Order matters here. When there are duplicates, the last one wins. # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = [] if config["PropertySplitEnabled"]:
variables += [ "ADDITIONAL_VENDOR_PROPERTIES", "PRODUCT_VENDOR_PROPERTIES", # TODO(b/117892318): deprecate this "PRODUCT_DEFAULT_PROPERTY_OVERRIDES", "PRODUCT_PROPERTY_OVERRIDES",
]
# Order matters here. When there are duplicates, the last one wins. # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = [ "ADDITIONAL_PRODUCT_PROPERTIES", "PRODUCT_PRODUCT_PROPERTIES",
]
gen_common_build_props = True
# Skip common /product properties generation if device released before R and # has no product partition. This is the first part of the check. if config["Shipping_api_level"] and int(config["Shipping_api_level"]) < 30:
gen_common_build_props = False
# The second part of the check - always generate common properties for the # devices with product partition regardless of shipping level. if config["UsesProductImage"]:
gen_common_build_props = True
# Product is the most product-specific partition. So it is the best place to # have the build info. # Product props will be read for any duplicatied properties.
build_prop(args, gen_build_info=True, gen_common_build_props=gen_common_build_props, variables=variables)
if config["OemProperties"]:
print("####################################")
print("# PRODUCT_OEM_PROPERTIES")
print("####################################")
for prop in config["OemProperties"]:
print(f"import /oem/oem.prop {prop}")
if gen_common_build_props:
generate_common_build_props(args)
if gen_build_info:
generate_build_info(args)
for prop_file in args.prop_files:
write_properties_from_file(prop_file)
for variable in variables: if variable in config:
write_properties_from_variable(variable, config[variable], args.build_broken_dup_sysprop)
def main():
args = parse_args()
with contextlib.redirect_stdout(args.out):
match args.partition:
case "system":
build_system_prop(args)
case "system_ext":
build_system_ext_prop(args)
case "odm":
build_odm_prop(args)
case "product":
build_product_prop(args)
case "vendor":
build_vendor_prop(args)
case "system_dlkm" | "vendor_dlkm" | "odm_dlkm" | "bootimage":
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=[])
case _:
sys.exit(f"not supported partition {args.partition}")
if __name__ == "__main__":
main()
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.