1#!/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 buildinfo.prop""" 18 19import argparse 20import contextlib 21import subprocess 22 23def parse_args(): 24 """Parse commandline arguments.""" 25 parser = argparse.ArgumentParser() 26 parser.add_argument('--use-vbmeta-digest-in-fingerprint', action='store_true') 27 parser.add_argument('--build-flavor', required=True) 28 parser.add_argument('--build-hostname-file', required=True, type=argparse.FileType('r')), 29 parser.add_argument('--build-id', required=True) 30 parser.add_argument('--build-keys', required=True) 31 parser.add_argument('--build-number-file', required=True, type=argparse.FileType('r')) 32 parser.add_argument('--build-thumbprint-file', type=argparse.FileType('r')) 33 parser.add_argument('--build-type', required=True) 34 parser.add_argument('--build-username', required=True) 35 parser.add_argument('--build-variant', required=True) 36 parser.add_argument('--cpu-abis', action='append', required=True) 37 parser.add_argument('--date-file', required=True, type=argparse.FileType('r')) 38 parser.add_argument('--default-locale') 39 parser.add_argument('--default-wifi-channels', action='append', default=[]) 40 parser.add_argument('--device', required=True) 41 parser.add_argument("--display-build-number", action='store_true') 42 parser.add_argument('--platform-base-os', required=True) 43 parser.add_argument('--platform-display-version', required=True) 44 parser.add_argument('--platform-min-supported-target-sdk-version', required=True) 45 parser.add_argument('--platform-preview-sdk-fingerprint-file', 46 required=True, 47 type=argparse.FileType('r')) 48 parser.add_argument('--platform-preview-sdk-version', required=True) 49 parser.add_argument('--platform-sdk-version', required=True) 50 parser.add_argument('--platform-security-patch', required=True) 51 parser.add_argument('--platform-version', required=True) 52 parser.add_argument('--platform-version-codename',required=True) 53 parser.add_argument('--platform-version-all-codenames', action='append', required=True) 54 parser.add_argument('--platform-version-known-codenames', required=True) 55 parser.add_argument('--platform-version-last-stable', required=True) 56 parser.add_argument('--product', required=True) 57 58 parser.add_argument('--out', required=True, type=argparse.FileType('w')) 59 60 return parser.parse_args() 61 62def main(): 63 option = parse_args() 64 65 build_hostname = option.build_hostname_file.read().strip() 66 build_number = option.build_number_file.read().strip() 67 build_version_tags = option.build_keys 68 if option.build_type == "debug": 69 build_version_tags = "debug," + build_version_tags 70 71 raw_date = option.date_file.read().strip() 72 date = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip() 73 date_utc = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip() 74 75 # build_desc is human readable strings that describe this build. This has the same info as the 76 # build fingerprint. 77 # e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys" 78 build_desc = f"{option.product}-{option.build_variant} {option.platform_version} " \ 79 f"{option.build_id} {build_number} {build_version_tags}" 80 81 platform_preview_sdk_fingerprint = option.platform_preview_sdk_fingerprint_file.read().strip() 82 83 with contextlib.redirect_stdout(option.out): 84 print("# begin build properties") 85 print("# autogenerated by buildinfo.py") 86 87 # The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest. 88 if option.use_vbmeta_digest_in_fingerprint: 89 print(f"ro.build.legacy.id={option.build_id}") 90 else: 91 print(f"ro.build.id?={option.build_id}") 92 93 # ro.build.display.id is shown under Settings -> About Phone 94 if option.build_variant == "user": 95 # User builds should show: 96 # release build number or branch.buld_number non-release builds 97 98 # Dev. branches should have DISPLAY_BUILD_NUMBER set 99 if option.display_build_number: 100 print(f"ro.build.display.id?={option.build_id}.{build_number} {option.build_keys}") 101 else: 102 print(f"ro.build.display.id?={option.build_id} {option.build_keys}") 103 else: 104 # Non-user builds should show detailed build information (See build desc above) 105 print(f"ro.build.display.id?={build_desc}") 106 print(f"ro.build.version.incremental={build_number}") 107 print(f"ro.build.version.sdk={option.platform_sdk_version}") 108 print(f"ro.build.version.preview_sdk={option.platform_preview_sdk_version}") 109 print(f"ro.build.version.preview_sdk_fingerprint={platform_preview_sdk_fingerprint}") 110 print(f"ro.build.version.codename={option.platform_version_codename}") 111 print(f"ro.build.version.all_codenames={','.join(option.platform_version_all_codenames)}") 112 print(f"ro.build.version.known_codenames={option.platform_version_known_codenames}") 113 print(f"ro.build.version.release={option.platform_version_last_stable}") 114 print(f"ro.build.version.release_or_codename={option.platform_version}") 115 print(f"ro.build.version.release_or_preview_display={option.platform_display_version}") 116 print(f"ro.build.version.security_patch={option.platform_security_patch}") 117 print(f"ro.build.version.base_os={option.platform_base_os}") 118 print(f"ro.build.version.min_supported_target_sdk={option.platform_min_supported_target_sdk_version}") 119 print(f"ro.build.date={date}") 120 print(f"ro.build.date.utc={date_utc}") 121 print(f"ro.build.type={option.build_variant}") 122 print(f"ro.build.user={option.build_username}") 123 print(f"ro.build.host={build_hostname}") 124 # TODO: Remove any tag-related optional property declarations once the goals 125 # from go/arc-android-sigprop-changes have been achieved. 126 print(f"ro.build.tags?={build_version_tags}") 127 # ro.build.flavor are used only by the test harness to distinguish builds. 128 # Only add _asan for a sanitized build if it isn't already a part of the 129 # flavor (via a dedicated lunch config for example). 130 print(f"ro.build.flavor={option.build_flavor}") 131 132 # These values are deprecated, use "ro.product.cpu.abilist" 133 # instead (see below). 134 print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,") 135 print(f"# use ro.product.cpu.abilist instead.") 136 print(f"ro.product.cpu.abi={option.cpu_abis[0]}") 137 if len(option.cpu_abis) > 1: 138 print(f"ro.product.cpu.abi2={option.cpu_abis[1]}") 139 140 if option.default_locale: 141 print(f"ro.product.locale={option.default_locale}") 142 print(f"ro.wifi.channels={' '.join(option.default_wifi_channels)}") 143 144 print(f"# ro.build.product is obsolete; use ro.product.device") 145 print(f"ro.build.product={option.device}") 146 147 print(f"# Do not try to parse description or thumbprint") 148 print(f"ro.build.description?={build_desc}") 149 if option.build_thumbprint_file: 150 build_thumbprint = option.build_thumbprint_file.read().strip() 151 print(f"ro.build.thumbprint={build_thumbprint}") 152 153 print(f"# end build properties") 154 155if __name__ == "__main__": 156 main() 157