aboutsummaryrefslogtreecommitdiff
path: root/scripts/buildinfo.py
blob: e4fb0da09c012f3a828046789849f8bc71f17a53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/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 buildinfo.prop"""

import argparse
import contextlib
import subprocess

def parse_args():
  """Parse commandline arguments."""
  parser = argparse.ArgumentParser()
  parser.add_argument('--use-vbmeta-digest-in-fingerprint', action='store_true')
  parser.add_argument('--build-flavor', required=True)
  parser.add_argument('--build-hostname-file', required=True, type=argparse.FileType('r')),
  parser.add_argument('--build-id', required=True)
  parser.add_argument('--build-keys', required=True)
  parser.add_argument('--build-number-file', required=True, type=argparse.FileType('r'))
  parser.add_argument('--build-thumbprint-file', type=argparse.FileType('r'))
  parser.add_argument('--build-type', required=True)
  parser.add_argument('--build-username', required=True)
  parser.add_argument('--build-variant', required=True)
  parser.add_argument('--cpu-abis', action='append', required=True)
  parser.add_argument('--date-file', required=True, type=argparse.FileType('r'))
  parser.add_argument('--default-locale')
  parser.add_argument('--default-wifi-channels', action='append', default=[])
  parser.add_argument('--device', required=True)
  parser.add_argument("--display-build-number", action='store_true')
  parser.add_argument('--platform-base-os', required=True)
  parser.add_argument('--platform-display-version', required=True)
  parser.add_argument('--platform-min-supported-target-sdk-version', required=True)
  parser.add_argument('--platform-preview-sdk-fingerprint-file',
                      required=True,
                      type=argparse.FileType('r'))
  parser.add_argument('--platform-preview-sdk-version', required=True)
  parser.add_argument('--platform-sdk-version', required=True)
  parser.add_argument('--platform-security-patch', required=True)
  parser.add_argument('--platform-version', required=True)
  parser.add_argument('--platform-version-codename',required=True)
  parser.add_argument('--platform-version-all-codenames', action='append', required=True)
  parser.add_argument('--platform-version-known-codenames', required=True)
  parser.add_argument('--platform-version-last-stable', required=True)
  parser.add_argument('--product', required=True)

  parser.add_argument('--out', required=True, type=argparse.FileType('w'))

  return parser.parse_args()

def main():
  option = parse_args()

  build_hostname = option.build_hostname_file.read().strip()
  build_number = option.build_number_file.read().strip()
  build_version_tags = option.build_keys
  if option.build_type == "debug":
    build_version_tags = "debug," + build_version_tags

  raw_date = option.date_file.read().strip()
  date = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip()
  date_utc = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip()

  # 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"
  build_desc = f"{option.product}-{option.build_variant} {option.platform_version} " \
               f"{option.build_id} {build_number} {build_version_tags}"

  platform_preview_sdk_fingerprint = option.platform_preview_sdk_fingerprint_file.read().strip()

  with contextlib.redirect_stdout(option.out):
    print("# begin build properties")
    print("# autogenerated by buildinfo.py")

    # The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
    if option.use_vbmeta_digest_in_fingerprint:
      print(f"ro.build.legacy.id={option.build_id}")
    else:
      print(f"ro.build.id?={option.build_id}")

    # ro.build.display.id is shown under Settings -> About Phone
    if option.build_variant == "user":
      # User builds should show:
      # release build number or branch.buld_number non-release builds

      # Dev. branches should have DISPLAY_BUILD_NUMBER set
      if option.display_build_number:
        print(f"ro.build.display.id?={option.build_id} {build_number} {option.build_keys}")
      else:
        print(f"ro.build.display.id?={option.build_id} {option.build_keys}")
    else:
      # Non-user builds should show detailed build information (See build desc above)
      print(f"ro.build.display.id?={build_desc}")
    print(f"ro.build.version.incremental={build_number}")
    print(f"ro.build.version.sdk={option.platform_sdk_version}")
    print(f"ro.build.version.preview_sdk={option.platform_preview_sdk_version}")
    print(f"ro.build.version.preview_sdk_fingerprint={platform_preview_sdk_fingerprint}")
    print(f"ro.build.version.codename={option.platform_version_codename}")
    print(f"ro.build.version.all_codenames={','.join(option.platform_version_all_codenames)}")
    print(f"ro.build.version.known_codenames={option.platform_version_known_codenames}")
    print(f"ro.build.version.release={option.platform_version_last_stable}")
    print(f"ro.build.version.release_or_codename={option.platform_version}")
    print(f"ro.build.version.release_or_preview_display={option.platform_display_version}")
    print(f"ro.build.version.security_patch={option.platform_security_patch}")
    print(f"ro.build.version.base_os={option.platform_base_os}")
    print(f"ro.build.version.min_supported_target_sdk={option.platform_min_supported_target_sdk_version}")
    print(f"ro.build.date={date}")
    print(f"ro.build.date.utc={date_utc}")
    print(f"ro.build.type={option.build_variant}")
    print(f"ro.build.user={option.build_username}")
    print(f"ro.build.host={build_hostname}")
    # 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?={build_version_tags}")
    # 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={option.build_flavor}")

    # 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={option.cpu_abis[0]}")
    if len(option.cpu_abis) > 1:
      print(f"ro.product.cpu.abi2={option.cpu_abis[1]}")

    if option.default_locale:
      print(f"ro.product.locale={option.default_locale}")
    print(f"ro.wifi.channels={' '.join(option.default_wifi_channels)}")

    print(f"# ro.build.product is obsolete; use ro.product.device")
    print(f"ro.build.product={option.device}")

    print(f"# Do not try to parse description or thumbprint")
    print(f"ro.build.description?={build_desc}")
    if option.build_thumbprint_file:
      build_thumbprint = option.build_thumbprint_file.read().strip()
      print(f"ro.build.thumbprint={build_thumbprint}")

    print(f"# end build properties")

if __name__ == "__main__":
  main()