blob: 2167741b857d55f302952045debf32c5b890d6cc [file] [log] [blame]
Inseob Kimbac07552024-06-18 11:09:12 +09001#!/usr/bin/env python3
2#
3# Copyright (C) 2024 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""A tool for generating {partition}/build.prop"""
18
19import argparse
20import contextlib
21import json
Justin Yun962f9112024-07-03 13:34:29 +090022import os
Inseob Kimbac07552024-06-18 11:09:12 +090023import subprocess
24import sys
25
Justin Yun962f9112024-07-03 13:34:29 +090026TEST_KEY_DIR = "build/make/target/product/security"
27
Inseob Kimbac07552024-06-18 11:09:12 +090028def get_build_variant(product_config):
29 if product_config["Eng"]:
30 return "eng"
31 elif product_config["Debuggable"]:
32 return "userdebug"
33 else:
34 return "user"
35
36def get_build_flavor(product_config):
37 build_flavor = product_config["DeviceProduct"] + "-" + get_build_variant(product_config)
38 if "address" in product_config.get("SanitizeDevice", []) and "_asan" not in build_flavor:
39 build_flavor += "_asan"
40 return build_flavor
41
42def get_build_keys(product_config):
43 default_cert = product_config.get("DefaultAppCertificate", "")
micky3875ac00262024-11-09 21:03:38 -050044 if "ROM_BUILDTYPE" in product_config:
45 return "release-keys"
micky3875ac00262024-11-09 21:03:38 -050046 elif default_cert == os.path.join(TEST_KEY_DIR, "testKey"):
Inseob Kimbac07552024-06-18 11:09:12 +090047 return "test-keys"
micky387c7e4b662024-11-12 15:54:28 -050048 else:
49 return "dev-keys"
Inseob Kimbac07552024-06-18 11:09:12 +090050
Luca Stefani74b53962024-09-07 11:49:03 +020051def override_config(config):
52 if "PRODUCT_BUILD_PROP_OVERRIDES" in config:
53 current_key = None
54 props_overrides = {}
55
56 for var in config["PRODUCT_BUILD_PROP_OVERRIDES"]:
57 if "=" in var:
58 current_key, value = var.split("=")
59 props_overrides[current_key] = value
60 else:
61 props_overrides[current_key] += f" {var}"
62
63 for key, value in props_overrides.items():
64 if key not in config:
65 print(f"Key \"{key}\" isn't a valid prop override", file=sys.stderr)
66 sys.exit(1)
67 config[key] = value
68
Inseob Kimbac07552024-06-18 11:09:12 +090069def parse_args():
70 """Parse commandline arguments."""
71 parser = argparse.ArgumentParser()
72 parser.add_argument("--build-fingerprint-file", required=True, type=argparse.FileType("r"))
73 parser.add_argument("--build-hostname-file", required=True, type=argparse.FileType("r"))
74 parser.add_argument("--build-number-file", required=True, type=argparse.FileType("r"))
75 parser.add_argument("--build-thumbprint-file", type=argparse.FileType("r"))
76 parser.add_argument("--build-username", required=True)
77 parser.add_argument("--date-file", required=True, type=argparse.FileType("r"))
78 parser.add_argument("--platform-preview-sdk-fingerprint-file", required=True, type=argparse.FileType("r"))
79 parser.add_argument("--prop-files", action="append", type=argparse.FileType("r"), default=[])
80 parser.add_argument("--product-config", required=True, type=argparse.FileType("r"))
81 parser.add_argument("--partition", required=True)
82 parser.add_argument("--build-broken-dup-sysprop", action="store_true", default=False)
83
84 parser.add_argument("--out", required=True, type=argparse.FileType("w"))
85
86 args = parser.parse_args()
87
88 # post process parse_args requiring manual handling
89 args.config = json.load(args.product_config)
90 config = args.config
91
92 config["BuildFlavor"] = get_build_flavor(config)
93 config["BuildKeys"] = get_build_keys(config)
94 config["BuildVariant"] = get_build_variant(config)
95
96 config["BuildFingerprint"] = args.build_fingerprint_file.read().strip()
97 config["BuildHostname"] = args.build_hostname_file.read().strip()
98 config["BuildNumber"] = args.build_number_file.read().strip()
99 config["BuildUsername"] = args.build_username
Inseob Kimb2b1b562024-06-25 19:09:12 +0900100
101 build_version_tags_list = config["BuildVersionTags"]
Inseob Kimbac07552024-06-18 11:09:12 +0900102 if config["BuildType"] == "debug":
Inseob Kimb2b1b562024-06-25 19:09:12 +0900103 build_version_tags_list.append("debug")
104 build_version_tags_list.append(config["BuildKeys"])
105 build_version_tags = ",".join(sorted(set(build_version_tags_list)))
106 config["BuildVersionTags"] = build_version_tags
Inseob Kimbac07552024-06-18 11:09:12 +0900107
108 raw_date = args.date_file.read().strip()
109 config["Date"] = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip()
110 config["DateUtc"] = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip()
111
112 # build_desc is human readable strings that describe this build. This has the same info as the
113 # build fingerprint.
114 # e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys"
115 config["BuildDesc"] = f"{config['DeviceProduct']}-{config['BuildVariant']} " \
116 f"{config['Platform_version_name']} {config['BuildId']} " \
117 f"{config['BuildNumber']} {config['BuildVersionTags']}"
118
119 config["PlatformPreviewSdkFingerprint"] = args.platform_preview_sdk_fingerprint_file.read().strip()
120
121 if args.build_thumbprint_file:
122 config["BuildThumbprint"] = args.build_thumbprint_file.read().strip()
123
basamaryan4baf3062024-10-22 12:08:07 -0400124 config["OmniRomDesc"] = config["BuildDesc"]
Michael Bestasbcfcf762024-10-20 07:20:42 +0300125 config["OmniRomDevice"] = config["DeviceName"]
126
Luca Stefani74b53962024-09-07 11:49:03 +0200127 override_config(config)
128
Inseob Kimbac07552024-06-18 11:09:12 +0900129 append_additional_system_props(args)
130 append_additional_vendor_props(args)
131 append_additional_product_props(args)
132
133 return args
134
135def generate_common_build_props(args):
136 print("####################################")
Spandan Das301c2302024-12-12 23:40:52 +0000137 print("# from generate-common-build-props")
Inseob Kimbac07552024-06-18 11:09:12 +0900138 print("# These properties identify this partition image.")
139 print("####################################")
140
141 config = args.config
Spandan Das7cf5d502024-11-06 04:09:21 +0000142 build_flags = config["BuildFlags"]
Inseob Kimbac07552024-06-18 11:09:12 +0900143 partition = args.partition
144
145 if partition == "system":
146 print(f"ro.product.{partition}.brand={config['SystemBrand']}")
147 print(f"ro.product.{partition}.device={config['SystemDevice']}")
148 print(f"ro.product.{partition}.manufacturer={config['SystemManufacturer']}")
149 print(f"ro.product.{partition}.model={config['SystemModel']}")
150 print(f"ro.product.{partition}.name={config['SystemName']}")
151 else:
152 print(f"ro.product.{partition}.brand={config['ProductBrand']}")
153 print(f"ro.product.{partition}.device={config['DeviceName']}")
154 print(f"ro.product.{partition}.manufacturer={config['ProductManufacturer']}")
155 print(f"ro.product.{partition}.model={config['ProductModel']}")
156 print(f"ro.product.{partition}.name={config['DeviceProduct']}")
157
158 if partition != "system":
Inseob Kimaaf72f22024-08-05 12:51:05 +0900159 if config["ProductModelForAttestation"]:
160 print(f"ro.product.model_for_attestation={config['ProductModelForAttestation']}")
161 if config["ProductBrandForAttestation"]:
162 print(f"ro.product.brand_for_attestation={config['ProductBrandForAttestation']}")
163 if config["ProductNameForAttestation"]:
164 print(f"ro.product.name_for_attestation={config['ProductNameForAttestation']}")
165 if config["ProductDeviceForAttestation"]:
166 print(f"ro.product.device_for_attestation={config['ProductDeviceForAttestation']}")
167 if config["ProductManufacturerForAttestation"]:
168 print(f"ro.product.manufacturer_for_attestation={config['ProductManufacturerForAttestation']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900169
170 if config["ZygoteForce64"]:
171 if partition == "vendor":
172 print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList64']}")
173 print(f"ro.{partition}.product.cpu.abilist32=")
174 print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
175 else:
176 if partition == "system" or partition == "vendor" or partition == "odm":
177 print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList']}")
178 print(f"ro.{partition}.product.cpu.abilist32={config['DeviceAbiList32']}")
179 print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
180
181 print(f"ro.{partition}.build.date={config['Date']}")
182 print(f"ro.{partition}.build.date.utc={config['DateUtc']}")
183 # Allow optional assignments for ARC forward-declarations (b/249168657)
184 # TODO: Remove any tag-related inconsistencies once the goals from
185 # go/arc-android-sigprop-changes have been achieved.
186 print(f"ro.{partition}.build.fingerprint?={config['BuildFingerprint']}")
187 print(f"ro.{partition}.build.id?={config['BuildId']}")
188 print(f"ro.{partition}.build.tags?={config['BuildVersionTags']}")
189 print(f"ro.{partition}.build.type={config['BuildVariant']}")
190 print(f"ro.{partition}.build.version.incremental={config['BuildNumber']}")
191 print(f"ro.{partition}.build.version.release={config['Platform_version_last_stable']}")
192 print(f"ro.{partition}.build.version.release_or_codename={config['Platform_version_name']}")
193 print(f"ro.{partition}.build.version.sdk={config['Platform_sdk_version']}")
MÃ¥rten Kongstad035cfb12024-12-20 10:27:36 +0100194 print(f"ro.{partition}.build.version.sdk_full={config['Platform_sdk_version_full']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900195
196def generate_build_info(args):
197 print()
198 print("####################################")
199 print("# from gen_build_prop.py:generate_build_info")
200 print("####################################")
201 print("# begin build properties")
202
203 config = args.config
204 build_flags = config["BuildFlags"]
205
Michael Bestas982a5042024-10-17 06:10:07 +0300206 print(f"ro.build.fingerprint?={config['BuildFingerprint']}")
207
Inseob Kimbac07552024-06-18 11:09:12 +0900208 # The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
209 if config["BoardUseVbmetaDigestInFingerprint"]:
210 print(f"ro.build.legacy.id={config['BuildId']}")
211 else:
212 print(f"ro.build.id?={config['BuildId']}")
213
214 # ro.build.display.id is shown under Settings -> About Phone
215 if config["BuildVariant"] == "user":
216 # User builds should show:
217 # release build number or branch.buld_number non-release builds
218
219 # Dev. branches should have DISPLAY_BUILD_NUMBER set
220 if config["DisplayBuildNumber"]:
Inseob Kim643157d2024-07-19 09:25:38 +0900221 print(f"ro.build.display.id?={config['BuildId']}.{config['BuildNumber']} {config['BuildKeys']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900222 else:
223 print(f"ro.build.display.id?={config['BuildId']} {config['BuildKeys']}")
224 else:
225 # Non-user builds should show detailed build information (See build desc above)
basamaryan4baf3062024-10-22 12:08:07 -0400226 print(f"ro.build.display.id?={config['OmniRomDesc']}")
Inseob Kim2da72af2024-06-18 11:09:12 +0900227 print(f"ro.build.display.id?={config['BuildDesc']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900228 print(f"ro.build.version.incremental={config['BuildNumber']}")
229 print(f"ro.build.version.sdk={config['Platform_sdk_version']}")
MÃ¥rten Kongstad035cfb12024-12-20 10:27:36 +0100230 print(f"ro.build.version.sdk_full={config['Platform_sdk_version_full']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900231 print(f"ro.build.version.preview_sdk={config['Platform_preview_sdk_version']}")
232 print(f"ro.build.version.preview_sdk_fingerprint={config['PlatformPreviewSdkFingerprint']}")
233 print(f"ro.build.version.codename={config['Platform_sdk_codename']}")
234 print(f"ro.build.version.all_codenames={','.join(config['Platform_version_active_codenames'])}")
235 print(f"ro.build.version.known_codenames={config['Platform_version_known_codenames']}")
236 print(f"ro.build.version.release={config['Platform_version_last_stable']}")
237 print(f"ro.build.version.release_or_codename={config['Platform_version_name']}")
238 print(f"ro.build.version.release_or_preview_display={config['Platform_display_version_name']}")
239 print(f"ro.build.version.security_patch={config['Platform_security_patch']}")
240 print(f"ro.build.version.base_os={config['Platform_base_os']}")
241 print(f"ro.build.version.min_supported_target_sdk={build_flags['RELEASE_PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION']}")
242 print(f"ro.build.date={config['Date']}")
243 print(f"ro.build.date.utc={config['DateUtc']}")
244 print(f"ro.build.type={config['BuildVariant']}")
245 print(f"ro.build.user={config['BuildUsername']}")
246 print(f"ro.build.host={config['BuildHostname']}")
247 # TODO: Remove any tag-related optional property declarations once the goals
248 # from go/arc-android-sigprop-changes have been achieved.
249 print(f"ro.build.tags?={config['BuildVersionTags']}")
250 # ro.build.flavor are used only by the test harness to distinguish builds.
251 # Only add _asan for a sanitized build if it isn't already a part of the
252 # flavor (via a dedicated lunch config for example).
253 print(f"ro.build.flavor={config['BuildFlavor']}")
254
Michael Bestasbcfcf762024-10-20 07:20:42 +0300255 print(f"ro.omni.device={config['OmniRomDevice']}")
256
Inseob Kimbac07552024-06-18 11:09:12 +0900257 # These values are deprecated, use "ro.product.cpu.abilist"
258 # instead (see below).
259 print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
260 print(f"# use ro.product.cpu.abilist instead.")
261 print(f"ro.product.cpu.abi={config['DeviceAbi'][0]}")
262 if len(config["DeviceAbi"]) > 1:
263 print(f"ro.product.cpu.abi2={config['DeviceAbi'][1]}")
264
265 if config["ProductLocales"]:
266 print(f"ro.product.locale={config['ProductLocales'][0]}")
267 print(f"ro.wifi.channels={' '.join(config['ProductDefaultWifiChannels'])}")
268
269 print(f"# ro.build.product is obsolete; use ro.product.device")
270 print(f"ro.build.product={config['DeviceName']}")
271
272 print(f"# Do not try to parse description or thumbprint")
273 print(f"ro.build.description?={config['BuildDesc']}")
Inseob Kim1d052472024-07-31 07:58:23 +0900274 if "BuildThumbprint" in config:
Inseob Kimbac07552024-06-18 11:09:12 +0900275 print(f"ro.build.thumbprint={config['BuildThumbprint']}")
276
277 print(f"# end build properties")
278
279def write_properties_from_file(file):
Spandan Das301c2302024-12-12 23:40:52 +0000280 # Make and Soong use different intermediate files to build vendor/build.prop.
281 # Although the sysprop contents are same, the absolute paths of these
282 # intermediate files are different.
283 # Print the filename for the intermediate files (files in OUT_DIR).
284 # This helps with validating mk->soong migration of android partitions.
285 filename = os.path.basename(file.name) if file.name.startswith(os.environ.get("OUT_DIR")) else file.name
Inseob Kimbac07552024-06-18 11:09:12 +0900286 print()
287 print("####################################")
Spandan Das301c2302024-12-12 23:40:52 +0000288 print(f"# from {filename}")
Inseob Kimbac07552024-06-18 11:09:12 +0900289 print("####################################")
290 print(file.read(), end="")
291
292def write_properties_from_variable(name, props, build_broken_dup_sysprop):
293 print()
294 print("####################################")
295 print(f"# from variable {name}")
296 print("####################################")
297
298 # Implement the legacy behavior when BUILD_BROKEN_DUP_SYSPROP is on.
299 # Optional assignments are all converted to normal assignments and
300 # when their duplicates the first one wins.
301 if build_broken_dup_sysprop:
302 processed_props = []
303 seen_props = set()
304 for line in props:
305 line = line.replace("?=", "=")
306 key, value = line.split("=", 1)
307 if key in seen_props:
308 continue
309 seen_props.add(key)
310 processed_props.append(line)
311 props = processed_props
312
313 for line in props:
314 print(line)
315
316def append_additional_system_props(args):
317 props = []
318
319 config = args.config
320
321 # Add the product-defined properties to the build properties.
Inseob Kim4a363392024-07-31 02:09:34 +0000322 if not config["PropertySplitEnabled"] or not config["VendorImageFileSystemType"]:
Inseob Kimbac07552024-06-18 11:09:12 +0900323 if "PRODUCT_PROPERTY_OVERRIDES" in config:
324 props += config["PRODUCT_PROPERTY_OVERRIDES"]
325
326 props.append(f"ro.treble.enabled={'true' if config['FullTreble'] else 'false'}")
327 # Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK
328 # in the system partition supports.
329 if config["VendorApiLevel"]:
330 props.append(f"ro.llndk.api_level={config['VendorApiLevel']}")
331
332 # Sets ro.actionable_compatible_property.enabled to know on runtime whether
333 # the allowed list of actionable compatible properties is enabled or not.
334 props.append("ro.actionable_compatible_property.enabled=true")
335
336 # Enable core platform API violation warnings on userdebug and eng builds.
337 if config["BuildVariant"] != "user":
338 props.append("persist.debug.dalvik.vm.core_platform_api_policy=just-warn")
339
340 # Define ro.sanitize.<name> properties for all global sanitizers.
341 for sanitize_target in config["SanitizeDevice"]:
342 props.append(f"ro.sanitize.{sanitize_target}=true")
343
344 # Sets the default value of ro.postinstall.fstab.prefix to /system.
Bowgo Tsai027601a2025-01-15 02:55:14 -0800345 #
346 # Device board configs can override this to /product to use a
347 # product-specific fstab.postinstall file (installed to
348 # /product/etc/fstab.postinstall). If not overridden, the
349 # system/extras/cppreopts/fstab.postinstall file (installed to
350 # /system/etc/fstab.postinstall) will be used.
351 # Note: The default fstab.postinstall is generic and may be slower
352 # because it tries different mount options line by line to ensure
353 # compatibility across various devices.
Inseob Kimbac07552024-06-18 11:09:12 +0900354 #
355 # PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
356 #
357 # It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to
358 # mount system_other partition.
359 props.append("ro.postinstall.fstab.prefix=/system")
360
361 enable_target_debugging = True
Inseob Kim4a363392024-07-31 02:09:34 +0000362 enable_dalvik_lock_contention_logging = True
Inseob Kimbac07552024-06-18 11:09:12 +0900363 if config["BuildVariant"] == "user" or config["BuildVariant"] == "userdebug":
364 # Target is secure in user builds.
365 props.append("ro.secure=1")
366 props.append("security.perf_harden=1")
367
368 if config["BuildVariant"] == "user":
369 # Disable debugging in plain user builds.
370 props.append("ro.adb.secure=1")
371 enable_target_debugging = False
Inseob Kim4a363392024-07-31 02:09:34 +0000372 enable_dalvik_lock_contention_logging = False
373 else:
374 # Disable debugging in userdebug builds if PRODUCT_NOT_DEBUGGABLE_IN_USERDEBUG
375 # is set.
376 if config["ProductNotDebuggableInUserdebug"]:
377 enable_target_debugging = False
Inseob Kimbac07552024-06-18 11:09:12 +0900378
379 # Disallow mock locations by default for user builds
380 props.append("ro.allow.mock.location=0")
381 else:
382 # Turn on checkjni for non-user builds.
383 props.append("ro.kernel.android.checkjni=1")
384 # Set device insecure for non-user builds.
385 props.append("ro.secure=0")
386 # Allow mock locations by default for non user builds
387 props.append("ro.allow.mock.location=1")
388
Inseob Kim4a363392024-07-31 02:09:34 +0000389 if enable_dalvik_lock_contention_logging:
Inseob Kimbac07552024-06-18 11:09:12 +0900390 # Enable Dalvik lock contention logging.
391 props.append("dalvik.vm.lockprof.threshold=500")
392
Inseob Kim4a363392024-07-31 02:09:34 +0000393 if enable_target_debugging:
Inseob Kimbac07552024-06-18 11:09:12 +0900394 # Target is more debuggable and adbd is on by default
395 props.append("ro.debuggable=1")
396 else:
397 # Target is less debuggable and adbd is off by default
398 props.append("ro.debuggable=0")
399
400 if config["BuildVariant"] == "eng":
401 if "ro.setupwizard.mode=ENABLED" in props:
402 # Don't require the setup wizard on eng builds
403 props = list(filter(lambda x: not x.startswith("ro.setupwizard.mode="), props))
404 props.append("ro.setupwizard.mode=OPTIONAL")
405
Inseob Kimbac07552024-06-18 11:09:12 +0900406 # b/323566535
407 props.append("init.svc_debug.no_fatal.zygote=true")
408
409 if config["SdkBuild"]:
410 props.append("xmpp.auto-presence=true")
411 props.append("ro.config.nocheckin=yes")
412
413 props.append("net.bt.name=Android")
414
415 # This property is set by flashing debug boot image, so default to false.
416 props.append("ro.force.debuggable=0")
417
418 config["ADDITIONAL_SYSTEM_PROPERTIES"] = props
419
420def append_additional_vendor_props(args):
421 props = []
422
423 config = args.config
424 build_flags = config["BuildFlags"]
425
426 # Add cpu properties for bionic and ART.
427 props.append(f"ro.bionic.arch={config['DeviceArch']}")
428 props.append(f"ro.bionic.cpu_variant={config['DeviceCpuVariantRuntime']}")
429 props.append(f"ro.bionic.2nd_arch={config['DeviceSecondaryArch']}")
430 props.append(f"ro.bionic.2nd_cpu_variant={config['DeviceSecondaryCpuVariantRuntime']}")
431
432 props.append(f"persist.sys.dalvik.vm.lib.2=libart.so")
433 props.append(f"dalvik.vm.isa.{config['DeviceArch']}.variant={config['Dex2oatTargetCpuVariantRuntime']}")
434 if config["Dex2oatTargetInstructionSetFeatures"]:
435 props.append(f"dalvik.vm.isa.{config['DeviceArch']}.features={config['Dex2oatTargetInstructionSetFeatures']}")
436
437 if config["DeviceSecondaryArch"]:
438 props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.variant={config['SecondaryDex2oatCpuVariantRuntime']}")
439 if config["SecondaryDex2oatInstructionSetFeatures"]:
440 props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.features={config['SecondaryDex2oatInstructionSetFeatures']}")
441
442 # Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger
443 # mode (via libminui).
444 if config["RecoveryDefaultRotation"]:
445 props.append(f"ro.minui.default_rotation={config['RecoveryDefaultRotation']}")
446
447 if config["RecoveryOverscanPercent"]:
448 props.append(f"ro.minui.overscan_percent={config['RecoveryOverscanPercent']}")
449
450 if config["RecoveryPixelFormat"]:
451 props.append(f"ro.minui.pixel_format={config['RecoveryPixelFormat']}")
452
453 if "UseDynamicPartitions" in config:
454 props.append(f"ro.boot.dynamic_partitions={'true' if config['UseDynamicPartitions'] else 'false'}")
455
456 if "RetrofitDynamicPartitions" in config:
457 props.append(f"ro.boot.dynamic_partitions_retrofit={'true' if config['RetrofitDynamicPartitions'] else 'false'}")
458
459 if config["ShippingApiLevel"]:
460 props.append(f"ro.product.first_api_level={config['ShippingApiLevel']}")
461
462 if config["ShippingVendorApiLevel"]:
463 props.append(f"ro.vendor.api_level={config['ShippingVendorApiLevel']}")
464
465 if config["BuildVariant"] != "user" and config["BuildDebugfsRestrictionsEnabled"]:
466 props.append(f"ro.product.debugfs_restrictions.enabled=true")
467
468 # Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
469 # This must not be defined for the non-GRF devices.
470 # The values of the GRF properties will be verified by post_process_props.py
471 if config["BoardShippingApiLevel"]:
Inseob Kim4a363392024-07-31 02:09:34 +0000472 props.append(f"ro.board.first_api_level={config['BoardShippingApiLevel']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900473
474 # Build system set BOARD_API_LEVEL to show the api level of the vendor API surface.
475 # This must not be altered outside of build system.
476 if config["VendorApiLevel"]:
Justin Yun3f84f6e2024-10-24 09:20:48 +0900477 props.append(f"ro.board.api_level?={config['VendorApiLevel']}")
478 if config["VendorApiLevelPropOverride"]:
479 props.append(f"ro.board.api_level={config['VendorApiLevelPropOverride']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900480
481 # RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen.
482 if build_flags["RELEASE_BOARD_API_LEVEL_FROZEN"]:
483 props.append(f"ro.board.api_frozen=true")
484
485 # Set build prop. This prop is read by ota_from_target_files when generating OTA,
486 # to decide if VABC should be disabled.
487 if config["DontUseVabcOta"]:
488 props.append(f"ro.vendor.build.dont_use_vabc=true")
489
490 # Set the flag in vendor. So VTS would know if the new fingerprint format is in use when
491 # the system images are replaced by GSI.
492 if config["BoardUseVbmetaDigestInFingerprint"]:
493 props.append(f"ro.vendor.build.fingerprint_has_digest=1")
494
495 props.append(f"ro.vendor.build.security_patch={config['VendorSecurityPatch']}")
496 props.append(f"ro.product.board={config['BootloaderBoardName']}")
497 props.append(f"ro.board.platform={config['BoardPlatform']}")
Spandan Das876c1c92024-12-06 20:37:05 +0000498 props.append(f"ro.hwui.use_vulkan={config['UsesVulkan']}")
Inseob Kimbac07552024-06-18 11:09:12 +0900499
500 if config["ScreenDensity"]:
501 props.append(f"ro.sf.lcd_density={config['ScreenDensity']}")
502
503 if "AbOtaUpdater" in config:
504 props.append(f"ro.build.ab_update={'true' if config['AbOtaUpdater'] else 'false'}")
505 if config["AbOtaUpdater"]:
506 props.append(f"ro.vendor.build.ab_ota_partitions={config['AbOtaPartitions']}")
507
508 config["ADDITIONAL_VENDOR_PROPERTIES"] = props
509
510def append_additional_product_props(args):
511 props = []
512
513 config = args.config
514
515 # Add the system server compiler filter if they are specified for the product.
516 if config["SystemServerCompilerFilter"]:
517 props.append(f"dalvik.vm.systemservercompilerfilter={config['SystemServerCompilerFilter']}")
518
519 # Add the 16K developer args if it is defined for the product.
520 props.append(f"ro.product.build.16k_page.enabled={'true' if config['Product16KDeveloperOption'] else 'false'}")
521
Inseob Kim6b3ec752024-08-08 17:47:14 +0900522 props.append(f"ro.product.page_size={16384 if config['TargetBoots16K'] else 4096}")
523
Inseob Kimbac07552024-06-18 11:09:12 +0900524 props.append(f"ro.build.characteristics={config['AAPTCharacteristics']}")
525
526 if "AbOtaUpdater" in config and config["AbOtaUpdater"]:
527 props.append(f"ro.product.ab_ota_partitions={config['AbOtaPartitions']}")
528
529 # Set this property for VTS to skip large page size tests on unsupported devices.
530 props.append(f"ro.product.cpu.pagesize.max={config['DeviceMaxPageSizeSupported']}")
531
532 if config["NoBionicPageSizeMacro"]:
533 props.append(f"ro.product.build.no_bionic_page_size_macro=true")
534
Inseob Kim4a363392024-07-31 02:09:34 +0000535 # This is a temporary system property that controls the ART module. The plan is
536 # to remove it by Aug 2025, at which time Mainline updates of the ART module
537 # will ignore it as well.
Inseob Kimbac07552024-06-18 11:09:12 +0900538 # If the value is "default", it will be mangled by post_process_props.py.
539 props.append(f"ro.dalvik.vm.enable_uffd_gc={config['EnableUffdGc']}")
540
541 config["ADDITIONAL_PRODUCT_PROPERTIES"] = props
542
543def build_system_prop(args):
544 config = args.config
545
546 # Order matters here. When there are duplicates, the last one wins.
547 # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
548 variables = [
549 "ADDITIONAL_SYSTEM_PROPERTIES",
550 "PRODUCT_SYSTEM_PROPERTIES",
551 # TODO(b/117892318): deprecate this
552 "PRODUCT_SYSTEM_DEFAULT_PROPERTIES",
553 ]
554
555 if not config["PropertySplitEnabled"]:
556 variables += [
557 "ADDITIONAL_VENDOR_PROPERTIES",
558 "PRODUCT_VENDOR_PROPERTIES",
559 ]
560
561 build_prop(args, gen_build_info=True, gen_common_build_props=True, variables=variables)
562
Inseob Kimaaf72f22024-08-05 12:51:05 +0900563def build_system_ext_prop(args):
564 config = args.config
565
566 # Order matters here. When there are duplicates, the last one wins.
567 # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
568 variables = ["PRODUCT_SYSTEM_EXT_PROPERTIES"]
569
570 build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
571
Inseob Kimbac07552024-06-18 11:09:12 +0900572def build_vendor_prop(args):
573 config = args.config
574
575 # Order matters here. When there are duplicates, the last one wins.
576 # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
577 variables = []
578 if config["PropertySplitEnabled"]:
579 variables += [
580 "ADDITIONAL_VENDOR_PROPERTIES",
581 "PRODUCT_VENDOR_PROPERTIES",
582 # TODO(b/117892318): deprecate this
583 "PRODUCT_DEFAULT_PROPERTY_OVERRIDES",
584 "PRODUCT_PROPERTY_OVERRIDES",
585 ]
586
587 build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
588
589def build_product_prop(args):
590 config = args.config
591
592 # Order matters here. When there are duplicates, the last one wins.
593 # TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
594 variables = [
595 "ADDITIONAL_PRODUCT_PROPERTIES",
micky387c7f7c0d2024-11-09 17:57:43 -0500596 "OMNI_PRODUCT_PROPERTIES",
Inseob Kimbac07552024-06-18 11:09:12 +0900597 "PRODUCT_PRODUCT_PROPERTIES",
598 ]
Inseob Kim6b3ec752024-08-08 17:47:14 +0900599
600 gen_common_build_props = True
601
602 # Skip common /product properties generation if device released before R and
603 # has no product partition. This is the first part of the check.
604 if config["Shipping_api_level"] and int(config["Shipping_api_level"]) < 30:
605 gen_common_build_props = False
606
607 # The second part of the check - always generate common properties for the
608 # devices with product partition regardless of shipping level.
609 if config["UsesProductImage"]:
610 gen_common_build_props = True
611
Inseob Kimbac07552024-06-18 11:09:12 +0900612 build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
Inseob Kim6b3ec752024-08-08 17:47:14 +0900613
614 if config["OemProperties"]:
615 print("####################################")
616 print("# PRODUCT_OEM_PROPERTIES")
617 print("####################################")
618
619 for prop in config["OemProperties"]:
620 print(f"import /oem/oem.prop {prop}")
621
622def build_odm_prop(args):
623 variables = ["ADDITIONAL_ODM_PROPERTIES", "PRODUCT_ODM_PROPERTIES"]
624 build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
Inseob Kimbac07552024-06-18 11:09:12 +0900625
626def build_prop(args, gen_build_info, gen_common_build_props, variables):
627 config = args.config
628
629 if gen_common_build_props:
630 generate_common_build_props(args)
631
632 if gen_build_info:
633 generate_build_info(args)
634
635 for prop_file in args.prop_files:
636 write_properties_from_file(prop_file)
637
638 for variable in variables:
639 if variable in config:
640 write_properties_from_variable(variable, config[variable], args.build_broken_dup_sysprop)
641
642def main():
643 args = parse_args()
644
645 with contextlib.redirect_stdout(args.out):
Inseob Kim6b3ec752024-08-08 17:47:14 +0900646 match args.partition:
647 case "system":
648 build_system_prop(args)
649 case "system_ext":
650 build_system_ext_prop(args)
651 case "odm":
652 build_odm_prop(args)
653 case "product":
654 build_product_prop(args)
Spandan Das859cdef2024-10-25 21:06:18 +0000655 case "vendor":
656 build_vendor_prop(args)
Cole Faust4385d352024-11-12 15:13:37 -0800657 case "system_dlkm" | "vendor_dlkm" | "odm_dlkm" | "bootimage":
Spandan Dasb9cef3b2024-11-06 22:08:28 +0000658 build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=[])
Inseob Kim6b3ec752024-08-08 17:47:14 +0900659 case _:
660 sys.exit(f"not supported partition {args.partition}")
Inseob Kimbac07552024-06-18 11:09:12 +0900661
662if __name__ == "__main__":
663 main()